📄 parse_video_cmdline.c
字号:
fprintf(stderr, "CCfifo error %s\n", RMstatusToString(err)); return err; } if(dcc_info->pStcSource) DCCSTCGetModuleId(dcc_info->pStcSource, &stc_id); cc_open.UncachedAddress = DCCMalloc(dcc_info->pDCC, 0, RUA_DRAM_UNCACHED, fifo_size); cc_open.EntryCount = entry_count; cc_open.UncachedSize = fifo_size; cc_open.STCModuleId = stc_id; dcc_info->ccfifo_out_addr = cc_open.UncachedAddress; err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_out_id, RMCCFifoPropertyID_Open, &cc_open, sizeof(cc_open), 0); if (RMFAILED(err)) { fprintf(stderr, "Cannot open ccfifo %s\n", RMstatusToString(err)); return err; } } else { dcc_info->ccfifo_out_id = dcc_info->ccfifo_in_id; dcc_info->ccfifo_out_addr = 0; } if (options->use_soft_cc_decoder){ RMbool enable; struct DCCOSDProfile osd_profile; Rtk86Handle rtk_handle; struct EMhwlibDisplayWindow window; struct rmscc_init scc_init; RMuint32 scaler, src_index, used_colors; RMpalette_8BPP cc_palette; scaler = DispOSDScaler; /* create a buffer to draw the closed caption on */ osd_profile.ColorSpace = EMhwlibColorSpace_RGB_0_255; osd_profile.SamplingMode = EMhwlibSamplingMode_444; osd_profile.ColorFormat = EMhwlibColorFormat_32BPP; /* eia708 does not support indexed mode yet */ if(options->use_soft_cc_decoder == 1) osd_profile.ColorMode = EMhwlibColorMode_LUT_8BPP; else if(options->use_soft_cc_decoder == 2) osd_profile.ColorMode = EMhwlibColorMode_TrueColor; osd_profile.PixelAspectRatio.X = 1; osd_profile.PixelAspectRatio.Y = 1; osd_profile.Width = 640; osd_profile.Height = 480; window.X = 2048; window.Y = 2048; window.Width = 4096; window.Height = 4096; window.XPositionMode = EMhwlibDisplayWindowPositionMode_FrontEdgeToCenter; window.YPositionMode = EMhwlibDisplayWindowPositionMode_FrontEdgeToCenter; window.XMode = EMhwlibDisplayWindowValueMode_Relative; window.YMode = EMhwlibDisplayWindowValueMode_Relative; window.WidthMode = EMhwlibDisplayWindowValueMode_Relative; window.HeightMode = EMhwlibDisplayWindowValueMode_Relative; /* Disable the scaler while we program it */ enable = FALSE; err = RUASetProperty(dcc_info->pRUA, scaler, RMGenericPropertyID_Enable, &enable, sizeof(enable), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot enable scaler\n")); return err; } err = DCCOpenOSDVideoSource(dcc_info->pDCC, &osd_profile, &(dcc_info->pCCOSDSource)); if (RMFAILED(err)) { fprintf(stderr, "Cannot open OSD decoder %d\n", err); return err; } while ((err = RUASetProperty(dcc_info->pRUA, scaler, RMGenericPropertyID_ScalerInputWindow, &(window), sizeof(window), 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set scaler input window on OSD surface %d\n", err)); return err; } err = DCCSetSurfaceSource(dcc_info->pDCC, scaler, dcc_info->pCCOSDSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set the surface source %d\n", err)); return err; } err = DCCEnableVideoSource(dcc_info->pCCOSDSource, TRUE); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error enabling OSD buffer : %d\n",err)); return err; } err = RUAExchangeProperty(dcc_info->pRUA, mixer, RMGenericPropertyID_MixerSourceIndex, &scaler, sizeof(scaler), &src_index, sizeof(src_index)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get scaler index\n")); return err; } /* display the osd only on the active region of the screen (80% width, 80% height) */ mixer = EMHWLIB_TARGET_MODULE(mixer, 0, src_index); window.Width = 8*4096/10; window.Height = 8*4096/10; while ((err = RUASetProperty(dcc_info->pRUA, mixer, RMGenericPropertyID_MixerSourceWindow, &(window), sizeof(window), 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set scaler output window %d\n", err)); return err; } if(options->use_soft_cc_decoder == 2){ /* this asks the video decoder to put only the eia708 closed caption * data into the fifo. The default is to put only eia608 so we don't need * to handle this when use_soft_cc_decoder == 1 */ struct CCFifo_AllowedTypes_type allowed_types; allowed_types.Allow608 = FALSE; allowed_types.Allow708 = TRUE; err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_AllowedTypes, &(allowed_types), sizeof(allowed_types), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set scaler input window on OSD surface %d\n", err)); return err; } /* make this instance of rmscc a eia708 decoder */ scc_init.format = rmscc_eia_708; } else if (options->use_soft_cc_decoder == 1){ /* make this instance of rmscc a eia608 decoder */ scc_init.format = rmscc_eia_608; } else{ RMDBGLOG((ENABLE, "Wrong value for use_soft_decoder\n")); return RM_ERROR; } rtk_handle.pOSDSource = dcc_info->pCCOSDSource; rtk_handle.pRUA = dcc_info->pRUA; scc_init.rtk = RMFRTKOpen(&rtk_handle); if(scc_init.rtk == NULL){ RMDBGLOG((ENABLE, "Error opening rtk: %d\n",err)); return RM_ERROR; } scc_init.resize_callback = NULL; scc_init.cc_select = (enum rmscc_ccselect)((RMuint32)options->cc_select - 1); dcc_info->scc = RMSCCOpen(&scc_init); if(dcc_info->scc == NULL){ RMDBGLOG((ENABLE, "Error opening scc: %d\n",err)); return RM_ERROR; } dcc_info->rtk= scc_init.rtk; /* ask rmscc which palette needs to be set... */ err = RMSCCGetPalette(dcc_info->scc, &cc_palette, &used_colors); if (RMFAILED(err)){ RMDBGLOG((ENABLE, "Error enabling OSD buffer : %d\n",err)); return err; } /* and set it */ while ((err = RUASetProperty(dcc_info->pRUA, scaler, RMGenericPropertyID_8BPP_LUT, &cc_palette, sizeof(cc_palette), 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set LUT for OSD scaler: %s\n", RMstatusToString(err))); return err; } while ((err = RUASetProperty(dcc_info->pRUA, scaler, RMGenericPropertyID_Validate, NULL, 0, 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot validate scaler input window: %s\n", RMstatusToString(err))); return err; } /* rmscc has cleared the osd so now we can displayed it */ enable = TRUE; err = RUASetProperty(dcc_info->pRUA, scaler, RMGenericPropertyID_Enable, &enable, sizeof(enable), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot enable scaler\n")); return err; } } else{ while ((err = RUASetProperty(dcc_info->pRUA, mixer, RMGenericPropertyID_CCFifo, &dcc_info->ccfifo_out_id, sizeof(dcc_info->ccfifo_out_id), 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set CC_fifo\n")); return err; } } while ((err = RUASetProperty(dcc_info->pRUA, mixer, RMGenericPropertyID_Validate, NULL, 0, 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot validate mixer settings\n")); return err; } err = RUASetProperty(dcc_info->pRUA, dcc_info->video_decoder, RMGenericPropertyID_CCFifo, &dcc_info->ccfifo_in_id, sizeof(dcc_info->ccfifo_in_id), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set CC_fifo on video decoder\n")); return err; } } else { dcc_info->ccfifo_in_id = 0; dcc_info->ccfifo_out_id = 0; } if (options->display_ttx) { RMuint32 mixer; mixer = EMHWLIB_MODULE(DispMainMixer, 0); dcc_info->ttx_fifo_id = EMHWLIB_MODULE(TTXFifo, 0); // use one ttx fifo for now if( dcc_info->ttx_sw_decoder == 0 ) // make sure the TTXfifo is opened dcc_info->ttx_sw_decoder = RMTTXOpen( dcc_info->pRUA, dcc_info->ttx_fifo_id, TTX_FIFO_SIZE ); while ((err = RUASetProperty(dcc_info->pRUA, mixer, RMGenericPropertyID_TTXFifo, &(dcc_info->ttx_fifo_id), sizeof(RMuint32), 0)) == RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set TTX_fifo\n")); return err; } } return RM_OK;}RMstatus clear_video_options(struct dcc_context *dcc_info, struct video_cmdline *options){ RMstatus err; struct RUAEvent evt; RMuint32 wait_count; RMbool cc_done = FALSE; RMbool mute = TRUE; err = RM_OK; evt.ModuleID = DisplayBlock; evt.Mask = EMHWLIB_DISPLAY_EVENT_ID(DispMainMixer); if (dcc_info->ccfifo_in_id) { if (options->use_soft_cc_decoder) { RMDBGLOG((DEBUG, "Closing soft CC decoder...\n")); RMFRTKClose(dcc_info->rtk); err = DCCCloseVideoSource(dcc_info->pCCOSDSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot close cc-osd source %s\n", RMstatusToString(err))); return err; } dcc_info->pCCOSDSource = NULL; RMDBGLOG((DEBUG, "Done closing soft CC decoder.\n")); RMSCCClose(dcc_info->scc); } else{ wait_count = 0; while((err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_Mute, &mute, sizeof(mute), 0) == RM_PENDING) && (wait_count <4)){ RUAWaitForMultipleEvents(dcc_info->pRUA, &evt, 1, 500000, NULL); wait_count++; } wait_count = 0; while((err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_Flush, NULL, 0, 0) == RM_PENDING) && (wait_count <4)){ RUAWaitForMultipleEvents(dcc_info->pRUA, &evt, 1, 500000, NULL); wait_count++; } wait_count = 0; while((err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_Clear, NULL, 0, 0) == RM_PENDING) && (wait_count <4)){ RUAWaitForMultipleEvents(dcc_info->pRUA, &evt, 1, 500000, NULL); wait_count++; } } /* the clear and flush commands can take some vsyncs to execute (flush(1), clear(4)) here we wait until they are finished before closing the CCFifo */ wait_count = 0; do{ err = RUAGetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_FifoEmpty, &cc_done, sizeof(cc_done)); if(!cc_done){ RUAWaitForMultipleEvents(dcc_info->pRUA, &evt, 1, 500000, NULL); wait_count++; } }while((!cc_done) && wait_count<16); if(!cc_done) RMDBGLOG((ENABLE, "ERROR CLEARING CCFIFO!\n")); while( (err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_Close, NULL, 0, 0)) == RM_PENDING); if (RMFAILED(err)) { fprintf(stderr, "Cannot close ccfifo %s\n", RMstatusToString(err)); } } if ((dcc_info->ccfifo_out_id) && (dcc_info->ccfifo_out_id != dcc_info->ccfifo_in_id)) { RMDBGLOG((DEBUG, "Clearing CC fifo #%lu...\n", EMHWLIB_MODULE_INDEX(dcc_info->ccfifo_out_id))); err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_out_id, RMCCFifoPropertyID_Clear, NULL, 0, 0); if (RMFAILED(err)) { fprintf(stderr, "Cannot clear passthrough CCfifo %s\n", RMstatusToString(err)); } RMDBGLOG((DEBUG, "Done clearing CC fifo.\n")); RMDBGLOG((DEBUG, "Closing CC passthrough fifo #%lu...\n", EMHWLIB_MODULE_INDEX(dcc_info->ccfifo_out_id))); while( (err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_out_id, RMCCFifoPropertyID_Close, NULL, 0, 0)) == RM_PENDING); if (RMFAILED(err)) { fprintf(stderr, "Cannot close passthrough ccfifo %s\n", RMstatusToString(err)); } RMDBGLOG((DEBUG, "Done closing CC passthrough fifo.\n")); } if (dcc_info->ccfifo_in_addr) { DCCFree(dcc_info->pDCC, dcc_info->ccfifo_in_addr); RMDBGLOG((DEBUG, "Done freeing CC fifo memory.\n")); } if (dcc_info->ccfifo_out_addr) { DCCFree(dcc_info->pDCC, dcc_info->ccfifo_out_addr); RMDBGLOG((DEBUG, "Done freeing CC passthrough fifo memory.\n")); } if (options->display_ttx) { // close ttx in case of program change if( dcc_info->ttx_sw_decoder != 0 ) { RMTTXClose( dcc_info->ttx_sw_decoder ); dcc_info->ttx_sw_decoder = 0; } } return RM_OK;}RMstatus refresh_soft_cc(struct dcc_context *dcc_info){ RMstatus err; struct CCFifo_CCEntry_type cc_entry; enum rmscc_ccselect ccselect = RMSCCGetDisplayCCType(dcc_info->scc); while (RMSUCCEEDED(RUAGetProperty(dcc_info->pRUA, dcc_info->ccfifo_in_id, RMCCFifoPropertyID_CCEntry, &cc_entry, sizeof(cc_entry)))) { if (RMFAILED(err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_out_id, RMCCFifoPropertyID_CCEntry, &cc_entry, sizeof(cc_entry), 0))) { RMDBGLOG((DEBUG, "Failed to pass through CC entry! %s\n", RMstatusToString(err))); if (err == RM_PENDING) { // probably a STC discontinuity, flush old CC data RMuint64 usec; RMDBGLOG((DEBUG, "Flushing and clearing CC fifo #%lu...\n", EMHWLIB_MODULE_INDEX(dcc_info->ccfifo_out_id))); usec = get_ustime(); while (RMFAILED(err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_out_id, RMCCFifoPropertyID_Flush, NULL, 0, 0)) && (get_ustime() - usec < 20000)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot flush CCfifo %s\n", RMstatusToString(err))); } usec = get_ustime(); while (RMFAILED(err = RUASetProperty(dcc_info->pRUA, dcc_info->ccfifo_out_id, RMCCFifoPropertyID_Clear, NULL, 0, 0)) && (get_ustime() - usec < 20000)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot clear CCfifo %s\n", RMstatusToString(err))); } RMDBGLOG((DEBUG, "Done flushing and clearing CC fifo.\n")); } } if (cc_entry.Enable){ switch(cc_entry.Type){ case EMhwlibCCType_TopField: case EMhwlibCCType_BottomField: if( (ccselect != rmscc_not_available) && (((RMuint32)ccselect & 0x2)>>1 == cc_entry.Type) ) { if(ccsize >= 128 - 2){ RMSCCDecode(dcc_info->scc, ccbuf, ccsize, get_ustime() ); ccsize = 0; } ccbuf[ccsize++] = cc_entry.CC1; ccbuf[ccsize++] = cc_entry.CC2; } break; case EMhwlibCCType_DTVCCHeader: if(dtvsize){ dtvsize = 0; } case EMhwlibCCType_DTVCCData:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -