视频帧

对于一份视频,实质上是多张图片高速播放形成的。每一张图片即为该视频的一帧。而每秒钟播放的图片张数便为所谓的帧率(Frame Rate/Frame Per Second)。常见的帧率有24fps(即一秒播放24张图片),60fps(一秒播放60张图片)等。也就是说,对于一个时长60秒的图片,如果帧率为24fps,那么这个视频便有60*24=1440帧。

上图是一张常见的1920*1080分辨率的屏幕截图,格式为png。可以看到其大小为1.2MB。而对于一部电影来说,假设电影时长一个小时,也就是3600秒,假设帧率为24fps,那么这部电影便有3600*24=86400帧。如果每一帧都保存为png格式,那么这部电影的大小便是86400*1.2MB=103.68GB。也就是一部1080p高清的电影竟然需要103个G!这是不可接受的。而对于4k分辨率(3840*2160)的视频,那存储所需要的空间只会更多。如何解决这个问题呢?

编码与解码

为了解决视频存储空间过大的问题,人们发明了视频编码技术。可以想象一个数字序列

\(111111555666\),可以看出他其实有许多重复的部分,因此我们可以定义这样一种方式来表示\(165363\)表示6个1,3个5,3个6,这样我们就可以用更少的数字来表示原来的数字序列。

让我们回到视频,对于一个视频,为了保证播放时的效果不割裂,相邻两帧的内容实际上是非常相似的,因此我们只需要记录这一帧与前一帧的差异像素即可,不需要保存这一帧所有的像素。这样就大大减少的所需的存储空间,播放时再利用前帧的像素加上差异像素得出这一帧的像素进行解码即可。实际上的编解码策略会更加复杂多样。

I,P,B帧

在编码时,视频帧被分为三种类型:I帧,P帧,B帧。

  • I帧,保留原始图片的所有像素信息,无需参考其他帧便可获取完整的图片,通常作为其他帧的参考
  • P帧,前向预测帧,解码时需要参考前一帧的I帧或P帧,通过前一帧的像素信息加上差异像素信息得到当前帧的像素信息
  • B帧,双向预测帧,解码时需要参考前一帧的I帧或P帧和后一帧的I帧或P帧,通过前后帧的像素信息加上差异像素信息得到当前帧的像素信息

不难看出,I帧的编码效率是最低的,而P帧保留与前一帧的差异像素,编码效率较高,B帧保留与前后帧的差异像素,大部分信息来自于前后帧,自身保留的信息较少,编码效率最高。编码时将多个帧组成一个GOP(Group of Picture,即图像组),GOP中的第一帧一定为I帧,最后一帧一定为P帧,中间一般为P帧与B帧的规律性排列。下图便为一个图像组的排列。

图中每一个箭头的起始为提供信息的帧,箭头指向需要该信息进行解码的帧。可以看出没有任何箭头指向I帧,因为I帧不需要参考其他帧即可解码。图中的每个P帧均只有一个前向的箭头指向它们,箭头的来源可能是P帧也可能是I帧。而每个B帧仅有箭头指向它们,而且箭头的数量均为2,来源分别为该B帧前面的I帧或者P帧以及后面的I帧或者P帧。

pts与dts

由上图可以看出来,在一个图像组中,播放的顺序应该为

I->B->B->P->B->B->B->P

但是由于IPB帧解码规则的设计,解码的顺序与播放的顺序并不一致,解码时,一般会先读取一个I帧,然后跳过B帧先去解码第一个P帧,接着跳回来使用解码后的I,P帧去解码B帧,之后在跳过B帧去解码第二个P帧,然后跳回来解码两个P帧间的B帧,循环这个操作。这也正符合P帧依赖前帧,B帧依赖前后帧的逻辑,也就是说上图的解码顺序为

I->P->B->B->P->B->B->B

参考博客

显然解码的帧顺序与显示的帧顺序截然不同,如果我们想直接顺序的解码一帧就显示一帧的话,整个的视频就乱套了。而且在解码和播放时图片本身是不含时间信息的,也就是说他自己不知道自己这一帧应该在什么时候被解码,在什么时候被播放,因此需要一个索引来指示每一帧的解码顺序,与播放顺序,这便是pts与dts。

  • PTS(Presentation Time Stamp),显示时间戳,指示该帧应该在什么时候被显示
  • DTS(Decode Time Stamp),解码时间戳,指示该帧应该在什么时候被解码

以上图为例,一个图像组的pts与dts分别为

    I->B->B->P->B->B->B->P
pts:1 2 3 4 5 6 7 8
dts:1 3 4 2 6 7 8 5

(OS:这里只是做一个示例,实际上可能不同,错了的话请评论批评QWQ)

这样的话,在解码时按照dts的顺序进行解码,而播放时使用pts进行播放。因此在解码时可能并不能解码一帧就能获取一个播放帧,因为P帧以及B帧依赖其他帧的信息,因此在解码时可能需要等待其他帧的解码结果。

对于不同的编码格式,一个图像组的IPB帧的个数以及排列都有可能是不一样的。

ffmpeg简易播放器(1)--了解视频格式的更多相关文章

  1. FFmpeg简易播放器的实现-音视频同步

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  2. FFmpeg简易播放器的实现-视频播放

    本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10047035.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  3. FFmpeg简易播放器的实现-音视频播放

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10235926.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  4. FFmpeg简易播放器的实现-音频播放

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10068490.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  5. FFmpeg简易播放器的实现-最简版

    本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10040202.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  6. <Win32_17>集音频和视频播放功能于一身的简易播放器

    前段时间,在学习中科院杨老师的教学视频时,他说了一句话: "我很反对百八十行的教学程序,要来就来一个完整的程序" 对此,我很是赞同.所谓真刀真枪的做了,你才会发现其中的奥秘——然而 ...

  7. 基于ffmpeg网络播放器的教程与总结

    基于ffmpeg网络播放器的教程与总结   一.         概述 为了解决在线无广告播放youku网上的视频.(youku把每个视频切换成若干个小视频). 视频资源解析可以从www.flvcd. ...

  8. 基于QtAV的简易播放器(开源)

    这个开源代码,是我利用QtAV源码,提取其中一部分代码,进行整合到我自己项目中,做的一个小型播放器测试,至于怎么安装一些环境以及QtAV源码编译在我以前写的一篇博客中可以看到(Qt第三方库QtAV-- ...

  9. ffmpeg+SDl+ 播放器 -01

    最近因公司项目需要,打算自己在LINUX平台整一个播放器,来学习和研究音频编解码. 项目需求: 支持下列格式文件播放. 1> WMA 硬件解码,但需要软件分析ASF格式,提取Payload数据 ...

  10. Opencv实现简易播放器

    实现了在MFC中显示图片,再要显示一个视频就是轻而易举的事了,本篇介绍使用Opencv制作一个简易的播放器,实现打开文件.暂停.继续播放.再次播放和总\当前帧数显示功能. 首先还是先看一下界面效果: ...

随机推荐

  1. 6. jenkins触发器

    常用的触发器 Jenkins内置4种构建触发器 触发远程 构建其他工程构建后触发(Build after other projects are build) 定时构建(Build periodical ...

  2. JAVA 传输post传输长字符、数据编码解码 反序列化字符串

    JAVA 传输post传输长字符.数据编码解码 1.前段传输 这是传输的数组对象 2.后端接收格式已解码 JS代码: $.ajax({ url:prefix+"/importModelTre ...

  3. 第三篇:低功耗模组Air724UG硬件设计手册

    ​ 今天我们分享最后一篇. 3.20 省电功能 根据系统需求,有两种方式可以使模块进入到低功耗的状态.对于AT版本使用"AT+CFUN"命令可以使模块 进入最少功能状态. 具体的功 ...

  4. js+jquery实现贪吃蛇经典小游戏

    项目只使用到了html,css,js,jquery技术点,没有使用游戏框架,下载本地直接双击index.html 运行即可体验游戏效果. 项目展示 进入游戏 游戏开始 游戏暂停 html文件 < ...

  5. zookeeper 分布式锁服务

    分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那一层来挡.当大量的行锁.表锁.事务充斥着数据库的时候.一般web应用很多的瓶颈都在数据库上,这里给大家介绍的是减轻数据库锁负担的一种 ...

  6. 基于Spring源码分析AOP的实现机制

    Spring一个重要的特性就是提供了AOP,使得我们可以在原有的基础上增加我们自己的系统业务逻辑.使得我们系统业务逻辑与应用业务逻辑相分离,耦合性降低,并且大大的提高了开发的效率.Spring的AOP ...

  7. MySQL原理简介—9.MySQL索引原理

    大纲 1.磁盘数据页的存储结构 2.没有索引数据库如何搜索数据 3.在表中插入数据时如何进行页分裂 4.如何设计主键索引及如何根据主键索引查询 5.索引的物理存储结构 6.更新数据时自动维护的聚簇索引 ...

  8. confd+Nacos实现nginx配置文件管理

    场景: 由于公司内部站点保护的需求, 将部分的站点添加白名单, 这边的操作是在nginx配置文件中添加如下代码 allow 127.0.0.1: deny all; 但随之问题也出现了, 需要添加一个 ...

  9. Xdebug+Phpstorm远程调试

    开发环境: 本地 Windows10 日常开发使用的环境 装有PHPStorm 远程主机 Linux 服务器 装php-fpm/nginx等所有开发依赖环境 本地可以访问远程主机 但远程主机无法访问本 ...

  10. ZCMU-1053

    比较简单记录一下主要感觉它这个题目没说清楚,题目要求:先有n,接着给出长度为n的标准组,然后给出猜测组,输出的两个数一个是有多少个是相对应的既相同坐标其数值也相同,后一个是两个都有但是位置不同(不含已 ...