h264 rgb yuv之间的关联

一  名词解释h264(一种视频压缩算法),rgb(红绿蓝三基色),yuv(亮度,U颜色分量,V颜色分量)

1 h264是动态压缩的,基于帧内和帧间参考的

2 rgb是最直观的静态画面(彩色的LED灯,液晶屏幕)

3 yuv 传统的黑白电视,没有uv数据即是黑白电视。

二 在windows上实现解码渲染(渲染用Direct X)

    AVPacket f_pPackage;
    av_init_packet(&f_pPackage);

avcodec_decode_video2(f_pCodecCtx,pFrame,GetFrame,&f_pPackage);

解码后的数据结构为

typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
    /**
     * pointer to the picture/channel planes.
     * This might be different from the first allocated byte
     * - encoding: Set by user
     * - decoding: set by AVCodecContext.get_buffer()
     */
    uint8_t *data[AV_NUM_DATA_POINTERS];//数据


    /**
     * Size, in bytes, of the data for each picture/channel plane.
     *
     * For audio, only linesize[0] may be set. For planar audio, each channel
     * plane must be the same size.
     *
     * - encoding: Set by user
     * - decoding: set by AVCodecContext.get_buffer()
     */
    int linesize[AV_NUM_DATA_POINTERS];//stride size  stride size一般要比图像宽度大,渲染的时候,要跳过这一块数据。

详见如下代码:

HRESULT lRet;
if(m_pDirect3DSurfaceRender == NULL)
return -1;
D3DLOCKED_RECT d3d_rect;
lRet=m_pDirect3DSurfaceRender->LockRect(&d3d_rect,NULL,D3DLOCK_DONOTWAIT);
if(FAILED(lRet))
return -2;


int i,j,k;
//拷贝Y数据
for(i = 0 ; i < height ; i++)//data[0] 循环行
{
memcpy(pSrc+width*i,
f_pFrame->data[0]+f_pFrame->linesize[0]*i,//linesize[0]个字节,每次拷贝,
width);
}


//拷贝U数据
for(j = 0 ; j < height/2 ; j++)
{
memcpy(pSrc+width*i+width/2*j,
f_pFrame->data[1]+f_pFrame->linesize[1]*j,
width/2);
}


//拷贝V数据
for(k  =0 ; k < height/2 ; k++)
{
memcpy(pSrc+width*i+width/2*j+width/2*k,
f_pFrame->data[2]+f_pFrame->linesize[2]*k, 
width/2);
}


byte * pDest = (byte *)d3d_rect.pBits;
int stride = d3d_rect.Pitch;



for(i = 0;i < height;i ++){
memcpy(pDest + i * stride,pSrc + i * width, width);
}
for(i = 0;i < height/2;i ++){
memcpy(pDest + stride * height + i * stride / 2,pSrc + width * height + width * height / 4 + i * width / 2, width / 2);
}
for(i = 0;i < height/2;i ++){
memcpy(pDest + stride * height + stride * height / 4 + i * stride / 2,pSrc + width * height + i * width / 2, width / 2);
}


  


   


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现H264YUV的过程一般可以分为以下几个步骤: 1. 打开H264文件并读取其中的视频帧数据。 2. 解析H264码流并从中提取出YUV数据。 3. 将提取出的YUV数据写入到目标文件中。 以下是一个简单的C语言示例代码,演示如何实现H264YUV的功能: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_FRAME_SIZE 1024*1024 // 最大帧大小 int main(int argc, char **argv) { FILE *fp_in = NULL, *fp_out = NULL; // 输入输出文件指针 unsigned char *buf = NULL; // 存储读取的帧数据 int nSize = 0, nLen = 0, nWidth = 0, nHeight = 0, nFrameType = 0, nFrameRate = 0; // 帧数据的大小、长度、宽度、高度、类型、帧率等信息 unsigned char *pY = NULL, *pU = NULL, *pV = NULL; // YUV数据指针 int nYSize = 0, nUSize = 0, nVSize = 0; // YUV数据大小 if (argc != 3) { printf("usage: %s <input.h264> <output.yuv>\n", argv[0]); return -1; } // 打开输入文件 fp_in = fopen(argv[1], "rb"); if (!fp_in) { printf("failed to open input file %s\n", argv[1]); return -1; } // 打开输出文件 fp_out = fopen(argv[2], "wb"); if (!fp_out) { printf("failed to open output file %s\n", argv[2]); return -1; } // 分配缓冲区 buf = (unsigned char*)malloc(MAX_FRAME_SIZE); if (!buf) { printf("failed to allocate memory\n"); return -1; } // 读取帧数据 while ((nLen = fread(buf + nSize, 1, MAX_FRAME_SIZE - nSize, fp_in)) > 0) { nSize += nLen; if (nSize >= 4 && buf[nSize-4] == 0x00 && buf[nSize-3] == 0x00 && buf[nSize-2] == 0x00 && buf[nSize-1] == 0x01) { // 解析帧数据 if (nWidth && nHeight) { fwrite(pY, 1, nYSize, fp_out); fwrite(pU, 1, nUSize, fp_out); fwrite(pV, 1, nVSize, fp_out); } nFrameType = (buf[4] & 0x1f); nWidth = ((buf[5] & 0xff) << 8) | (buf[6] & 0xff); nHeight = ((buf[7] & 0xff) << 8) | (buf[8] & 0xff); nFrameRate = (buf[9] & 0xff); if (nFrameType == 5) { // IDR帧 nYSize = nWidth * nHeight; nUSize = nVSize = nYSize / 4; pY = buf + nSize - (nYSize + nUSize + nVSize); pU = pY + nYSize; pV = pU + nUSize; } else { // 非IDR帧 pY = pU = pV = NULL; } } } // 关闭文件 if (fp_in) { fclose(fp_in); } if (fp_out) { fclose(fp_out); } // 释放缓冲区 if (buf) { free(buf); } return 0; } ``` 以上代码只是一个简单的示例,实际的H264YUV过程可能还需要进行一些其他的处理,例如进行解码、图像处理等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值