1

我正在将实时渲染的视频数据和现有的 .wav 文件编码为 mpg 文件。

为此,我首先编写所有音频帧,然后是来自渲染引擎的视频帧。对于较小的 .wav 文件(< 25 秒),一切正常。但是,一旦我使用更长的 .wav 文件,av_write_frame(在写入音频帧时)在写入大约 100 帧后就会返回 -1。它永远不是失败的同一帧,也永远不是最后一帧。我测试过的任何播放器都可以完美播放所有测试文件。

我正在关注复用示例(或多或少)。

这是我编写音频帧的函数:

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 中(都使用完全相同的编码)。

这里有什么问题?

4

1 回答 1

1

尝试使用av_interleaved_write_frame而不是av_write_frame

于 2012-11-24T06:55:43.367 回答