[Libav-user] mpeg4 decoding only decodes 36395 out of 154959 frames
Bob Self
bobslf at gmail.com
Fri May 11 11:12:39 CEST 2012
I finally found an incomplete example that I was able to get sort-of working
with non-deprecated functions. The only error (or warning?) that I get is
"[mpeg4 @ 0x1367c80] Invalid and inefficient vfw-avi packed B frames detected"
once. Other than that the program runs without errors, but there is still
something that I don't understand.
pFormatCtx->streams[videoStream]->nb_frames says that there are 154,959 frames
But if I count the decoded frames (frame++), I only get 36,395 frames
before the loop quits. Why does this happen?
the program output:
-------------------------------
[avi @ 0x1361920] Format avi probed with size=2048 and score=100
[AVI demuxer @ 0x1361e60] use odml:1
st:1 removing common factor 128 from timebase
[mpeg4 @ 0x1367c80] Invalid and inefficient vfw-avi packed B frames detected
[avi @ 0x1361920] All info found
Input #0, avi, from 'test.avi':
Metadata:
encoder : FairUse Wizard - http://fairusewizard.com
Duration: 01:47:43.08, start: 0.000000, bitrate: 1815 kb/s
Stream #0:0, 1, 1001/24000: Video: mpeg4 (Advanced Simple Profile)
(XVID / 0x44495658), yuv420p, 688x368 [SAR 1:1 DAR 43:23], 1001/24000,
23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #0:1, 21, 3/125: Audio: mp3 (U[0][0][0] / 0x0055), 48000
Hz, stereo, s16, 128 kb/s
the test function:
----------------------------
int test(void) {
const char *inputfile = "test.avi";
int totalFrames = 0;
int frameLocation = 0;
AVFormatContext *pFormatCtx;
unsigned int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameYUV;
int numBytes;
uint8_t *buffer;
int status;
unsigned int codec_version;
av_register_all();
codec_version = avcodec_version();
// avcodec version: 54.10.100
printf("avcodec version = %d.%d.%d\n",
(codec_version&0x00ff0000)>>16, (codec_version&0x0000ff00)>>8,
codec_version&0x000000ff); // version 52.72.2
av_log_set_level(AV_LOG_DEBUG);
pFormatCtx = avformat_alloc_context();
status = avformat_open_input(&pFormatCtx, inputfile, NULL, NULL);
if (status != 0) {
return -1;
}
status = avformat_find_stream_info(pFormatCtx, NULL);
if (status<0) {
return -2;
}
av_dump_format(pFormatCtx, 0, inputfile, false);
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++) {
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
}
if(videoStream==-1) {
return -3;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
double duration = double(pFormatCtx->duration) / AV_TIME_BASE;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
return -4;
}
if(pCodec->capabilities & CODEC_CAP_TRUNCATED) {
pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
}
if(avcodec_open2(pCodecCtx, pCodec, NULL)<0) {
return -5;
}
printf("Using codec: %s\n", pCodec->name);
pFrame = avcodec_alloc_frame();
pFrameYUV=avcodec_alloc_frame();
if(pFrameYUV==NULL) {
return -6;
}
numBytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width,
pCodecCtx->height); // 379776
buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P,
pCodecCtx->width, pCodecCtx->height);
totalFrames = pFormatCtx->streams[videoStream]->nb_frames;
// 154959
printf("Frames: %d\n", totalFrames);
AVPacket packet;
int isFrameFinished = 0;
int pixelScanCount = 0;
printf("video width = %d\n", pCodecCtx->width);
printf("video height = %d\n", pCodecCtx->height);
int frame = 0;
int loops = 0;
while (av_read_frame(pFormatCtx, &packet) >= 0) {
status = av_read_frame(pFormatCtx, &packet);
if (status<0) {
break;
}
loops++;
if (packet.stream_index == videoStream) {
status = avcodec_decode_video2(pCodecCtx, pFrame,
&isFrameFinished, &packet);
if (isFrameFinished) {
frame++;
if ( (frame%1000) == 0) {
printf("%d\n", frame);
}
pixelScanCount = 0;
for (int y = 0; y < pCodecCtx->height; y++) {
uint8_t *p = pFrame->data[0] + y * pFrame->linesize[0];
for (int x = 0; x < pCodecCtx->width; x++) {
pixelScanCount++;
}
}
av_free_packet(&packet);
}
else {
av_free_packet(&packet);
}
}
}
printf("frame = %d\n", frame); // frame = 36395
printf("loops = %d\n", loops); // loops = 212127
printf("totalFrames = %d\n", totalFrames); // totalFrames = 154959
delete [] buffer;
av_free(pFrameYUV);
av_free(pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
More information about the Libav-user
mailing list