这两天在阅读电视转发服务器中的流媒体底层库的源码时,在看到显示部分的时候,遇到了一些疑问:

就是在用d3d做显示时候,我们显示的数据格式,指定为yv12,对于YV12的数据格式在内存中的分布,可以参考YV12的相关文章,这里我就暂时略过。

下面是将数据拷贝到显示的锁定内存中,用于显示:

for(i = 0;i < h;i ++){//Y数据拷贝
memcpy(p + i * stride,item->output + i * w, w);
}
for(i = 0;i < h/2;i ++){//U数据拷贝
memcpy(p + stride * h + i * stride / 2,item->output + w * h + w * h / 4 + i * w / 2, w / 2);
}
for(i = 0;i < h/2;i ++){//V数据拷贝
memcpy(p + stride * h + stride * h / 4 + i * stride / 2,item->output + w * h + i * w / 2, w / 2);
}

而在显示之前,也就是解码的时候,也进行过数据的拷贝:

memcpy(&(pItemF.head),&(m_tRecentItem.head),sizeof(AV_HEAD_PARAM));
for (int i=0;i<m_tRecentItem.head.height;i++)//Y数据拷贝   
memcpy(pYUVBuf+i*m_tRecentItem.head.width , m_tRecentItem.picture->data[0]+i*m_tRecentItem.picture ->linesize[0], m_tRecentItem.head.width);
for (int i=0;i<m_tRecentItem.head.height/2;i++)//U数据拷贝
memcpy(pYUVBuf+m_tRecentItem.head.height*m_tRecentItem.head.width+i*m_tRecentItem.head.width/2 , m_tRecentItem.picture->data[1]+i*m_tRecentItem.picture ->linesize[1], m_tRecentItem.head.width/2);
for (int i=0;i<m_tRecentItem.head.height/2;i++)//V数据拷贝
memcpy(pYUVBuf + m_tRecentItem.head.height*m_tRecentItem.head.width + m_tRecentItem.head.height/2 * m_tRecentItem.head.width/2 + i*m_tRecentItem.head.width/2 , m_tRecentItem.picture->data[2]+i*m_tRecentItem.picture ->linesize[2], m_tRecentItem.head.width/2);

而上面的item->output=pYUVBuf

如果显示的数据是YV12,那么解码以后的数据格式又是怎么样的格式?

--------------------------------------------------------------

在经过一番查找资料以后知道,解码以后的数据格式是I420.

在此博客中提过:http://blog.sina.com.cn/s/blog_4ae178ba01018o7q.html

解码

如果您只要求解成YUV 420I数据,只需一次调用就可以了:

avcodec_decode_video(g_pCodecCtx, g_pavfFrame, (int *)&nGot, (unsigned __int8 *)pSrcData, dwDataLen);

这里,nGot用来返回解码成功与否,avcodec_decode_video调用完成后,如果nGot不等于0,则表示解码成功,否则未解出视频帧。

pSrcData是待解的H264编码的一段数据流,dwDataLen表示该段数据流的长度,单位是byte。

解 码后的视频帧(YUV数据)被存入g_pavfFrame,g_pavfFrame->data[0]、 g_pavfFrame->data[1]、g_pavfFrame->data[2]即是YUV数据。下面的示例代码把YUV数据压在了一 块内存里,排列方式为:

YY

YY

U

V

该函数有返回值:如果解码成功,则返回本次解码使用的码流字节数,否则返回0。

------------------------------------------------------------------------

YV12和I420的区别
一般来说,直接采集到的视频数据是RGB24的格式,RGB24一帧的大小size=width×heigth×3 Bit,RGB32的size=width×heigth×4,如果是I420(即YUV标准格式4:2:0)的数据量是 size=width×heigth×1.5 Bit。
在采集到RGB24数据后,需要对这个格式的数据进行第一次压缩。即将图像的颜色空间由RGB2YUV。因为,X264在进行编码的时候需要标准的YUV(4:2:0)。但是这里需要注意的是,虽然YV12也是(4:2:0),但是YV12和I420的却是不同的,在存储空间上面有些区别。如下:
YV12 : 亮度(行×列) + V(行×列/4) + U(行×列/4)
I420 : 亮度(行×列) + U(行×列/4) + V(行×列/4)
可以看出,YV12和I420基本上是一样的,就是UV的顺序不同。
------------------------------------------------------------------

从上面这段话,我们可以知道,在做显示的时候,因为i420的格式数据和yv12格式的数据uv存储顺序不一样,所以我们在做显示的时候,对数据进行了一次从新存储。

FFMPEG的解码后的数据格式的更多相关文章

  1. FFMPEG结构体分析:AVFrame(解码后的数据)

    https://blog.csdn.net/jxcr1984/article/details/52766524 本文转自: http://blog.csdn.net/leixiaohua1020/ar ...

  2. 学习FFmpeg API – 解码视频

    本文转载 视频播放过程 首先简单介绍以下视频文件的相关知识.我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的 ...

  3. ffmpeg编解码视频导致噪声增大的一种解决方法

    一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...

  4. 【转】学习FFmpeg API – 解码视频

    ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料.可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快 ...

  5. FFmpeg编解码处理4-音频编码

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584948.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...

  6. FFmpeg编解码处理3-视频编码

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584937.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...

  7. FFmpeg编解码处理2-编解码API详解

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584925.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...

  8. FFmpeg编解码处理1-转码全流程简介

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584901.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...

  9. ffmpeg 编解码详细过程

    ffmpeg编解码详细过程     bobbypollo 转:ffmpeg编解码详细过程 原文地址:ffmpeg编解码详细过程(转)作者:心在飞翔原文出处: http://www.360doc.com ...

随机推荐

  1. scikit-learn 入门练习

    1. 一个简单的SVM实例: from sklearn import svm X = [[2, 0], [1, 1], [2,3]] y = [0, 0, 1] clf = svm.SVC(kerne ...

  2. Token:服务端身份验证的流行方案【转】

    01- 身份认证 服务端提供资源给客户端,但是某些资源是有条件的.所以服务端要能够识别请求者的身份,然后再判断所请求的资源是否可以给请求者. token是一种身份验证的机制,初始时用户提交账号数据给服 ...

  3. CSS2中的伪类与伪元素

    CSS 伪类用于向某些选择器添加特殊的效果. 我们最常见的就是有超链接的时候,向下面这样 a:link {color: #FF0000} /* 未访问的链接 */ a:visited {color: ...

  4. 使struct对象拥有可变大小的数组——(C++深度探索)

    首先摘录<Inside The C++ Object Model>中的一段话: 把单一元素的数组放在一个struct的尾端,于是每个 struct objects 可以拥有可变大小的数组: ...

  5. asp.net 通用的连接数据库实例代码

    asp.net中数据库连接代码,有需要的朋友可以参考一下. <%@ Page Language="C#" AutoEventWireup="true" C ...

  6. Error LNK2019:Unresolved External Symbol 的解决方案

    当头文件中声明了一个函数,但是在相应的源文件中却没有对该函数进行定义,则会出现为“解决的外部符号”(unresolved external symbol )错误.另外,当一个函数调用了外部的一个库文件 ...

  7. uniqueIdentifier在ios7不支持后的替代方法

    UIDevice的uniqueIdentifier方法在ios7就不支持了, 为了获得设备相关的唯一标识符, 参考了这里:https://github.com/Itayber/UIDevice-uni ...

  8. feginclient demo

    1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...

  9. 【转】Mysql两种存储引擎的异同【MyISAM和InnoDB】

    MySQL默认采用的是MyISAM. MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以 ...

  10. hdu 1007最近点对问题

    先说下题意,很简单,给n个点的坐标,求距离最近的一对点之间距离的一半.第一行是一个数n表示有n个点,接下来n行是n个点的x坐标和y坐标,实数. 这个题目其实就是求最近点对的距离.主要思想就是分治.先把 ...