YV12的视频回放

视频存储格式YUV420 NV12 NV21 i420 YV12详解 1、YUV简介 YUV格式有两大类:planar和packed。 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。 对于packed的YUV格式,每个像素点的Y,U,V是连续交*存储的。 YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色... 阅读详情

这两天等待应聘的offer,闲着无聊,回忆起1年多以前做的东西,mpeg4标准的rtp流,收到后在本地回放
我使用的是ddraw来显示,1开始为了先显示出东西进行调试,并且当时重点在同步以及接受流,所以当时用了yuv2bmp
这个东西;把yv12转换成了bmp,然后1桢1桢贴到窗口dc上。呵呵,效果可想;) 经过了矩阵转换又是draw->dc
后来项目进入优化阶段,决定用ddraw的overlay来显示yv12视频。具体的方法就是参照Dxsdk7里的“蚊子”程序。
把yv12直接传到overlay显示. ;)
蚊子现实的是yuv422,和yv12相比较,在逐行memcpy到pSurf的时候排列不同而已,具体参照yuv标准就行了

(简介ddraw的实用,dxsdk7是ddraw的最后版本了)

yuv2bmp的实现:
void  yuv2rgb_32(uint8_t *puc_y, int stride_y,
                uint8_t *puc_u, uint8_t *puc_v, int stride_uv,
                uint8_t *puc_out, int width_y, int height_y,
        unsigned int _stride_out)
{
/* int x, y;
 int stride_diff = 4 * (_stride_out - width_y);

 if (height_y < 0) {
  // we are flipping our output upside-down
  height_y  = -height_y;
  puc_y     += (height_y   - 1) * stride_y ;
  puc_u     += (height_y/2 - 1) * stride_uv;
  puc_v     += (height_y/2 - 1) * stride_uv;
  stride_y  = -stride_y;
  stride_uv = -stride_uv;
 }

 for (y=0; y<height_y; y++)
 {
  for (x=0; x<width_y; x++)
  {
   signed int _r,_g,_b;
   signed int r, g, b;
   signed int y, u, v;

   y = puc_y[x] +10;//- 16;
   u = puc_u[x>>1]-128;
   v = puc_v[x>>1]-128;

   _r = _R(y,u,v);
   _g = _G(y,u,v);
   _b = _B(y,u,v);

   r = _S(_r);
   g = _S(_g);
   b = _S(_b);

   puc_out[0] = r;
   puc_out[1] = g;
   puc_out[2] = b;
   puc_out[3] = 0;

   puc_out+=4;
  }

  puc_y   += stride_y;
  if (y%2) {
   puc_u   += stride_uv;
   puc_v   += stride_uv;
  }
  puc_out += stride_diff;
 }*/


/////////////  Intel MMX ///////////////

 int y, horiz_count;
 int stride_out = width_y <<2;

 if (height_y < 0) {
  // we are flipping our output upside-down
  height_y  = -height_y;
  puc_y     += (height_y   - 1) * stride_y ;
  puc_u     += ((height_y>>1) - 1) * stride_uv;
  puc_v     += ((height_y>>1) - 1) * stride_uv;
  stride_y  = -stride_y;
  stride_uv = -stride_uv;
 }

 horiz_count = -(width_y >> 3);

 
 for (y=0; y<height_y; y++) {
 
  _asm {
   push eax
   push ebx
   push ecx
   push edx
   push edi

   mov eax, puc_out      
   mov ebx, puc_y      
   mov ecx, puc_u      
   mov edx, puc_v
   mov edi, horiz_count
   
  horiz_loop:

   movd mm2, [ecx]
   pxor mm7, mm7

   movd mm3, [edx]
   punpcklbw mm2, mm7       ; mm2 = __u3__u2__u1__u0

   movq mm0, [ebx]          ; mm0 = y7y6y5y4y3y2y1y0 
   punpcklbw mm3, mm7       ; mm3 = __v3__v2__v1__v0

   movq mm1, mmw_0x00ff     ; mm1 = 00ff00ff00ff00ff

   psubusb mm0, mmb_0x10    ; mm0 -= 16

   psubw mm2, mmw_0x0080    ; mm2 -= 128
   pand mm1, mm0            ; mm1 = __y6__y4__y2__y0

   psubw mm3, mmw_0x0080    ; mm3 -= 128
   psllw mm1, 3             ; mm1 *= 8

   psrlw mm0, 8             ; mm0 = __y7__y5__y3__y1
   psllw mm2, 3             ; mm2 *= 8

   pmulhw mm1, mmw_mult_Y   ; mm1 *= luma coeff
   psllw mm0, 3             ; mm0 *= 8

   psllw mm3, 3             ; mm3 *= 8
   movq mm5, mm3            ; mm5 = mm3 = v

   pmulhw mm5, mmw_mult_V_R ; mm5 = red chroma
   movq mm4, mm2            ; mm4 = mm2 = u

   pmulhw mm0, mmw_mult_Y   ; mm0 *= luma coeff
   movq mm7, mm1            ; even luma part

   pmulhw mm2, mmw_mult_U_G ; mm2 *= u green coeff
   paddsw mm7, mm5          ; mm7 = luma + chroma    __r6__r4__r2__r0

   pmulhw mm3, mmw_mult_V_G ; mm3 *= v green coeff 
   packuswb mm7, mm7        ; mm7 = r6r4r2r0r6r4r2r0

   pmulhw mm4, mmw_mult_U_B ; mm4 = blue chroma
   paddsw mm5, mm0          ; mm5 = luma + chroma    __r7__r5__r3__r1

   packuswb mm5, mm5        ; mm6 = r7r5r3r1r7r5r3r1
   paddsw mm2, mm3          ; mm2 = green chroma

   movq mm3, mm1            ; mm3 = __y6__y4__y2__y0
   movq mm6, mm1            ; mm6 = __y6__y4__y2__y0

   paddsw mm3, mm4          ; mm3 = luma + chroma    __b6__b4__b2__b0
   paddsw mm6, mm2          ; mm6 = luma + chroma    __g6__g4__g2__g0
   
   punpcklbw mm7, mm5       ; mm7 = r7r6r5r4r3r2r1r0
   paddsw mm2, mm0          ; odd luma part plus chroma part    __g7__g5__g3__g1

   packuswb mm6, mm6        ; mm2 = g6g4g2g0g6g4g2g0
   packuswb mm2, mm2        ; mm2 = g7g5g3g1g7g5g3g1

   packuswb mm3, mm3        ; mm3 = b6b4b2b0b6b4b2b0
   paddsw mm4, mm0          ; odd luma part plus chroma part    __b7__b5__b3__b1

   packuswb mm4, mm4        ; mm4 = b7b5b3b1b7b5b3b1
   punpcklbw mm6, mm2       ; mm6 = g7g6g5g4g3g2g1g0

   punpcklbw mm3, mm4       ; mm3 = b7b6b5b4b3b2b1b0

   // 32-bit shuffle....
   pxor mm0, mm0            ; is this needed?

   movq mm1, mm6            ; mm1 = g7g6g5g4g3g2g1g0
   punpcklbw mm1, mm0       ; mm1 = __g3__g2__g1__g0

   movq mm0, mm3            ; mm0 = b7b6b5b4b3b2b1b0
   punpcklbw mm0, mm7       ; mm0 = r3b3r2b2r1b1r0b0

   movq mm2, mm0            ; mm2 = r3b3r2b2r1b1r0b0

   punpcklbw mm0, mm1       ; mm0 = __r1g1b1__r0g0b0
   punpckhbw mm2, mm1       ; mm2 = __r3g3b3__r2g2b2

   // 32-bit save...
   movq  [eax], mm0         ; eax[0] = __r1g1b1__r0g0b0
   movq mm1, mm6            ; mm1 = g7g6g5g4g3g2g1g0

   movq 8[eax], mm2         ; eax[8] = __r3g3b3__r2g2b2

   // 32-bit shuffle....
   pxor mm0, mm0            ; is this needed?

   punpckhbw mm1, mm0       ; mm1 = __g7__g6__g5__g4

   movq mm0, mm3            ; mm0 = b7b6b5b4b3b2b1b0
   punpckhbw mm0, mm7       ; mm0 = r7b7r6b6r5b5r4b4

   movq mm2, mm0            ; mm2 = r7b7r6b6r5b5r4b4

   punpcklbw mm0, mm1       ; mm0 = __r5g5b5__r4g4b4
   punpckhbw mm2, mm1       ; mm2 = __r7g7b7__r6g6b6

   //32-bit save...
   add ebx, 8               ; puc_y   += 8;
   add ecx, 4               ; puc_u   += 4;

   movq 16[eax], mm0        ; eax[16] = __r5g5b5__r4g4b4
   add edx, 4               ; puc_v   += 4;

   movq 24[eax], mm2        ; eax[24] = __r7g7b7__r6g6b6
   
   // 0 1 2 3 4 5 6 7 rgb save order

   add eax, 32              ; puc_out += 32

   inc edi
   jne horiz_loop   

   pop edi
   pop edx
   pop ecx
   pop ebx
   pop eax

   emms
      
  }


  puc_y   += stride_y;
  if (y&0x01){//%2) {
   puc_u   += stride_uv;
   puc_v   += stride_uv;
  }
  puc_out += stride_out;
 }
}

YV12转opencv IplImage void Yv12ToImg(uchar *pin, IplImage* img) { uchar y, cb, cr; int ySize = img->width * img->height; int uSize = ySize / 4; uchar *pY = pin; uchar *pU = pY 阅读详情

相关推荐

YV12转为I420

YV12在内存的中的存储顺序为: Y Y Y Y Y Y Y Y Y Y  U U U U U U U U U V  V  V  V  V  V  V V  I420在内存中的存储顺序为: Y Y Y Y Y Y Y Y Y Y  V  V  V  V  V  V  V V  U U U U U U U U U 二者只是U、V排列顺序不同,YV12(YU

tkp2014的专栏 1603

音视频数据处理入门:原始视频格式YUV,NV12,NV21,YV12,YU12(I420)

我们知道,在Camera中设置Preview的回调函数onPreviewFrame时谷歌推荐我们使用NV21,YV12两种格式,因为这两种格式几乎在所有的设备里都通用。然而,视频的格式远远不止这俩种,有时可能需要转成NV12,YU12(I420)。。。。。那么,我们就需要理解如何将这些码流格式实现互相转换。 我们首先先了解什么是YUV,什么是RGB,因为这是构成图像的基本元素。音视频编码颜色模型中就包括两种RGB和YUV。 1.什么是YUV,什么是RGB 1.1 什么是RGB RGB我们比较熟悉,它就是我们

hirezy 1万+

D3D优化YV12视频渲染功能增强

YV12是一种广泛应用于视频处理和传输的颜色格式,属于YUV颜色空间的一种。它的特点是将图像数据分为亮度(Y)和色度(U和V)三个组成部分。Y对应于亮度信息,而U和V则包含了色度信息,记录了图像的颜色信息。YV12格式将色度数据以空间采样率进行降低,从而实现了更高的压缩比,同时保持了图像质量。YV12格式的另一大特点是对数据存储结构的优化,通常采用平面结构,使得内存访问模式更为高效。它利用了人类视觉系统对于亮度变化更加敏感的特性,将色度信息的分辨率降低到亮度的四分之一,既节省了空间,又减少了计算量。

weixin_35696112的博客 1022

高效率视频播放: 如何使用3D API 进行视频的高质量回放

http://blog.youkuaiyun.com/Nhsoft/archive/2007/10/16/1826933.aspx 这个月准备写一些关于如何使用3D API搭建一个高质量的视频回放后端,其实想想也是时候了,在这个公司快一年了,Backend从开始的支持RGB24,到YUV的支持,到后来质量的不断提高, 尤其是播放质量被SONY这样苛刻的公司接受以后,总觉得该写一点东西了.    

杨德龙的专栏 1389

实现海康摄像头视频捕获与YV12格式数据的DirectDraw显示

简介:本文将详细讨论如何使用DirectDraw技术来展示由海康摄像头捕获并解码成YV12格式的视频数据。首先解释YV12色彩空间的概念,然后阐述从海康摄像头获取原始视频流、解码成YV12格式的过程。接着介绍DirectDraw的基本使用,包括初始化、创建显示表面、处理YV12数据以及如何实现高效显示。最后,讨论实际应用中需要注意的问题,如错误处理、多线程等,并指明DirectDraw在现代系统中的替代技术。文章可能提供名为"HKCapture"的文件作为实现该功能的代码参考。

weixin_35756892的博客 1302

海康摄像头捕获并解码成YV12数据用directdraw显示

海康摄像头捕获并解码成YV12数据用directdraw显示,优快云必须要设置资源分,没办法设置为0分

高效率视频播放: 如何使用3D API 进行视频的高质量回放(1)

文章最初发表于it168http://tech.it168.com/n/d/2007-04-18/200704181517531.shtml 这个月准备写一些关于如何使用3D API搭建一个高质量的视频回放后端,其实想想也是时候了,在这个公司快一年了,Backend从开始的支持RGB24,到YUV的支持,到后来质量的不断提高, 尤其是播放质量被SONY这样苛刻的公司接受以后,总觉得该写一...

javahigh1 93

基于D3D的YV12视频渲染

基于D3D的YUV视频显示源代码,可以同时支持YV12、I420、NV12、YUY2、UYVY、RGB24、RGB32、RGB555、RGB565格式。支持半透明文本叠加。Windows XP SP2 DXSDK9.0c 9800GT测试通过。

海康网络摄像机调用SDK解码Java版

两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack    解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.dll interface PlayCtrl extends StdCallLibrary { PlayCtrl INSTANCE = (PlayCtrl) Native...

weixin_34248849的博客 1220

NULL: file not found

NULL: file not found

Linux CentOS7文件系统(/dev/var)的容量扩充

原因是之前安装docker后,再想安装Nessus,系统说home、var文件系统的内存都不够。

JHoanna的博客 3226

DDraw7 overlay 使用心得

本应DDraw7 overlay的东西都很老了,还去学习他干嘛?没办法,爱技术,爱专研。但你别说,现在D3D的东西都已经很厉害,但只有overlay能很好的重现视频回放,无论从性能,或者效果(tearing effect)都是最好的。 闲话少说,重新挖出dx7sdk来专研的一番,里面mosqiuto(蚊子)的样例好好看看了。发现了有些东西还是值得记下了的: 1. 开始的是很快都把视频解码出...

weixin_30779691的博客 133

线性分类器(Linear Classifier)

线性分类器 如上图所示,这是二维空间中的一个数据集,如果他正好能够被一条直线分成两类,那么我们称它为线性可分数据集,这条直线就是一个线性分类器。 在三维空间中,如果数据集线性可分,是指能够被一个平面分为两类。 在一维空间中,所有的点都在一条直线上,如果线性可分。可以理解为它们能够被一个点分开。 这里的直线、平面、点被分为决策边界。 一个 m 维空间中的数据集,如果能够被一个超平面一分为二,那么这个数据集就是线性可分的,这个超平面就是决策边界。 例如,这是二维平面上的一条直线, 它可以把平面切分成两

xuechanba的博客 1万+

YV12转换到RGB32[]

在做视频回调解码时,需要用到数据转换,找了很多,后来公司同事写了一个,基本上可以通用,发出来给大家分享下。 /// /// 将YV12转换成RGB32 /// /// yv12数据 /// 图片高度 /// 图片宽度 /// public static byte[]

mt122的专栏 3959

带隙基准电路实战:温度补偿与流片调优全解析

带隙基准(BGR)是模拟芯片中实现高精度、低温漂电压参考的核心电路,其本质是利用硅材料禁带宽度的物理稳定性,通过PTAT(正温度系数)与CTAT(负温度系数)电压的加权叠加抵消温度影响。原理上需兼顾一阶线性补偿与二阶曲率校正,技术价值在于支撑ADC/DAC/LDO等关键模块的精度与可靠性。典型应用场景涵盖车规级MCU、工业传感器和高精度电源管理芯片。工程落地难点集中于工艺偏差、运放失调、寄生效应及版图热电耦合——这正是‘带隙基准设计’与‘带隙基准调优’的根本分野。本文聚焦真实流片经验,深入拆解Widlar架

weixin_42628280的博客 255

撸毛笔记-朴朴超市 v1.01

朴朴超市 v1.01脚本地址:自动签到和组队赚朴分, 朴分可以抵扣50%的金额组队瓜分需要4人成团, 每个号每天只能开团和入队各一次每天跑一两次即可使用扫码或自己想办法捉refreshToken扫码获取token: (先微信进入朴朴超市小程序并登录注册过账号再扫码)把获取的refreshToken和备注(非必须)填到文件pupuCookie.txt里(第一次运行会自动创建), 多账号换行或&或@隔开。

xiaoshun007的专栏 1813

YV12和I420的区别

一般来说,直接采集到的视频数据是RGB24的格式,RGB24一帧的大小 RGB24 size=width×heigth×3 Bit RGB32 size=width×heigth×4 Bit 如果是I420(即YUV标准格式4:2:0)的数据量是 size=width×heigth×1.5 Bit 在采集到RGB24数据后,需要对这个格式的数据进行第一次压缩。即将图像的颜色空间由RGB2Y...

宁静致远 2775

视觉Transformer实战 | Vision Transformer(ViT)详解与实现

在计算机视觉领域,卷积神经网络 (CNN) 长期以来一直是处理图像任务的主流架构。然而,随着 Transformer 在自然语言处理领域的巨大成功,研究人员开始探索将这种基于自注意力机制的架构应用于视觉任务。Vision Transformer (ViT) 是这一探索的重要里程碑,它首次证明了纯 Transformer 架构在图像分类任务上可以超越最先进的 CNN 模型。本文将详细介绍 ViT 的技术原理,并使用 PyTorch 从零开始构建 ViT 模型用于图像分类任务。

盼小辉丶的博客 4万+
上一篇: 文件过滤驱动的开发(上)
下一篇: 时间太少了
code_farmer
博客等级 码龄22年 9粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值