h264 rgb yuv之间的关联

来源:互联网 发布:阿里健康数据研究中心 编辑:程序博客网 时间:2024/06/05 20:29

一  名词解释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);
}


    

更多开源流媒体技术,请关注我们的微信:EasyDarwin 


   


原创粉丝点击