使用FFMPEG编码H264时如何转储缓冲区?

时间:2011-12-15 10:45:53

标签: c++ ffmpeg buffer h.264

我正在使用c ++库将从网络摄像头捕获的图像写入libx264编码的mp4文件。 编码工作正常,但启动时会向缓冲区写入40帧。当我关闭文件时,这些帧没有被刷新,所以大约6秒的视频没有被写入(凸轮大约是6fps)。

所以我在打电话:

out_size = libffmpeg::avcodec_encode_video( codecContext, data->VideoOutputBuffer,data->VideoOutputBufferSize, data->VideoFrame );

// if zero size, it means the image was buffered
if ( out_size > 0 )
{
//... write to file
}

我看不到访问缓冲区中剩余图像的方法。有什么想法吗?

2 个答案:

答案 0 :(得分:6)

我使用以下代码来清除缓冲区。似乎我在寻找错误的术语 - 应该是“延迟帧”...

void VideoFileWriter::Flush(void)
{
if ( data != nullptr )
{
    int out_size = 0;
    int ret = 0;

    libffmpeg::AVCodecContext* c = data->VideoStream->codec;
    /* get the delayed frames */
    while (1) {
        libffmpeg::AVPacket packet;
        libffmpeg::av_init_packet(&packet);

        out_size = libffmpeg::avcodec_encode_video(c, data->VideoOutputBuffer, data->VideoOutputBufferSize, NULL);
        if (out_size < 0) {
            //fprintf(stderr, "Error encoding delayed frame %d\n", out_size);
            break;
        }
        if (out_size == 0) {
            break;
        }
        if (c->coded_frame->pts != AV_NOPTS_VALUE) {
            packet.pts = av_rescale_q(c->coded_frame->pts,
                          c->time_base,
                          data->VideoStream->time_base);
            //fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
        } else {
            //fprintf(stderr, "Video Frame PTS: not set\n");
        }
        if (c->coded_frame->key_frame) {
            packet.flags |= AV_PKT_FLAG_KEY;
        }
        packet.stream_index = data->VideoStream->index;
        packet.data = data->VideoOutputBuffer;
        packet.size = out_size;

        ret = libffmpeg::av_interleaved_write_frame( data->FormatContext, &packet );
        if (ret != 0) {
            //fprintf(stderr, "Error writing delayed frame %d\n", ret);
            break;
        }
    }
    libffmpeg::avcodec_flush_buffers(data->VideoStream->codec);
}
}

答案 1 :(得分:1)

Here是关于使用avcodec的ffmpeg的教程,声明avcodec使用了一些需要刷新的内部缓冲区。还有一些代码显示了如何刷新这些缓冲区(“刷新我们的缓冲区”)。