具体实施方式
在本发明的实施例中,通过利用MPEG4译码模块的内部中断信号,驱动行缓冲区模块将解码得到的YUV格式的视频图像数据直接显示到视频层。
为了使本发明实施例的目的、技术方案和优点更加清楚明白,下面结合实施例和附图,对本发明实施例做进一步详细地说明。在此,本发明的示意性实施例及说明用于解释本发明,但并不作为对本发明的限定。
参见图1,为本发明的实施例中视频软解码输出的方法流程图,具体步骤如下:
步骤101、MPEG4译码模块将视频压缩数据解码为YUV格式的视频图像数据,并将解码得到的YUV格式的视频图像数据存放到行缓冲区模块的输入缓冲区中;
在本步骤中,首先通过MPEG4译码模块将属于RMVB格式、H.264格式和WMV格式中的任意一种的视频压缩数据解码为YUV格式的视频图像数据,然后将解码得到的YUV格式的视频图像数据存放到行缓冲区模块的输入缓冲区中,具体可以是MPEG4译码模块先将该YUV格式的视频图像数据存储到MPEG4译码模块的输出缓冲区中,然后再将该YUV格式的视频图像数据转移至行缓冲区模块的输入缓冲区,该MPEG4译码模块的输出缓冲区和行缓冲区模块的输入缓冲区为同一个内存空间。
步骤102、当行缓冲区模块接收到中断信号后,行缓冲区模块将输入缓冲区中存放的YUV格式的视频图像数据传输给图像传送处理模块;
上述中断信号可以是MPEG4译码模块的内部中断信号,例如在该MPEG4译码模块的输入缓冲区中预先存储一段固定的原始mp4码流,当YUV格式的视频图像数据都存储到行缓冲区的输入缓冲区中时,启动MPEG4译码模块对该预先存储的固定的原始mp4码流进行解码,MPEG4译码模块将解码后的数据,以UYVY方式排列输出到MPEG4译码模块的输出缓冲区中,解码完成后,该MPEG4译码模块向行缓冲区模块发送一内部中断信号;当行缓冲区模块接收到中断信号后,该行缓冲区模块将输入缓冲区中存放的YUV格式的视频图像数据传输给图像传送处理模块。
步骤103、图像传送处理模块将YUV格式的视频图像数据传送给显示控制模块,并通过显示控制模块将YUV格式的视频图像数据显示到视频层。
在本实施例中,该显示控制模块可以是液晶显示控制(LCDC,LiquidDisplay Controller)模块,该液晶显示控制模块接收从图像传送处理(IPP,ImagePost Processing)模块传送来的YUV格式的视频数据,并将该YUV格式的视频数据显示到视频层。
液晶显示控制模块是用来对液晶屏幕上每个像素的颜色和亮度进行控制的模块,这个模块将视频、图片和背景颜色按各种要求柔和在一起形成一个完整的帧图像,并且将整帧图像传送到LCD接口上从而在液晶屏上显示出来。
由上述技术方案可知,通过利用MPEG4译码模块的内部中断信号,驱动行缓冲区模块将解码得到的YUV格式的视频图像数据直接显示到视频层,并且软解码后的视频显示可以实现放大、缩小、特效和旋转等功能。从而不必像现有技术中,需要首先将得到的YUV格式的视频图像数据转换为RGB格式的视频图像数据,然后将该RGB格式的视频图像数据显示到背景层,而是可以直接将解码得到的YUV格式的视频图像数据显示到视频层。
下面介绍在本实施例中预先的配置过程:
在本实施例中,可预先存储一段固定的原始mp4码流,此段mp4码流视频数据的size为64×64,配置如下:
static_align(4)unsigned char mp4d_data[536]={
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x20,0x00,0xC8,0x88,0x80,0x0F,0x50,0x20,0x40,
......
0x50,0x72,0x9E,0x95,0x72,0xC6,0x9E,0xBE,0x4D,0x9F,0xB4,0xAE,0x40,0xC 1,0xC5,0x99,
0x62,0x5F,0x28,0x0C,0xA9,0x10,0xC2,0x83,0xC1,0x7F,0xC3,0xE6,0x94,0x0C,0x76,0xED,
0xC8,0x13,0xBE,0xBA,0x2E,0xA5,0xCB,0x2E,0x5E,0x2E,0x4B,0xAD,0xEF,0x01,0x1A,0x72,
0x49,0xC1,0x9C,0x71,0x7B,0x22,0x69,0x40,0x7D,0x8E,0x35,0x7E,0xA9,0x74,0x76,0x22,
0x7F,0xB8,0xDF,0x17,0x98,0xF8,0xEA,0xff
};
下面再介绍本实施例中其他的配置程序说明。
1)定义初始化函数,主要配置MPEG4译码模块、行缓冲区模块、图像传送处理模块、控制模块的寄存器,在视频软解码初始化时调用;
2)定义结构体,用于相关参数输入
typedef struct tag_VIM_DECODEINFO{
VIM_HAPI_DISPLAY_MODE DisplayMode;//显示工作模式
VIM_HAPI_SPECIAL_EFFECT EffectMode;//显示特效
VIM_HAPI_ROTATEMODE RotationMode;//显示旋转模式
TPoint LcdWantPt;//显示控制模块视频层的输出坐标点
TSize LcdWantSize;//显示控制模块视频层的输出大小
VIM_JPEG_Index ImageInfo;//原始视频文件的属性,主要是原始视频文件的大小size
UINT32 JpegLbufAddr;//YUV格式的视频图像数据的缓冲区buffer的地址
}VIM_JPEG_DECODE_INFO,*PVIM_JPEG_DECODE_INFO;
UINT32VIM_HAPI_DisplayYUVInit(PVIM_JPEG_DECODE_INFODecodeInfo)
{
VIM_RESULT result;
TSize DisplaySize,DestDisplaySize,ImageSize;
TPoint pt={0,0};
UINT32 JpegYUVAddr,temp;
UINT8 pixelrate;
UINT16blank;
UINT8*mp4bit;
UINT32BitStreamAddr;
UINT32BitLength;
ImageSize=DecodeInfo->ImageInfo.JpgSize;//获取原始视频文件的大小size ,也就是配置MPEG4译码模块获取原始视频文件的大小;
JpegYUVAddr=DecodeInfo->JpegLbufAddr;//获取YUV格式的视频图像数据的buffer地址,也就是配置MPEG4译码模块中存储该YUV格式的视频图像数据的缓冲区的地址;
mp4bit=mp4d_data;//获取全局数据区中的一段固定的并且size很小的原始mp4码流地址,也就是获取MPEG4译码模块中预先存储的原始mp4码流的地址信息;
BitStreamAddr=(UINT32)((UINT32)mp4bit|0x40000000);
BitLength=536;
gVc0578b_Info.LcdStatus.ARotationMode=DecodeInfo->RotationMode//配置显示的旋转模式
gVc0578b_Info.DisplayStatus.LcdWantPt=DecodeInfo->LcdWantPt;//配置视频层显示起始坐标
gVc0578b_Info.DisplayStatus.LcdWantSize=DecodeInfo->LcdWantSize;//配置视频层显示宽高
通过以上程序来配置YUV格式的视频图像数据的显示参数。
//set mode
VIM_MAPI_SetChipMode (VIM_MARB_DISPLAYDEBUG_MODE,VIM_IPP_HAVE_NOFRAME);//配置MPEG4译码模块、行缓冲区模块、图像传送处理模块工作模式
VIM_IPP_SetMpeg4BufModeVIM_IPP_MPG4_ONEFRAME);//配置MPEG4译码模块工作在onefram模式
result = VIM_MAPI_CheckDisplaySize( gVc0578b_Info.DisplayStatus.LcdWantPt.x ,gVc0578b_Info.DisplayStatus.LcdWantPt.y ,gVc0578b_Info.DisplayStatus.LcdWantSize.cx ,gVc0578b_Info.DisplayStatus.LcdWantSize.cy,&DisplaySize);//验证输入的显示坐标是否合法
if(result)
goto DISPLAYERROR;
//from version 0.2need display whole pic in LCD,so source size=jpegimage size
result=VIM_IPP_ToolCaculateBigDstWindow(ImageSize,DisplaySize,&DestDisplaySize);//调整实际显示的宽高比,保证输出图像不会变形
if(result)
goto DISPLAYERROR;
//set ipp module image size
VIM_IPP_SetImageSize(ImageSize.cx,ImageSize.cy);//配置图像传送处理模块的原始视频宽高
result=VIM_IPP_SetCaptureSize(NULL,pt,ImageSize,DestDisplaySize);//配置图像传送处理模块的显示视频宽高
if(result)
goto DISPLAYERROR;
//set LCDC A layer memory size and window size
pt.x=pt.y=0;
if(DestDisplaySize.cx>DisplaySize.cx)
pt.x=(((DestDisplaySize.cx-DisplaySize.cx)>>1))&0xfffc;
if(DestDisplaySize.cy>DisplaySize.cy)
pt.y=(((DestDisplaySize.cy-DisplaySize.cy)>>1))&0xfffc;
result=VIM_DISP_SetA_Memory(pt,DestDisplaySize);
if(result)
goto DISPLAYERROR;
pt.x=(gVc0578b_Info.DisplayStatus.LcdWantPt.x)&0xfffc;
pt.y=(gVc0578b_Info.DisplayStatus.LcdWantPt.y)&0xfffc;
if(DestDisplaySize.cx<=DisplaySize.cx)
pt.x=(((DisplaySize.cx-DestDisplaySize.cx)>>1)+gVc0578b_Info.DisplayStatus.LcdWantPt.x)&0xfffc;
else
DestDisplaySize.cx=DisplaySize.cx;
if(DestDisplaySize.cy<=DisplaySize.cy)
pt.y=(((DisplaySize.cy-DestDisplaySize.cy)>>1)+gVc0578b_Info.DisplayStatus.LcdWantPt.y)&0xfffc;
else
DestDisplaySize.cy=DisplaySize.cy;
VIM_DISP_SetA_DisplayPanel(pt,DestDisplaySize);//设置液晶控制模块视频层的坐标和宽高
result=VIM_MAPI_AdjustPoint ((VIM_DISP_ROTATEMODE)gVc0578b_Info.LcdStatus.ARotationMode,
VIM_DISP_NOTCHANGE);
if(result)
goto DISPLAYERROR;
VIM_DISP_SetRotateMode ((VIM_DISP_ROTATEMODE )gVc0578b_Info.LcdStatus.ARotationMode);//设置视频层的旋转模式
//enable a layer
VIM_DISP_ResetState();
//set layer A mode,normal display use ALAYER_LINEBUF mode
gVc0578b_Info.MarbStatus.ALayerMode =VIM_USER_DISPLAY_USELINEBUF;
//(12)set mp4dec module image size
VIM_HIF_SetReg 16(V5_REG_LBUF_MP4DEC_IMAGESIZE,ImageSize.cx);//设置行缓冲区模块的输入YUV格式的视频图像数据的宽度,即原始视频数据宽度
VIM_HIF_SetReg16(V5_REG_LBUF_MP4DEC_IMAGESIZE+2,ImageSize.cy);//设置行缓冲区模块的输入YUV格式的视频图像数据的高度,即原始视频数据高度
VIM_HIF_SetReg16(V5_REG_LBUF_IMAGESIZE,ImageSize.cx);
VIM_HIF_SetReg16(V5_REG_LBUF_IMAGESIZE+2,ImageSize.cy);
VIM_HIF_SetReg8(V5_REG_MP4DEC_PINGPANG_MBL,(64>>4));//配置MPGE4译码模块输入视频数据的宽度,例如为64
VIM_HIF_SetReg8(V5_REG_MP4DEC_PINGPANG_MBL+1,(64>>4));//配置MPEG4译码模块输入视频数据的高度,例如为64
temp=((ImageSize.cx*ImageSize.cy+63)>>6);
VIM_HIF_SetReg32(V5_REG_LBUF_BURSTNUMBER0,temp);//设置行缓冲区模块的取数方式
//(14)marb map memory
result=VIM_MARB_SetMap(gVc0578b_Info.MarbStatus.WorkMode,gVc0578b_Info.MarbStatus.ALayerMode,
(PVIM_MARB_Map)&gVc0578b_Info.MarbStatus.MapList);//分配各个模块的内存空间
if(result)
return result;
VIM_DISP_SetLayerEnable(VIM_DISP_ALAYER,ENABLE);
VIM_HIF_SetReg32(V5_REG_LBUF_Y_INI0_DEC,JpegYUVAddr);//设置行缓冲区模块的输入buffer地址,即软解码输出YUV格式的视频图像数据的地址
VIM_HIF_SetReg32(V5_REG_LBUF_Y_INI1_DEC,0);
//(15)set interrupt
VIM_HIF_ClearIntModule(VM_HIF_INT_VDEC);
//set mpeg
VIM_MPEG4_RegisterI SR (VIM_INT_MPEG4_DEC_DONE,VIM_MAPI_ISR_MpegDecDoneDebug);//登记MPEG4译码模块中断响应函数
VIM_MPEG4_SetIntEnable(VIM_INT_MPEG4_DEC_DONE,ENABLE);//使能MPEG4译码模块中断
//(16)pisel rate
pixelrate=2;
VIM_JPEG_SetPixelRate(pixelrate);//设置行缓冲区模块pixelrate
blank=0;
VIM_JPEG_SetLineBlank(blank);//设置行缓冲区模块blank
VIM_HIF_SetReg32(V5_REG_MP4DEC_BITSTREAM_INI_ADD,BitStreamAddr);//设置MPEG4译码模块输入视频数据的地址
VIM_HIF_SetReg32(V5_REG_MP4DEC_BITSTREAM_SIZE,BitLength);//设置MPEG4译码模块输入视频数据的长度
DISPLAYERROR:
if(result)
{
return(UINT16)result;
}
return VIM_SUCCEED;
}
3)定义启动软解码数据输出函数,当一帧YUV格式的视频图像数据解码完成后,可调用此函数进行输出
UINT32 VIM_HAPI_DisplayYUVStart(void)
{
VIM_HIF_SetReg32(V5_REG_MP4DEC_RESET,0);//重启MPEG4译码模块
VIM_MPEG4_StartDec(0x0f);//启动解码
return VIM_SUCCEED;
参见图2,为本发明的实施例中视频软解码输出的装置框图,该装置包括:
MPEG4译码模块21,用于将视频压缩数据解码为YUV格式的视频图像数据,并将解码得到的所述YUV格式的视频图像数据存放到缓冲区中;
该视频压缩数据的格式为RMVB格式、H.264格式、和WMV格式中的任意一种。
在本实施例中,缓冲区为MPEG4译码模块的输出缓冲区或者行缓冲区模块的输入缓冲区;
行缓冲区模块22,用于在接收到中断信号后,将所述缓冲区中存放的所述YUV格式的视频图像数据传输出去;
图像传送处理模块23,用于接收行缓冲区模块22发送的YUV格式的视频图像数据,然后将所述YUV格式的视频图像数据传送出去;
显示控制模块24,用于接收图像传送处理模块23发送的YUV格式的视频图像数据,并将所述YUV格式的视频图像数据显示到视频层。
以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以作出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。