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