
The Israeli hi-tech market inspired me...
My blog about stuff, work in the israeli high-tech industry, and programming.
void VideoThread::run() {Ok so I have a frame-grabber that emits a frameReady signal everytime the buffer is full and ready for painting.
/*
... Initialize libavformat & libavcodec data structures.
You can see it in the example i referred to before
*/
// Open video file
if(av_open_input_file(&pFormatCtx,
"lala.avi",
NULL, 0, NULL)!=0)
return -1; // Couldn't open file
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information
// Find the first video stream ...
// Get a pointer to the codec context for the video
// stream...
// Find the decoder for the video stream...
// Open codec...
// Allocate video frame
pFrame=avcodec_alloc_frame();
// Allocate an AVFrame structure
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1;
int dst_fmt = PIX_FMT_RGB24;
int dst_w = 160;
int dst_h = 120;
// Determine required buffer size and allocate buffer
numBytes = avpicture_get_size(dst_fmt, dst_w, dst_h);
buffer = new uint8_t[numBytes + 64];
//put a PPM header on the buffer
int headerlen = sprintf((char *) buffer,
"P6\n%d %d\n255\n",
dst_w, dst_h);
_v->buf = (uchar*)buffer;
_v->len = avpicture_get_size(dst_fmt,dst_w,dst_h) +
headerlen;
// Assign appropriate parts of buffer to image planes
// in pFrameRGB...
// I use libswscale to scale the frames to the required
// size.
// Setup the scaling context:
SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(
pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt,
dst_w, dst_h, dst_fmt,
SWS_BICUBIC, NULL, NULL, NULL);
// Read frames and notify
i=0;
while(av_read_frame(pFormatCtx, &packet)>=0)
{
// Is this a packet from the video stream?
if(packet.stream_index==videoStream)
{
// Decode video frame
avcodec_decode_video(pCodecCtx,
pFrame,
&frameFinished,
packet.data,
packet.size);
// Did we get a video frame?
if(frameFinished)
{
// Convert the image to RGB
sws_scale(img_convert_ctx,
pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize);
emit frameReady();
//My video is 5FPS so sleep for 200ms.
this->msleep(200);
}
}
// Free the packet that was allocated by
// av_read_frame
av_free_packet(&packet);
}
// Free the RGB image
delete [] buffer;
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
// Close the codec...
// Close the video file...
} //end VideoThread::run
void VideoWidget::paintEvent(QPaintEvent * e) {Two things to note:
QPainter painter(this);
if(buf) {
QImage i = QImage::fromData(buf,len,"PPM");
painter.drawImage(QPoint(0,0),i);
}
}
....And:
vt = new VideoThread();
connect(vt,SIGNAL(frameReady()),this,SLOT(updateVideoWidget()));
vt->start();
....
void playMessage::updateVideoWidget() {This will make the widget repaint on each frame ready.
videoWidget->repaint(); //or update().
}
delegate System::Void AlgProgressDelegate(unsigned int done, unsigned outOf);Meanwhile, back in my UI...
ref class Algorithm {
event AlgProgressDelegate^ AlgProgress;
public: void StartAlgorithm() {
...
AlgProgress(done, outOf);
...
}
}
public: System::Void OnProgress(unsigned int done,unsigned int outOf) {Of course I registered my form to recieve these events:
progressBar1->Maximum = outOf;
progressBar1->Value = done;
progressBar1->Invalidate();
if((done % 100) == 0) {
label4->Text = String::Format("{0}/{1}",done,outOf);
label4->Invalidate();
}
}
Algorithm a();Naively, I thought this would run perfectly, as I could see nothing wrong in the code, can you?
a.AlgProgress += gcnew AlgProgressDelegate(this, &Form1::OnProgress);


Now you can cut it up to fit your cow...