From 855761432235369badffb320de03009496a5c9f7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 11 Dec 2014 22:25:11 +0300 Subject: [PATCH] cellPamf improved --- rpcs3/Emu/SysCalls/Modules/cellPamf.cpp | 417 +++++++++++++----------- rpcs3/Emu/SysCalls/Modules/cellPamf.h | 53 ++- rpcs3/Emu/SysCalls/Modules/cellVdec.cpp | 12 +- 3 files changed, 269 insertions(+), 213 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index 16a5064293..4be694dac8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -1,157 +1,201 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "cellPamf.h" Module *cellPamf = nullptr; -int pamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr pEsFilterId) +s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) { - //TODO: convert type and ch to EsFilterId - pEsFilterId->filterIdMajor = 0; - pEsFilterId->filterIdMinor = 0; - pEsFilterId->supplementalInfo1 = 0; - pEsFilterId->supplementalInfo2 = 0; - + // convert type and ch to EsFilterId + assert(ch < 16); + pEsFilterId.supplementalInfo1 = type == CELL_PAMF_STREAM_TYPE_AVC; + pEsFilterId.supplementalInfo2 = 0; + switch (type) { case CELL_PAMF_STREAM_TYPE_AVC: - { - if (ch < 16) - { - pEsFilterId->filterIdMajor = 0xe0 + ch; - pEsFilterId->filterIdMinor = 0; - pEsFilterId->supplementalInfo1 = 0x01; - pEsFilterId->supplementalInfo2 = 0; - } - else - cellPamf->Error("pamfStreamTypeToEsFilterId: invalid CELL_PAMF_STREAM_TYPE_AVC channel (ch=%d)", ch); - } - break; - case CELL_PAMF_STREAM_TYPE_ATRAC3PLUS: - if (ch == 0) - { - pEsFilterId->filterIdMajor = 0xbd; - pEsFilterId->filterIdMinor = 0; - pEsFilterId->supplementalInfo1 = 0; - pEsFilterId->supplementalInfo2 = 0; - } - else - cellPamf->Todo("pamfStreamTypeToEsFilterId: CELL_PAMF_STREAM_TYPE_ATRAC3PLUS (ch=%d)", ch); - break; - case CELL_PAMF_STREAM_TYPE_PAMF_LPCM: - if (ch == 0) - { - pEsFilterId->filterIdMajor = 0xbd; - pEsFilterId->filterIdMinor = 0x40; - pEsFilterId->supplementalInfo1 = 0; - pEsFilterId->supplementalInfo2 = 0; - } - else - cellPamf->Todo("pamfStreamTypeToEsFilterId: CELL_PAMF_STREAM_TYPE_LPCM (ch=%d)", ch); - break; - case CELL_PAMF_STREAM_TYPE_USER_DATA: - if (ch == 0) - { - pEsFilterId->filterIdMajor = 0xbd; - pEsFilterId->filterIdMinor = 0x20; - pEsFilterId->supplementalInfo1 = 0; - pEsFilterId->supplementalInfo2 = 0; - } - else - cellPamf->Todo("pamfStreamTypeToEsFilterId: CELL_PAMF_STREAM_TYPE_USER_DATA (ch=%d)", ch); - break; - case CELL_PAMF_STREAM_TYPE_AC3: - cellPamf->Todo("pamfStreamTypeToEsFilterId: CELL_PAMF_STREAM_TYPE_AC3 (ch=%d)", ch); + { + // code = 0x1b + pEsFilterId.filterIdMajor = 0xe0 | ch; + pEsFilterId.filterIdMinor = 0; break; + } + case CELL_PAMF_STREAM_TYPE_M2V: - cellPamf->Todo("pamfStreamTypeToEsFilterId: CELL_PAMF_STREAM_TYPE_M2V (ch=%d)", ch); + { + // code = 0x02 + pEsFilterId.filterIdMajor = 0xe0 | ch; + pEsFilterId.filterIdMinor = 0; break; + } + + case CELL_PAMF_STREAM_TYPE_ATRAC3PLUS: + { + // code = 0xdc + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = ch; + break; + } + + case CELL_PAMF_STREAM_TYPE_PAMF_LPCM: + { + // code = 0x80 + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = 0x40 | ch; + break; + } + + case CELL_PAMF_STREAM_TYPE_AC3: + { + // code = 0x81 + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = 0x30 | ch; + break; + } + + case CELL_PAMF_STREAM_TYPE_USER_DATA: + { + // code = 0xdd + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = 0x20 | ch; + break; + } + + case 6: + { + // code = 0xff + pEsFilterId.filterIdMajor = 0xe0 | ch; + pEsFilterId.filterIdMinor = 0; + break; + } + + case 7: + { + // code = 0xff + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = ch; + break; + } + + case 8: + { + // code = 0xff + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = 0x10 | ch; + break; + } + + case 9: + { + // code = 0xff + pEsFilterId.filterIdMajor = 0xbd; + pEsFilterId.filterIdMinor = 0x20 | ch; + break; + } + default: + { + cellPamf->Error("pamfStreamTypeToEsFilterId(): unknown type (%d, ch=%d)", type, ch); + Emu.Pause(); return CELL_PAMF_ERROR_INVALID_ARG; } + } + return CELL_OK; } u8 pamfGetStreamType(vm::ptr pSelf, u8 stream) { - //TODO: get stream type correctly - switch (pSelf->pAddr->stream_headers[stream].type) + // TODO: get stream type correctly + auto& header = pSelf->pAddr->stream_headers[stream]; + + switch (header.type) { case 0x1b: return CELL_PAMF_STREAM_TYPE_AVC; + case 0x02: return CELL_PAMF_STREAM_TYPE_M2V; case 0xdc: return CELL_PAMF_STREAM_TYPE_ATRAC3PLUS; case 0x80: return CELL_PAMF_STREAM_TYPE_PAMF_LPCM; + case 0x81: return CELL_PAMF_STREAM_TYPE_AC3; case 0xdd: return CELL_PAMF_STREAM_TYPE_USER_DATA; - default: - cellPamf->Todo("pamfGetStreamType: unsupported stream type found(0x%x)", pSelf->pAddr->stream_headers[stream].type); - return 0; } + + cellPamf->Todo("pamfGetStreamType(): unsupported stream type found(0x%x)", header.type); + Emu.Pause(); + return 0xff; } u8 pamfGetStreamChannel(vm::ptr pSelf, u8 stream) { - //TODO: get stream channel correctly + // TODO: get stream channel correctly + auto& header = pSelf->pAddr->stream_headers[stream]; - switch (pSelf->pAddr->stream_headers[stream].type) + switch (header.type) { - case 0x1b: - if ((pSelf->pAddr->stream_headers[stream].stream_id >= 0xe0) && (pSelf->pAddr->stream_headers[stream].stream_id <= 0xef)) - { - return pSelf->pAddr->stream_headers[stream].stream_id - 0xe0; - } - else - { - cellPamf->Error("pamfGetStreamChannel: stream type 0x%x got invalid stream id=0x%x", - pSelf->pAddr->stream_headers[stream].type, pSelf->pAddr->stream_headers[stream].stream_id); - return 0; - } - case 0xdc: - cellPamf->Todo("pamfGetStreamChannel: CELL_PAMF_STREAM_TYPE_ATRAC3PLUS"); - return 0; - case 0x80: - cellPamf->Todo("pamfGetStreamChannel: CELL_PAMF_STREAM_TYPE_PAMF_LPCM"); - return 0; + case 0x1b: // AVC + case 0x02: // M2V + { + assert((header.fid_major & 0xf0) == 0xe0 && header.fid_minor == 0); + return header.fid_major % 16; + } + + case 0xdc: // ATRAC3PLUS + { + assert(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0); + return header.fid_minor % 16; + } + + case 0x80: // LPCM + { + assert(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x40); + return header.fid_minor % 16; + } + case 0x81: // AC3 + { + assert(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x30); + return header.fid_minor % 16; + } case 0xdd: - cellPamf->Todo("pamfGetStreamChannel: CELL_PAMF_STREAM_TYPE_USER_DATA"); - return 0; - default: - cellPamf->Todo("pamfGetStreamType: unsupported stream type found(0x%x)", pSelf->pAddr->stream_headers[stream].type); - return 0; + { + assert(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x20); + return header.fid_minor % 16; + } } + cellPamf->Todo("pamfGetStreamChannel(): unsupported stream type found(0x%x)", header.type); + Emu.Pause(); + return 0xff; } -int cellPamfGetHeaderSize(vm::ptr pAddr, u64 fileSize, vm::ptr pSize) +s32 cellPamfGetHeaderSize(vm::ptr pAddr, u64 fileSize, vm::ptr pSize) { cellPamf->Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)", pAddr.addr(), fileSize, pSize.addr()); - //if ((u32)pAddr->magic != 0x464d4150) - //return CELL_PAMF_ERROR_UNKNOWN_TYPE; + //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; *pSize = offset; return CELL_OK; } -int cellPamfGetHeaderSize2(vm::ptr pAddr, u64 fileSize, u32 attribute, vm::ptr pSize) +s32 cellPamfGetHeaderSize2(vm::ptr pAddr, u64 fileSize, u32 attribute, vm::ptr pSize) { cellPamf->Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, attribute, pSize.addr()); - //if ((u32)pAddr->magic != 0x464d4150) - //return CELL_PAMF_ERROR_UNKNOWN_TYPE; + //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; *pSize = offset; return CELL_OK; } -int cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm::ptr pOffset, vm::ptr pSize) +s32 cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm::ptr pOffset, vm::ptr pSize) { cellPamf->Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, pOffset.addr(), pSize.addr()); - //if ((u32)pAddr->magic != 0x464d4150) - //return CELL_PAMF_ERROR_UNKNOWN_TYPE; + //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; const u64 offset = (u64)pAddr->data_offset << 11; *pOffset = offset; @@ -160,14 +204,15 @@ int cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm:: return CELL_OK; } -int cellPamfVerify(vm::ptr pAddr, u64 fileSize) +s32 cellPamfVerify(vm::ptr pAddr, u64 fileSize) { - cellPamf->Warning("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.addr(), fileSize); + cellPamf->Todo("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.addr(), fileSize); + // TODO return CELL_OK; } -int cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pAddr, u64 fileSize, u32 attribute) +s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pAddr, u64 fileSize, u32 attribute) { cellPamf->Warning("cellPamfReaderInitialize(pSelf=0x%x, pAddr=0x%x, fileSize=%d, attribute=0x%x)", pSelf.addr(), pAddr.addr(), fileSize, attribute); @@ -175,7 +220,7 @@ int cellPamfReaderInitialize(vm::ptr pSelf, vm::ptrfileSize = fileSize; } - else //if fileSize is unknown + else // if fileSize is unknown { pSelf->fileSize = ((u64)pAddr->data_offset << 11) + ((u64)pAddr->data_size << 11); } @@ -183,70 +228,59 @@ int cellPamfReaderInitialize(vm::ptr pSelf, vm::ptrTodo("cellPamfReaderInitialize(): verification"); } - pSelf->stream = 0; //??? currently set stream + pSelf->stream = 0; // currently set stream return CELL_OK; } -int cellPamfReaderGetPresentationStartTime(vm::ptr pSelf, vm::ptr pTimeStamp) +s32 cellPamfReaderGetPresentationStartTime(vm::ptr pSelf, vm::ptr pTimeStamp) { cellPamf->Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } + // always returns CELL_OK pTimeStamp->upper = (u32)(u16)pSelf->pAddr->start_pts_high; pTimeStamp->lower = pSelf->pAddr->start_pts_low; return CELL_OK; } -int cellPamfReaderGetPresentationEndTime(vm::ptr pSelf, vm::ptr pTimeStamp) +s32 cellPamfReaderGetPresentationEndTime(vm::ptr pSelf, vm::ptr pTimeStamp) { cellPamf->Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } + // always returns CELL_OK pTimeStamp->upper = (u32)(u16)pSelf->pAddr->end_pts_high; pTimeStamp->lower = pSelf->pAddr->end_pts_low; return CELL_OK; } -int cellPamfReaderGetMuxRateBound(vm::ptr pSelf) +u32 cellPamfReaderGetMuxRateBound(vm::ptr pSelf) { cellPamf->Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.addr()); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - + // cannot return error code return pSelf->pAddr->mux_rate_max; } -int cellPamfReaderGetNumberOfStreams(vm::ptr pSelf) +u8 cellPamfReaderGetNumberOfStreams(vm::ptr pSelf) { cellPamf->Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.addr()); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - + // cannot return error code return pSelf->pAddr->stream_count; } -int cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 streamType) +u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 streamType) { cellPamf->Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)", pSelf.addr(), streamType); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } + // cannot return error code - int counts[6] = {0, 0, 0, 0, 0, 0}; + u8 counts[256] = {}; for (u8 i = 0; i < pSelf->pAddr->stream_count; i++) { @@ -261,46 +295,48 @@ int cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 s case CELL_PAMF_STREAM_TYPE_PAMF_LPCM: case CELL_PAMF_STREAM_TYPE_AC3: case CELL_PAMF_STREAM_TYPE_USER_DATA: + { return counts[streamType]; - case CELL_PAMF_STREAM_TYPE_VIDEO: - return counts[CELL_PAMF_STREAM_TYPE_AVC] + counts[CELL_PAMF_STREAM_TYPE_M2V]; - case CELL_PAMF_STREAM_TYPE_AUDIO: - return counts[CELL_PAMF_STREAM_TYPE_ATRAC3PLUS] + counts[CELL_PAMF_STREAM_TYPE_PAMF_LPCM] + counts[CELL_PAMF_STREAM_TYPE_AC3]; - default: - return 0; } + + case CELL_PAMF_STREAM_TYPE_VIDEO: + { + return counts[CELL_PAMF_STREAM_TYPE_AVC] + counts[CELL_PAMF_STREAM_TYPE_M2V]; + } + + case CELL_PAMF_STREAM_TYPE_AUDIO: + { + return counts[CELL_PAMF_STREAM_TYPE_ATRAC3PLUS] + counts[CELL_PAMF_STREAM_TYPE_PAMF_LPCM] + counts[CELL_PAMF_STREAM_TYPE_AC3]; + } + } + + cellPamf->Todo("cellPamfReaderGetNumberOfSpecificStreams(): unsupported stream type (0x%x)", streamType); + Emu.Pause(); + return 0; } -int cellPamfReaderSetStreamWithIndex(vm::ptr pSelf, u8 streamIndex) +s32 cellPamfReaderSetStreamWithIndex(vm::ptr pSelf, u8 streamIndex) { cellPamf->Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)", pSelf.addr(), streamIndex); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - - if (streamIndex < pSelf->pAddr->stream_count) + if (streamIndex >= pSelf->pAddr->stream_count) { - pSelf->stream = streamIndex; - return CELL_OK; + return CELL_PAMF_ERROR_INVALID_ARG; } - cellPamf->Error("cellPamfReaderSetStreamWithIndex: CELL_PAMF_ERROR_INVALID_ARG"); - return CELL_PAMF_ERROR_INVALID_ARG; + pSelf->stream = streamIndex; + return CELL_OK; } -int cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 streamType, u8 ch) +s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 streamType, u8 ch) { cellPamf->Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)", pSelf.addr(), streamType, ch); - - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - if (streamType > 5) + // it probably doesn't support "any audio" or "any video" argument + if (streamType > 5 || ch >= 16) { - cellPamf->Error("cellPamfReaderSetStreamWithTypeAndChannel: invalid stream type(%d)", streamType); - //it probably doesn't support "any audio" or "any video" argument + cellPamf->Error("cellPamfReaderSetStreamWithTypeAndChannel(): invalid arguments (streamType=%d, ch=%d)", streamType, ch); + Emu.Pause(); return CELL_PAMF_ERROR_INVALID_ARG; } @@ -319,14 +355,10 @@ int cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 return CELL_PAMF_ERROR_STREAM_NOT_FOUND; } -int cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 streamType, u8 streamIndex) +s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 streamType, u8 streamIndex) { cellPamf->Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)", pSelf.addr(), streamType, streamIndex); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - u32 found = 0; for (u8 i = 0; i < pSelf->pAddr->stream_count; i++) @@ -340,23 +372,31 @@ int cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 st else switch(streamType) { case CELL_PAMF_STREAM_TYPE_VIDEO: - if (type == CELL_PAMF_STREAM_TYPE_AVC || type == CELL_PAMF_STREAM_TYPE_M2V) + { + if (type == CELL_PAMF_STREAM_TYPE_AVC || type == CELL_PAMF_STREAM_TYPE_M2V) { found++; } break; + } + case CELL_PAMF_STREAM_TYPE_AUDIO: + { if (type == CELL_PAMF_STREAM_TYPE_ATRAC3PLUS || type == CELL_PAMF_STREAM_TYPE_AC3 || type == CELL_PAMF_STREAM_TYPE_PAMF_LPCM) { found++; } break; + } + default: + { if (streamType > 5) { return CELL_PAMF_ERROR_INVALID_ARG; } } + } if (found > streamIndex) { @@ -368,46 +408,57 @@ int cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 st return CELL_PAMF_ERROR_STREAM_NOT_FOUND; } -int cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr pEsFilterId) +s32 cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr pEsFilterId) { cellPamf->Warning("cellPamfStreamTypeToEsFilterId(type=%d, ch=%d, pEsFilterId_addr=0x%x)", type, ch, pEsFilterId.addr()); + + if (!pEsFilterId) + { + return CELL_PAMF_ERROR_INVALID_ARG; + } - return pamfStreamTypeToEsFilterId(type, ch, pEsFilterId); + return pamfStreamTypeToEsFilterId(type, ch, *pEsFilterId); } -int cellPamfReaderGetStreamIndex(vm::ptr pSelf) +s32 cellPamfReaderGetStreamIndex(vm::ptr pSelf) { cellPamf->Log("cellPamfReaderGetStreamIndex(pSelf=0x%x)", pSelf.addr()); + // seems that CELL_PAMF_ERROR_INVALID_PAMF must be already written in pSelf->stream if it's the case return pSelf->stream; } -int cellPamfReaderGetStreamTypeAndChannel(vm::ptr pSelf, vm::ptr pType, vm::ptr pCh) +s32 cellPamfReaderGetStreamTypeAndChannel(vm::ptr pSelf, vm::ptr pType, vm::ptr pCh) { cellPamf->Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=0x%x (stream=%d), pType_addr=0x%x, pCh_addr=0x%x", pSelf.addr(), pSelf->stream, pType.addr(), pCh.addr()); + // unclear + *pType = pamfGetStreamType(pSelf, pSelf->stream); *pCh = pamfGetStreamChannel(pSelf, pSelf->stream); return CELL_OK; } -int cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptr pEsFilterId) +s32 cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptr pEsFilterId) { cellPamf->Warning("cellPamfReaderGetEsFilterId(pSelf=0x%x (stream=%d), pEsFilterId_addr=0x%x)", pSelf.addr(), pSelf->stream, pEsFilterId.addr()); - return pamfStreamTypeToEsFilterId(pamfGetStreamType(pSelf, pSelf->stream), - pamfGetStreamChannel(pSelf, pSelf->stream), pEsFilterId); + // always returns CELL_OK + + auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; + pEsFilterId->filterIdMajor = header.fid_major; + pEsFilterId->filterIdMinor = header.fid_minor; + pEsFilterId->supplementalInfo1 = header.type == 0x1b ? 1 : 0; + pEsFilterId->supplementalInfo2 = 0; + return CELL_OK; } -int cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u32 size) +s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u32 size) { cellPamf->Warning("cellPamfReaderGetStreamInfo(pSelf=0x%x, stream=%d, pInfo_addr=0x%x, size=%d)", pSelf.addr(), pSelf->stream, pInfo_addr, size); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - + // TODO (many parameters are wrong) memset(vm::get_ptr(pInfo_addr), 0, size); switch (pamfGetStreamType(pSelf, pSelf->stream)) @@ -509,58 +560,46 @@ int cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_OK; } -int cellPamfReaderGetNumberOfEp(vm::ptr pSelf) +u32 cellPamfReaderGetNumberOfEp(vm::ptr pSelf) { cellPamf->Warning("cellPamfReaderGetNumberOfEp(pSelf=0x%x, stream=%d)", pSelf.addr(), pSelf->stream); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - + // cannot return error code return pSelf->pAddr->stream_headers[pSelf->stream].ep_num; } -int cellPamfReaderGetEpIteratorWithIndex(vm::ptr pSelf, u32 epIndex, vm::ptr pIt) +s32 cellPamfReaderGetEpIteratorWithIndex(vm::ptr pSelf, u32 epIndex, vm::ptr pIt) { cellPamf->Todo("cellPamfReaderGetEpIteratorWithIndex(pSelf=0x%x, stream=%d, epIndex=%d, pIt_addr=0x%x)", pSelf.addr(), pSelf->stream, epIndex, pIt.addr()); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - - //TODO: + // TODO return CELL_OK; } -int cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr pSelf, vm::ptr pTimeStamp, vm::ptr pIt) +s32 cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr pSelf, vm::ptr pTimeStamp, vm::ptr pIt) { cellPamf->Todo("cellPamfReaderGetEpIteratorWithTimeStamp(pSelf=0x%x, pTimeStamp_addr=0x%x, pIt_addr=0x%x)", pSelf.addr(), pTimeStamp.addr(), pIt.addr()); - if (!pSelf->pAddr) { - return CELL_PAMF_ERROR_INVALID_PAMF; - } - - //TODO: - + // TODO return CELL_OK; } -int cellPamfEpIteratorGetEp(vm::ptr pIt, vm::ptr pEp) +s32 cellPamfEpIteratorGetEp(vm::ptr pIt, vm::ptr pEp) { cellPamf->Todo("cellPamfEpIteratorGetEp(pIt_addr=0x%x, pEp_addr=0x%x)", pIt.addr(), pEp.addr()); - //TODO: - + // always returns CELL_OK + // TODO return CELL_OK; } -int cellPamfEpIteratorMove(vm::ptr pIt, s32 steps, vm::ptr pEp) +s32 cellPamfEpIteratorMove(vm::ptr pIt, s32 steps, vm::ptr pEp) { cellPamf->Todo("cellPamfEpIteratorMove(pIt_addr=0x%x, steps=%d, pEp_addr=0x%x)", pIt.addr(), steps, pEp.addr()); - //TODO: - - return CELL_OK; + // cannot return error code + // TODO + return 0; } void cellPamf_init(Module *pxThis) diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.h b/rpcs3/Emu/SysCalls/Modules/cellPamf.h index 639b02b662..e740ca006d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.h @@ -168,7 +168,8 @@ struct CellCodecEsFilterId }; // AVC (MPEG4 AVC Video) Specific Information -struct CellPamfAvcInfo { +struct CellPamfAvcInfo +{ u8 profileIdc; u8 levelIdc; u8 frameMbsOnlyFlag; @@ -196,7 +197,8 @@ struct CellPamfAvcInfo { }; // M2V (MPEG2 Video) Specific Information -struct CellPamfM2vInfo { +struct CellPamfM2vInfo +{ u8 profileAndLevelIndication; bool progressiveSequence; u8 videoSignalInfoFlag; @@ -216,27 +218,32 @@ struct CellPamfM2vInfo { }; // LPCM Audio Specific Information -struct CellPamfLpcmInfo { +struct CellPamfLpcmInfo +{ be_t samplingFrequency; u8 numberOfChannels; be_t bitsPerSample; }; // ATRAC3+ Audio Specific Information -struct CellPamfAtrac3plusInfo { +struct CellPamfAtrac3plusInfo +{ be_t samplingFrequency; u8 numberOfChannels; }; // AC3 Audio Specific Information -struct CellPamfAc3Info { +struct CellPamfAc3Info +{ be_t samplingFrequency; u8 numberOfChannels; }; -#pragma pack(push, 1) //file data +#pragma pack(push, 1) // file data -struct PamfStreamHeader_AVC { //AVC specific information +// AVC specific information +struct PamfStreamHeader_AVC +{ u8 profileIdc; u8 levelIdc; u8 unk0; @@ -256,11 +263,15 @@ struct PamfStreamHeader_AVC { //AVC specific information u32 unk12; //0 }; -struct PamfStreamHeader_M2V { //M2V specific information - u8 unknown[32]; //no information yet +// M2V specific information +struct PamfStreamHeader_M2V +{ + u8 unknown[32]; }; -struct PamfStreamHeader_Audio { //Audio specific information +// Audio specific information +struct PamfStreamHeader_Audio +{ u16 unknown; //== 0 u8 channels; //number of channels (1, 2, 6 or 8) u8 freq; //== 1 (always 48000) @@ -268,14 +279,14 @@ struct PamfStreamHeader_Audio { //Audio specific information u8 reserved[27]; //probably nothing }; -struct PamfStreamHeader //48 bytes +struct PamfStreamHeader { //TODO: look for correct beginning of stream header u8 type; //0x1B for video (AVC), 0xDC ATRAC3+, 0x80 LPCM, 0xDD userdata u8 unknown[3]; //0 //TODO: examine stream_ch encoding - u8 stream_id; - u8 private_stream_id; + u8 fid_major; + u8 fid_minor; u8 unknown1; //????? u8 unknown2; //????? //Entry Point Info @@ -285,6 +296,8 @@ struct PamfStreamHeader //48 bytes u8 data[32]; }; +static_assert(sizeof(PamfStreamHeader) == 48, "Invalid PamfStreamHeader size"); + struct PamfHeader { u32 magic; //"PAMF" @@ -317,21 +330,25 @@ struct PamfHeader PamfStreamHeader stream_headers[256]; }; -struct PamfEpHeader { //12 bytes +struct PamfEpHeader +{ be_t value0; //mixed indexN (probably left 2 bits) and nThRefPictureOffset be_t pts_high; be_t pts_low; be_t rpnOffset; }; +static_assert(sizeof(PamfEpHeader) == 12, "Invalid PamfEpHeader size"); + #pragma pack(pop) +// not directly accessed by virtual CPU, fields are unknown struct CellPamfReader { - //this struct can be used in any way, if it is not accessed directly by virtual CPU - //be_t internalData[16]; vm::ptr pAddr; - int stream; + s32 stream; u64 fileSize; u32 internalData[28]; -}; \ No newline at end of file +}; + +static_assert(sizeof(CellPamfReader) == 128, "Invalid CellPamfReader size"); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index d923273dde..9482895b54 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -494,11 +494,11 @@ u32 vdecOpen(VideoDecoder* data) { switch ((u64)vdec.ctx->time_base.den + (u64)(vdec.ctx->ticks_per_frame - 1) * 0x100000000ull) { - case 24: case 48 + 0x100000000: frame.frc = CELL_VDEC_FRC_24; break; - case 25: case 50 + 0x100000000: frame.frc = CELL_VDEC_FRC_25; break; - case 30: case 60 + 0x100000000: frame.frc = CELL_VDEC_FRC_30; break; - case 50: case 100 + 0x100000000: frame.frc = CELL_VDEC_FRC_50; break; - case 60: case 120 + 0x100000000: frame.frc = CELL_VDEC_FRC_60; break; + case 24: case 0x100000000ull + 48: frame.frc = CELL_VDEC_FRC_24; break; + case 25: case 0x100000000ull + 50: frame.frc = CELL_VDEC_FRC_25; break; + case 30: case 0x100000000ull + 60: frame.frc = CELL_VDEC_FRC_30; break; + case 50: case 0x100000000ull + 100: frame.frc = CELL_VDEC_FRC_50; break; + case 60: case 0x100000000ull + 120: frame.frc = CELL_VDEC_FRC_60; break; default: { cellVdec->Error("vdecDecodeAu: unsupported time_base.den (%d/1, tpf=%d)", vdec.ctx->time_base.den, vdec.ctx->ticks_per_frame); @@ -553,7 +553,7 @@ u32 vdecOpen(VideoDecoder* data) case vdecSetFrameRate: { - cellVdec->Error("vdecSetFrameRate(0x%x)", task.frc); + cellVdec->Warning("vdecSetFrameRate(0x%x)", task.frc); vdec.frc_set = task.frc; break; }