📄 hdmi.c
字号:
} } if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->InputColorSpaceValid = TRUE; pUpdate->InputColorSpace = cs; pUpdate->InputColorFormatValid = TRUE; pUpdate->InputColorFormat = icf; } } // Get aspect ratio from AVI avi_asp.X = 0; avi_asp.Y = 0; switch (avi->aspect_ratio) { case DH_ar_no_info: break; // no data in AVI about aspect ratio, use implicit aspect ratio from VIC case DH_ar_4x3: avi_asp.X = 4; avi_asp.Y = 3; break; case DH_ar_16x9: avi_asp.X = 16; avi_asp.Y = 9; break; default: if (force || (avi->aspect_ratio != pHDMI->last_avi.aspect_ratio)) RMDBGLOG((ENABLE, "newavi - unknown aspect ratio code: %lu\n", avi->aspect_ratio)); break; } // Apply new video mode from AVI asp = pHDMI->PictureAspectRatio; if (force || (pHDMI->last_avi.vic != avi->vic) || ((pHDMI->TVStandard == EMhwlibTVStandard_Custom) && avi->vic)) { RMDBGLOG((ENABLE, "newavi - VIC: %lu\n", avi->vic)); if ((avi->vic > 0) && (avi->vic < (sizeof(cap_hdmi_cea861_modes) / sizeof(enum EMhwlibTVStandard)))) { // Use TVStandard from VIC if (cap_hdmi_cea861_modes[avi->vic] != pHDMI->TVStandard) { RMDBGLOG((ENABLE, "newavi - video mode from VIC %lu: %s\n", avi->vic, CEA861VICNames[avi->vic])); pHDMI->TVStandard = cap_hdmi_cea861_modes[avi->vic]; if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->TVStandardUpdate = TRUE; } } if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->TVStandardValid = TRUE; pUpdate->TVStandard = pHDMI->TVStandard; } if (pHDMI->last_avi.vic != avi->vic) { RMDBGLOG((ENABLE, "\n\n\t\t%s %s\n\n\n", CEA861VICNames[avi->vic], (pHDMI->InputColorSpace == EMhwlibColorSpace_RGB_0_255) ? "RGB 0-255" : (pHDMI->InputColorSpace == EMhwlibColorSpace_RGB_16_235) ? "RGB 16-235" : (pHDMI->InputColorSpace == EMhwlibColorSpace_YUV_601) ? "YCbCr601" : (pHDMI->InputColorSpace == EMhwlibColorSpace_YUV_709) ? "YCbCr709" : (pHDMI->InputColorSpace == EMhwlibColorSpace_xvYCC_601) ? "xvYCC601" : (pHDMI->InputColorSpace == EMhwlibColorSpace_xvYCC_709) ? "xvYCC709" : "unknown")); } // 640x480 or first of two identical modes: 4:3 if ((avi->vic == 1) || ((avi->vic + 1 < (sizeof(cap_hdmi_cea861_modes) / sizeof(enum EMhwlibTVStandard))) && (cap_hdmi_cea861_modes[avi->vic] == cap_hdmi_cea861_modes[avi->vic + 1]))) { asp.X = 4; asp.Y = 3; } else { // otherwise 16:9 asp.X = 16; asp.Y = 9; } if (RMMemcmp(&asp, &(pHDMI->PictureAspectRatio), sizeof(struct EMhwlibAspectRatio))) { RMDBGLOG((ENABLE, "newavi - aspect ratio from VIC %lu: %lu by %lu\n", avi->vic, asp.X, asp.Y)); } } else { if (avi->vic != 0) RMDBGLOG((ENABLE, "Error, unknown CEA 861-C timing descriptor in AVI: %lu\n", avi->vic)); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->VideoUpdate = TRUE; } if ((! avi_asp.X) || (! avi_asp.Y)) { cap_get_aspect_ratio_from_video_mode(pHDMI->TVStandard, NULL, FALSE, &asp.X, &asp.Y); } else { asp = avi_asp; } } } if (avi_asp.X && avi_asp.Y && RMMemcmp(&avi_asp, &asp, sizeof(struct EMhwlibAspectRatio))) { RMDBGLOG((ENABLE, "newavi - aspect ratio in AVI (%lux%lu) does not match VIC %ld (%lux%lu)\n", avi_asp.X, avi_asp.Y, avi->vic, asp.X, asp.Y)); asp = avi_asp; } if (RMMemcmp(&asp, &(pHDMI->PictureAspectRatio), sizeof(struct EMhwlibAspectRatio))) { pHDMI->PictureAspectRatio = asp; if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->PictureAspectRatioUpdate = TRUE; } } if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->PictureAspectRatioValid = TRUE; pUpdate->PictureAspectRatio = pHDMI->PictureAspectRatio; } // set to neutral zoom window x = ZOOM_0; y = ZOOM_0; w = ZOOM_1; h = ZOOM_1; // report active format if (force || (avi->active_format != pHDMI->last_avi.active_format)) {#ifdef _DEBUG enum DH_active_format_aspect_ratio act = (enum DH_active_format_aspect_ratio)(avi->active_format & 0x0F);#endif RMDBGLOG((ENABLE, "newavi - %sactive format: %u - %s\n", (avi->active_format & 0x10) ? "" : "in", act, (act == DH_af_reserved_0) ? "No info" : (act == DH_af_16x9_top) ? "16:9 content: at top of 4:3 frame, fills up 16:9 frame" : (act == DH_af_14x9_top) ? "14:9 content: at top of 4:3 frame, centered on 16:9 frame" : (act == DH_af_64x27_centered) ? "Cinemascope widescreen (2.35:1, 64:27) content: centered on 4:3 or 16:9 frame" : (act == DH_af_same_as_picture) ? "content fills up frame" : (act == DH_af_4x3_centered) ? "4:3 content: fills up 4:3 frame, centered on 16:9 frame" : (act == DH_af_16x9_centered) ? "16:9 content: centered on 4:3 frame, fills up 16:9 frame" : (act == DH_af_14x9_centered) ? "14:9 content: centered on 4:3 frame, centered on 16:9 frame" : (act == DH_af_4x3_centered_prot_14x9) ? "4:3 content with essential content in 14:9 centered portion" : (act == DH_af_16x9_centered_prot_14x9) ? "16:9 content with essential content in 14:9 centered portion" : (act == DH_af_16x9_centered_prot_4x3) ? "16:9 content with essential content in 4:3 centered portion" : "unknown format code!")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->ContentAFDUpdate = TRUE; } } if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->ContentAFDValid = TRUE; pUpdate->ContentAFD.ActiveFormat = (enum EMhwlibActiveFormat)(avi->active_format & 0x0F); pUpdate->ContentAFD.ActiveFormatValid = (avi->active_format & 0x10) ? TRUE : FALSE; pUpdate->ContentAFD.FrameAspectRatio = pHDMI->PictureAspectRatio; } if (force || (avi->h_bar != pHDMI->last_avi.h_bar) || (avi->top != pHDMI->last_avi.top) || (avi->bottom != pHDMI->last_avi.bottom) || (avi->v_bar != pHDMI->last_avi.v_bar) || (avi->left != pHDMI->last_avi.left) || (avi->right != pHDMI->last_avi.right)) { if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->ContentBarInfoUpdate = TRUE; } } if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->ContentBarInfoValid = TRUE; pUpdate->ContentBarInfo.FrameSizeX = 0; // TODO pUpdate->ContentBarInfo.FrameSizeY = 0; pUpdate->ContentBarInfo.VerticalBarDataValid = avi->v_bar; pUpdate->ContentBarInfo.HorizontalBarDataValid = avi->h_bar; pUpdate->ContentBarInfo.EndLeftBarPixelNum = avi->left; pUpdate->ContentBarInfo.StartRightBarPixelNum = avi->right; pUpdate->ContentBarInfo.EndTopBarLineNum = avi->top; pUpdate->ContentBarInfo.StartBottomBarLineNum = avi->bottom; } // report scan info switch (avi->scan_info) { case DH_overscanned: scan = EMhwlibScanInfo_Overscanned; break; case DH_underscanned: scan = EMhwlibScanInfo_Underscanned; break; default: // no info, determine default scan mode from video code scan = (avi->vic > 1) ? EMhwlibScanInfo_Overscanned : EMhwlibScanInfo_Underscanned; } if (force || (avi->scan_info != pHDMI->last_avi.scan_info) || (avi->vic != pHDMI->last_avi.vic)) { RMDBGLOG((ENABLE, "newavi - picture scan info: %s\n", (avi->scan_info == DH_overscanned) ? "overscanned (will be cropped)" : (avi->scan_info == DH_underscanned) ? "underscanned (will not be cropped)" : (scan == DH_overscanned) ? "no data, overscanned VIC (will be cropped)" : (scan == DH_underscanned) ? "no data, underscanned VIC (will not be cropped)" : "no data")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->ContentScanInfoUpdate = TRUE; } } if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->ContentScanInfoValid = TRUE; pUpdate->ContentScanInfo = scan; } /* TODO move to main // apply active format if (avi->active_format & 0x10) { enum EMhwlibActiveFormat act = (enum EMhwlibActiveFormat)(avi->active_format & 0x0F); struct EMhwlibActiveFormatDescription afd; struct EMhwlibAspectRatio scaler_ar; RMbool output_variable_ar, variable_output; struct EMhwlibActiveFormatDescription output_afd; afd.ActiveFormat = act; afd.ActiveFormatValid = TRUE; afd.FrameAspectRatio = pHDMI->PictureAspectRatio; err = get_scaler_output_aspect_ratio( dcc_info->pRUA, dcc_info->disp_info->osd_scaler[input], (dcc_info->route == DCCRoute_Secondary) ? DispVCRMixer : DispMainMixer, &scaler_ar, &variable_output); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Can not get scaler output aspect ratio! %s\n", RMstatusToString(err))); // fallback, this assumes full screen scaler window. scaler_ar.X = disp_opt->ar_x; scaler_ar.Y = disp_opt->ar_y; } RMDBGLOG((LOCALDBG, "Scaler output aspect ratio: %lu:%lu\n", scaler_ar.X, scaler_ar.Y)); output_afd.FrameAspectRatio.X = disp_opt->ar_x; output_afd.FrameAspectRatio.Y = disp_opt->ar_y; output_afd.ActiveFormat = disp_opt->active_format; output_afd.ActiveFormatValid = disp_opt->active_format_valid; if (variable_output) { get_output_variable_aspect_ratio(disp_opt->standard, &output_variable_ar); } else { output_variable_ar = FALSE; } err = apply_active_format_rel( afd, scaler_ar, output_variable_ar, &output_afd, &x, &y, &w, &h, &update_zoom); if (variable_output && ( (output_afd.FrameAspectRatio.X != disp_opt->ar_x) || (output_afd.FrameAspectRatio.Y != disp_opt->ar_y) || (output_afd.ActiveFormatValid && (output_afd.ActiveFormat != disp_opt->active_format)) || (output_afd.ActiveFormatValid != disp_opt->active_format_valid) )) { apply_active_format_output(dcc_info->pRUA, (dcc_info->route == DCCRoute_Secondary) ? DispVCRMixer : DispMainMixer, disp_opt->dh_info->pDH, output_afd); disp_opt->ar_x = output_afd.FrameAspectRatio.X; disp_opt->ar_y = output_afd.FrameAspectRatio.Y; disp_opt->active_format_valid = output_afd.ActiveFormatValid; disp_opt->active_format = output_afd.ActiveFormat; } if (RMFAILED(err) && (force || (avi->active_format != pHDMI->last_avi.active_format))) { RMDBGLOG((ENABLE, "newavi - failed to apply active format: %u\n", act)); } } else if (pHDMI->last_avi.active_format & 0x10) { // no more active format, return to full screen update_zoom = TRUE; } // apply horizontal bars if (avi->h_bar) { if (avi->bottom && (avi->bottom > avi->top)) { // sanity check if (force || (avi->h_bar != pHDMI->last_avi.h_bar) || (avi->top != pHDMI->last_avi.top) || (avi->bottom != pHDMI->last_avi.bottom) ) RMDBGLOG((ENABLE, "newavi - horizontal bars to line %ld, from line %ld\n", avi->top, avi->bottom)); y = avi->top; h = avi->bottom - avi->top - 1; update_zoom = TRUE; } } else if (pHDMI->last_avi.h_bar) { // no more horizontal bars, return to full height update_zoom = TRUE; } // apply vertical bars if (avi->v_bar) { if (avi->right && (avi->right > avi->left)) { // sanity check if (force || (avi->v_bar != pHDMI->last_avi.v_bar) || (avi->left != pHDMI->last_avi.left) || (avi->right != pHDMI->last_avi.right) ) RMDBGLOG((ENABLE, "newavi - vertical bars to col %ld, from col %ld\n", avi->left, avi->right)); x = avi->left * (avi->in_pixel_rep + 1); w = (avi->right - avi->left - 1) * (avi->in_pixel_rep + 1); update_zoom = TRUE; } } else if (pHDMI->last_avi.v_bar) { // no more vertical bars, return to full width update_zoom = TRUE; } // determine default scan mode from video mode scan = (avi->vic > 1) ? EMhwlibScanInfo_Overscanned : EMhwlibScanInfo_Underscanned; // override scan mode from AVI if (avi->scan_info != pHDMI->last_avi.scan_info) { // unused for now RMDBGLOG((ENABLE, "newavi - picture scan info: %s\n", (avi->scan_info == DH_overscanned) ? "overscanned (will be cropped)" : (avi->scan_info == DH_underscanned) ? "underscanned (will not be cropped)" : "no data")); } switch (avi->scan_info) { case DH_overscanned: scan = EMhwlibScanInfo_Overscanned; break; case DH_underscanned: scan = EMhwlibScanInfo_Underscanned; break; } // picture is overscanned, need to crop "dirty" edge if (scan == EMhwlibScanInfo_Overscanned) { RMuint32 adj = (ZOOM_0 * pHDMI->overscan_crop + 100) / 200; // cut off half of the percentage on each side RMDBGLOG((ENABLE, "newavi - applying %lu%% overscan crop\n", pHDMI->overscan_crop)); if ((x >= ZOOM_0) && (w >= ZOOM_0)) { x += adj; w -= (adj * 2); } else { // TODO RMDBGLOG((ENABLE, "newavi - vertical bar info present, overscan crop not applied\n")); } if ((y >= ZOOM_0) && (h >= ZOOM_0)) { y += adj; h -= (adj * 2); } else { // TODO RMDBGLOG((ENABLE, "newavi - horizontal bar info present, overscan crop not applied\n")); } } // update bar information if ((! pHDMI->zoom_force) && ( (pHDMI->zoom_x != x) || (pHDMI->zoom_y != y) || (pHDMI->zoom_w != w) || (pHDMI->zoom_h != h) )) { if ((x == ZOOM_0) && (y == ZOOM_0) && (w == ZOOM_1) && (h == ZOOM_1)) { RMDBGLOG((ENABLE, "newavi - full screen zoom window\n")); } else { RMDBGLOG((ENABLE, "newavi - zoom window: ")); if (x >= ZOOM_0) { RMuint32 xx = (((x - ZOOM_0) * 10000) + ((ZOOM_1 - ZOOM_0) / 2)) / (ZOOM_1 - ZOOM_0); RMDBGPRINT((ENABLE, "x=%ld.%02ld%% ", xx / 100, xx % 100)); } else RMDBGPRINT((ENABLE, "x=%ld ", x)); if (y >= ZOOM_0) { RMuint32 yy = (((y - ZOOM_0) * 10000) + ((ZOOM_1 - ZOOM_0) / 2)) / (ZOOM_1 - ZOOM_0); RMDBGPRINT((ENABLE, "y=%ld.%02ld%% ", yy / 100, yy % 100)); } else RMDBGPRINT((ENABLE, "y=%ld ", y)); if (w >= ZOOM_0) { RMuint32 ww = (((w - ZOOM_0) * 10000) + ((ZOOM_1 - ZOOM_0) / 2)) / (ZOOM_1 - ZOOM_0); RMDBGPRINT((ENABLE, "w=%ld.%02ld%% ", ww / 100, ww % 100)); } else RMDBGPRINT((ENABLE, "w=%ld ", w)); if (h >= ZOOM_0) { RMuint32 hh = (((h - ZOOM_0) * 10000) + ((ZOOM_1 - ZOOM_0) / 2)) / (ZOOM_1 - ZOOM_0); RMDBGPRINT((ENABLE, "h=%ld.%02ld%% ", hh / 100, hh % 100)); } else RMDBGPRINT((ENABLE, "h=%ld ", h)); RMDBGPRINT((ENABLE, "\n")); } pHDMI->zoom_x = x; pHDMI->zoom_y = y; pHDMI->zoom_w = w; pHDMI->zoom_h = h; if (! update_mode) { // when update_mode, setup_input() is already performing set_scaler_source_zoom() set_scaler_source_zoom(dcc_info->pRUA, dcc_info->disp_info->osd_scaler[input], pHDMI->zoom_x, pHDMI->zoom_y, pHDMI->zoom_w, pHDMI->zoom_h); } } */ pHDMI->last_avi = *avi; /* // update capture, if neccessary if (update_mode) { RMDBGLOG((ENABLE, "newavi - updating capture mode\n")); err = close_input(dcc_info, ppVideoSource, capture_opt, disp_opt, local_opt, input); if (RMFAILED(err)) RMDBGLOG((ENABLE, "Error closing capture!\n")); err = setup_input(dcc_info, ppVideoSource, capture_opt, disp_opt, audio_opt, local_opt, input); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "FATAL: Error setting up capture!\n")); exit(1); } if (audio_opt->AudioIn) { RMDBGLOG((ENABLE, "AVI Video mode has changed, restarting audio\n")); local_opt->restart_audio = TRUE; } } */ return RM_OK;}RMstatus cap_hdmi_parse_spd_info_frame( struct cap_hdmi_instance *pHDMI, RMuint8 *header, RMuint8 *data, // spd_data[1] through spd_data[25] are used
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -