📄 play_spu.c
字号:
/***************************************************************************** * Copyright (c) 2005 * Sigma Designs, Inc. All Rights Reserved * Proprietary and Confidential *****************************************************************************//** @file play_spu.c @brief - long description - @author Bertrand Mollinier Toublet @date 2005-09-07 */#include "sample_os.h"#ifndef ALLOW_OS_CODE#define ALLOW_OS_CODE 1#endif#include "common.h"#define KEYFLAGS (SET_KEY_DISPLAY | SET_KEY_DEBUG)#define RM_PRINT_ERROR(status, msg, ...) \ fprintf(stderr, "Error %s: " msg , RMstatusToString(status) , ##__VA_ARGS__ )#define DEBUG ENABLE, "Debug: "#define NOTICE ENABLE, "Notice: "static RMstatus parse_cmdline(int, char **);static void show_usage(char *);static RMstatus do_play_spu(struct dcc_context *);static RMstatus do_display_on_spu_scaler(struct dcc_context *);static RMstatus do_set_palette_and_display(struct dcc_context *);static RMstatus do_loop_and_handle_keys(struct dcc_context *);static RMstatus change_LUT_on_spu_scaler(struct dcc_context *);static struct playback_cmdline *play_opt;static struct display_cmdline *disp_opt;static struct DisplayBlock_SetPaletteOnPicture_type global_palette_info;int main(int argc, char **argv){ /*for MONO compatibility, always access these variables through the global pointers*/ struct playback_cmdline playback_options; /*access through play_opt*/ struct display_cmdline display_options; /*access through disp_opt*/ struct display_context disp_info; struct dh_context dh_info = { 0 }; struct dcc_context dcc_info = { 0 }; RMstatus status;#ifdef RMFEATURE_HAS_GENERIC_SPU_SCALER RM_PRINT_ERROR(RM_ERROR, "Cannot run on a chip with a Generic SPU scaler\n"); RM_PRINT_ERROR(RM_ERROR, "Tries on EM862x series\n"); return -1;#endif // RMFEATURE_HAS_GENERIC_SPU_SCALER play_opt = &playback_options; disp_opt = &display_options; dcc_info.disp_info = &disp_info; dcc_info.dh_info = &dh_info; init_playback_options(play_opt); init_display_options(disp_opt); disp_opt->dh_info = &dh_info; status = parse_cmdline(argc, argv); if (! RMFAILED(status)) { RMDBGLOG((NOTICE "creating RUA instance.\n")); status = RUACreateInstance(&dcc_info.pRUA, play_opt->chip_num); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot create RUA instance.\n"); } else { RMDBGLOG((NOTICE "creating DCC instance.\n")); status = DCCOpen(dcc_info.pRUA, &dcc_info.pDCC); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot create DCC instance.\n"); } else { RMDBGLOG((NOTICE "initializing display chain.\n")); status = DCCInitChainEx(dcc_info.pDCC, disp_opt->init_mode); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot initialize display chain.\n"); } else { dcc_info.route = DCCRoute_Main; dcc_info.chip_num = play_opt->chip_num; RMDBGLOG((NOTICE "applying display options.\n")); status = apply_display_options(&dcc_info, disp_opt); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot apply display " "options.\n"); } else { do_play_spu(&dcc_info); } } RMDBGLOG((NOTICE "closing DCC instance.\n")); status = DCCClose(dcc_info.pDCC); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot close DCC instance.\n"); } } RMDBGLOG((NOTICE "closing RUA instance.\n")); status = RUADestroyInstance(dcc_info.pRUA); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot destroy RUA instance.\n"); } } } return status == RM_OK ? EXIT_SUCCESS : EXIT_FAILURE;}static RMstatus do_play_spu(struct dcc_context *pdcc_info){ RMstatus status; RMDBGLOG((NOTICE "getting surface to display OSD source.\n")); status = DCCGetScalerModuleID(pdcc_info->pDCC, DCCRoute_Main, DCCSurface_SPU, disp_opt->osd_pictures[0].scaler, pdcc_info->disp_info->osd_scaler); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot get surface to display OSD source.\n"); } else { RMuint32 scaler = pdcc_info->disp_info->osd_scaler[0]; RMuint32 mixer = EMHWLIB_MODULE(DispMainMixer, 0); RMuint32 source_index; RMDBGLOG((NOTICE "getting mixer source index.\n")); status = RUAExchangeProperty(pdcc_info->pRUA, mixer, RMGenericPropertyID_MixerSourceIndex, &scaler, sizeof scaler, &source_index, sizeof source_index); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot get mixer source index.\n"); } else { RMuint32 mixer_src = EMHWLIB_TARGET_MODULE(mixer, 0, source_index); RMuint32 state = EMhwlibMixerSourceState_Master; RMDBGLOG((NOTICE "setting scaler state on mixer.\n")); while (RM_PENDING == (status = RUASetProperty(pdcc_info->pRUA, mixer_src, RMGenericPropertyID_MixerSourceState, &state, sizeof state, 0))); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot set scaler state on mixer.\n"); } else { RMDBGLOG((NOTICE "setting scaler input window.\n")); while (RM_PENDING == (status = RUASetProperty(pdcc_info->pRUA, mixer_src, RMGenericPropertyID_MixerSourceWindow, &disp_opt->osd_pictures[0].output_window, sizeof disp_opt->osd_pictures[0].output_window, 0))); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot set scaler input window.\n"); } else { RMDBGLOG((NOTICE "validating mixer.\n")); while (RM_PENDING == (status = RUASetProperty(pdcc_info->pRUA, mixer_src, RMGenericPropertyID_Validate, NULL, 0, 0))); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot validate mixer.\n"); } else { RMbool enable = TRUE; RMDBGLOG((NOTICE "enabling scaler.\n")); while (RM_PENDING == (status = RUASetProperty(pdcc_info->pRUA, scaler, RMGenericPropertyID_Enable, &enable, sizeof enable, 0))); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot enable " "scaler.\n"); } else { status = do_display_on_spu_scaler(pdcc_info); } } } } } } return status;}static RMstatus do_display_on_spu_scaler(struct dcc_context *pdcc_info){ RMstatus status; struct DCCOSDProfile profile = { .ColorSpace = EMhwlibColorSpace_YUV_601, .SamplingMode = EMhwlibSamplingMode_444, .ColorMode = EMhwlibColorMode_LUT_8BPP, .ColorFormat = EMhwlibColorFormat_24BPP, .PixelAspectRatio = { .X = 1, .Y = 1 }, .Width = 16, .Height = 16 }; struct DCCVideoSource *posd_source; RMDBGLOG((NOTICE "opening OSD video source.\n")); status = DCCOpenOSDVideoSource(pdcc_info->pDCC, &profile, &posd_source); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot open OSD video source.\n"); } else { RMuint32 luma_addr; RMuint32 luma_size; RMuint32 chroma_addr; RMuint32 chroma_size; pdcc_info->pOSDSource[0] = posd_source; RMDBGLOG((NOTICE "getting luma and chroma info.\n")); status = DCCGetOSDVideoSourceInfo(posd_source, &luma_addr, &luma_size, &chroma_addr, &chroma_size); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot get luma and chroma info.\n"); } else { RMDBGLOG((DEBUG "luma_size = %lu, chroma_size = %lu.\n", luma_size, chroma_size)); RMDBGLOG((NOTICE "locking OSD buffer.\n")); status = RUALock(pdcc_info->pRUA, luma_addr, luma_size); if (RMFAILED(status)) { RM_PRINT_ERROR(status, "cannot lock OSD buffer.\n"); } else { RMuint8 *pLuma; RMDBGLOG((NOTICE "mapping OSD buffer.\n")); pLuma = RUAMap(pdcc_info->pRUA, luma_addr, luma_size); if (NULL == pLuma) { status = RM_ERROR; RM_PRINT_ERROR(status, "cannot map OSD buffer.\n"); } else { RMuint8 *pwLuma; RMuint8 index, alpha; RMbool enable = TRUE; RMDBGLOG((NOTICE "creating image.\n")); RMDBGLOG((DEBUG "pLuma = %p, end_ptr = %p.\n", pLuma, pLuma + luma_size)); index = 0; alpha = 0; for (pwLuma = pLuma; pwLuma < pLuma + luma_size; pwLuma++) { /* Note: from the EM8622L hardware specification: * "The sub-picture block receives a picture from * DRAM, as an 8 bit per pixel stream [...]. Each * pixel consists of 4 bits of color index (bits[7:4]) * and 4 bits of alpha (bits[3:0])" * * Here we want to go through our table, and each * time we go through all 16 available colors, we * want to increase the alpha value by one unit.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -