📄 dcc_video.c
字号:
/***************************************** Copyright © 2001-2003 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//** @file dcc.c @brief Decoding Chain Control API @author Julien Soulier @date 2003-10-02*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 0#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#define ENABLE_SPU_OP 1#include "dcc_common.h"static RMstatus send_video_command(struct RUA *pRUA, RMuint32 video_decoder, enum VideoDecoder_Command_type v_command) { struct RUAEvent evt; enum VideoDecoder_State_type state; RMuint32 index; RMstatus err; RMstatus cmdStatus; evt.ModuleID = video_decoder; evt.Mask = RUAEVENT_COMMANDCOMPLETION; err = RUAResetEvent(pRUA, &evt); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot reset video command completion event, %s\n", RMstatusToString(err))); return err; }#ifdef _DEBUG err = RUAGetProperty(pRUA, video_decoder, RMVideoDecoderPropertyID_State, &state, sizeof(state)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get video state, %s\n", RMstatusToString(err))); return err; } RMDBGLOG((LOCALDBG, "current VIDEO state = %s\n", VIDEO_STATE_TO_STRING(state))); RMDBGLOG((LOCALDBG, "send command = %s\n", VIDEO_COMMAND_TO_STRING(v_command)));#endif err = RUASetProperty(pRUA, video_decoder, RMVideoDecoderPropertyID_Command, &v_command, sizeof(v_command), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send video command, %s\n", RMstatusToString(err))); return err; } evt.ModuleID = video_decoder; evt.Mask = RUAEVENT_COMMANDCOMPLETION; err = RUAWaitForMultipleEvents(pRUA, &evt, 1, WAIT_COMMAND_TIMEOUT_US, &index); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "wait for video command completion failed, %s\n", RMstatusToString(err))); return err; } err = RUAGetProperty(pRUA, video_decoder, RMVideoDecoderPropertyID_State, &state, sizeof(state)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get video state, %s\n", RMstatusToString(err))); return err; } RMDBGLOG((LOCALDBG, "Now VIDEO state = %s\n", VIDEO_STATE_TO_STRING(state))); err = RUAGetProperty(pRUA, video_decoder, RMVideoDecoderPropertyID_CommandStatus, &cmdStatus, sizeof(cmdStatus)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get command status, %s\n", RMstatusToString(err))); return err; } return cmdStatus;}static RMstatus send_spu_command(struct RUA *pRUA, RMuint32 spu_decoder, enum SpuDecoder_Command_type v_command) { struct RUAEvent evt; enum SpuDecoder_State_type state; RMuint32 index; RMstatus err; RMDBGLOG((LOCALDBG, "send_spu_command addr=0x%08lx command=%ld\n", pRUA, (int)v_command)); evt.ModuleID = spu_decoder; evt.Mask = RUAEVENT_COMMANDCOMPLETION; err = RUAResetEvent(pRUA, &evt); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot reset spu command completion event, %s\n", RMstatusToString(err))); return err; } err = RUASetProperty(pRUA, spu_decoder, RMSpuDecoderPropertyID_Command, &v_command, sizeof(v_command), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send spu command, %s\n", RMstatusToString(err))); return err; } evt.ModuleID = spu_decoder; evt.Mask = RUAEVENT_COMMANDCOMPLETION; err = RUAWaitForMultipleEvents(pRUA, &evt, 1, WAIT_COMMAND_TIMEOUT_US, &index); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "wait for spu command completion failed, %s\n", RMstatusToString(err))); return err; } err = RUAGetProperty(pRUA, spu_decoder, RMSpuDecoderPropertyID_State, &state, sizeof(state)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get spu state, %s\n", RMstatusToString(err))); return err; } RMDBGLOG((LOCALDBG, "Now SPU state = %s\n", SPU_STATE_TO_STRING(state))); return RM_OK;}RMstatus DCCOpenVideoDecoderSource(struct DCC *pDCC, struct DCCVideoProfile *dcc_profile, struct DCCVideoSource **ppVideoSource){ struct VideoDecoder_DRAMSize_in_type dram_in; struct VideoDecoder_DRAMSize_out_type dram_out; struct VideoDecoder_Open_type profile; RMuint32 surface, mpeg_engine, video_decoder; RMuint32 nb_mpeg_engines, nb_video_decoders; RMuint32 temp; RMstatus err; *ppVideoSource = (struct DCCVideoSource *) RMMalloc(sizeof(struct DCCVideoSource)); if (*ppVideoSource == NULL) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in system memory %lu!\n", sizeof(struct DCCVideoSource))); return RM_FATALOUTOFMEMORY; } RMMemset((void*)(*ppVideoSource), 0, sizeof(struct DCCVideoSource)); (*ppVideoSource)->pRUA = pDCC->pRUA; (*ppVideoSource)->pDCC = pDCC; // Get number of video engines and video decoders temp = MpegEngine; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_mpeg_engines, sizeof(nb_mpeg_engines)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMEnumeratorPropertyID_CategoryIDToNumberOfInstances %s\n", RMstatusToString(err))); return err; } else { if (dcc_profile->MpegEngineID < nb_mpeg_engines) RMDBGLOG((LOCALDBG, "Number of video engines: %d%s\n", (int) nb_mpeg_engines)); else { RMDBGLOG((ENABLE, "Error: video engine index %d out of range!!! Should be < %d\n", (int) dcc_profile->MpegEngineID, (int) nb_mpeg_engines)); err = RM_PARAMETER_OUT_OF_RANGE; return err; } } temp = VideoDecoder; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_video_decoders, sizeof(nb_video_decoders)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMEnumeratorPropertyID_CategoryIDToNumberOfInstances %s\n", RMstatusToString(err))); return err; } else { if (dcc_profile->VideoDecoderID < (nb_video_decoders / nb_mpeg_engines)) RMDBGLOG((LOCALDBG, "Number of video decoders: %d%s\n", (int) nb_video_decoders)); else { RMDBGLOG((ENABLE, "Error: video decoder index %d out of range!!! Should be < %d\n", (int) dcc_profile->VideoDecoderID, (int) (nb_video_decoders / nb_mpeg_engines))); err = RM_PARAMETER_OUT_OF_RANGE; return err; } } // Check for MPEG engine on right DRAM. Second MPEG engine on Tango 2 only. In this case, MPEG engine // must be the same as DRAM controller. We do not support Mambo in this branch (Mambo would have been // able to play MPEG Engine 0 on DRAM controller 1...). Not on Tango 2. if (pDCC->dram != dcc_profile->MpegEngineID) { RMDBGLOG((ENABLE, "Error: cannot play Video Engine %d on DRAM %d.\n", (int) dcc_profile->MpegEngineID, (int) pDCC->dram)); return RM_ERROR; } mpeg_engine = EMHWLIB_MODULE(MpegEngine, dcc_profile->MpegEngineID); (*ppVideoSource)->engine_moduleID = mpeg_engine; RMDBGLOG((LOCALDBG, "MpegEngine: 0x%08lX\n", mpeg_engine)); // !!Hack!! We assume there are an equal amount of decoders per engine; (nb_video_decoders / nb_mpeg_engines) // gives the number of decoders per engine. video_decoder = EMHWLIB_MODULE(VideoDecoder, dcc_profile->MpegEngineID * (nb_video_decoders / nb_mpeg_engines) + dcc_profile->VideoDecoderID); (*ppVideoSource)->decoder_moduleID = video_decoder; RMDBGLOG((LOCALDBG, "VideoDecoder: 0x%08lX\n", video_decoder)); profile.DemuxProgramId = dcc_profile->DemuxProgramID; profile.TimerId = dcc_profile->STCID; (*ppVideoSource)->timer_number = profile.TimerId; dram_in.MPEGProfile = dcc_profile->MPEGProfile; dram_in.BitstreamFIFOSize = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount = dcc_profile->XferFIFOCount; err = RUAExchangeProperty(pDCC->pRUA, video_decoder, RMVideoDecoderPropertyID_DRAMSize, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMVideoDecoderPropertyID_DRAMSize! %s\n", RMstatusToString(err))); return err; } profile.MPEGProfile = dram_in.MPEGProfile; profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.CachedAddress = 0; profile.CachedSize = dram_out.CachedSize; if (profile.CachedSize > 0) { profile.CachedAddress = pDCC->rua_malloc(pDCC->pRUA, video_decoder, pDCC->dram, RUA_DRAM_CACHED, profile.CachedSize); if (!profile.CachedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in cached DRAM %lu!\n", profile.CachedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "video cached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.CachedAddress, profile.CachedSize, profile.CachedAddress + profile.CachedSize)); } (*ppVideoSource)->cached_address = profile.CachedAddress; profile.UncachedAddress = 0; profile.UncachedSize = dram_out.UncachedSize; if (profile.UncachedSize > 0) { profile.UncachedAddress = pDCC->rua_malloc(pDCC->pRUA, video_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.UncachedSize); if (!profile.UncachedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in uncached DRAM %lu!\n", profile.UncachedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "video uncached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.UncachedAddress, profile.UncachedSize, profile.UncachedAddress + profile.UncachedSize)); } (*ppVideoSource)->uncached_address = profile.UncachedAddress; DCCSP(pDCC->pRUA, video_decoder, RMVideoDecoderPropertyID_Open, &profile, sizeof(profile)); err = RUAGetProperty(pDCC->pRUA, video_decoder, RMGenericPropertyID_Surface, &surface, sizeof(surface)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get the video surface, %s\n", RMstatusToString(err))); return err; } if (dcc_profile->SPUBitstreamFIFOSize > 0) { struct SpuDecoder_DRAMSize_in_type dram_in; struct SpuDecoder_DRAMSize_out_type dram_out; struct SpuDecoder_Open_type profile; RMuint32 spu_decoder; spu_decoder = EMHWLIB_MODULE(SpuDecoder, dcc_profile->MpegEngineID); (*ppVideoSource)->spu_decoder_moduleID = spu_decoder; dram_in.BitstreamFIFOSize = dcc_profile->SPUBitstreamFIFOSize; dram_in.XferFIFOCount = dcc_profile->SPUXferFIFOCount; err = RUAExchangeProperty(pDCC->pRUA, spu_decoder, RMSpuDecoderPropertyID_DRAMSize, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMSpuDecoderPropertyID_DRAMSize! %s\n", RMstatusToString(err))); return err; } profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.CachedAddress = 0; profile.CachedSize = dram_out.CachedSize; if (profile.CachedSize > 0) { profile.CachedAddress = pDCC->rua_malloc(pDCC->pRUA, spu_decoder, pDCC->dram, RUA_DRAM_CACHED, profile.CachedSize); if (!profile.CachedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in cached DRAM %lu!\n", profile.CachedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "subpicture cached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.CachedAddress, profile.CachedSize, profile.CachedAddress + profile.CachedSize)); } (*ppVideoSource)->spu_cached_address = profile.CachedAddress; profile.UncachedAddress = 0; profile.UncachedSize = dram_out.UncachedSize; if (profile.UncachedSize > 0) { profile.UncachedAddress = pDCC->rua_malloc(pDCC->pRUA, spu_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.UncachedSize); if (!profile.UncachedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in uncached DRAM %lu!\n", profile.UncachedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "subpicture uncached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.UncachedAddress, profile.UncachedSize, profile.UncachedAddress + profile.UncachedSize)); } (*ppVideoSource)->spu_uncached_address = profile.UncachedAddress; profile.DemuxProgramId = dcc_profile->DemuxProgramID; DCCSP(pDCC->pRUA, spu_decoder, RMSpuDecoderPropertyID_Open, &profile, sizeof(profile)); err = RUAGetProperty(pDCC->pRUA, spu_decoder, RMSpuDecoderPropertyID_VSyncSurface, &((*ppVideoSource)->spu_surface), sizeof(RMuint32)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMSpuDecoderPropertyID_VSyncSurface! %s\n", RMstatusToString(err))); return err; } } (*ppVideoSource)->surface = surface; return RM_OK;}RMstatus DCCCloseVideoSource(struct DCCVideoSource *pVideoSource){ RMbool surface_changed = FALSE; RMDBGLOG((LOCALDBG, "DCCCloseVideoSource()\n")); if (pVideoSource->spu_scaler_moduleID != 0) { struct EMhwlibSubPictureSurface_type val; val.Scaler = 0; val.Surface = 0; DCCSP(pVideoSource->pRUA, pVideoSource->scaler_moduleID, RMGenericPropertyID_SubPictureSurface, &val, sizeof(val)); DCCSP(pVideoSource->pRUA, pVideoSource->scaler_moduleID, RMGenericPropertyID_Validate, NULL, 0); surface_changed = TRUE; } if (pVideoSource->scaler_moduleID != 0) { RMuint32 surface; RMstatus err; err = RUAGetProperty(pVideoSource->pRUA, pVideoSource->scaler_moduleID, RMGenericPropertyID_Surface, &surface, sizeof(surface)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get the video surface, %s\n", RMstatusToString(err))); return err; } if(surface != 0){ surface = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -