ffmpeg向mp4容器写入无效的fps(在avi中是真的)。原因是什么?

问题描述 投票:0回答:1

我需要实时记录帧。为了测试这种情况,我使pts非线性(因为帧可能会丢失),因此。

// AVFrame
video_frame->pts = prev_pts + 2;

我使用libavformat来写入一个文件。参数AVCodecContext和AVStream。

#define STREAM_FRAME_RATE 25
#define CODEC_PIX_FMT  AV_PIX_FMT_YUV420P
#define FRAME_WIDTH 1440
#define FRAME_HEIGHT 900

// AVCodecContext
cc->codec_id = video_codec->id;
cc->bit_rate = 400000;
cc->width = FRAME_WIDTH;
cc->height = FRAME_HEIGHT;
cc->gop_size = 12;
cc->pix_fmt = CODEC_PIX_FMT;

// AVStream
video_stream->time_base = AVRational{ 1, STREAM_FRAME_RATE };
cc->time_base = video_stream->time_base;
cc->framerate = AVRational{ STREAM_FRAME_RATE , 1 };

写入文件:

static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{
    /* rescale output packet timestamp values from codec to stream timebase */
    //av_packet_rescale_ts(pkt, *time_base, st->time_base);
    pkt->pts = av_rescale_q(pkt->pts, *time_base, st->time_base);
    pkt->dts = av_rescale_q(pkt->dts, *time_base, st->time_base);
    pkt->stream_index = st->index;

    /* Write the compressed frame to the media file. */
    //log_packet(fmt_ctx, pkt);
    //return av_write_frame(fmt_ctx, pkt);
    return av_interleaved_write_frame(fmt_ctx, pkt);
}

如果你使用avi容器,那么每秒的帧数信息就会正确地显示在文件中。25帧/秒

enter image description here

如果您使用mp4容器,那么关于每秒帧数的文件信息将被错误地指示。12. 5帧/秒

enter image description here

请告诉我,还需要增加哪些设置?

c++ video ffmpeg multimedia
1个回答
2
投票

MP4s不存储帧率,而AVI则存储帧率。

在MP4中,只存储数据包的时间信息。由于你的pts expr是 video_frame->pts = prev_pts + 2 和流时基是 1/25帧之间的间隔是80ms,因此ffmpeg探测到的帧率是12.5 fps(正确)。

AVI没有每帧定时。相反,他们写的用户提供的帧速率。如果一个数据包的时间是大于上一帧的pts由 1/fps为了保持帧速率,复用器将写入空包的跳过帧。

© www.soinside.com 2019 - 2024. All rights reserved.