📄 dcc_video.c
字号:
*ppVideoSource = (struct DCCVideoSource *) RMMalloc(sizeof(struct DCCVideoSource)); if (*ppVideoSource == NULL) { RMDBGLOG((ENABLE, "Can't allocate %lu bytes in system memory!\n", sizeof(struct DCCVideoSource))); return RM_FATALOUTOFMEMORY; } RMMemset((void*)(*ppVideoSource), 0, sizeof(struct DCCVideoSource)); (*ppVideoSource)->pRUA = pDCC->pRUA; (*ppVideoSource)->pDCC = pDCC; status = DCCVideoGetModuleIDsFromIndexes(pDCC, pDCCVideoProfile->MpegEngineID, pDCCVideoProfile->VideoDecoderID, &engine_module_id, &decoder_module_id); if (status != RM_OK) { RMDBGLOG((ENABLE, "Couldn't get module IDs (%s)\n", RMstatusToString(status))); return status; } (*ppVideoSource)->engine_moduleID = engine_module_id; (*ppVideoSource)->decoder_moduleID = decoder_module_id; (*ppVideoSource)->timer_number = pDCCVideoProfile->STCID; (*ppVideoSource)->free_scheduler = FALSE; (*ppVideoSource)->free_shared = FALSE; (*ppVideoSource)->free_cached = FALSE; (*ppVideoSource)->free_uncached = FALSE; (*ppVideoSource)->free_spu_cached = FALSE; (*ppVideoSource)->free_spu_uncached = FALSE; (*ppVideoSource)->free_picture_protected = FALSE; if (pVideoResources->SchedulerSharedMemorySize) { struct MpegEngine_SchedulerSharedMemory_type schedmem; schedmem.Address = pVideoResources->SchedulerSharedMemoryAddress; schedmem.Size = pVideoResources->SchedulerSharedMemorySize; RMDBGLOG((ENABLE, "Setting Scheduler Memory for module 0x%lX: addr 0x%08lX, size 0x%08lX\n", engine_module_id, schedmem.Address, schedmem.Size)); DCCSP(pDCC->pRUA, engine_module_id, RMMpegEnginePropertyID_SchedulerSharedMemory, &schedmem, sizeof(schedmem)); } if (pVideoResources->DecoderSharedMemorySize) { struct MpegEngine_DecoderSharedMemory_type shared; shared.Address = pVideoResources->DecoderSharedMemoryAddress; shared.Size = pVideoResources->DecoderSharedMemorySize; RMDBGLOG((ENABLE, "Setting Video Shared Memory for module 0x%lX: addr: 0x%08lX, size 0x%08lX\n", engine_module_id, shared.Address, shared.Size)); DCCSP(pDCC->pRUA, engine_module_id, RMMpegEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); } profile.PictureProtectedAddress = pVideoResources->PictureProtectedMemoryAddress; profile.PictureProtectedSize = pVideoResources->PictureProtectedMemorySize; (*ppVideoSource)->picture_protected_address = profile.PictureProtectedAddress; profile.BitstreamProtectedAddress = pVideoResources->BitstreamProtectedMemoryAddress; profile.BitstreamProtectedSize = pVideoResources->BitstreamProtectedMemorySize; (*ppVideoSource)->cached_address = profile.BitstreamProtectedAddress; profile.UnprotectedAddress = pVideoResources->UnprotectedMemoryAddress; profile.UnprotectedSize = pVideoResources->UnprotectedMemorySize; (*ppVideoSource)->uncached_address = profile.UnprotectedAddress; profile.STCId = pDCCVideoProfile->STCID; { struct VideoDecoder_DecoderDataMemory_in_type memory_in; struct VideoDecoder_DecoderDataMemory_out_type memory_out; struct VideoDecoder_DRAMSizeX_in_type dram_in; struct VideoDecoder_DRAMSizeX_out_type dram_out; /* find the memory requirements for the specified codec, profile, level, width, height and extra pictures */ memory_in.Codec = pDCCVideoProfile->Codec; memory_in.Profile = pDCCVideoProfile->Profile; memory_in.Level = pDCCVideoProfile->Level; memory_in.ExtraPictureBufferCount = pDCCVideoProfile->ExtraPictureBufferCount; memory_in.MaxWidth = pDCCVideoProfile->MaxWidth; memory_in.MaxHeight = pDCCVideoProfile->MaxHeight; status = RUAExchangeProperty(pDCC->pRUA, decoder_module_id, RMVideoDecoderPropertyID_DecoderDataMemory, &memory_in, sizeof(memory_in), &memory_out, sizeof(memory_out)); if (status != RM_OK) { RMDBGLOG((ENABLE, "Can't get property RMVideoDecoderPropertyID_DecoderDataMemory! %s\n", RMstatusToString(status))); return status; } /* find the required protected, unprotected memory */ dram_in.ProtectedFlags = pDCCVideoProfile->ProtectedFlags; dram_in.BitstreamFIFOSize = pDCCVideoProfile->BitstreamFIFOSize;//TODO - it should be exposed to dcc ??? dram_in.UserDataSize = 0x1000; dram_in.DecoderDataSize = memory_out.DecoderDataSize; dram_in.XferFIFOCount = pDCCVideoProfile->XferFIFOCount; dram_in.PtsFIFOCount = pDCCVideoProfile->PtsFIFOCount; dram_in.InbandFIFOCount = pDCCVideoProfile->InbandFIFOCount; dram_in.XtaskInbandFIFOCount = pDCCVideoProfile->XtaskInbandFIFOCount; status = RUAExchangeProperty(pDCC->pRUA, decoder_module_id, RMVideoDecoderPropertyID_DRAMSizeX, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (status != RM_OK) { RMDBGLOG((ENABLE, "Can't get property RMVideoDecoderPropertyID_DRAMSize! %s\n", RMstatusToString(status))); return status; } profile.ProtectedFlags = dram_in.ProtectedFlags; profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.UserDataSize = dram_in.UserDataSize; profile.DecoderDataSize = dram_in.DecoderDataSize;//TODO to be removed when microcode calculates it profile.DecoderContextSize = memory_out.DecoderContextSize; profile.ExtraPictureBufferCount = pDCCVideoProfile->ExtraPictureBufferCount; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.PtsFIFOCount = dram_in.PtsFIFOCount; profile.InbandFIFOCount = dram_in.InbandFIFOCount; profile.XtaskInbandFIFOCount = dram_in.XtaskInbandFIFOCount; profile.XtaskId = pDCCVideoProfile->XtaskID; DCCSP(pDCC->pRUA, decoder_module_id, RMVideoDecoderPropertyID_OpenX, &profile, sizeof(profile)); } status = RUAGetProperty(pDCC->pRUA, decoder_module_id, RMGenericPropertyID_Surface, &surface, sizeof(surface)); if (status != RM_OK) { RMDBGLOG((ENABLE, "Cannot get the video surface, %s\n", RMstatusToString(status))); return status; } (*ppVideoSource)->surface = surface; return RM_OK;}#endif // DCC_WITH_RESOURCES RMstatus DCCXOpenVideoDecoderSource(struct DCC *pDCC, struct DCCXVideoProfile *pDCCVideoProfile, struct DCCVideoSource **ppVideoSource){#ifdef DCC_WITH_RESOURCES struct DCCVideoResources video_resources = { 0, }; RMstatus status; ASSERT_NULL_POINTER(pDCC); ASSERT_NULL_POINTER(pDCCVideoProfile); ASSERT_NULL_POINTER(ppVideoSource); // 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 != pDCCVideoProfile->MpegEngineID) { RMDBGLOG((ENABLE, "Error: cannot play Video Engine %d on DRAM %d.\n", (RMint32) pDCCVideoProfile->MpegEngineID, (RMint32) pDCC->dram)); return RM_ERROR; } status = DCCGetVideoResourcesRequired(pDCC, pDCCVideoProfile, &video_resources); if (status != RM_OK) { RMDBGLOG((ENABLE, "error getting required resources for video (%s)\n", RMstatusToString(status))); return status; } if (video_resources.SchedulerSharedMemorySize) { video_resources.SchedulerSharedMemoryAddress = pDCC->rua_malloc(pDCC->pRUA, 0, pDCC->dram, RUA_DRAM_UNCACHED, video_resources.SchedulerSharedMemorySize); RMDBGLOG((LOCALDBG, "Scheduler Shared Memory: allocated %lu bytes at %p\n", video_resources.SchedulerSharedMemorySize, video_resources.SchedulerSharedMemoryAddress)); } if (video_resources.DecoderSharedMemorySize) { video_resources.DecoderSharedMemoryAddress = pDCC->rua_malloc(pDCC->pRUA, 0, pDCC->dram, RUA_DRAM_UNCACHED, video_resources.DecoderSharedMemorySize); RMDBGLOG((LOCALDBG, "Decoder Shared Memory: allocated %lu bytes at %p\n", video_resources.DecoderSharedMemorySize, video_resources.DecoderSharedMemoryAddress)); } if (video_resources.PictureProtectedMemorySize) { video_resources.PictureProtectedMemoryAddress = pDCC->rua_malloc(pDCC->pRUA, 0, pDCC->dram, RUA_DRAM_UNCACHED, video_resources.PictureProtectedMemorySize); RMDBGLOG((LOCALDBG, "Picture Protected Memory: allocated %lu bytes at %p\n", video_resources.PictureProtectedMemorySize, video_resources.PictureProtectedMemoryAddress)); } if (video_resources.BitstreamProtectedMemorySize) { video_resources.BitstreamProtectedMemoryAddress = pDCC->rua_malloc(pDCC->pRUA, 0, pDCC->dram, RUA_DRAM_UNCACHED, video_resources.BitstreamProtectedMemorySize); RMDBGLOG((LOCALDBG, "Bitstream Protected Memory: allocated %lu bytes at %p\n", video_resources.BitstreamProtectedMemorySize, video_resources.BitstreamProtectedMemoryAddress)); } if (video_resources.UnprotectedMemorySize) { video_resources.UnprotectedMemoryAddress = pDCC->rua_malloc(pDCC->pRUA, 0, pDCC->dram, RUA_DRAM_UNCACHED, video_resources.UnprotectedMemorySize); RMDBGLOG((LOCALDBG, "Unprotected Memory: allocated %lu bytes at %p\n", video_resources.UnprotectedMemorySize, video_resources.UnprotectedMemoryAddress)); } status = DCCOpenVideoDecoderSourceWithResources(pDCC, pDCCVideoProfile, &video_resources, ppVideoSource); if (status != RM_OK) RMDBGLOG((ENABLE, "error opening video decoder source with resources (%s)\n", RMstatusToString(status))); // all resources were allocated inside DCC, mark them to be freed with DCCCloseVideoSource() (*ppVideoSource)->free_scheduler = TRUE; (*ppVideoSource)->free_shared = TRUE; (*ppVideoSource)->free_cached = TRUE; (*ppVideoSource)->free_uncached = TRUE; (*ppVideoSource)->free_spu_cached = TRUE; (*ppVideoSource)->free_spu_uncached = TRUE; (*ppVideoSource)->free_picture_protected = TRUE;#else // DCC_WITH_RESOURCES struct VideoDecoder_DecoderDataMemory_in_type memory_in; struct VideoDecoder_DecoderDataMemory_out_type memory_out; /* Decoder share memory is required for specific codecs as VC1 etc. The size of this memory depends on codec, profile, level, width, height. */ struct MpegEngine_DecoderSharedMemory_type shared; /* Scheduler memory is required for video RISC in order to run one or multiple video, spu tasks. The size of this memory is fixed at compile time. */ struct MpegEngine_SchedulerSharedMemory_type schedmem; struct VideoDecoder_DRAMSizeX_in_type dram_in; struct VideoDecoder_DRAMSizeX_out_type dram_out; struct VideoDecoder_OpenX_type profile; RMuint32 surface, video_decoder = 0; RMuint32 nb_mpeg_engines, nb_video_decoders; RMuint32 mpeg_engine = 0; RMuint32 temp; RMstatus err; ASSERT_NULL_POINTER(pDCC); ASSERT_NULL_POINTER(pDCCVideoProfile); ASSERT_NULL_POINTER(ppVideoSource); *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 (pDCCVideoProfile->MpegEngineID < nb_mpeg_engines) RMDBGLOG((LOCALDBG, "Number of video engines: %d\n", (RMint32) nb_mpeg_engines)); else { RMDBGLOG((ENABLE, "Error: video engine index %d out of range!!! Should be < %d\n", (RMint32) pDCCVideoProfile->MpegEngineID, (RMint32) 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 (pDCCVideoProfile->VideoDecoderID < (nb_video_decoders / nb_mpeg_engines)) RMDBGLOG((LOCALDBG, "Number of video decoders: %d%s\n", (RMint32) nb_video_decoders)); else { RMDBGLOG((ENABLE, "Error: video decoder index %d out of range!!! Should be < %d\n", (RMint32) pDCCVideoProfile->VideoDecoderID, (RMint32) (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 != pDCCVideoProfile->MpegEngineID) { RMDBGLOG((ENABLE, "Error: cannot play Video Engine %d on DRAM %d.\n", (RMint32) pDCCVideoProfile->MpegEngineID, (RMint32) pDCC->dram)); return RM_ERROR; } mpeg_engine = EMHWLIB_MODULE(MpegEngine, pDCCVideoProfile->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, pDCCVideoProfile->MpegEngineID * (nb_video_decoders / nb_mpeg_engines) + pDCCVideoProfile->VideoDecoderID); (*ppVideoSource)->decoder_moduleID = video_decoder; RMDBGLOG((LOCALDBG, "VideoDecoder: 0x%08lX\n", video_decoder)); profile.STCId = pDCCVideoProfile->STCID; (*ppVideoSource)->timer_number = profile.STCId; /* check if scheduler task database table is already initialized. */ err = RUAGetProperty(pDCC->pRUA, mpeg_engine, RMMpegEnginePropertyID_SchedulerSharedMemory, &schedmem, sizeof(schedmem)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get SchedulerSharedMemory, %s\n", RMstatusToString(err))); return err; } if (schedmem.Address) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -