📄 dcc_video.c
字号:
(*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\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.STCId = dcc_profile->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) { RMDBGLOG((ENABLE, "%lx_DRAM SCHEDULER MEMORY is already set addr=0x%lx size=0x%lx!\n", dcc_profile->MpegEngineID, schedmem.Address, schedmem.Size)); } else { schedmem.Address = pDCC->rua_malloc(pDCC->pRUA, mpeg_engine, pDCC->dram, RUA_DRAM_UNCACHED, schedmem.Size); if (!schedmem.Address) { RMDBGLOG((ENABLE, "ERROR: could not allocate scheduler table!\n")); return err; } RMDBGLOG((ENABLE, "ALLOCATING %lx_DRAM SCHEDULER MEMORY addr: 0x%08lX, size 0x%08lX\n", dcc_profile->MpegEngineID, schedmem.Address, schedmem.Size)); DCCSP(pDCC->pRUA, mpeg_engine, RMMpegEnginePropertyID_SchedulerSharedMemory, &schedmem, sizeof(schedmem)); } /* find the memory requirements for the specified codec, profile, level, width, height and extra pictures */ memory_in.Codec = dcc_profile->Codec; memory_in.Profile = dcc_profile->Profile; memory_in.Level = dcc_profile->Level; memory_in.ExtraPictureBufferCount = dcc_profile->ExtraPictureBufferCount; memory_in.MaxWidth = dcc_profile->MaxWidth; memory_in.MaxHeight = dcc_profile->MaxHeight; err = RUAExchangeProperty(pDCC->pRUA, video_decoder, RMVideoDecoderPropertyID_DecoderDataMemory, &memory_in, sizeof(memory_in), &memory_out, sizeof(memory_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMVideoDecoderPropertyID_DecoderDataMemory! %s\n", RMstatusToString(err))); return err; } /* check if video shared memory is already set in mpeg engine */ err = RUAGetProperty(pDCC->pRUA, mpeg_engine, RMMpegEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); if (err != RM_OK) { RMDBGLOG((ENABLE, "Cannot get DecoderSharedMemory, %s\n", RMstatusToString(err))); return err; } if (shared.Address) { if (shared.Size < memory_out.DecoderSharedSize) { RMDBGLOG((ENABLE, "ERROR: video shared memory is already set with a smaller value than needed by DCCOpen %s\n", RMstatusToString(err))); return err; } else { RMDBGLOG((ENABLE, "%lx_DRAM VIDEO SHARED MEMORY is already set addr=0x%lx size=0x%lx\n", dcc_profile->MpegEngineID, shared.Address, shared.Size)); } } else { /* allocate and set the shared memory used by all decoders of the same engine */ shared.Size = memory_out.DecoderSharedSize; if (shared.Size) { shared.Address = pDCC->rua_malloc(pDCC->pRUA, mpeg_engine, pDCC->dram, RUA_DRAM_UNCACHED, shared.Size); if (!shared.Address) { RMDBGLOG((ENABLE, "ERROR: could not allocate shared 0x%08lX bytes in DRAM %lu!\n", shared.Address, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((ENABLE, "ALLOCATING %lx_DRAM VIDEO SHARED MEMORY addr: 0x%08lX, size 0x%08lX\n", dcc_profile->MpegEngineID, shared.Address, shared.Size)); DCCSP(pDCC->pRUA, mpeg_engine, RMMpegEnginePropertyID_DecoderSharedMemory, &shared, sizeof(shared)); } } /* find the required protected, unprotected memory */ dram_in.ProtectedFlags = dcc_profile->ProtectedFlags; dram_in.BitstreamFIFOSize = dcc_profile->BitstreamFIFOSize; dram_in.UserDataSize = 0x1000; //TODO - it should be exposed to dcc ??? dram_in.DecoderDataSize = memory_out.DecoderDataSize; dram_in.XferFIFOCount = dcc_profile->XferFIFOCount; dram_in.PtsFIFOCount = dcc_profile->PtsFIFOCount; dram_in.InbandFIFOCount = dcc_profile->InbandFIFOCount; dram_in.XtaskInbandFIFOCount = dcc_profile->XtaskInbandFIFOCount; err = RUAExchangeProperty(pDCC->pRUA, video_decoder, RMVideoDecoderPropertyID_DRAMSizeX, &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; } /* allocate the picture protected memory for video decoder */ profile.PictureProtectedAddress = 0; profile.PictureProtectedSize = dram_out.PictureProtectedSize; if (profile.PictureProtectedSize > 0) { profile.PictureProtectedAddress = pDCC->rua_malloc(pDCC->pRUA, video_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.PictureProtectedSize); if (!profile.PictureProtectedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in Protected DRAM %lu!\n", profile.PictureProtectedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "video PictureProtectedAddress: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.PictureProtectedAddress, profile.PictureProtectedSize, profile.PictureProtectedAddress + profile.PictureProtectedSize)); } (*ppVideoSource)->picture_protected_address = profile.PictureProtectedAddress; /* allocate the bitstream protected memory for video decoder */ profile.BitstreamProtectedAddress = 0; profile.BitstreamProtectedSize = dram_out.BitstreamProtectedSize; if (profile.BitstreamProtectedSize > 0) { profile.BitstreamProtectedAddress = pDCC->rua_malloc(pDCC->pRUA, video_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.BitstreamProtectedSize); if (!profile.BitstreamProtectedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in Protected DRAM %lu!\n", profile.BitstreamProtectedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "video BitstreamProtectedAddress: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.BitstreamProtectedAddress, profile.BitstreamProtectedSize, profile.BitstreamProtectedAddress + profile.BitstreamProtectedSize)); } (*ppVideoSource)->cached_address = profile.BitstreamProtectedAddress; /* allocate the unprotected memory required for video decoder */ profile.UnprotectedAddress = 0; profile.UnprotectedSize = dram_out.UnprotectedSize; if (profile.UnprotectedSize > 0) { profile.UnprotectedAddress = pDCC->rua_malloc(pDCC->pRUA, video_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.UnprotectedSize); if (!profile.UnprotectedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in unprotected DRAM %lu!\n", profile.UnprotectedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "video UnprotectedAddress: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.UnprotectedAddress, profile.UnprotectedSize, profile.UnprotectedAddress + profile.UnprotectedSize)); } (*ppVideoSource)->uncached_address = profile.UnprotectedAddress; /* open VideoDecoder module */ profile.ProtectedFlags = dram_in.ProtectedFlags; profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.UserDataSize = dram_in.UserDataSize; profile.DecoderDataSize = dram_in.DecoderDataSize; profile.DecoderContextSize = memory_out.DecoderContextSize; //TODO to be removed when microcode calculates it profile.ExtraPictureBufferCount = dcc_profile->ExtraPictureBufferCount; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.PtsFIFOCount = dram_in.PtsFIFOCount; profile.InbandFIFOCount = dram_in.InbandFIFOCount; profile.XtaskInbandFIFOCount = dram_in.XtaskInbandFIFOCount; profile.XtaskId = dcc_profile->XtaskID; DCCSP(pDCC->pRUA, video_decoder, RMVideoDecoderPropertyID_OpenX, &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; } (*ppVideoSource)->surface = surface; if (dcc_profile->SPUBitstreamFIFOSize > 0) { struct SpuDecoder_DRAMSizeX_in_type dram_in; struct SpuDecoder_DRAMSizeX_out_type dram_out; struct SpuDecoder_DecoderDataMemory_in_type memory_in; struct SpuDecoder_DecoderDataMemory_out_type memory_out; struct SpuDecoder_OpenX_type profile; RMuint32 spu_decoder, nb_spu_decoders; RMDBGLOG((LOCALDBG, "-- Initializing SPU decoder!\n")); temp = SpuDecoder; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_spu_decoders, sizeof(nb_spu_decoders)); // !!Hack!! We assume there are an equal amount of decoders per engine spu_decoder = EMHWLIB_MODULE(SpuDecoder, dcc_profile->MpegEngineID * (nb_spu_decoders / nb_mpeg_engines) + 0); (*ppVideoSource)->spu_decoder_moduleID = spu_decoder; memory_in.Codec = dcc_profile->SPUCodec; memory_in.Profile = dcc_profile->SPUProfile; memory_in.Level = dcc_profile->SPULevel; memory_in.ExtraPictureBufferCount = dcc_profile->SPUExtraPictureBufferCount; memory_in.MaxWidth = dcc_profile->SPUMaxWidth; memory_in.MaxHeight = dcc_profile->SPUMaxHeight; err = RUAExchangeProperty(pDCC->pRUA, spu_decoder, RMSpuDecoderPropertyID_DecoderDataMemory, &memory_in, sizeof(memory_in), &memory_out, sizeof(memory_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMVideoDecoderPropertyID_DecoderDataMemory! %s\n", RMstatusToString(err))); return err; } dram_in.ProtectedFlags = dcc_profile->ProtectedFlags; dram_in.BitstreamFIFOSize = dcc_profile->SPUBitstreamFIFOSize; dram_in.XferFIFOCount = dcc_profile->SPUXferFIFOCount; dram_in.DecoderDataSize = memory_out.DecoderDataSize; dram_in.PtsFIFOCount = dcc_profile->PtsFIFOCount; dram_in.InbandFIFOCount = dcc_profile->InbandFIFOCount; dram_in.XtaskInbandFIFOCount = dcc_profile->XtaskInbandFIFOCount; dram_in.HilightCount = 3; err = RUAExchangeProperty(pDCC->pRUA, spu_decoder, RMSpuDecoderPropertyID_DRAMSizeX, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMSpuDecoderPropertyID_DRAMSizeX! %s\n", RMstatusToString(err))); return err; } /* allocate the unprotected memory required for Spu decoder */ profile.UnprotectedAddress = 0; profile.UnprotectedSize = dram_out.UnprotectedSize; if (profile.UnprotectedSize > 0) { profile.UnprotectedAddress = pDCC->rua_malloc(pDCC->pRUA, spu_decoder, pDCC->dram, RUA_DRAM_UNCACHED, profile.UnprotectedSize); if (!profile.UnprotectedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in unprotected DRAM %lu!\n", profile.UnprotectedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((LOCALDBG, "SPU UnprotectedAddress: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", profile.UnprotectedAddress, profile.UnprotectedSize, profile.UnprotectedAddress + profile.UnprotectedSize)); } (*ppVideoSource)->spu_uncached_address = profile.UnprotectedAddress; /* open SpuDecoder module */ profile.ProtectedFlags = dram_in.ProtectedFlags; profile.PictureProtectedAddress = 0; profile.PictureProtectedSize = 0; profile.BitstreamProtectedAddress = 0; profile.BitstreamProtectedSize = 0; profile.BitstreamFIFOSize = dram_in.BitstreamFIFOSize; profile.DecoderDataSize = memory_out.DecoderDataSize; profile.DecoderContextSize = memory_out.DecoderContextSize; profile.ExtraPictureBufferCount = dcc_profile->SPUExtraPictureBufferCount; profile.XferFIFOCount = dram_in.XferFIFOCount; profile.PtsFIFOCount = dram_in.PtsFIFOCount; profile.InbandFIFOCount = dram_in.InbandFIFOCount; profile.XtaskInbandFIFOCount = dram_in.XtaskInbandFIFOCount; profile.XtaskId = dcc_profile->XtaskID; profile.HilightCount = dram_in.HilightCount; profile.STCId = dcc_profile->STCID; DCCSP(pDCC->pRUA, spu_decoder, RMSpuDecoderPropertyID_OpenX, &profile, sizeof(profile));#ifdef ENABLE_SPU_OP 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; }#endif } return RM_OK;}RMstatus DCCXSetVideoDecoderSourceCodec(struct DCCVideoSource *pVideoSource, enum EMhwlibVideoCodec Codec){ RMstatus err; RMDBGLOG((LOCALDBG, "DCCXSetVideoDecoderSourceCodec codec = %ld\n", (int)Codec)); err = send_video_command(pVideoSource->pRUA, pVideoSource->decoder_moduleID, VideoDecoder_Command_Uninit); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send VideoDecoder_Command_Uninit, %s\n", RMstatusToString(err))); return err; } if (pVideoSource->spu_decoder_moduleID != 0) { err = send_spu_command(pVideoSource->pRUA, pVideoSource->spu_decoder_moduleID, SpuDecoder_Command_Uninit); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send SpuDecoder_Command_Uninit, %s\n", RMstatusToString(err))); return err; } } DCCSP(pVideoSource->pRUA, pVideoSource->decoder_moduleID, RMVideoDecoderPropertyID_CodecX, &Codec, sizeof(enum EMhwlibVideoCodec)); if (pVideoSource->spu_decoder_moduleID != 0) { Codec = EMhwlibDVDSpuCodec; DCCSP(pVideoSource->pRUA, pVideoSource->spu_decoder_moduleID, RMSpuDecoderPropertyID_CodecX, &Codec, sizeof(enum EMhwlibVideoCodec)); } err = send_video_command(pVideoSource->pRUA, pVideoSource->decoder_moduleID, VideoDecoder_Command_Init); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send VideoDecoder_Command_Init, %s\n", RMstatusToString(err))); return err; } if (pVideoSource->spu_decoder_moduleID != 0) { err = send_spu_command(pVideoSource->pRUA, pVideoSource->spu_decoder_moduleID, SpuDecoder_Command_Init); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot send SpuDecoder_Command_Init, %s\n", RMstatusToString(err))); return err; } } return RM_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -