繁体   English   中英

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

[英]ffmpeg writes invalid fps to the mp4 container (and in avi it is true). What is the reason?

我需要实时记录帧。 为了测试这种情况,我将 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 fps

在此处输入图像描述

如果你使用 mp4 容器,那么关于每秒帧数的文件信息指示不正确:12.5 fps

在此处输入图像描述

请告诉我,还需要添加哪些其他设置?

MP4 不存储帧率,AVI 有。

在 MP4 中,仅存储数据包的时间信息。 由于您的 pts expr 是video_frame->pts = prev_pts + 2并且 stream 时基是1/25 ,因此帧间隔为 80ms,因此 ffmpeg 探测帧速率为 12.5 fps(正确)。

AVI 没有每帧定时。 相反,他们编写用户提供的帧速率。 如果数据包时序比前一个帧 pts 大1/fps ,则复用器将写入空数据包的跳过帧,以保持帧速率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM