天天看點

從ffmpeg filter裡出來的資料直接送給avcodec_encode_audio2編碼,寫檔案有錯。

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;

叼,這樣寫的代碼有個潛規則,那就是:

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;

if(ret < 0)

ret = avcodec_encode_audio2(m_codeccontext, new_packet, filt_frame,

&got_frame);

av_frame_free( &filt_frame );

if ( got_frame )

從這裡編碼出來的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;你就詭異了,

嚴重懷疑c,c就是stream->codec,這個stream是在avformatcontext *m_oc裡的流。

跟到ffmpeg源碼裡去,發現是:

c->flags |= codec_flag_global_header;  

這個标志位沒設定,叼,一般這個都是寫在函數末尾,這裡先提前了,放到avcodec_open2前面去,這肯定是我粗心大意?

c->flags |= codec_flag_global_header;   

avcodec_open2( c, codec, null ); 喲西,沒事了。假裝沒事發生。。。。。。。。