我將實時呈現的視頻數據和現有的.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中(全部使用完全相同的編碼)。
這裏有什麼問題?
將嘗試當我回去工作。但爲什麼?所有的音頻幀都在一個塊中。 – TheSHEEEP
使用'av_write_frame'時,必須根據容器規範正確交錯數據包。因此,通常最好使用'av_interleaved_write_frame'。在這種情況下,交錯過程是自動的。 – pogorskiy
就是這樣,謝謝!我只是想知道爲什麼它可以處理較小的音頻文件。猜猜屬於ffmpeg的刺激魔法;) – TheSHEEEP