对于高标清同播的播出系统来说,如何正确完成标清与高清信号的上下变换,并保持画面内容的完整和美观,是系统设计中需要着重考虑的关键问题。
全流程应用AFD技术,可以保证高标清变换中幅型变化的正确性。常见的高标清上下变换有1000,1001,1010,1100等。软件根据比例在tvvideo_SetAspectRatio调用如下函数:
#if ENABLE_AFD
static MS_ASPECT_RATIO _CalAspectRatioWindow(MS_ASPECT_RATIO eAS,MS_U8 u8AFD,
MS_COMPONENT_OUTPUT_TYPE eCompType,
MS_U16 u16PicWidth, MS_U16 u16PicHeight,
MS_WINDOW_TYPE *pSrcWinInfo,MS_WINDOW_TYPE *pDestWinInfo)
{
MS_S16 s16Offset = 0;
MS_BOOL bCalSize = FALSE;
MVD_ASPECT_RATIO_CODE enAspectRatio;
GetDispAspectRatio(&enAspectRatio);
switch(eAS)
{
case MS_ASPECT_RATIO_169_PB:
case MS_ASPECT_RATIO_169:
if(0x09 == u8AFD)
{
s16Offset = u16PicWidth*9 - u16PicHeight*14;
if(s16Offset > 0) // 16:9
{
//source (W-xoffset*2)/H = 4/3
s16Offset = (3*u16PicWidth - 4*u16PicHeight);
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
s16Offset = s16Offset/6;
pSrcWinInfo->x= (s16Offset>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
else // 4:3
{
//source XOOffset= WO/8 ==>xoffet = W/8
//
if (enAspectRatio != MVD_ASP_4TO3)
{
s16Offset = u16PicWidth /8;
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pSrcWinInfo->x= (s16Offset>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
}
//dest (W-xoffset*2)/H = 4/3
s16Offset = (_setting[eCompType].u16Width - 4*_setting[eCompType].u16Height/3);
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pDestWinInfo->x= ((s16Offset/2)>>3)<<3;
pDestWinInfo->y = 0;
pDestWinInfo->width= _setting[eCompType].u16Width - pDestWinInfo->x*2;
pDestWinInfo->height= _setting[eCompType].u16Height;
bCalSize = TRUE;
}
else if(0x0B == u8AFD)
{
s16Offset = u16PicWidth*9 - u16PicHeight*14;
if(s16Offset > 0) // 16:9
{
//source (W-xoffset*2)/H = 14/9
s16Offset = (9*u16PicWidth - 14*u16PicHeight);
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
s16Offset = s16Offset/18;
pSrcWinInfo->x= (s16Offset>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
else // 4:3
{
//source XOOffset= WO/9 ==>xoffet = W/16
//
if (enAspectRatio != MVD_ASP_4TO3)
{
s16Offset = u16PicWidth/16;
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pSrcWinInfo->x= (s16Offset>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
}
//dest (W-xoffset*2)/H = 14/9
s16Offset = (9*_setting[eCompType].u16Width - 14*_setting[eCompType].u16Height);
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
s16Offset = s16Offset / 18;
pDestWinInfo->x= (s16Offset>>3)<<3;
pDestWinInfo->y = 0;
pDestWinInfo->width= _setting[eCompType].u16Width - 2*pDestWinInfo->x;
pDestWinInfo->height= _setting[eCompType].u16Height;
bCalSize = TRUE;
}
if(eAS == MS_ASPECT_RATIO_169)
{
pDestWinInfo->x= 0;
pDestWinInfo->y = 0;
pDestWinInfo->width= _setting[eCompType].u16Width;
pDestWinInfo->height= _setting[eCompType].u16Height;
}
else if(bCalSize)
{
eAS = MS_ASPECT_RATIO_169;
}
HB_printf("###AFD ====MS_ASPECT_RATIO_169_PB!\n");
break;
case MS_ASPECT_RATIO_169_PS:
HB_printf("###AFD ====MS_ASPECT_RATIO_169_PS!\n");
break;
case MS_ASPECT_RATIO_43_LB:
case MS_ASPECT_RATIO_43:
if(0x09 == u8AFD || 0x0F == u8AFD)
{
s16Offset = u16PicWidth*9 - u16PicHeight*14;
if(s16Offset > 0) // 16:9
{
//source (W-xoffset*2)/H = 4/3
s16Offset = (u16PicWidth - 4*u16PicHeight/3);
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pSrcWinInfo->x= ((s16Offset/2)>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
else
{
//source XOOffset= WO/8 ==>xoffet = W/8
//
if (enAspectRatio != MVD_ASP_4TO3)
{
s16Offset = u16PicWidth /8;
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pSrcWinInfo->x= (s16Offset>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
}
bCalSize = TRUE;
}
else if(0x0B == u8AFD || 0x0E == u8AFD)
{
s16Offset = u16PicWidth*9 - u16PicHeight*14;
if(s16Offset > 0) // 16:9
{
//source (W-xoffset*2)/H = 14/9
s16Offset = (u16PicWidth - 14*u16PicHeight/9);
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pSrcWinInfo->x= ((s16Offset/2)>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
else // 4:3
{
//source XOOffset= WO/9 ==>xoffet = W/16
//
if (enAspectRatio != MVD_ASP_4TO3)
{
s16Offset = u16PicWidth/16;
if(s16Offset < 0)
{
s16Offset = - s16Offset;
}
pSrcWinInfo->x= (s16Offset>>3)<<3;
pSrcWinInfo->y = 0;
pSrcWinInfo->width= u16PicWidth - 2*pSrcWinInfo->x;
pSrcWinInfo->height= u16PicHeight;
}
}
//Dest W/(H-2*yoffset)*(4H/3W)=14/9 -->yoffset = 6H/84
pDestWinInfo->x= 0;
pDestWinInfo->y = (( _setting[eCompType].u16Height *6/84)<<3)>>3;
pDestWinInfo->width= _setting[eCompType].u16Width;
pDestWinInfo->height= _setting[eCompType].u16Height - pDestWinInfo->y*2;
bCalSize = TRUE;
}
if(eAS == MS_ASPECT_RATIO_43)
{
pDestWinInfo->x= 0;
pDestWinInfo->y = 0;
pDestWinInfo->width= _setting[eCompType].u16Width;
pDestWinInfo->height= _setting[eCompType].u16Height;
}
else if(bCalSize)
{
eAS = MS_ASPECT_RATIO_43;
}
HB_printf("###AFD =====MS_ASPECT_RATIO_43_LB!=====\n");
break;
case MS_ASPECT_RATIO_43_PS:
HB_printf("###AFD =====MS_ASPECT_RATIO_43_PS!=====\n");
break;
case MS_ASPECT_RATIO_IGNORE:
HB_printf("###AFD =====EN_ASPECT_RATIO_IGNORE=====\n");
break;
default:
break;
}
return eAS;
}
#endif
|