http://hi.baidu.com/mingyuejingque/item/78e71aff57ae9ec5a835a2e4
st = avformat_new_stream( m_oc, NULL);
if (!st) {
fprintf(stderr, "Could not allocate stream\n");
exit(1);
}
st->id = m_oc->nb_streams-1;
AVCodecContext *c = st->codec;
c->codec_type = in_stream->codec->codec_type;
/* Some formats want stream headers to be separate. */
if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
switch ((codec)->type) {
case AVMEDIA_TYPE_AUDIO:
c->sample_fmt = FORCE_smaple_fmt;
// c->bit_rate = FORCE_BIT_RATE;
c->sample_rate = FORCE_sample_rate;
c->codec_id = FORCE_CODEC_AUDIO;
c->channels = in_stream->codec->channels;
c->channel_layout = in_stream->codec->channel_layout;
c->time_base = in_stream->codec->time_base;
// c->profile = FORCE_profile;
m_AudioStream = st;
/* open it */
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
printf("Could not open audio codec");
exit(1);
}
m_Codec = codec;
m_CodecContext = c; //這是音頻編碼的,視頻沒做編碼。
break;
}
/* Some formats want stream headers to be separate. */
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 看到返回0是正常的,內部調用了c->codec_init() 我也看到aacenc.c里去了,用反證法:它里面要是說參數又問題,肯定會返回負值,既然返回0就說明它是正常執行的。
AVCodec *codec = avcodec_find_encoder( codecid ); //這個沒什么好說,下面又沒對codec做什么改變。
下面的AVCodecContext *c = st->codec;你就詭異了,
/* open it */
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; 這個標志位沒設置,叼,一般這個都是寫在函數末尾,這里先提前了,放到avcodec_open2前面去,這肯定是我粗心大意?
/* Some formats want stream headers to be separate. */
if (m_oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
avcodec_open2( c, codec, NULL ); 喲西,沒事了。假裝沒事發生。。。。。。。。