ffmpeg播放时刻与视频文件时间戳对齐(同步)

这篇具有很好参考价值的文章主要介绍了ffmpeg播放时刻与视频文件时间戳对齐(同步)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述

当解码较快的时候,并不是解码后立马显示视频帧,这样看着是倍速的效果。如何还原实际的播放速率?

解决方案

为了解决在解码后视频播放还原原来每帧播放的时刻点。我们需要在解码较快的情况下对帧显示加一定的时间延时,这个延时策略就是计算出

延时调整时间 =(当前帧时间戳  -  上一帧时间戳)- (当前机器准显示时间  -  上一帧显示机器时间)

延时调整时间 有可能为负值则丢弃。如果为正值,可根据时长做一定调整,毕竟送帧显示也是耗时操作。

demo示例:

void dispThread(void *arg)
{
    Input *input = (Input *)arg;
    static const double interval = 1000000.0 / input->fps;
    double q2d = av_q2d(input->tb) * 1000000.0;
    int64_t pre_pts = 0;
    int64_t frame_pre_pts = AV_NOPTS_VALUE;
    AVFrame *pending_frm = NULL;

    while (!input->is_req_exit()) {
        int64_t cur_pts;
        int remaining_time = 10000;
        double duration = interval;
        AVFrame *frm;

        if (pending_frm) {
            frm = pending_frm;
        } else {
            frm = input->PopFrame();
            if (!frm) {
                msleep(10);
                continue;
            }
            // printf("pop frame pts: %ld\n", frm->pts);
        }
        static auto delete_func = [](AVFrame * f) {
            av_frame_free(&f);
        };

        cur_pts = av_gettime_relative();
        if (frame_pre_pts != AV_NOPTS_VALUE)
            duration = (frm->pts - frame_pre_pts) * q2d;

        int countdown = (pre_pts == 0) ? 0 : (int)(duration - (cur_pts - pre_pts));
        remaining_time = std::min<int>(remaining_time, countdown);

        // printf("countdown: %d, remaining_time: %d us\n",
        //         countdown, remaining_time);
        if (input->realtime) {
            countdown = 0;
            remaining_time = 0;
        }
        if (countdown <= 0) {
            frame_pre_pts = frm->pts;
            pre_pts = cur_pts;
            if (frm == pending_frm)
                pending_frm = NULL;
            push_frame(input->join, input->slice_idx,
                       std::shared_ptr<AVFrame>(frm, delete_func));
        } else {
            pending_frm = frm;
        }

        if (remaining_time > 0)
        {
            printf("countdown: %d, remaining_time: %d us\n",
                 countdown, remaining_time);
            std::this_thread::sleep_for(std::chrono::microseconds(remaining_time));
        }
    }
    if (pending_frm)
        av_frame_free(&pending_frm);
}

知识点1:av_q2d(AVRational a)函数

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

av_q2d(AVRational);该函数负责把AVRational结构转换成double,通过这个函数可以计算出某一帧在视频中的时间位置

timestamp(秒) = pts * av_q2d(st->time_base);

计算视频长度的方法:

time(秒) = st->duration * av_q2d(st->time_base);

知识点2:av_gettime_relative();

该函数是拿到当前的机器时间(系统时间)。

如果是直播的情况下我们不做延时。

大致的流程如下:

取得解码视频帧

记录当前机器时间

计算当前准显示时间与上次显示时间差值d1

计算当前帧时间戳与上次显示时间戳差值d2

计算延时时间 d2 - d1

延时时间大于0则进行sleep延时

并保存当前帧在下一次循环送显

以上步骤为解决方案。请参考。文章来源地址https://www.toymoban.com/news/detail-401405.html

到了这里,关于ffmpeg播放时刻与视频文件时间戳对齐(同步)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt基于FFmpeg解码本地视频生成H264文件并播放

    用eseye_u.exe 打开H264文件并播放 本文福利, 免费领取C++音视频学习资料包、技术视频 ,内容包括(音视频开发,面试题, FFmpeg , webRTC , rtmp , hls , rtsp , ffplay , srs ) ↓↓↓↓↓↓ 见下面↓↓文章底部点击免费领取↓↓   三、核心代码:  main中创建对象即可测试:

    2023年04月17日
    浏览(41)
  • 用Qt开发的ffmpeg流媒体播放器,支持截图、录像,支持音视频播放,支持本地文件播放、网络流播放

    本工程qt用的版本是5.8-32位,ffmpeg用的版本是较新的5.1版本。它支持TCP或UDP方式拉取实时流,实时流我采用的是监控摄像头的RTSP流。音频播放采用的是QAudioOutput,视频经ffmpeg解码并由YUV转RGB后是在QOpenGLWidget下进行渲染显示。本工程的代码有注释,可以通过本博客查看代码或者

    2024年02月03日
    浏览(105)
  • FFmpeg入门 - 视频播放

    音视频最好从能够直接看到东西,也更加贴近用户的播放开始学起. 我们可以通过http、rtmp或者本地的视频文件去播放视频。这里的\\\"视频\\\"实际上指的是mp4、avi这种既有音频也有视频的文件格式。 这样的视频文件可能会有多条轨道例如视频轨道、音频轨道、字幕轨道等. 有些格式

    2024年02月02日
    浏览(34)
  • Qt使用FFmpeg播放视频

    一、使用场景 因为项目中需要加载MP4播放开机视频,而我们的设备所使用的架构为arm架构,其中缺乏一些多媒体库。安装这些插件库比较麻烦,所以最终决定使用FFmpeg播放视频。 二、下载编译ffmpeg库 2.1 下载源码 源码下载路径:https://www.ffmpeg.org/download.html#build-windows 2.2 编译

    2024年02月07日
    浏览(34)
  • qt+ffmpeg 实现音视频播放(二)之音频播放

    通过  avformat_open_input () 打开媒体文件并分配和初始化  AVFormatContext   结构体。 函数原型如下: int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options); 参数说明: - `ps`:指向 `AVFormatContext` 结构体指针的指针,用于存储打开的媒体文件的信息。

    2024年04月22日
    浏览(57)
  • FFMPEG+mediamtx 实现海康相机视频播放

    使用FFMPEG对海康相机视频进行读取,重新编码后再进行推流,推到mediamtx,再通过网页播放器或其他客户端拉取视频并播放 随便找的一个安装教程:https://blog.csdn.net/weixin_44704985/article/details/109532224 安装后需配置到环境变量 https://github.com/bluenviron/mediamtx/releases 要是打不开自己

    2024年02月07日
    浏览(47)
  • 基于 FFmpeg 的跨平台视频播放器简明教程(五):使用 SDL 播放视频

    基于 FFmpeg 的跨平台视频播放器简明教程(一):FFMPEG + Conan 环境集成 基于 FFmpeg 的跨平台视频播放器简明教程(二):基础知识和解封装(demux) 基于 FFmpeg 的跨平台视频播放器简明教程(三):视频解码 基于 FFmpeg 的跨平台视频播放器简明教程(四):像素格式与格式转换

    2024年02月12日
    浏览(67)
  • QT ubuntu下开发视频播放 FFmpeg

    ubuntu 安装FFmpeg T113VideoDemo.pro mainwindow.h mainwindow.cpp

    2024年02月14日
    浏览(46)
  • Qt-FFmpeg开发-视频播放(5)

    目录 音视频/FFmpeg #Qt Qt-FFmpeg开发-视频播放【软/硬解码 + OpenGL显示YUV/NV12】 1、概述 2、实现效果 3、FFmpeg硬解码流程 4、优化av_hwframe_transfer_data()性能低问题 5、主要代码 5.1 解码代码 5.2 OpenGL显示RGB图像代码 6、完整源代码 更多精彩内容 👉个人内容分类汇总 👈 👉音视频开发

    2023年04月08日
    浏览(33)
  • Qt-FFmpeg开发-视频播放(4)

    更多精彩内容 👉个人内容分类汇总 👈 👉音视频开发 👈 最近研究了一下FFmpeg开发,功能实在是太强大了,网上ffmpeg3、4的文章还是很多的,但是学习嘛,最新的还是不能放过,就选了一个最新的ffmpeg n5.1.2版本,和3、4版本api变化还是挺大的; 在这个Demo里主要使用Qt + FFm

    2023年04月25日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包