mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-22 20:45:22 +00:00
cellPamf improved
This commit is contained in:
parent
2b4f858caf
commit
8557614322
3 changed files with 269 additions and 213 deletions
|
@ -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<CellCodecEsFilterId> 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<CellPamfReader> 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<CellPamfReader> 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<PamfHeader> pAddr, u64 fileSize, vm::ptr<u64> pSize)
|
||||
s32 cellPamfGetHeaderSize(vm::ptr<PamfHeader> pAddr, u64 fileSize, vm::ptr<u64> 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<PamfHeader> pAddr, u64 fileSize, u32 attribute, vm::ptr<u64> pSize)
|
||||
s32 cellPamfGetHeaderSize2(vm::ptr<PamfHeader> pAddr, u64 fileSize, u32 attribute, vm::ptr<u64> 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<PamfHeader> pAddr, u64 fileSize, vm::ptr<u64> pOffset, vm::ptr<u64> pSize)
|
||||
s32 cellPamfGetStreamOffsetAndSize(vm::ptr<PamfHeader> pAddr, u64 fileSize, vm::ptr<u64> pOffset, vm::ptr<u64> 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<PamfHeader> pAddr, u64 fileSize, vm::
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfVerify(vm::ptr<PamfHeader> pAddr, u64 fileSize)
|
||||
s32 cellPamfVerify(vm::ptr<PamfHeader> 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<CellPamfReader> pSelf, vm::ptr<const PamfHeader> pAddr, u64 fileSize, u32 attribute)
|
||||
s32 cellPamfReaderInitialize(vm::ptr<CellPamfReader> pSelf, vm::ptr<const PamfHeader> 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<CellPamfReader> pSelf, vm::ptr<const PamfHe
|
|||
{
|
||||
pSelf->fileSize = 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<CellPamfReader> pSelf, vm::ptr<const PamfHe
|
|||
|
||||
if (attribute & CELL_PAMF_ATTRIBUTE_VERIFY_ON)
|
||||
{
|
||||
//TODO
|
||||
// TODO
|
||||
cellPamf->Todo("cellPamfReaderInitialize(): verification");
|
||||
}
|
||||
|
||||
pSelf->stream = 0; //??? currently set stream
|
||||
pSelf->stream = 0; // currently set stream
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetPresentationStartTime(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> pTimeStamp)
|
||||
s32 cellPamfReaderGetPresentationStartTime(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> 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<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> pTimeStamp)
|
||||
s32 cellPamfReaderGetPresentationEndTime(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> 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<CellPamfReader> pSelf)
|
||||
u32 cellPamfReaderGetMuxRateBound(vm::ptr<CellPamfReader> 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<CellPamfReader> pSelf)
|
||||
u8 cellPamfReaderGetNumberOfStreams(vm::ptr<CellPamfReader> 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<CellPamfReader> pSelf, u8 streamType)
|
||||
u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr<CellPamfReader> 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<CellPamfReader> 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<CellPamfReader> pSelf, u8 streamIndex)
|
||||
s32 cellPamfReaderSetStreamWithIndex(vm::ptr<CellPamfReader> 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<CellPamfReader> pSelf, u8 streamType, u8 ch)
|
||||
s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr<CellPamfReader> 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<CellPamfReader> pSelf, u8
|
|||
return CELL_PAMF_ERROR_STREAM_NOT_FOUND;
|
||||
}
|
||||
|
||||
int cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr<CellPamfReader> pSelf, u8 streamType, u8 streamIndex)
|
||||
s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr<CellPamfReader> 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<CellPamfReader> 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<CellPamfReader> pSelf, u8 st
|
|||
return CELL_PAMF_ERROR_STREAM_NOT_FOUND;
|
||||
}
|
||||
|
||||
int cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr<CellCodecEsFilterId> pEsFilterId)
|
||||
s32 cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr<CellCodecEsFilterId> 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<CellPamfReader> pSelf)
|
||||
s32 cellPamfReaderGetStreamIndex(vm::ptr<CellPamfReader> 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<CellPamfReader> pSelf, vm::ptr<u8> pType, vm::ptr<u8> pCh)
|
||||
s32 cellPamfReaderGetStreamTypeAndChannel(vm::ptr<CellPamfReader> pSelf, vm::ptr<u8> pType, vm::ptr<u8> 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<CellPamfReader> pSelf, vm::ptr<CellCodecEsFilterId> pEsFilterId)
|
||||
s32 cellPamfReaderGetEsFilterId(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecEsFilterId> 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<CellPamfReader> pSelf, u32 pInfo_addr, u32 size)
|
||||
s32 cellPamfReaderGetStreamInfo(vm::ptr<CellPamfReader> 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<void>(pInfo_addr), 0, size);
|
||||
|
||||
switch (pamfGetStreamType(pSelf, pSelf->stream))
|
||||
|
@ -509,58 +560,46 @@ int cellPamfReaderGetStreamInfo(vm::ptr<CellPamfReader> pSelf, u32 pInfo_addr, u
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellPamfReaderGetNumberOfEp(vm::ptr<CellPamfReader> pSelf)
|
||||
u32 cellPamfReaderGetNumberOfEp(vm::ptr<CellPamfReader> 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<CellPamfReader> pSelf, u32 epIndex, vm::ptr<CellPamfEpIterator> pIt)
|
||||
s32 cellPamfReaderGetEpIteratorWithIndex(vm::ptr<CellPamfReader> pSelf, u32 epIndex, vm::ptr<CellPamfEpIterator> 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<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> pTimeStamp, vm::ptr<CellPamfEpIterator> pIt)
|
||||
s32 cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> pTimeStamp, vm::ptr<CellPamfEpIterator> 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<CellPamfEpIterator> pIt, vm::ptr<CellPamfEp> pEp)
|
||||
s32 cellPamfEpIteratorGetEp(vm::ptr<CellPamfEpIterator> pIt, vm::ptr<CellPamfEp> 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<CellPamfEpIterator> pIt, s32 steps, vm::ptr<CellPamfEp> pEp)
|
||||
s32 cellPamfEpIteratorMove(vm::ptr<CellPamfEpIterator> pIt, s32 steps, vm::ptr<CellPamfEp> 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)
|
||||
|
|
|
@ -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<u32> samplingFrequency;
|
||||
u8 numberOfChannels;
|
||||
be_t<u16> bitsPerSample;
|
||||
};
|
||||
|
||||
// ATRAC3+ Audio Specific Information
|
||||
struct CellPamfAtrac3plusInfo {
|
||||
struct CellPamfAtrac3plusInfo
|
||||
{
|
||||
be_t<u32> samplingFrequency;
|
||||
u8 numberOfChannels;
|
||||
};
|
||||
|
||||
// AC3 Audio Specific Information
|
||||
struct CellPamfAc3Info {
|
||||
struct CellPamfAc3Info
|
||||
{
|
||||
be_t<u32> 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<u16> value0; //mixed indexN (probably left 2 bits) and nThRefPictureOffset
|
||||
be_t<u16> pts_high;
|
||||
be_t<u32> pts_low;
|
||||
be_t<u32> 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<u64> internalData[16];
|
||||
vm::ptr<const PamfHeader> pAddr;
|
||||
int stream;
|
||||
s32 stream;
|
||||
u64 fileSize;
|
||||
u32 internalData[28];
|
||||
};
|
||||
};
|
||||
|
||||
static_assert(sizeof(CellPamfReader) == 128, "Invalid CellPamfReader size");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue