zoukankan      html  css  js  c++  java
  • 流媒体服务新手入门教程03--音视频基础

    对于简单的接入摄像头等硬件或者推送视频流、录制文件,那么直接下载m7s官网编译好的二进制文件即可。

    如果要做二次开发,那么就需要了一些基础的音视频基础,及m7s代码了,我们先了解一些音视频基础。

    视频基础

    视频帧

    对于视频来说,我们可以把其想象为一幅一幅图片组成的,当把这些图片连续快速播放时,由于人眼的视觉暂留,只要播放的速度大于1秒24幅图片,那么我们看起来就是连续的。其中这个每秒播放多少张图片就称为帧率 ,一副图片就称为。假如就这么把图片放在一起,我们来算一下现在流行的15秒短视频大概有多大。
    我们现在的手机摄像头都是千万像素,拍摄出来的照片基本都超过1M,这里就按1M计算,帧率按照24,则15秒的短视频有 24*1*15 = 360M
    是不是吓一跳,实际上视频并不简单的把图片组合起来,而是按照一定的规范压缩过。要不然我们刷几个短视频,流量蹭蹭蹭的往下掉,谁也扛不住啊!

    帧间压缩

    我们比较一下相邻的两幅图片,会发现第二幅图片相对第一幅来说变动很小。如果只记录这个变化的地方,那么存储不就降下来了吗。
    于是这些技术专家们提出了三种帧:
    I 帧(Intra-coded picture)表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面)
    P帧 (Predictive-coded Picture)前向预测编码图像帧,P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。
    B帧 (Bidirectionally predicted picture)双向预测编码图像帧,B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别,换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。

    帧内压缩

    看到这里,你可能会想到,除了对帧间压缩,我们是否还可以对帧内进行压缩呢?答案是肯定的。
    我们常见的图片是利用红、绿、蓝三原色来表示每一个像素点,即RGB模式。但实际上摄像头,流媒体里用的更多的是YUV。
    什么是YUV?
    Y表示明亮度(Luminance或Luma),也就是灰度值;
    U(Cb)表示色度(Chrominance)
    V(Cr)表示浓度(Chroma)
    它们直接的关系可以参考这副图片,YUV和RGB直接的换算关系可以参考此文

    和RGB类似,原始的YUV也是用三个分量代表颜色,这时存储大小也是和RGB一样的。
    但是人眼对亮度更敏感。于是我们就可以压缩U和V分量了。
    比如常见的YUV 422,表示 UV 分量的是 Y 分量的一半,那么存储空间就相当于以前的 (0.5 + 0.5 + 1) / 3 = 2/3 了。
    压缩更高的还有YUV 420,表示UV分量隔行存储,并且只有Y分量的一半,那么存储空间就相当于以前的 (0.25 + 0.25 + 1) / 3 = 1/2 了。
    对于YUV其实还有很多情况,我这里就不多说了,请自行查找。
    当然帧内压缩还有其它方式,这里只说一下最常见的情况。

    编解码和解封包

    视频压缩思路确定后,就是具体的压缩算法了。不同的机构提出了各种各样的压缩算法。
    压缩视频帧还原视频帧被称为编解码。
    编码就是指通过压缩技术,将原始视频格式的文件转换成另一种视频格式文件的方式。
    解码即对已编码的数字视频进行还原操作的过程。
    常见的编码有:

    • H264 当前主流编码,个人免费,商业收费
    • H265 H264的下一代,压缩率更高,已开始普及,个人免费,商业收费
    • VP8/VP9 Google推出,主要用在webrtc中, 开源免费
    • AV1 Google 推出,想要与H265争夺市场,开源免费
    • AVS 国产视频编码,AVS1替代H264,AVS2 替代H265,比同期的H264和H265都强。个人免费,商业收费,比H264、H265低很多。
      作为国人,希望国产编码标准能够开源免费,这样可以吸引到足够的开发者和硬件厂商,打造良好的生态,逐渐推广到世界。

    确定好编解码后,下一步就是怎么保存这些编码后的数据了。可以想象最简单的一种方案是直接保存编解码后的数据,对于直接保存为文件来说,这当然是没有问题的。
    但是把原始数据放在网络上传播,就有点困难了。我们知道网络是一个不确定的环境,数据有可能丢失或者顺序错位,这时给原始的视频数据加一层壳,在这层壳上添加
    编号,以及一些校验数据,就可以大大降低网络传输的不确定性了。
    在网络传输中,为了方便数据传输,常常对数据的打包后发送,被称为封包。打包的数据分成两个部分,包括控制信息,也就是表头(header),和数据本身,也就是负载(payload)。解包即封包的反向操作了,通过读取表头header里的信息,提取负载数据。
    虽然文件可以不用封包,但是我们常见的视频文件,其实也是对编码后的视频封包了,方便压缩传输和自定义(比如封装字幕加水印啥的)。

    比如常见的mkv格式,mkv实际是容器,内部可以装不同编码类型的原始视频,既可以是h264,也可以是h265的。

    音频基础

    采样率

    我们听到的声音是声波,声波是一种模拟信号,要想让计算机处理,得把其变成数字信号,这个转换被叫做A/D(模数)转换。
    怎么把声波变为数字信号呢?这就需要采样,或者叫抽样了。采样率则是指录音设备在一秒钟内对声音信号的采样次数,单位Hz(赫兹)
    如下图,如果采样的间隔越小,那么对声音的还原度不久越高了吗?

    音频压缩

    同视频一样,如果未经压缩,原始数字音频信号流(PCM编码)文件也是大的吓人。
    音频压缩也是应用了人的听觉差异,包括时域和空域。
    空域:人耳对低频和高频不敏感,可以直接把这些信号去除。
    时域:高频声音会覆盖前后几十毫秒的低频声音,那么这几十毫秒的信号也可以去除。
    当然这个同视频一样,这个是基础压缩,在这么处理后,还能够继续用算法来压缩。
    音频压缩又分为有损压缩(即能够还原原始音频),和无损压缩(即不能还原)。
    常见的音频编码又:

    • aac 收费
    • mp3 收费
    • ogg 开源
    • wav 原始 直接在PCM上加了描述信息,没有压缩
    • ape 无损压缩

    其它理论

    位数

    视频:比如我们保存图片有8位、16位,位数越多则单个像素点的色彩种类越多。
    音频:对声音来说,比如上面的采样率,如果纵坐标范围划分的越细,那么记录的声音强弱范围也越详细。

    码率/码流/比特率

    在摄像头配置界面,我们常见的一个选项就是码率了。知道码率后,可以直接用 码率x时间/8 来估算 文件大小。
    为什么除以8呢?因为码率的单位是b(bit),文件用的是B(Byte),一个字节是8位。
    码率有动态码率和静态码率,在确定分辨率和帧率后,码率仍然是可以调整的,码率调整的是压缩率。码率不仅是视频,也是音频的一个参数。
    码率越高,质量越好。但是网络传输条件下,我们往往要做取舍,选择适当的码率。
    我们先使用ffprobe -i 文件路径 发现输出了下面的内容,展示了视频文件的元数据、包括时长、码率、音视频编码器,分辨率等

     Metadata:
        major_brand     : mp42
        minor_version   : 1
        compatible_brands: mp41mp42isom
        creation_time   : 2019-10-22T07:09:16.000000Z
      Duration: 00:31:46.72, start: 0.000000, bitrate: 15047 kb/s
        Stream #0:0(zho): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 251 kb/s (default)
        Metadata:
          creation_time   : 2019-10-22T07:09:16.000000Z
          handler_name    : Core Media Audio
        Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 14791 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)
        Metadata:
          creation_time   : 2019-10-22T07:09:16.000000Z
          handler_name    : Core Media Video
    
    

    常见码率

    dts pts gop

    在播放视频的时候,网络情况不好,或者拖动进度条,会出现音视频不同步的问题。音视频不同步,就和下面两个概念有关了:
    DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
    PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

    要实现音视频同步,通常需要选择一个参考时钟,参考时钟上的时间是线性递增的,编码音视频流时依据参考时钟上的时间给每帧数据打上时间戳。在播放时,读取数据帧上的时间戳,同时参考当前参考时钟上的时间来安排播放。

    有时候还会遇到花屏,然后过一段时间后,自己又恢复了。这就和GOP有关了。
    GOP ( Group of Pictures) 是一组连续的画面,由一张 I 帧和数张 B / P 帧组成。花屏一般是因为中间有丢帧,造成解码失败,但上一组GOP结束后,便是新的GOP,新GOP的第一帧是I帧,可以独立解码。所以花屏后,过一会便自动恢复了。如果一直花屏,那么可能是视频文件错误了。

    下一章,我将分析m7s的代码结构,开始正式的音视频开发之旅。另外欢迎大家加入m7s微信群,共同探讨进步,加群链接

    参考文章及图片来源 :

    流媒体技术学习笔记之(五)码流、码率、采样率、比特率、帧速率、分辨率、高清视频的概念
    I帧、P帧、B帧、GOP、IDR 和PTS, DTS之间的关系
    音频开发基础
    什么是音频的采样率?采样率和音质有没有关系?


    作者:半山
    出处:http://www.cnblogs.com/xdao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    子类构造函数中调用虚函数问题验证
    socks5代理浅识
    关于C++标准库(第2版)std::remove_if的"特性"概述
    动态获取结构体中指定的属性值
    构造和析构函数定义为私有场景
    remove_pointer使用测验
    广播自定义消息实现进程间的通信问题
    遍历窗口权限问题
    嵌入窗口到桌面的问题
    实验一 熟悉实验环境
  • 原文地址:https://www.cnblogs.com/xdao/p/mediastream_03.html
Copyright © 2011-2022 走看看