最近学习ffmpeg,官网提供的示例代码transcoding.c演示了编解码和滤波器的使用,不过第一步的编译运行测试就卡了好久,今天终于找到了原因了,赶紧记录一下,我相信和我遇到同样问题的人不在少数,所以希望能为大家提供一篇有效的解决方案,减轻入门时的痛苦。
把官网示例拷一份在本地,以相同的名字命名为transcoding.c
, 因为官网的这个示例,用的是ffmpeg2.x的API,因为我也不太熟悉ffmpeg,用ffmpeg3.x编译时,提示了我几个API过时的问题,所以我装回了ffmpeg2.8.6来编译这个示例。下面是我的编译命令:
gcc -I /usr/local/include/ -L /usr/local/lib -lavformat -lavfilter -lavutil -lswscale -lavcodec transcoding.c -o transcoding
生成了名为transcoding
的二进制可执行文件,我使用自己的一个测试视频运行它:
./transcoding test.mp4 output.mp4
运行结果如下:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
Metadata:
major_brand : isom
minor_version : 1
compatible_brands: isomavc1
creation_time : 2016-01-10 07:17:18
encoder : FormatFactory : www.pcfreetime.com
Duration: 00:01:41.49, start: 0.000000, bitrate: 863 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 856x480 [SAR 480:481 DAR 856:481], 744 kb/s, SAR 427:428 DAR 427:240, 24 fps, 24 tbr, 24k tbn, 48 tbc (default)
Metadata:
creation_time : 2016-01-10 07:17:18
handler_name : video
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 116 kb/s (default)
Metadata:
creation_time : 2016-01-10 07:17:18
handler_name : sound
[libx264 @ 0x7fe4ac851600] broken ffmpeg default settings detected
[libx264 @ 0x7fe4ac851600] use an encoding preset (e.g. -vpre medium)
[libx264 @ 0x7fe4ac851600] preset usage: -vpre <speed> -vpre <profile>
[libx264 @ 0x7fe4ac851600] speed presets are listed in x264 --help
[libx264 @ 0x7fe4ac851600] profile is optional; x264 defaults to high
Cannot open video encoder for stream #0
Error occurred: Generic error in an external library
#issue 1 - [libx264 @ 0x7fe4ac851600] broken ffmpeg default settings detected
这个错误及其下面的信息告诉我们,在打开输出文件的视频编码器时出现了错误,这通常是由于编码器参数设置不当造成的。通过搜索,发现了这篇文章对这个问题解释的比较清楚:
http://blog.csdn.net/cffishappy/article/details/7680097
解决方法:
在transcoding.c
中的open_output_file
函数中,修改的部分如下(只增加了13-17行
):
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
enc_ctx->height = dec_ctx->height;
enc_ctx->width = dec_ctx->width;
enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
/* take first format from list of supported formats */
if (encoder->pix_fmts)
enc_ctx->pix_fmt = encoder->pix_fmts[0];
else
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
/* video time_base can be set to whatever is handy and supported by encoder */
enc_ctx->time_base = dec_ctx->time_base;
enc_ctx->me_range = 16;
enc_ctx->max_qdiff = 4;
enc_ctx->qmin = 10;
enc_ctx->qmax = 51;
enc_ctx->qcompress = 0.6;
} else {
enc_ctx->sample_rate = dec_ctx->sample_rate;
enc_ctx->channel_layout = dec_ctx->channel_layout;
enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
/* take first format from list of supported formats */
enc_ctx->sample_fmt = encoder->sample_fmts[0];
enc_ctx->time_base = (AVRational){
1, enc_ctx->sample_rate};
}
之后,我们保存编译再次运行结果如下:
...
Encoding frame
Pulling filtered frame from filters
Pushing decoded frame to filters
Pulling filtered frame from filters
Encoding frame
[mp4 @ 0x7fbe86803e00] Malformed AAC bitstream detected: use the audio bitstream filter 'aac_adtstoasc' to fix it ('-bsf:a aac_adtstoasc' option with ffmpeg)
[libx264 @ 0x7fbe86804400] frame I:1 Avg QP:45.67 size: 5439
[libx264 @ 0x7fbe86804400] frame P:1 Avg QP:46.05 size: 174
[libx264 @ 0x7fbe86804400] mb I I16..4: 71.7% 26.7% 1.5%
[libx264 @ 0x7fbe86804400] mb P I16..4: 0.2% 0.0% 0.0% P16..4: 5.2% 0.2% 0.0% 0.0% 0.0% skip:94.4%
[libx264 @ 0x7fbe86804400] final ratefactor: 56.92
[libx264 @ 0x7fbe86804400] 8x8 transform intra:26.7%
[libx264 @ 0x7fbe86804400] coded y,uvDC,uvAC intra: 8.4% 33.3% 10.1% inter: 0.0% 0.1% 0.0%
[libx264 @ 0x7fbe86804400] i16 v,h,dc,p: 39% 34% 7% 19%
[libx264 @ 0x7fbe86804400] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 6% 15% 22% 10% 10% 7% 16% 5% 9%
[libx264 @ 0x7fbe86804400] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 8% 33% 12% 10% 8% 8% 15% 2% 4%
[libx264 @ 0x7fbe86804400] i8c dc,h,v,p: 70% 16% 11% 3%
[libx264 @ 0x7fbe86804400] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x7fbe86804400] kb/s:538.85
[libfaac @ 0x7fbe862d2600] 4 frames left in the queue on closing
Error occurred: Operation not permitted
这次的视频编码可以打开并正常编码了,可是音频部分又出现了问题,关于这个问题的解答可以看这个文章:
http://www.tuicool.com/articles/NNNVv2z
博主跟踪发现了困扰我许久的问题,在这里顺便感谢一下。
#issue2 - [mp4 @ 0x7fbe86803e00] Malformed AAC bitstream detected
这个问题在网上搜了好久,stackoverflow
中提供了一种方法,可以使程序正常运行,但处理结果中只有音频被保留, 这显然不是我想要的。
其实,只需要调整一下代码顺序就可以了。知道真相的我眼泪掉下来。
解决方法
还是在transcoding.c
中的open_output_file
函数中,只是把for循环
尾部的那句代码:
if (ofmt_ctx