使用ffmpeg生成I帧

背景

====

    我使用旧版的ffmpeg做转码, 但是apiexample.c不能解最新版ffmpeg的生成的mpeg1video, 虽然其他工具生成的可以。于是我想搞清楚是啥回事。


另一工具生成正常的可以解码:
$ ./apiexample.exe aaa.mpeg
Video decoding
fill_buffer 31505
code 1b3        code 1b8        code 100        code 101        code 1b7        mb 44/45 32/33    code 1b7        
fill_buffer 0
xxsaving frame   0 linesze 752 376 376

ffmpeg 生成的不能解:
$ ./apiexample.exe huo.mpg
Video decoding
fill_buffer 30673
code 1b3        code 1b8        code 100        code 101        code 10e        mb 49/50 12/38    code 11a        mb 49/50 24/38  code ffffffff   
fill_buffer 0

1. "code ffffffff" 表示code=-1没有找到形如0x00 00 01 xx的起始码。xx=
b3 -- sequence header, b8 -- group start, 00 -- picture start, 01-af slice start, b7 -- sequence end

2. 注意到slice多一个,我以为slice不能多,ffmpeg 我加上-slices 1 也不行,也试过 -g 0 都不行。
 
3. 观察上面的执行序列,第一个slice start 并没有立即mb, 而是接着遇到起始码才mb。
即每个slice start 的mb解码在该slice内容结束(即再次遇到起始码时)才开始。
仔细阅读代码,发现libavcodec 对于输入, 内部缓存,只有找到下一个起始码才开始:
 input_size = s->buf_ptr - s->buffer;
 mpeg_decode_slice(avctx, picture, start_code, s->buffer, input_size);

ffmpeg 追加结束码可以解码:
$ ./apiexample.exe huo.mpg
Video decoding
fill_buffer 30677
code 1b3        code 1b8        code 100        code 101        code 10e        mb 49/50 12/38    code 11a        mb 49/50 24/38  code 1b7        mb 49/50 37/38  
fill_buffer 0
xxsaving frame   0 linesze 832 416 416

旧版移植代码加上:

	{/*a raw mpeg1 video frame generated by:
	    ffmpeg -i dragon.jpg  -f mpeg1video -y dragon.mpg
	  has no sequence end code, which will cause decode fail,	
	  so we append one here. --ludi 2014.08
	  */
		unsigned char seq_end_code[] = {0x00, 0x00, 0x01, 0xb7};
		memcpy(mpgbuf + mpglen, seq_end_code, sizeof(seq_end_code));
		mpglen += sizeof(seq_end_code);
	}

我试了最新的ffmpeg/decoding_encoding.c 是可以的,因为有ff_er_frame_end修复坏帧。于是尝试修改mpeg12.c 到现在10点, 无解

特此纪念!



你可能感兴趣的:(ffmpeg,Codec)