码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 音视频入门基础:H.264专题(14)——计算视频帧率的公式


    =================================================================

    音视频入门基础:H.264专题系列文章:

    音视频入门基础:H.264专题(1)——H.264官方文档下载

    音视频入门基础:H.264专题(2)——使用FFmpeg命令生成H.264裸流文件

    音视频入门基础:H.264专题(3)——EBSP, RBSP和SODB

    音视频入门基础:H.264专题(4)——NALU Header:forbidden_zero_bit、nal_ref_idc、nal_unit_type简介

    音视频入门基础:H.264专题(5)——FFmpeg源码中 解析NALU Header的函数分析

    音视频入门基础:H.264专题(6)——FFmpeg源码:从H.264码流中提取NALU Header、EBSP、RBSP和SODB

    音视频入门基础:H.264专题(7)——FFmpeg源码中 指数哥伦布编码的解码实现

    音视频入门基础:H.264专题(8)——H.264官方文档的描述符

    音视频入门基础:H.264专题(9)——SPS简介

    音视频入门基础:H.264专题(10)——FFmpeg源码中,存放SPS属性的结构体和解码SPS的函数分析

    音视频入门基础:H.264专题(11)——计算视频分辨率的公式

    音视频入门基础:H.264专题(12)——FFmpeg源码中通过SPS属性计算视频分辨率的实现

    音视频入门基础:H.264专题(13)——FFmpeg源码中通过SPS属性获取视频色彩格式的实现

    音视频入门基础:H.264专题(14)——计算视频帧率的公式

    音视频入门基础:H.264专题(15)——FFmpeg源码中通过SPS属性获取视频帧率的实现

    音视频入门基础:H.264专题(16)——FFmpeg源码中,判断某文件是否为H.264裸流文件的实现

    音视频入门基础:H.264专题(17)——FFmpeg源码获取H.264裸流文件信息(视频压缩编码格式、色彩格式、视频分辨率、帧率)的总流程

    =================================================================

    一、引言

    通过FFmpeg命令可以获取到H.264裸流文件的视频帧率:

    在vlc中也可以获取到视频帧率(vlc底层也使用了FFmpeg进行解码):

    所以FFmpeg和vlc是怎样获取到H.264编码的视频的帧率呢?它们其实是通过SPS中的VUI parameters中的属性timing_info_present_flag、num_units_in_tick、time_scale、fixed_frame_rate_flag(划掉,我测过实际不需要fixed_frame_rate_flag这个属性)获取的。

    二、H.264官方文档对视频帧率相关属性的描述

    根据H.264官方文档《T-REC-H.264-202108-I!!PDF-E.pdf》第45页,当vui_parameters_present_flag值为1时, SPS中存在vui_parameters( ),也就是视频可用参数:

    《T-REC-H.264-202108-I!!PDF-E.pdf》第422页到第423页定义了VUI parameters syntax(视频可用参数语法):

    根据第436页,timing_info_present_flag等于1表示num_units_in_tick,time_scale和fixed_frame_rate_flag在比特流中存在。timing_info_present_flag等于0表示num_units_in_tick,time_scale和fixed_frame_rate_flag在比特流中不存在。

     num_units_in_tick是运行在time_scale Hz的频率(相应地时钟跳变计数器加一,称作一个时钟跳变)下的时钟的时间单元的数量。num_units_in_tick应大于0。一个时钟跳变是在编码数据中可以再现的最小时间间隔。

    time_scale是在一秒钟内的时间单元的数量。

    fixed_frame_rate_flag等于1表示是在输出顺序上相连的任意两幅图像的HRD输出时间的暂时间隔受下述限制。fixed_frame_rate_flag等于0表示对输出顺序上相连的任意两幅图像的HRD输出时间的暂时时间间隔没有该限制:

    也就是说:只有当vui_prameters_present_flag和timing_info_present_flag都等于1的情况下,才能从H.264码流的SPS中获取到视频帧率。

    根据第355页,视频帧率 = time_scale / (2 * num_units_in_tick):

    网上某些文章会写到:fixed_frame_rate_flag的值不同时,计算视频帧率的公式也会不一样,分别为:“视频帧率 = time_scale / (2 * num_units_in_tick)”和“视频帧率 = time_scale / num_units_in_tick”。

    但我阅读FFmpeg源码时发现:FFmepg判断视频帧率时似乎没用到fixed_frame_rate_flag这个属性。H.264官方文档对fixed_frame_rate_flag属性也没有作过多的说明。

    根据文章《Find frame rate SPS》里面的说法:

    “当fixed_frame_rate_flag为1时,那么你的图像速率(以fps计算)是:time_scale / num_units_in_tick。如果你使用的是基于场的视频,那么这将是一个场速率,所以你必须将其减半才能得到帧速率。”

    所以到底哪种说法是正确的呢?计算视频帧率到底要不要考虑fixed_frame_rate_flag?下面我们分别以fixed_frame_rate_flag的值为0和值为1的两个视频为例子,实际看一下。

    三、计算视频帧率的例子

    (一)fixed_frame_rate_flag值为0的视频

    用Elecard Stream Analyzer工具打开一个用H.264编码的视频文件,其vui_prameters_present_flag值为1,timing_info_present_flag值为1,num_units_in_tick值为1,time_scale值为60,fixed_frame_rate_flag值为0:

    用Elecard StreamEye工具可以看到其帧率为30。符合公式:视频帧率 = time_scale / (2 * num_units_in_tick) = 60 / (2 * 1) = 30:

    所以fixed_frame_rate_flag值为0时,视频帧率 = time_scale / (2 * num_units_in_tick)

    (二)fixed_frame_rate_flag值为1的视频

    用Elecard Stream Analyzer工具打开一个用H.264编码的视频文件,其vui_prameters_present_flag值为1,timing_info_present_flag值为1,num_units_in_tick值为125,time_scale值为5994,fixed_frame_rate_flag值为1:

    用Elecard StreamEye、vlc等工具可以看到其帧率为23.98。也符合公式:视频帧率 = time_scale / (2 * num_units_in_tick) = 5994 / (2 * 125) = 23.976 ≈ 23.98:

    所以fixed_frame_rate_flag值为1时,视频帧率 = time_scale / (2 * num_units_in_tick)

    综上所述,我们可以得出一个结论:

    H.264编码的视频,无论其SPS中的fixed_frame_rate_flag值为多少,视频帧率的计算公式都是:视频帧率 = time_scale / (2 * num_units_in_tick) !!!

  • 相关阅读:
    OpenGL 的学习之路-4(变换)
    目标检测论文、代码、数据集汇总
    kubeadm初始化的k8s集群证书续期—— 筑梦之路
    kubeflow核心功能
    1167 Cartesian Tree – PAT甲级真题
    一、excel转pdf格式jacob.jar
    Nacos安装及在项目中的使用
    JSP学习日记
    推荐一个基于.NET Core 3.1开发开源的分布式任务调度系统
    [量化投资-学习笔记008]Python+TDengine从零开始搭建量化分析平台-CCI和ATR
  • 原文地址:https://blog.csdn.net/u014552102/article/details/140441476
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号