音视频解码之YUV视频格式

前言: 由于工作的需要接触到了音视频方面的知识,在这里就行一些知识的

整理,以免后面忘记.后面我也会写一些工作中遇到的问题整理,以及在音视

频这方面的进阶,期待自己的成长.

我在音视频开发的过程中,最早接触到的就是camera了,上一篇也有讲到camera的预览拍照以及camera的相关类的介绍,在这一篇中,来总结下视频格式方面的知识.

复制代码

1.YUV的介绍

YUV其实就是一种颜色的编码方式,Y表示亮度,U(Cb)V(Cr)表示色度.当

我们只显示Y数据时,那么图像信息就会显示是灰色,彩色电视采用YUV就

是为了解决黑白电视的兼容.

复制代码

YUV包含YUV_444,YUV_422,YUV_420,其实这些格式只是对采样率的不同还有YUV数据存储方式的不同来分类的:

YUV 4:4:4采样,每一个Y对应一组UV分量。

YUV 4:2:2采样,每两个Y共用一组UV分量。

YUV 4:2:0采样,每四个Y共用一组UV分量。

复制代码

下面分别介绍下常见的YUV的存储方式:

1.0 YUVY 格式(YUV 4:2:2)

Y0 Cb0 Y1 Cr0 Y2 Cb1 Y3 Cr1

Y4 Cb2 Y5 Cr2 Y6 Cb3 Y7 Cr3

YUYV为YUV422采样的存储格式中的一种,相邻的两个Y共用其相邻的两

个Cb、Cr,分析,对于像素点Y0、Y1 而言,其Cb、Cr的值均为 Cb0、Cr0,其他的像素点的

YUV取值依次类推。

2.0 UYVY 格式 (属于YUV422)

Cb0 Y0 Cr0 Y1 Cb1 Y2 Cr1 Y3

Cb2 Y4 Cr2 Y5 Cb3 Y6 Cr3 Y7

这种方式与1.0类似,只是排列方式不同而已

3.YUV422P(属于YUV422)

Y0 Y1 Y2 Y3

Y4 Y5 Y6 Y7

Cb0 Cb1

Cb2 Cb3

Cr0 Cr1

Cr2 Cr3

YUV422P也属于YUV422的一种,它是一种Plane模式,即打包模式,并不是将YUV数据交错存储,

而是先存放所有的Y分量,然后存储所有的U(Cb)分量,最后存储所有的V(Cr)分量,如上所示。

其每一个像素点的YUV值提取方法也是遵循YUV422格式

的最基本提取方法,即两个Y共用一个UV。比如,

对于像素点Y0、Y1 而言,其Cb、Cr的值均为 Cb0、Cr0。

4.0YV12,YU12格式(属于YUV420)

Y0 Y1 Y2 Y3

Y4 Y5 Y6 Y7

Cb0 Cb1

Cr0 Cr1

YU12和YV12属于YUV420格 式,也是一种Plane模式,将Y、U、V分量分别打包,依次存储。其每一

个像素点的YUV数据提取遵循YUV420格式的提取方式,即4个Y分量共用一

组UV。注意,上图中,Y0、Y1、Y4、Y5共用Cr0、Cb0,其他

依次类推。

5.0NV21,NV12格式(属于YUV420)

Y0 Y1 Y2 Y3

Y4 Y5 Y6 Y7

Cb0 Cr0 Cb1 Cr1

V12和NV21属于YUV420格式,是一种two-plane模式,即Y和UV分为两个

Plane,但是UV(CbCr)为交错存储,而不是分为三个plane。其提取方

式与上一种类似,即Y0、Y1、Y4、Y5共用Cr0、Cb0

总结:

I420: YYYYYYYY UU VV =>YUV420P

YV12: YYYYYYYY VV UU =>YUV420P

NV12: YYYYYYYY UVUV =>YUV420SP

NV21: YYYYYYYY VUVU =>YUV420SP

复制代码

2.0 YUV_420888格式介绍

Android PAI 对 YUV420_888的介绍 ,大致意思如下:

它是YCbCr的泛化格式,能够表示任何4:2:0的平面和半平面格式,每个分量用8 bits 表示。带有这种格式的图像使用3个独立的Buffer表示,每一个Buffer表示一个颜色平面(Plane),除了Buffer外,它还提供rowStride、pixelStride来描述对应的Plane。

使用Image的getPlanes()获取plane数组:

Image.Plane[] planes = image.getPlanes();

它保证planes[0] 总是Y ,planes[1] 总是U(Cb),

planes[2]总是V(Cr)。并保证Y-Plane永远不会和U/V交叉

(yPlane.getPixelStride()总是返回)。U/V-Plane总是有相同

的rowStride和 pixelStride()(即有:uPlane.getRowStride()

== vPlane.getRowStride() 和 uPlane.getPixelStride() == vPlane.getPixelStride();)。

复制代码

以分辨率1280*720为例,获取相关信息如下:

Image image = reader.acquireNextImage();

if (image == null) {

return;

}

Image.Plane[] planes = image.getPlanes();

if (!isFrist) {

isFrist = true;

for (int i = 0; i < planes.length; i++) {

int rowStride = planes[i].getRowStride();

int pixelStride = planes[i].getPixelStride();

int remaining = planes[i].getBuffer().remaining();

int width = image.getWidth();

int height = image.getHeight();

Log.i(TAG, "pixelStride " + pixelStride);

Log.i(TAG, "rowStride " + rowStride);

Log.i(TAG, "buffersize " + remaining);

Log.i(TAG, "width " + width);

Log.i(TAG, "height " + height);

Log.i(TAG, "Finished reading data from plane " + i);

}

}

复制代码pixelStride 1

rowStride 1280

buffersize 921600

width 1280

height 720

Finished reading data from plane 0

pixelStride 2

rowStride 1280

buffersize 460799

width 1280

height 720

Finished reading data from plane 1

pixelStride 2

rowStride 1280

buffersize 460799

width 1280

height 720

Finished reading data from plane 2

复制代码

plane[0] 是Y数据,从rowStride是1280和 pixelStride是1,可知每行1280个像素且Y数据之间无间隔,从buffer size / rowStride = 720 Y数据有720行。

plane[1] 是U数据,rowStride 是1280, rowStride是2 ,说明每行1280个像素中每两个连续的U之间隔了一个像素,buffer中索引为: 0 , 2 , 4, 6, 8 … 是U数据,即步长为2。 每行实际的U数据只占1/2 ,buffer size / rowStride = 360 只有360行,说明纵向采样也是1/2 ,但buffer size 是 plane[0]的 1/2而不是1/4, 连续的U之间到底存储了什么数据,才使得buffer size 变为plane[0]的1/2了?

同plane[1]。

其中当pixelStride等于1的时候说明planes[1]是连续的U数据 planes[2]是连续的V数据,

当pixelStride等于2的时候说明planes[1]是非连续的U数据而是UVUV排列 planes[2]是非连续的V数据而是VUVU,不难看出当pixelStride=1时 planes[0]+planes[1]+planes[2]为I420格式 planes[0]+planes[2]+planes[1]位YV12格式,

其中当pixelStride=2的时候,planes[0]+planes[1]为NV12格式数据 planes[0]+planes[2]为NV21数据

参考文章

android 显示yuv数据格式,YUV数据格式的理解相关推荐

  1. 【转】自上而下解读Android显示流程

    同济大学 计算机系统结构硕士 107 人赞同了该文章 当我们点击"知乎"这个应用后,它是怎么在屏幕上显示出来的? 这个问题困扰我很久了,当我刚接触显示的时候,大约是十年前的事情了, ...

  2. Android显示系统详解

    一.显示系统的分类: 我们来思考一个问题:从普通用户角度来说,某个APP页面(例如购物APP首页)是怎么被显示到屏幕的? 首先看到的是物理屏幕,然后是屏幕中软件工程师编写的APP页面,也就是手机屏幕驱 ...

  3. 【Android显示系统初探】surface初相识

    Android显示系统非常复杂,从早期版本演化至今有很大的变化和改进,所以从当前的版本直接去查看会很困难. 初学者看到繁多的概念和类会感到无从下手. 这里我们将从实践应用的方式来展开这一系列,试图对A ...

  4. Android显示架构

    一.术语 二.显示机制 2.1 水平和垂直同步信号 在早期的CRT显示器,电子枪从上到下逐行扫描,扫描完成后显示器就呈现一帧画面.然后电子枪回到初始位置进行下一次扫描.为了同步显示器的显示过程和系统的 ...

  5. 图文浅析之Android显示原理

    一,写在前面 本篇文章会以图文的方式介绍Android设备的显示原理,不会深入到源码去分析一些细节,阅读本篇文章会对显示原理有个感性的认识,以便更好的理解Android性能优化相关的原理. 二,为什么 ...

  6. [深入理解Android卷二 全文-第六章]深入理解ActivityManagerService

    由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该因为纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的全部内容 第 ...

  7. Android 显示刷新机制、VSYNC和三重缓存机制

    Android 显示刷新机制.VSYNC和三重缓存机制 为了理解 APP 是如何进行渲染的,我们就必须了解手机硬件是如何工作的,也必须理解什么是 VSYNC. 首先,我们需要了解2个相关概念: 刷新率 ...

  8. Android 显示、隐藏状态栏和导航栏

    Android 显示.隐藏状态栏和导航栏 控制状态栏显示,Activity的主题中配置全屏属性 <item name="android:windowFullscreen"&g ...

  9. android显示多个网络图片不显示,Android显示网络图片实例

    本文实例讲述了Android显示网络图片的方法,分享给大家供大家参考.具体方法如下: 一般来说,在Android中显示一张网络图片其实是非常简单的,下面就是一个非常简单的例子: 步骤1: ① 创建你的 ...

  10. Android显示九宫图(自定义圆角,仿微信九宫格图)

    详细解析Android显示九宫图(自定义圆角,仿微信九宫格图) 这是一个自定义九宫格图片框架,里面有设置圆角大小,还有当图片一张的时候控件自定义的大小,图片的间隔,四张图片的时候图片自定义为两行两列等 ...

最新文章

  1. 聊聊EIGRP的自动汇总与手工汇总
  2. note 11 字典
  3. 【安全牛学习笔记】漏洞扫描
  4. 02数据库表的相关操作
  5. 20190830:(leetcode习题)二叉树的最大深度
  6. web服务器去掉域名www的301重定向设置方法
  7. Java 谷歌翻译 api 调用
  8. 课时5 企业Web服务器现场抓鸡案例分享
  9. python分析国家统计局数据网站人口结构、出生率、死亡率等基本情况
  10. 虚函数表和虚函数指针
  11. 历代治国理政者的教科书——金木水火土的起源之书:周朝的统治大法——《洪范》...
  12. Cesium设置三维球的视角和位置(中心点)
  13. 发那科机器人GI分配_发那科机器人应用-运动指令入门(1)
  14. 网易七鱼“大闹”客服行业,真能一举定乾坤?
  15. Weex Android 动画揭秘
  16. 使用微软的语音识别引擎Microsoft Speech API进行语音控制
  17. Tf2实现MogrifierLSTM分类
  18. Microsoft 智能手机(Smartphone)C#开发入门
  19. 2022CoCa: Contrastive Captioners are Image-Text Fountion Models
  20. 我敢说80% 的程序员都掉进了「老鼠赛跑」的陷阱

热门文章

  1. 寻找隐形冠军 支付宝、微信用得那么溜,可谁知道背后有一名“上海功臣
  2. Visual Studio 2017 - Windows应用程序打包成exe文件(1)- 工具简单总结
  3. Mybatis【配置文件】就是这么简单
  4. 可伸缩系统的设计模式(译)
  5. http://www.cnblogs.com/youfan/articles/3216816.html
  6. PHP日期格式转时间戳
  7. Cygwin鸡毛蒜皮
  8. 针对19端口的Chargen进行Dos***
  9. [原]不祥的CPU——Alpha
  10. Ansible04-任务控制