Video 재생시에 화면 비율(16:9 또는 4:3) 에서 각 4 가지의 모드를 조절하기 위한 내용을 담고 있다. 7020 의 경우 아래의 4가지 모드를 지원한다.
- letter-box
- pan and scan
- combined
- ignore
각 모드마다, 특징이 있다. 자세한 것은 stvid application datasheet 를 참고하기 바란다.
직면한 문제
Video 재생 도중에, 위의 4 가지 중 하나로 출력 모드를 바꿔야 하는데, 제대로 바뀌지 않는다.
한가지 힌트가 될 만한 것은 DACS1000 의 경우에는 제대로 동작하는 것이다. 하지만, DACS100 의 경우에는 5517 자체에서 Video 를 재생하기 때문에 세팅이 다를 수 있었다.
또한 7020stem_j 역시 scenario02 에서 4 가지 모드가 제대로 동작하였다.
해결 방법
DACS1000 과 DACS5000 모두 Video 모드를 바꾸기 위해서 'STVID_SetDisplayAspectRatioConversion()' 함수를 제공하고 있었다.
모드 | 설명 |
1 | pan and scan |
2 | letter box |
4 | combinded |
8 | ignore |
DACS1000 의 경우
src/system/vid.c 에서 다음과 같이 함수를 선언했다.
ST_ErrorCode_t VID_SetRatioConversion(U32 mode) // mode 는 위의 표를 참조 { ST_ErrorCode_t ST_ErrorCode; ST_ErrorCode = STVID_SetDisplayAspectRatioConversion(VID_ViewPortHandle, mode); if (ST_ErrorCode != ST_NO_ERROR) { STTBX_Print(("VID_SetDisplayAspectRatioConversion()=%s\n", GetErrorText(ST_ErrorCode) )); } }
그리고 나서, src/ui/ui_system.c 에서 아래와 같이 추가해 주었다.
void NonMenuMsgProcessing(U8 inputKey) { U8 keyValue=0; setTimer(10,EndUi,NULL); switch(inputKey) { case ZERO_KEY: keyValue=0; DigitProcesser(keyValue); break; case ONE_KEY: keyValue=1; DigitProcesser(keyValue); break; case TWO_KEY: keyValue=2; DigitProcesser(keyValue); break; case THREE_KEY: keyValue=3; DigitProcesser(keyValue); break; case FOUR_KEY: keyValue=4; DigitProcesser(keyValue); break; case FIVE_KEY: keyValue=5; DigitProcesser(keyValue); break; case SIX_KEY: keyValue=6; DigitProcesser(keyValue); break; case SEVEN_KEY: keyValue=7; DigitProcesser(keyValue); break; case EIGHT_KEY: keyValue=8; DigitProcesser(keyValue); break; case NINE_KEY: keyValue=9; DigitProcesser(keyValue); break; case UP_KEY: digitInput=FALSE; CONFIRM_CHANNEL(ChUpMode); break; case DOWN_KEY: digitInput=FALSE; CONFIRM_CHANNEL(ChDnMode); break; case OK_KEY: digitInput=FALSE; if(inputValue==0) { EndUi(); if(pMainWindow==pOriginWindow) { pMainWindow=pTestWindow; } else { pMainWindow=pOriginWindow; } } else CONFIRM_CHANNEL(ChInMode); break; case RIGHT_KEY: // clearTimer(EndInput); Update_Data(); avVolumeControl(TRUE, &volpercentage); // if(preMode != curMode) { Fill_Rect(150, SCREEN_HEIGHT-100, 410, 29, 22); Fill_Rect(156, SCREEN_HEIGHT-97, 400, 24, 1); Put_Draw(120, SCREEN_HEIGHT-100, 40); // volume icon // } Fill_Rect(156, SCREEN_HEIGHT-97, (U16)volpercentage*4, 24, 162); // setTimer(UI_TIMEOUT/2,EndUi,NULL); // curMode=NoneMode; break; case LEFT_KEY: // clearTimer(EndInput); Update_Data(); //AUD_SetAttenuation(((100 - volpercentage)*76)/100); avVolumeControl(FALSE, &volpercentage); // if(preMode != curMode) { Fill_Rect(150, SCREEN_HEIGHT-100, 410, 29, 22); Fill_Rect(156, SCREEN_HEIGHT-97, 400, 24, 1); Put_Draw(120, SCREEN_HEIGHT-100, 40); // volume icon // } HideRegion(155, SCREEN_HEIGHT-98, 400, 26, 1); Fill_Rect(156, SCREEN_HEIGHT-97, (U16)volpercentage*4, 24, 162); // setTimer(UI_TIMEOUT,EndUi,NULL); // curMode=NoneMode; break; case MUTE_KEY: //clearTimer(CloseMenu); Update_Data(); if(isAudMute == TRUE) { isAudMute=FALSE; AUD_Mute(isAudMute); Put_Draw(SCREEN_WIDTH/2-15, 300, 43); // speaker_off } else { isAudMute=TRUE; AUD_Mute(isAudMute); Put_Draw(SCREEN_WIDTH/2-15, 300, 44); // speaker_on } // setTimer(UI_TIMEOUT, EndUi, NULL); // curMode=NoneMode; break; case RED_KEY: // 추가한 부분 // STVID_SetDisplayAspectRatioConversion(VID_ViewPortHandle, 1); VID_SetRatioConversion(1); break; case GREEN_KEY: // 추가한 부분 // STVID_SetDisplayAspectRatioConversion(VID_ViewPortHandle, 2); VID_SetRatioConversion(2); break; case YELLOW_KEY: // 추가한 부분 // STVID_SetDisplayAspectRatioConversion(VID_ViewPortHandle, 4); VID_SetRatioConversion(4); break; case BLUE_KEY: // 추가한 부분 // STVID_SetDisplayAspectRatioConversion(VID_ViewPortHandle, 8); VID_SetRatioConversion(8); break; default: digitInput=FALSE; break; } }
리모콘의 특정 키에 맵핑을 시켰다.
DACS1000 의 경우에는 위의 과정만으로도, 원하는 Video 모드를 얻을 수 있었다.
DAC5000 의 경우
처음에는 앞에서의 DACS1000 과 같이 했지만, 각 모드를 바꿀 때마다 아주 미세한 변화만 있을 뿐 바뀌지 않았다.
이외에도 Window_mode 를 AUTO_MATIC 으로 바꿔주어야 했다.
일단 먼저, src/ui/vidutils.c 에서 함수를 만든다.
void SET_AUTOMODE(void) { STVID_WindowParams_t WinParams = {STVID_WIN_ALIGN_TOP_HCENTRE,STVID_WIN_SIZE_DONT_CARE}; STVID_SetOutputWindowMode(VID_ViewPortHandle, TRUE, &WinParams); // TRUE 를 유의해서 보기 바란다 }
이번에는 src/system/vid.c 에서 함수를 추가한다.
ST_ErrorCode_t VID_SetRatioConversion(U32 mode) { ST_ErrorCode_t ST_ErrorCode; ST_ErrorCode = STVID_SetDisplayAspectRatioConversion(VID_ViewPortHandle, mode); if(ST_ErrorCode != ST_NO_ERROR) { printf("VID_SetRatioConversion Error\n"); } }
이제 리모콘 키와 맵핑시키면 된다.
void NonMenuMsgProcessing(U8 inputKey) { U8 keyValue=0,result; U16 major,minor; U16 tempString[10]; setTimer(UI_TIMEOUT-270,EndUi,NULL); switch(inputKey) { case ZERO_KEY: keyValue=0; DigitProcesser(keyValue); break; case ONE_KEY: keyValue=1; DigitProcesser(keyValue); break; case TWO_KEY: keyValue=2; DigitProcesser(keyValue); break; case THREE_KEY: keyValue=3; DigitProcesser(keyValue); break; case FOUR_KEY: keyValue=4; DigitProcesser(keyValue); break; case FIVE_KEY: keyValue=5; DigitProcesser(keyValue); break; case SIX_KEY: keyValue=6; DigitProcesser(keyValue); break; case SEVEN_KEY: keyValue=7; DigitProcesser(keyValue); break; case EIGHT_KEY: keyValue=8; DigitProcesser(keyValue); break; case NINE_KEY: keyValue=9; DigitProcesser(keyValue); break; case UP_KEY: digitInput=FALSE; CONFIRM_CHANNEL(ChUpMode); break; case DOWN_KEY: digitInput=FALSE; CONFIRM_CHANNEL(ChDnMode); break; case OK_KEY: digitInput=FALSE; MAJOR=TRUE; if(inputValue==0) { EndUi(); if(pMainWindow==pOriginWindow) { pMainWindow=pTestWindow; } else { pMainWindow=pOriginWindow; } } else { ChannnelChange(inMajor,inMinor); inMajor=0; inMinor=0; bStartChInput=FALSE; MAJOR=TRUE; digitInput=FALSE; bDashInput=FALSE; clearTimer(TimeupChannelChange); } break; case RIGHT_KEY: // clearTimer(EndInput); // Update_Data(); avVolumeControl(TRUE, &volpercentage); // if(preMode != curMode) { if((prevKey==RIGHT_KEY)||(prevKey==LEFT_KEY)) { // Fill_Rect(156, SCREEN_HEIGHT-97, 400, 24, 1); // Fill_Rect(156, SCREEN_HEIGHT-97, (U16)volpercentage*4, 24, 162); ReDrawVolumeControl(volpercentage); } else { DrawVolumeControl(volpercentage); /* Fill_Rect(150, SCREEN_HEIGHT-100, 410, 29, 22); Fill_Rect(156, SCREEN_HEIGHT-97, 400, 24, 1); Put_Draw(120, SCREEN_HEIGHT-100, 40); // volume icon Fill_Rect(156, SCREEN_HEIGHT-97, (U16)volpercentage*4, 24, 162);*/ } // setTimer(UI_TIMEOUT/2,EndUi,NULL); // curMode=NoneMode; UpdateWindow(); break; case LEFT_KEY: // clearTimer(EndInput); // Update_Data(); //AUD_SetAttenuation(((100 - volpercentage)*76)/100); avVolumeControl(FALSE, &volpercentage); // if(preMode != curMode) { if((prevKey==RIGHT_KEY)||(prevKey==LEFT_KEY)) { // Fill_Rect(156, SCREEN_HEIGHT-97, 400, 24, 1); // Fill_Rect(156, SCREEN_HEIGHT-97, (U16)volpercentage*4, 24, 162); ReDrawVolumeControl(volpercentage); } else { /* Fill_Rect(150, SCREEN_HEIGHT-100, 410, 29, 22); Fill_Rect(156, SCREEN_HEIGHT-97, 400, 24, 1); Put_Draw(120, SCREEN_HEIGHT-100, 40); // volume icon Fill_Rect(156, SCREEN_HEIGHT-97, (U16)volpercentage*4, 24, 162);*/ DrawVolumeControl(volpercentage); } // UpdateWindow(); // setTimer(UI_TIMEOUT,EndUi,NULL); // curMode=NoneMode; break; case MUTE_KEY: //clearTimer(CloseMenu); // Update_Data(); if(isAudMute == TRUE) { isAudMute=FALSE; AUD_Mute(isAudMute); Put_Draw(120, SCREEN_HEIGHT-100, 26); // speaker_off } else { isAudMute=TRUE; AUD_Mute(isAudMute); Put_Draw(120, SCREEN_HEIGHT-100, 25); // speaker_on } // setTimer(UI_TIMEOUT, EndUi, NULL); // curMode=NoneMode; break; case HELP_KEY: if(bHelpEnable) { bHelpEnable=FALSE; Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,100,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_helpoff,10,10); } else { bHelpEnable=TRUE; Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,100,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_helpon,10,10); } break; case MAJOR_MINOR_BAR: if(digitInput) { MAJOR=FALSE; bDashInput=TRUE; } OutputChannelNumber(inMajor,inMinor); break; case INFO_KEY: if(bActiveInfoWindow) { ClearWindow(); bActiveInfoWindow=FALSE; } else { DrawChInfomationWindow(); bActiveInfoWindow=TRUE; } break; case MUILTI_LANG_KEY: Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,250,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage,10,10); break; /* case TIME_KEY: //Fill_RectBasicTrans(300,800,200,50,2); //PrintText(U32 x, U32 y, U8 * letter, U32 f_color, U32 b_color) break;*/ /* case SOUND_KEY: Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,250,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage,10,10); //Fill_RectBasicTrans(300,800,200,50,2); //PrintText(U32 x, U32 y, U8 * letter, U32 f_color, U32 b_color) break;*/ case FLASHBACK_KEY: BackChannnelChange(); break; case CHANNEL_ADD: //pMessage_channeladd if((currentMajor!=0)&&(currentMinor!=0)) { /* if(CheckCurrentChannelInfo()) { }*/ printf("Edit ch %d-%d\n",currentMajor,currentMinor); result=CheckChannel(currentMajor,currentMinor,HIDE_STATE); if(result==2) { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,200,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_liked_channel,10,10); } else if(result) { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,80,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_channeladd,10,10); } else { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,80,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_channeldel,10,10); } } break; case RATIO_KEY: /* result=vidToggleVideMode(); if(result==2) { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,50,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_video_wide,10,10); } else if(result==3) { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,50,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_video_normal,10,10); } else { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,50,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_video_exten,10,10); }*/ tempString[0]=pMessage_book_sleep[0]; tempString[1]=pMessage_book_sleep[1]; tempString[2]=pMessage_book_sleep[2]; tempString[3]=pMessage_book_sleep[3]; tempString[4]=0x0020; SleepPowerOnMin+=10; if(SleepPowerOnMin==60) { SleepPowerOnMin=0; bEnableSleepOff=TRUE; tempString[5]=0xaebc; tempString[6]=0xc9d0; tempString[7]=0; } else { bEnableSleepOff=TRUE; tempString[5]=SleepPowerOnMin/10+48; tempString[6]='0'; tempString[7]=0xbd84; tempString[8]=0; } Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,120,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)tempString,10,10); break; //선호 case FAVORITE_ADD_KEY: //pMessage_channeladd if((currentMajor!=0)&&(currentMinor!=0)) { /* if(CheckCurrentChannelInfo()) { }*/ result=CheckChannel(currentMajor,currentMinor,FAV_STATE); if(result==2) { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,200,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_delete_channel,10,10); } else if(result) { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,80,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_like_delete,10,10); } else { Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,80,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage_like_regist,10,10); } } break; case EPG_KEY: SetKeyAction(pChCurInfoWindow, 2,MENU_KEY, CloseInputInfoWindow); NewWindow(pChCurInfoWindow); break; case DIGITAL_CAPTION: Fill_RectBasicTrans(MESSAGE_BOX_X,MESSAGE_BOX_Y,250,20,SUB_BG); PrintUnicode(MESSAGE_X,MESSAGE_Y,(U16*)pMessage,10,10); break; case FAVORITE_PLAY_KEY: CONFIRM_CHANNEL(FavChMode); break; case EXIT_KEY: EndUi(); break; case RED_KEY: // 추가한 부분 SET_AUTOMODE(); VID_SetRatioConversion(1); break; case GREEN_KEY: // 추가한 부분 SET_AUTOMODE(); VID_SetRatioConversion(2); break; case YELLOW_KEY: // 추가한 부분 SET_AUTOMODE(); VID_SetRatioConversion(4); break; case BLUE_KEY: // 추가한 부분 SET_AUTOMODE(); VID_SetRatioConversion(8); break; default: digitInput=FALSE; break; } }
결론
Video 를 재생하기 전에, window mode 와 ratio 를 바꿀 수 있는 함수를 통해 원하는 모드로 변경가능하다.