diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h new file mode 100644 index 0000000000..ca7cb9fe15 --- /dev/null +++ b/Utilities/SQueue.h @@ -0,0 +1,101 @@ +#pragma once + +template +class SQueue +{ + SMutex m_mutex; + u32 m_pos; + u32 m_count; + T m_data[SQSize]; + +public: + SQueue() + : m_pos(0) + , m_count(0) + { + } + + bool Push(T& data) + { + while (true) + { + if (Emu.IsStopped()) + { + return false; + } + + if (m_mutex.GetOwner() == m_mutex.GetDeadValue()) + { + return false; + } + + if (m_count >= SQSize) + { + Sleep(1); + continue; + } + + { + SMutexLocker lock(m_mutex); + + if (m_count >= SQSize) continue; + + m_data[(m_pos + m_count++) % SQSize] = data; + + return true; + } + } + } + + bool Pop(T& data) + { + while (true) + { + if (Emu.IsStopped()) + { + return false; + } + + if (m_mutex.GetOwner() == m_mutex.GetDeadValue()) + { + return false; + } + + if (!m_count) + { + Sleep(1); + continue; + } + + { + SMutexLocker lock(m_mutex); + + if (!m_count) continue; + + data = m_data[m_pos]; + m_pos = (m_pos + 1) % SQSize; + m_count--; + + return true; + } + } + } + + u32 GetCount() + { + SMutexLocker lock(m_mutex); + return m_count; + } + + bool IsEmpty() + { + SMutexLocker lock(m_mutex); + return !m_count; + } + + void Clear() + { + SMutexLocker lock(m_mutex); + m_count = 0; + } +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 50290f9e97..ecf52c7c49 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -298,7 +298,7 @@ int cellAudioInit() m_config.m_indexes = Memory.Alloc(sizeof(u64) * m_config.AUDIO_PORT_COUNT, 16); memset(Memory + m_config.m_indexes, 0, sizeof(u64) * m_config.AUDIO_PORT_COUNT); - thread t("AudioThread", []() + thread t("Audio Thread", []() { WAVHeader header(2); // WAV file header (stereo) diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 84e54578c2..bd1d4d9d14 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -4,75 +4,310 @@ #include "cellPamf.h" #include "cellDmux.h" +extern "C" +{ +#include "libavformat\avformat.h" +} + void cellDmux_init(); Module cellDmux(0x0007, cellDmux_init); +void dmuxQueryAttr(u32 info_addr /* may be 0 */, mem_ptr_t attr) +{ + attr->demuxerVerLower = 0; // TODO: check values + attr->demuxerVerUpper = 0; + attr->memSize = 1024 * 1024; // 1M +} + +void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, const mem_ptr_t esFilterId, + const u32 esSpecificInfo_addr, mem_ptr_t attr) +{ + attr->memSize = 1024 * 1024; +} + int cellDmuxQueryAttr(const mem_ptr_t demuxerType, mem_ptr_t demuxerAttr) { - cellDmux.Error("cellDmuxQueryAttr(demuxerType_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType.GetAddr(), demuxerAttr.GetAddr()); + cellDmux.Warning("cellDmuxQueryAttr(demuxerType_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType.GetAddr(), demuxerAttr.GetAddr()); + + if (!demuxerType.IsGood() || !demuxerAttr.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + dmuxQueryAttr(0, demuxerAttr); return CELL_OK; } int cellDmuxQueryAttr2(const mem_ptr_t demuxerType2, mem_ptr_t demuxerAttr) { - cellDmux.Error("cellDmuxQueryAttr2(demuxerType2_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType2.GetAddr(), demuxerAttr.GetAddr()); + cellDmux.Warning("cellDmuxQueryAttr2(demuxerType2_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType2.GetAddr(), demuxerAttr.GetAddr()); + + if (!demuxerType2.IsGood() || !demuxerAttr.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + dmuxQueryAttr(demuxerType2->streamSpecificInfo_addr, demuxerAttr); return CELL_OK; } +u32 dmuxOpen(Demuxer* data) +{ + Demuxer& dmux = *data; + + u32 id = cellDmux.GetNewId(data); + + thread t("Demuxer [" + std::to_string(id) + "] Thread", [&]() + { + ConLog.Write("Demuxer enter (mem=0x%x, size=0x%x, cb=0x%x, arg=0x%x)", dmux.memAddr, dmux.memSize, dmux.cbFunc, dmux.cbArg); + + DemuxerTask task; + + while (true) + { + if (!dmux.job.Pop(task)) + { + break; + } + + switch (task.type) + { + case dmuxSetStream: + case dmuxResetStream: + case dmuxEnableEs: + case dmuxDisableEs: + case dmuxResetEs: + case dmuxGetAu: + case dmuxPeekAu: + case dmuxReleaseAu: + case dmuxFlushEs: + case dmuxClose: + dmux.is_finished = true; + ConLog.Write("Demuxer exit"); + return; + default: + ConLog.Error("Demuxer error: unknown task(%d)", task.type); + } + } + + ConLog.Warning("Demuxer aborted"); + }); + + t.detach(); + + return id; +} + int cellDmuxOpen(const mem_ptr_t demuxerType, const mem_ptr_t demuxerResource, const mem_ptr_t demuxerCb, mem32_t demuxerHandle) { - cellDmux.Error("cellDmuxOpen(demuxerType_addr=0x%x, demuxerResource_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", + cellDmux.Warning("cellDmuxOpen(demuxerType_addr=0x%x, demuxerResource_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", demuxerType.GetAddr(), demuxerResource.GetAddr(), demuxerCb.GetAddr(), demuxerHandle.GetAddr()); + + if (!demuxerType.IsGood() || !demuxerResource.IsGood() || !demuxerCb.IsGood() || !demuxerHandle.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + if (!Memory.IsGoodAddr(demuxerResource->memAddr, demuxerResource->memSize)) + { + return CELL_DMUX_ERROR_FATAL; + } + + // TODO: check demuxerResource and demuxerCb arguments + + demuxerHandle = dmuxOpen(new Demuxer(demuxerResource->memAddr, demuxerResource->memSize, (CellDmuxCbMsg&)demuxerCb->cbMsgFunc, demuxerCb->cbArg_addr)); + return CELL_OK; } int cellDmuxOpenEx(const mem_ptr_t demuxerType, const mem_ptr_t demuxerResourceEx, const mem_ptr_t demuxerCb, mem32_t demuxerHandle) { - cellDmux.Error("cellDmuxOpenEx(demuxerType_addr=0x%x, demuxerResourceEx_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", + cellDmux.Warning("cellDmuxOpenEx(demuxerType_addr=0x%x, demuxerResourceEx_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", demuxerType.GetAddr(), demuxerResourceEx.GetAddr(), demuxerCb.GetAddr(), demuxerHandle.GetAddr()); + + if (!demuxerType.IsGood() || !demuxerResourceEx.IsGood() || !demuxerCb.IsGood() || !demuxerHandle.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + if (!Memory.IsGoodAddr(demuxerResourceEx->memAddr, demuxerResourceEx->memSize)) + { + return CELL_DMUX_ERROR_FATAL; + } + + // TODO: check demuxerResourceEx and demuxerCb arguments + + demuxerHandle = dmuxOpen(new Demuxer(demuxerResourceEx->memAddr, demuxerResourceEx->memSize, (CellDmuxCbMsg&)demuxerCb->cbMsgFunc, demuxerCb->cbArg_addr)); + return CELL_OK; } int cellDmuxOpen2(const mem_ptr_t demuxerType2, const mem_ptr_t demuxerResource2, const mem_ptr_t demuxerCb, mem32_t demuxerHandle) { - cellDmux.Error("cellDmuxOpen2(demuxerType2_addr=0x%x, demuxerResource2_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", + cellDmux.Warning("cellDmuxOpen2(demuxerType2_addr=0x%x, demuxerResource2_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", demuxerType2.GetAddr(), demuxerResource2.GetAddr(), demuxerCb.GetAddr(), demuxerHandle.GetAddr()); + + if (!demuxerType2.IsGood() || !demuxerResource2.IsGood() || !demuxerCb.IsGood() || !demuxerHandle.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + if (!Memory.IsGoodAddr(demuxerResource2->memAddr, demuxerResource2->memSize)) + { + return CELL_DMUX_ERROR_FATAL; + } + + // TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments + + demuxerHandle = dmuxOpen(new Demuxer(demuxerResource2->memAddr, demuxerResource2->memSize, (CellDmuxCbMsg&)demuxerCb->cbMsgFunc, demuxerCb->cbArg_addr)); + return CELL_OK; } int cellDmuxClose(u32 demuxerHandle) { - cellDmux.Error("cellDmuxClose(demuxerHandle=0x%x)", demuxerHandle); + cellDmux.Warning("cellDmuxClose(demuxerHandle=%d)", demuxerHandle); + + Demuxer* dmux; + if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + { + return CELL_DMUX_ERROR_ARG; + } + + dmux->job.Push(DemuxerTask(dmuxClose)); + + while (!dmux->is_finished) + { + if (Emu.IsStopped()) + { + ConLog.Warning("cellDmuxClose(%d) aborted", demuxerHandle); + return CELL_OK; + } + + Sleep(1); + } + + Emu.GetIdManager().RemoveID(demuxerHandle); return CELL_OK; } int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize, bool discontinuity, u64 userData) { - cellDmux.Error("cellDmuxSetStream(demuxerHandle=0x%x, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx", + cellDmux.Warning("cellDmuxSetStream(demuxerHandle=%d, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx", demuxerHandle, streamAddress, streamSize, discontinuity, userData); + + Demuxer* dmux; + if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + { + return CELL_DMUX_ERROR_ARG; + } + + if (!Memory.IsGoodAddr(streamAddress, streamSize)) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (!dmux->job.IsEmpty()) + { + return CELL_DMUX_ERROR_BUSY; + } + + DemuxerTask task(dmuxSetStream); + auto& info = task.stream; + info.addr = streamAddress; + info.size = streamSize; + info.discontinuity = discontinuity; + info.userdata = userData; + + dmux->job.Push(task); return CELL_OK; } int cellDmuxResetStream(u32 demuxerHandle) { - cellDmux.Error("cellDmuxResetStream(demuxerHandle=0x%x)", demuxerHandle); + cellDmux.Warning("cellDmuxResetStream(demuxerHandle=%d)", demuxerHandle); + + Demuxer* dmux; + if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + { + return CELL_DMUX_ERROR_ARG; + } + + dmux->job.Push(DemuxerTask(dmuxResetStream)); + return CELL_OK; } int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) { - cellDmux.Error("cellDmuxResetStreamAndWaitDone(demuxerHandle=0x%x)", demuxerHandle); + cellDmux.Error("cellDmuxResetStreamAndWaitDone(demuxerHandle=%d)", demuxerHandle); + + Demuxer* dmux; + if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + { + return CELL_DMUX_ERROR_ARG; + } + + dmux->job.Push(DemuxerTask(dmuxResetStream)); + + // TODO: wait done + return CELL_OK; } int cellDmuxQueryEsAttr(const mem_ptr_t demuxerType, const mem_ptr_t esFilterId, const u32 esSpecificInfo_addr, mem_ptr_t esAttr) { - cellDmux.Error("cellDmuxQueryEsAttr(demuxerType_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", + cellDmux.Warning("cellDmuxQueryEsAttr(demuxerType_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", demuxerType.GetAddr(), esFilterId.GetAddr(), esSpecificInfo_addr, esAttr.GetAddr()); + + if (!demuxerType.IsGood() || !esFilterId.IsGood() || !esAttr.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (!Memory.IsGoodAddr(esSpecificInfo_addr, 12)) + { + cellDmux.Error("cellDmuxQueryEsAttr: invalid specific info addr (0x%x)", esSpecificInfo_addr); + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + // TODO: check esFilterId and esSpecificInfo correctly + + dmuxQueryEsAttr(0, esFilterId, esSpecificInfo_addr, esAttr); return CELL_OK; } @@ -81,6 +316,26 @@ int cellDmuxQueryEsAttr2(const mem_ptr_t demuxerType2, const mem_ { cellDmux.Error("cellDmuxQueryEsAttr2(demuxerType2_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", demuxerType2.GetAddr(), esFilterId.GetAddr(), esSpecificInfo_addr, esAttr.GetAddr()); + + if (!demuxerType2.IsGood() || !esFilterId.IsGood() || !esAttr.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (!Memory.IsGoodAddr(esSpecificInfo_addr, 12)) + { + cellDmux.Error("cellDmuxQueryEsAttr2: invalid specific info addr (0x%x)", esSpecificInfo_addr); + return CELL_DMUX_ERROR_FATAL; + } + + if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + { + return CELL_DMUX_ERROR_ARG; + } + + // TODO: check demuxerType2, esFilterId and esSpecificInfo correctly + + dmuxQueryEsAttr(demuxerType2->streamSpecificInfo_addr, esFilterId, esSpecificInfo_addr, esAttr); return CELL_OK; } @@ -88,21 +343,81 @@ int cellDmuxEnableEs(u32 demuxerHandle, const mem_ptr_t esF const mem_ptr_t esResourceInfo, const mem_ptr_t esCb, const u32 esSpecificInfo_addr, mem32_t esHandle) { - cellDmux.Error("cellDmuxEnableEs(demuxerHandle=0x%x, esFilterId_addr=0x%x, esResourceInfo_addr=0x%x, esCb_addr=0x%x, " + cellDmux.Warning("cellDmuxEnableEs(demuxerHandle=%d, esFilterId_addr=0x%x, esResourceInfo_addr=0x%x, esCb_addr=0x%x, " "esSpecificInfo_addr=0x%x, esHandle_addr=0x%x)", demuxerHandle, esFilterId.GetAddr(), esResourceInfo.GetAddr(), esCb.GetAddr(), esSpecificInfo_addr, esHandle.GetAddr()); + + if (!esFilterId.IsGood() || !esResourceInfo.IsGood() || !esCb.IsGood() || !esHandle.IsGood()) + { + return CELL_DMUX_ERROR_FATAL; + } + + if (!Memory.IsGoodAddr(esSpecificInfo_addr, 12)) + { + cellDmux.Error("cellDmuxEnableEs: invalid specific info addr (0x%x)", esSpecificInfo_addr); + return CELL_DMUX_ERROR_FATAL; + } + + if (!Memory.IsGoodAddr(esResourceInfo->memAddr, esResourceInfo->memSize)) + { + return CELL_DMUX_ERROR_FATAL; + } + + Demuxer* dmux; + if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + { + return CELL_DMUX_ERROR_ARG; + } + + // TODO: check esFilterId, esResourceInfo, esCb and esSpecificInfo correctly + + ElementaryStream* es = new ElementaryStream(dmux, esResourceInfo->memAddr, esResourceInfo->memSize, + esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2, + (CellDmuxCbEsMsg&)esCb->cbEsMsgFunc, esCb->cbArg_addr, esSpecificInfo_addr); + + u32 id = cellDmux.GetNewId(es); + + DemuxerTask task(dmuxEnableEs); + task.au.es = id; + task.au.es_ptr = es; + + dmux->job.Push(task); return CELL_OK; } int cellDmuxDisableEs(u32 esHandle) { - cellDmux.Error("cellDmuxDisableEs(esHandle=0x%x)", esHandle); + cellDmux.Warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle); + + ElementaryStream* es; + if (!Emu.GetIdManager().GetIDData(esHandle, es)) + { + return CELL_DMUX_ERROR_ARG; + } + + DemuxerTask task(dmuxDisableEs); + task.esHandle = esHandle; + task.au.es_ptr = es; + + es->dmux->job.Push(task); return CELL_OK; } int cellDmuxResetEs(u32 esHandle) { - cellDmux.Error("cellDmuxResetEs(esHandle=0x%x)", esHandle); + cellDmux.Warning("cellDmuxResetEs(esHandle=0x%x)", esHandle); + + ElementaryStream* es; + if (!Emu.GetIdManager().GetIDData(esHandle, es)) + { + return CELL_DMUX_ERROR_ARG; + } + + DemuxerTask task(dmuxResetEs); + task.esHandle = esHandle; + task.au.es_ptr = es; + + es->dmux->job.Push(task); return CELL_OK; } @@ -136,13 +451,37 @@ int cellDmuxPeekAuEx(u32 esHandle, const u32 auInfoEx_ptr_addr, u32 auSpecificIn int cellDmuxReleaseAu(u32 esHandle) { - cellDmux.Error("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); + cellDmux.Warning("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); + + ElementaryStream* es; + if (!Emu.GetIdManager().GetIDData(esHandle, es)) + { + return CELL_DMUX_ERROR_ARG; + } + + DemuxerTask task(dmuxReleaseAu); + task.esHandle = esHandle; + task.au.es_ptr = es; + + es->dmux->job.Push(task); return CELL_OK; } int cellDmuxFlushEs(u32 esHandle) { - cellDmux.Error("cellDmuxFlushEs(esHandle=0x%x)", esHandle); + cellDmux.Warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle); + + ElementaryStream* es; + if (!Emu.GetIdManager().GetIDData(esHandle, es)) + { + return CELL_DMUX_ERROR_ARG; + } + + DemuxerTask task(dmuxFlushEs); + task.esHandle = esHandle; + task.au.es_ptr = es; + + es->dmux->job.Push(task); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index 77bab0fcdb..b2a3fe5ec8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -1,5 +1,7 @@ #pragma once +#include "Utilities/SQueue.h" + // Error Codes enum { @@ -30,6 +32,118 @@ enum CellDmuxEsMsgType CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE = 1, }; +enum CellDmuxPamfM2vLevel +{ + CELL_DMUX_PAMF_M2V_MP_LL = 0, + CELL_DMUX_PAMF_M2V_MP_ML, + CELL_DMUX_PAMF_M2V_MP_H14, + CELL_DMUX_PAMF_M2V_MP_HL, +}; + +enum CellDmuxPamfAvcLevel +{ + CELL_DMUX_PAMF_AVC_LEVEL_2P1 = 21, + CELL_DMUX_PAMF_AVC_LEVEL_3P0 = 30, + CELL_DMUX_PAMF_AVC_LEVEL_3P1 = 31, + CELL_DMUX_PAMF_AVC_LEVEL_3P2 = 32, + CELL_DMUX_PAMF_AVC_LEVEL_4P1 = 41, + CELL_DMUX_PAMF_AVC_LEVEL_4P2 = 42, +}; + +struct CellDmuxPamfAuSpecificInfoM2v +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoAvc +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoLpcm +{ + u8 channelAssignmentInfo; + u8 samplingFreqInfo; + u8 bitsPerSample; +}; + +struct CellDmuxPamfAuSpecificInfoAc3 +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoAtrac3plus +{ + be_t reserved1; +}; + +struct CellDmuxPamfAuSpecificInfoUserData +{ + be_t reserved1; +}; + +struct CellDmuxPamfEsSpecificInfoM2v +{ + be_t profileLevel; +}; + +struct CellDmuxPamfEsSpecificInfoAvc +{ + be_t level; +}; + +struct CellDmuxPamfEsSpecificInfoLpcm +{ + be_t samplingFreq; + be_t numOfChannels; + be_t bitsPerSample; +}; + +struct CellDmuxPamfEsSpecificInfoAc3 +{ + be_t reserved1; +}; + +struct CellDmuxPamfEsSpecificInfoAtrac3plus +{ + be_t reserved1; +}; + +struct CellDmuxPamfEsSpecificInfoUserData +{ + be_t reserved1; +}; + +enum CellDmuxPamfSamplingFrequency +{ + CELL_DMUX_PAMF_FS_48K = 48000, +}; + +enum CellDmuxPamfBitsPerSample +{ + CELL_DMUX_PAMF_BITS_PER_SAMPLE_16 = 16, + CELL_DMUX_PAMF_BITS_PER_SAMPLE_24 = 24, +}; + +enum CellDmuxPamfLpcmChannelAssignmentInfo +{ + CELL_DMUX_PAMF_LPCM_CH_M1 = 1, + CELL_DMUX_PAMF_LPCM_CH_LR = 3, + CELL_DMUX_PAMF_LPCM_CH_LRCLSRSLFE = 9, + CELL_DMUX_PAMF_LPCM_CH_LRCLSCS1CS2RSLFE = 11, +}; + +enum CellDmuxPamfLpcmFs +{ + CELL_DMUX_PAMF_LPCM_FS_48K = 1, +}; + +enum CellDmuxPamfLpcmBitsPerSamples +{ + CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_16 = 1, + CELL_DMUX_PAMF_LPCM_BITS_PER_SAMPLE_24 = 3, +}; + struct CellDmuxMsg { be_t msgType; //CellDmuxMsgType enum @@ -44,13 +158,19 @@ struct CellDmuxEsMsg struct CellDmuxType { - CellDmuxStreamType streamType; + be_t streamType; be_t reserved[2]; //0 }; +struct CellDmuxPamfSpecificInfo +{ + be_t thisSize; + bool programEndCodeCb; +}; + struct CellDmuxType2 { - CellDmuxStreamType streamType; + be_t streamType; be_t streamSpecificInfo_addr; }; @@ -112,17 +232,21 @@ struct CellDmuxResource2 }; }; +typedef mem_func_ptr_t demuxerMsg, u32 cbArg_addr)> CellDmuxCbMsg; + struct CellDmuxCb { // CellDmuxCbMsg callback - be_t demuxerMsg, u32 cbArg_addr)>> cbMsgFunc; + be_t cbMsgFunc; be_t cbArg_addr; }; +typedef mem_func_ptr_t esMsg, u32 cbArg_addr)> CellDmuxCbEsMsg; + struct CellDmuxEsCb { // CellDmuxCbEsMsg callback - be_t esMsg, u32 cbArg_addr)>> cbEsMsgFunc; + be_t cbEsMsgFunc; be_t cbArg_addr; }; @@ -165,4 +289,122 @@ struct CellDmuxAuInfoEx be_t userData; CellCodecTimeStamp pts; CellCodecTimeStamp dts; +}; + +/* Demuxer Thread Classes */ + +struct AccessUnit +{ + u32 addr; + u32 size; + u32 ptsUpper; + u32 ptsLower; + u32 dtsUpper; + u32 dtsLower; + u64 userData; + bool isRap; +}; + +class ElementaryStream; + +enum DemuxerJobType +{ + dmuxSetStream, + dmuxResetStream, + dmuxEnableEs, + dmuxDisableEs, + dmuxResetEs, + dmuxGetAu, + dmuxPeekAu, + dmuxReleaseAu, + dmuxFlushEs, + dmuxClose, +}; + +#pragma pack(push, 1) +struct DemuxerTask +{ + DemuxerJobType type; + + union + { + struct + { + u32 addr; + u64 userdata; + u32 size; + /*bool*/u32 discontinuity; + } stream; + + u32 esHandle; + + struct + { + u32 es; + u32 auInfo_ptr_addr; + u32 auSpec_ptr_addr; + ElementaryStream* es_ptr; + } au; + }; + + DemuxerTask() + { + } + + DemuxerTask(DemuxerJobType type) + : type(type) + { + } +}; +static_assert(sizeof(DemuxerTask) == 24, ""); +#pragma pack(pop) + +class Demuxer +{ +public: + SQueue job; + const u32 memAddr; + const u32 memSize; + const CellDmuxCbMsg cbFunc; + const u32 cbArg; + bool is_finished; + + + Demuxer(u32 addr, u32 size, CellDmuxCbMsg func, u32 arg) + : is_finished(false) + , memAddr(addr) + , memSize(size) + , cbFunc(func) + , cbArg(arg) + { + } +}; + +class ElementaryStream +{ +public: + Demuxer* dmux; + const u32 memAddr; + const u32 memSize; + const u32 fidMajor; + const u32 fidMinor; + const u32 sup1; + const u32 sup2; + const CellDmuxCbEsMsg cbFunc; + const u32 cbArg; + const u32 spec; //addr + + ElementaryStream(Demuxer* dmux, u32 addr, u32 size, u32 fidMajor, u32 fidMinor, u32 sup1, u32 sup2, CellDmuxCbEsMsg cbFunc, u32 cbArg, u32 spec) + : dmux(dmux) + , memAddr(addr) + , memSize(size) + , fidMajor(fidMajor) + , fidMinor(fidMinor) + , sup1(sup1) + , sup2(sup2) + , cbFunc(cbFunc) + , cbArg(cbArg) + , spec(spec) + { + } }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.h b/rpcs3/Emu/SysCalls/Modules/cellPamf.h index b88c473af0..152faa29c0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.h @@ -135,13 +135,15 @@ enum }; // Timestamp information (time in increments of 90 kHz) -struct CellCodecTimeStamp { +struct CellCodecTimeStamp +{ be_t upper; be_t lower; }; // Entry point information -struct CellPamfEp { +struct CellPamfEp +{ be_t indexN; be_t nThRefPictureOffset; CellCodecTimeStamp pts; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index c9b3ad0722..24e51cea61 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -69,20 +69,20 @@ - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\..\ffmpeg;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\Include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) $(ProjectName)-$(PlatformShortName)-dbg - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\..\ffmpeg;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) $(ProjectName)-$(PlatformShortName)-dbg false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\..\ffmpeg;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\Include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) false @@ -91,7 +91,7 @@ false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\..\ffmpeg;$(IncludePath) + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(IncludePath) $(SolutionDir)bin\ ..\libs\$(Configuration)\;$(LibraryPath) false @@ -109,10 +109,10 @@ true - wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;%(AdditionalDependencies) + wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_lib + ..\wxWidgets\lib\vc_lib;..\ffmpeg\Windows\x86\lib @@ -129,14 +129,17 @@ true - wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;%(AdditionalDependencies) + wxmsw31ud_adv.lib;wxbase31ud.lib;wxmsw31ud_core.lib;wxmsw31ud_aui.lib;wxtiffd.lib;wxjpegd.lib;wxpngd.lib;wxzlibd.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_x64_lib + ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib "$(SolutionDir)\Utilities\git-version-gen.cmd" + + false + @@ -158,12 +161,12 @@ true true true - wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies) + wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_lib + ..\wxWidgets\lib\vc_lib;..\ffmpeg\Windows\x86\lib @@ -190,12 +193,12 @@ true true true - wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies) + wxmsw31u_adv.lib;wxbase31u.lib;wxmsw31u_core.lib;wxmsw31u_aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregexu.lib;wxexpat.lib;wsock32.lib;wininet.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies) %(IgnoreSpecificDefaultLibraries) false - ..\wxWidgets\lib\vc_x64_lib + ..\wxWidgets\lib\vc_x64_lib;..\ffmpeg\Windows\x86_64\lib @@ -341,6 +344,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 041ee71a3a..c1a23c8016 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -597,5 +597,8 @@ Utilities + + Utilities + \ No newline at end of file