📄 gfx_demo.c
字号:
err = DCCOpen(pRUA, &pDCC); if (RMFAILED(err)) { fprintf(stderr, "Error Opening DCC! %d\n", err); return err; } err = DCCInitMicroCodeEx(pDCC, disp_opt.init_mode); if (RMFAILED(err)) { fprintf(stderr, "Cannot initialize microcode %d\n", err); return err; } dcc_info.pRUA = pRUA; dcc_info.pDCC = pDCC; dcc_info.route = DCCRoute_Main; err = apply_display_options(&dcc_info, &disp_opt); if (RMFAILED(err)) { fprintf(stderr, "Cannot set display options %d\n", err); return err; } /* the mixer should not modify the GFX scaler's config */ { enum EMhwlibMixerSourceState state; RMuint32 mixer, scaler, src_index, mixer_src; mixer = EMHWLIB_MODULE(DispMainMixer, 0); scaler= EMHWLIB_MODULE(DispOSDScaler,0); /* set a NULL surface, this will force a full register update when next surface is set */ err = DCCSetSurfaceSource(dcc_info.pDCC, scaler, NULL); if (RMFAILED(err)) { fprintf(stderr, "Cannot unset gfx scaler's surface\n"); goto cleanup; } 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")); goto cleanup; } mixer_src = EMHWLIB_TARGET_MODULE(mixer, 0 , src_index ); state = EMhwlibMixerSourceState_Slave; while((err = RUASetProperty(dcc_info.pRUA, mixer_src, RMGenericPropertyID_MixerSourceState, &state, sizeof(state), 0))==RM_PENDING); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot set scaler's state on mixer\n")); goto cleanup; } while ((err = RUASetProperty(dcc_info.pRUA, mixer, RMGenericPropertyID_Validate, NULL, 0, 0)) == RM_PENDING); if (RMFAILED(err)) { fprintf(stderr, "Cannot validate mixer\n"); goto cleanup; } do{ err = RUAGetProperty(dcc_info.pRUA, mixer_src, RMGenericPropertyID_MixerSourceState, &state, sizeof(state)); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "error getting source state %s\n", RMstatusToString(err))); } /* this is just to avoid busy loops, can be substituted by a sleep function or removed */ if(state != EMhwlibMixerSourceState_Slave){ struct RUAEvent evt; evt.ModuleID = EMHWLIB_MODULE(DisplayBlock, 0); evt.Mask = EMHWLIB_DISPLAY_EVENT_ID(mixer); err = RUAWaitForMultipleEvents(dcc_info.pRUA, &evt, 1, TIMEOUT_US, NULL); if(RMFAILED(err)){ RMDBGLOG((ENABLE, "wait for display update event completion failed, %s\n", RMstatusToString(err))); } } }while(state != EMhwlibMixerSourceState_Slave); } { // open first stc module struct DCCStcProfile stc_profile; stc_profile.STCID = 0; stc_profile.master = Master_STC; stc_profile.stc_timer_id = 0; stc_profile.stc_time_resolution = 90000; stc_profile.video_timer_id = 1; stc_profile.video_time_resolution = 90000; stc_profile.video_offset = 0; stc_profile.audio_timer_id = NO_TIMER; stc_profile.audio_time_resolution = 0; stc_profile.audio_offset = 0; err = DCCSTCOpen(dcc_info.pDCC, &stc_profile, &dcc_info.pStcSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot open stc module %d\n", err)); goto cleanup; } err = DCCSTCSetTime(dcc_info.pStcSource, 0, 90000); if (RMFAILED(err)) { fprintf(stderr, "Cannot insert picture inside surface %d\n", err); goto cleanup; } err = DCCSTCSetSpeed(dcc_info.pStcSource, 1, inv_speed); if (RMFAILED(err)) { fprintf(stderr, "Cannot insert picture inside surface %d\n", err); goto cleanup; } } err = load_bitmaps(); if (RMFAILED(err)) { fprintf(stderr, "Error loading bitmaps %d\n", err); goto cleanup; } /* if(EMHWLIB_MODULE_CATEGORY(scalers[0]) == DispVideoPlane){ *//* struct EMhwlibTVFormatAnalog tv_format; *//* err = RUAExchangeProperty(pRUA, DisplayBlock, RMDisplayBlockPropertyID_TVFormatAnalog, &(disp_opt->standard), sizeof(disp_opt->standard), &tv_format, sizeof(tv_format)); *//* if (RMFAILED(err)) { *//* fprintf(stderr, "Cannot get TV format %d\n", err); *//* goto cleanup; *//* } *//* mosaic_width = tv_format.ActiveWidth; *//* mosaic_height = tv_format.ActiveHeight; *//* fprintf(stderr, "active width %ld, active height %ld\n", tv_format.ActiveWidth, tv_format.ActiveHeight); *//* } */ /* open a video source with two pictures */ err = DCCOpenMultiplePictureOSDVideoSource(dcc_info.pDCC, &bitmap_profile, 2, &(pVideoSource), dcc_info.pStcSource ); if (RMFAILED(err)) { fprintf(stderr, "Cannot open OSD decoder %d\n", err); goto cleanup; } err = DCCGetOSDSurfaceInfo(dcc_info.pDCC, pVideoSource, NULL, &surface_addr, NULL); if (RMFAILED(err)) { fprintf(stderr, "Cannot get surface address %d\n", err); goto cleanup; } err = DCCGetOSDPictureInfo(pVideoSource, 0, &(pic_addr[0]), &(pic_luma_addr[0]), NULL, NULL, NULL); if (RMFAILED(err)) { fprintf(stderr, "Cannot get osd buffer info %d\n", err); goto cleanup; } err = DCCGetOSDPictureInfo(pVideoSource, 1, &(pic_addr[1]), &(pic_luma_addr[1]), NULL, NULL, NULL); if (RMFAILED(err)) { fprintf(stderr, "Cannot get osd buffer info %d\n", err); goto cleanup; } /* works only for tango2 */ if (multiple_readers) {#ifdef RMFEATURE_HAS_VIDEOPLANE err = init_scaler(pDCC, pRUA, pVideoSource, EMHWLIB_MODULE(DispVideoPlane,0)); if (RMFAILED(err)) { fprintf(stderr, "Cannot set VideoPlane %d\n", err); goto cleanup; }#endif #ifdef RMFEATURE_HAS_VCR_SCALER err = init_scaler(pDCC, pRUA, pVideoSource, EMHWLIB_MODULE(DispVCRMultiScaler,0)); if (RMFAILED(err)) { fprintf(stderr, "Cannot set vcr scaler %d\n", err); goto cleanup; }#endif } /* set OSD last. so it it cleared when DCCCloseVideoSource */ err = init_scaler(pDCC, pRUA, pVideoSource, scalers[0]); if (RMFAILED(err)) { fprintf(stderr, "Cannot set osd scaler %d\n", err); goto cleanup; } err = DCCClearOSDPicture(pVideoSource, 0); if (RMFAILED(err)) { fprintf(stderr, "Cannot clear OSD\n"); goto cleanup; } err = DCCInsertPictureInMultiplePictureOSDVideoSource(pVideoSource, 0, 0); if (RMFAILED(err)) { fprintf(stderr, "Cannot insert picture inside surface %d\n", err); goto cleanup; } /* init the gfx_engine */ { RMuint32 chip_num; RMuint32 gfx_count; struct GFXEngine_DRAMSize_in_type dramSizeIn; struct GFXEngine_DRAMSize_out_type dramSizeOut; RMint32 i; chip_num = 0; dramSizeIn.CommandFIFOCount = 10; err = RUAExchangeProperty(pRUA, EMHWLIB_MODULE(GFXEngine,0), RMGFXEnginePropertyID_DRAMSize, &dramSizeIn, sizeof(dramSizeIn), &dramSizeOut, sizeof(dramSizeOut)); if (RMFAILED(err)) { fprintf(stderr, "Error getting dram size for gfx engine\n"); goto cleanup; } gfx_profile.CommandFIFOCount = dramSizeIn.CommandFIFOCount; gfx_profile.Priority = 1; gfx_profile.CachedSize = dramSizeOut.CachedSize; gfx_profile.UncachedSize = dramSizeOut.UncachedSize; if (gfx_profile.CachedSize > 0) { gfx_profile.CachedAddress = RUAMalloc(pRUA, 0, RUA_DRAM_CACHED, gfx_profile.CachedSize); } else { gfx_profile.CachedAddress = 0; } gfx_profile.UncachedSize = dramSizeOut.UncachedSize; if (gfx_profile.UncachedSize > 0) { gfx_profile.UncachedAddress = RUAMalloc(pRUA, 0, RUA_DRAM_UNCACHED, gfx_profile.UncachedSize); } else { gfx_profile.UncachedAddress = 0; } gfx = GFXEngine; err = RUAExchangeProperty(pRUA, EMHWLIB_MODULE(Enumerator,0), RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &gfx, sizeof(gfx), &gfx_count, sizeof(gfx_count)); if (RMFAILED(err)) { fprintf(stderr, "Error getting gfx engine count\n"); goto cleanup; } for (i=0 ; i<(RMint32) gfx_count ; i++) { gfx = EMHWLIB_MODULE(GFXEngine, i); err = RUASetProperty(pRUA, gfx, RMGFXEnginePropertyID_Open, &gfx_profile, sizeof(gfx_profile), 0); if (err == RM_OK) break; } if (i==(RMint32)gfx_count) { fprintf(stderr, "Cannot open a gfx engine [0..%lu[\n", gfx_count); goto cleanup; } }//*/ err = DCCSTCPlay(dcc_info.pStcSource); if (RMFAILED(err)) { fprintf(stderr, "Cannot insert picture inside surface %d\n", err); goto cleanup; } { struct GFXEngine_Surface_type NX_surface; struct GFXEngine_DisplayPicture_type display_pic; NX_surface.SurfaceID = GFX_SURFACE_ID_NX; NX_surface.TotalWidth = bitmap_profile.Width; NX_surface.Tiled = FALSE; RMTermInit(TRUE); RMSignalInit(NULL, NULL); /* wait for the picture to be on display. This is the correct way to make the next double buffering implementation work 100% */ { struct RUAEvent e; RMuint32 index; e.ModuleID = EMHWLIB_MODULE(DisplayBlock, 0); e.Mask = EMHWLIB_DISPLAY_NEW_PICTURE_EVENT_ID(DispOSDScaler); err = RUAWaitForMultipleEvents(pRUA, &e, 1, 1000000, &index); if (err == RM_ERROR) { fprintf(stderr, "cannot wait for the picture to be on display\n"); goto cleanup; } } pic_index = 0; display_pic.Pts = 0; while(!end){ pic_index++; pic_index &= 0x1; /*block until the picture we're editing it's released*/ SEND_GFX_COMMAND( RMGFXEnginePropertyID_WaitForPicture, &(pic_addr[pic_index]), sizeof(pic_addr[pic_index])); /* setup NX to point to the picture we're editing */ NX_surface.StartAddress = pic_luma_addr[pic_index]; SEND_GFX_COMMAND( RMGFXEnginePropertyID_Surface, &NX_surface, sizeof(NX_surface)); /* edit the picture */ gfx_demo_draw_picture(pic_luma_addr[pic_index], pic_index); /* display the picture */ display_pic.Surface = surface_addr; display_pic.Picture = pic_addr[pic_index]; display_pic.Pts += 1800; SEND_GFX_COMMAND( RMGFXEnginePropertyID_DisplayPicture, &display_pic, sizeof(display_pic)); update_hdmi(&dcc_info, &disp_opt, NULL); } } cleanup: RMTermExit(); if(buf_addr) RUAFree(pRUA, buf_addr); if(elephant_glyph.OutAddr) RUAFree(pRUA, elephant_glyph.OutAddr); err = RUASetProperty(pRUA, gfx, RMGFXEnginePropertyID_Close, &close_profile, sizeof(close_profile), 0); if (RMFAILED(err)) fprintf(stderr, "Cannot close the gfx accelerator\n"); if(gfx_profile.CachedAddress) RUAFree(pRUA, gfx_profile.CachedAddress); if(gfx_profile.UncachedAddress) RUAFree(pRUA, gfx_profile.UncachedAddress); clear_display_options(&dcc_info, &disp_opt); err = DCCCloseVideoSource(pVideoSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot close osd source %s\n", RMstatusToString(err))); goto cleanup; } if (multiple_readers) { RMuint32 surface = 0;#ifdef RMFEATURE_HAS_VIDEOPLANE RUASetProperty(pRUA, DispVideoPlane, RMGenericPropertyID_Surface, &surface, sizeof(surface), 0);#endif#ifdef RMFEATURE_HAS_VCR_SCALER RUASetProperty(pRUA, DispVCRMultiScaler, RMGenericPropertyID_Surface, &surface, sizeof(surface), 0);#endif /* to avoid compilation warning */ surface ++; } err = DCCClose(pDCC); if (RMFAILED(err)) { fprintf(stderr, "Cannot close DCC %d\n", err); goto cleanup; } err = RUADestroyInstance(pRUA); if (RMFAILED(err)) { fprintf(stderr, "Cannot destroy RUA instance %d\n", err); goto cleanup; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -