Ffmpeg 使用AVFilter 转码程序过程中出现的错误(包括解码的编码)
(2016-03-16 08:51:10)分类: 2016-03 |
[mp4 @ 0119ad00] Malformed AAC bitstream detected: use audio
bitstream filter
'aac_adtstoasc' to fix it ('-bsf:a aac_adtstoasc' option with ffmpeg)
解决办法以及分析:
st = avformat_new_stream( m_oc, NULL);
AVCodecContext *c = st->codec;
c->codec_type = in_stream->codec->codec_type;
if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
c->codec_id = FORCE_CODEC_AUDIO;
c->channel_layout
c->time_base = in_stream->codec->time_base;
// c->profile = FORCE_profile;
m_AudioStream = st;
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
printf("Could not open audio codec");
exit(1);
}
m_Codec = codec;
m_CodecContext = c; //这是音频编码的,视频没做编码。
}
if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
叼,这样写的代码有个潜规则,那就是:
if (av_buffersrc_add_frame_flags(m_filter_in_param.buffersrc_ctx, in_frame, 0) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
goto quit;
}
while (1) {
ret = av_buffersink_get_frame(m_filter_in_param.buffersink_ctx, filt_frame);
if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
ret = -1;
goto quit;
}
if(ret < 0)
goto quit;
ret = avcodec_encode_audio2(m_CodecContext, new_packet, filt_frame, &got_frame);
av_frame_free( &filt_frame );
if ( got_frame )
goto quit;
}
从这里编码出来的packet,让ffmpeg写到文件里去的时候会报错:
[mp4 @ 0119ad00] Malformed AAC bitstream detected: use audio
bitstream filter
'aac_adtstoasc' to fix it ('-bsf:a aac_adtstoasc' option with ffmpeg)
小孩子要什么filter来修正啊,叼,试了大半天也不知道哪个合适,并且也不想随便就加filter下去,万一它消耗太多cpu怎么办。
又是看ffmpeg的源码,avcodec_open2
AVCodec *codec = avcodec_find_encoder( codecid ); //这个没什么好说,下面又没对codec做什么改变。
下面的AVCodecContext *c = st->codec;你就诡异了,
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
printf("Could not open audio codec");
exit(1);
}
严重怀疑c,c就是stream->codec,这个stream是在AVFormatContext *m_oc里的流。 跟到ffmpeg源码里去,发现是:
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |=
CODEC_FLAG_GLOBAL_HEADER;
avcodec_open2( c, codec, NULL ); 哟西,没事了。假装没事发生。。。。。。。。