[FFmpeg-user] avcodec_decode_video2 question
Bob Self
bobslf at gmail.com
Fri Dec 16 16:47:29 CET 2011
I am trying to get the following program to work to simply get video frames
from an avi file. I will run through this outer loop for about 7000 times,
and
then crashes with an unhandled exception. I'm trying to get individual video
frames so I can display them with opengl. I have a VFW version working that
does that, but would like to switch to ffmpeg.
Is this the correct way to get frames from a video file?
thanks,
Bob
void test_ffmpeg(void) {
AVFormatContext *ic;
char fname[256];
int err;
AVCodec *codec=NULL;
AVCodecContext *codec_context = NULL;
FILE *stream=NULL;
AVFrame *picture=NULL;
int frame, got_picture, len;
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
char buf[1024];
AVPacket packet;
strcpy(fname, "test.avi");
avcodec_init();
avcodec_register_all();
av_init_packet(&packet);
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
codec = avcodec_find_decoder(CODEC_ID_MPEG4);
if (!codec) {
goto finis;
}
codec_context = avcodec_alloc_context();
picture = avcodec_alloc_frame();
codec_context->debug = FF_DEBUG_PICT_INFO;
if(codec->capabilities&CODEC_CAP_TRUNCATED) {
codec_context->flags|= CODEC_FLAG_TRUNCATED; // we do not send
complete frames
}
if (avcodec_open(codec_context, codec) < 0) {
bp = 3;
goto finis;
}
stream = fopen(fname, "rb");
if (!stream) {
goto finis;
}
frame = 0;
while(1) {
packet.size = fread(inbuf, 1, INBUF_SIZE, stream); // 4096
if (packet.size == 0) {
break;
}
packet.data = inbuf;
while (packet.size > 0) {
len = avcodec_decode_video2(codec_context, picture, &got_picture,
len ? &packet : NULL);
if (len < 0) {
// do what here?
}
if (got_picture) {
frame++;
}
else {
if (len<0) {
break;
}
}
packet.size -= len;
packet.data += len;
} // while (avpkt.size > 0) {
} // while(1) {
packet.data = NULL;
packet.size = 0;
len = avcodec_decode_video2(codec_context, picture, &got_picture,
&packet);
if (got_picture) {
frame++;
}
finis:
FCLOSE(stream);
if (codec_context) {
avcodec_close(codec_context);
av_free(codec_context);
codec_context = NULL;
}
if (picture) {
av_free(picture);
picture = NULL;
}
return;
} // test_ffmpeg()
More information about the ffmpeg-user
mailing list