cellPamf improved

This commit is contained in:
Nekotekina 2014-12-11 22:25:11 +03:00
parent 2b4f858caf
commit 8557614322
3 changed files with 269 additions and 213 deletions

View file

@ -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)

View file

@ -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");

View file

@ -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;
}