2012-11-23 59 views
1

我將實時呈現的視頻數據和現有的.wav文件編碼爲mpg文件。將較大的音頻文件編碼爲.mpg時av_write_frame失敗

爲此,我首先編寫所有音頻幀,然後寫入從渲染引擎進入的視頻幀。對於較小的.wav文件(< 25秒),一切正常。但是,只要我使用更長的.wav文件,av_write_frame(寫入音頻幀時)在寫入大約100幀後返回-1。它從來不是同一個框架,也不是最後一個框架。 所有測試文件都可以在我測試的任何播放器上完美播放。

我跟隨the muxing example(或多或少)。

這裏是我的功能寫入音頻幀:

void write_audio_frame(Cffmpeg_dll * ptr, AVFormatContext *oc, AVStream *st, int16_t sample_val) 
{ 
AVCodecContext *c; 
AVPacket pkt = { 0 }; // data and size must be 0; 
AVFrame *frame = avcodec_alloc_frame(); 
int got_packet; 

av_init_packet(&pkt); 
c = st->codec; 

get_audio_frame(ptr, ptr->samples, ptr->audio_input_frame_size, c->channels); 
frame->nb_samples = ptr->audio_input_frame_size; 
int result = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, 
         (uint8_t *) ptr->samples, 
         ptr->audio_input_frame_size * 
         av_get_bytes_per_sample(c->sample_fmt) * 
         c->channels, 0); 
if (result != 0) 
{ 
    av_log(c, AV_LOG_ERROR, "Error filling audio frame. Code: %i\n", result); 
    exit(1); 
} 

result = avcodec_encode_audio2(c, &pkt, frame, &got_packet); 
if (result != 0) 
{ 
    av_log(c, AV_LOG_ERROR, "Error encoding audio. Code: %i\n", result); 
    exit(1); 
} 


if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) 
    pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base); 
pkt.flags |= AV_PKT_FLAG_KEY; 

pkt.stream_index= st->index; 
av_log(c, AV_LOG_ERROR, "Got? %i Pts: %i Dts: %i Flags: %i Side Elems: %i Size: %i\n", 
     got_packet, pkt.pts, pkt.dts, pkt.flags, pkt.side_data_elems, pkt.size); 

/* write the compressed frame in the media file */ 
result = av_write_frame(oc, &pkt); 
if (result != 0) 
{ 
    av_log(c, AV_LOG_ERROR, "Error while writing audio frame. Result: %i\n", result); 
    exit(1); 
} 
} 

所以。「而寫的音頻幀錯誤結果:-1」是我的一些幀後總是得到。

這裏是我的get_audio_frame功能:

void get_audio_frame(Cffmpeg_dll* ptr, int16_t* samples, int frame_size, int nb_channels, int16_t sample_val) 
{ 
    fread(samples, sizeof(int16_t), frame_size * nb_channels, ptr->fp_sound_input); 
}; 

最後,這是我寫的所有音頻幀(不用擔心這些.wav頭,我那循環之前跳過吧)環路:

while (!feof(ptr->fp_sound_input)) 
    { 
     write_audio_frame(ptr, ptr->oc, ptr->audio_st, -1); 
    } 

正如你所看到的,我輸出包中的幾乎所有東西,並檢查是否有可能的錯誤。除了av_write_frame在我編碼一個較長的音頻文件後的一段時間失敗,一切似乎都很好。我所跟蹤的所有數據包值對於所有幀都是100%(顯然除了數據指針)。另外,如前所述,對於較短的fp_sound_input文件,同樣的過程完美無缺。 avcodec_encode_audio2()和avcodec_fill_audio_frame()也永遠不會失敗。

我用於編碼的編解碼器是CODEC_ID_MPEG2VIDEO(視頻)和CODEC_ID_MP2(音頻)。 .wav文件保存在PCM 16 LE中(全部使用完全相同的編碼)。

這裏有什麼問題?

回答

1

嘗試使用av_interleaved_write_frame代替av_write_frame

+0

將嘗試當我回去工作。但爲什麼?所有的音頻幀都在一個塊中。 – TheSHEEEP

+0

使用'av_write_frame'時,必須根據容器規範正確交錯數據包。因此,通常最好使用'av_interleaved_write_frame'。在這種情況下,交錯過程是自動的。 – pogorskiy

+0

就是這樣,謝謝!我只是想知道爲什麼它可以處理較小的音頻文件。猜猜屬於ffmpeg的刺激魔法;) – TheSHEEEP

相關問題