rpcs3/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp
2014-12-13 19:54:01 +03:00

765 lines
21 KiB
C++

#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/System.h"
#include "Emu/SysCalls/Modules.h"
#include "cellPamf.h"
Module *cellPamf = nullptr;
s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId)
{
// 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:
{
// code = 0x1b
pEsFilterId.filterIdMajor = 0xe0 | ch;
pEsFilterId.filterIdMinor = 0;
break;
}
case CELL_PAMF_STREAM_TYPE_M2V:
{
// 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, u32 stream)
{
// TODO: get stream type correctly
assert(stream < (u32)pSelf->pAddr->stream_count);
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;
}
cellPamf->Todo("pamfGetStreamType(): unsupported stream type found(0x%x)", header.type);
Emu.Pause();
return 0xff;
}
u8 pamfGetStreamChannel(vm::ptr<CellPamfReader> pSelf, u32 stream)
{
// TODO: get stream channel correctly
assert(stream < (u32)pSelf->pAddr->stream_count);
auto& header = pSelf->pAddr->stream_headers[stream];
switch (header.type)
{
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:
{
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;
}
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;
const u64 offset = (u64)pAddr->data_offset << 11;
*pSize = offset;
return CELL_OK;
}
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;
const u64 offset = (u64)pAddr->data_offset << 11;
*pSize = offset;
return CELL_OK;
}
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;
const u64 offset = (u64)pAddr->data_offset << 11;
*pOffset = offset;
const u64 size = (u64)pAddr->data_size << 11;
*pSize = size;
return CELL_OK;
}
s32 cellPamfVerify(vm::ptr<PamfHeader> pAddr, u64 fileSize)
{
cellPamf->Todo("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.addr(), fileSize);
// TODO
return CELL_OK;
}
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);
if (fileSize)
{
pSelf->fileSize = fileSize;
}
else // if fileSize is unknown
{
pSelf->fileSize = ((u64)pAddr->data_offset << 11) + ((u64)pAddr->data_size << 11);
}
pSelf->pAddr = pAddr;
if (attribute & CELL_PAMF_ATTRIBUTE_VERIFY_ON)
{
// TODO
cellPamf->Todo("cellPamfReaderInitialize(): verification");
}
pSelf->stream = 0; // currently set stream
return CELL_OK;
}
s32 cellPamfReaderGetPresentationStartTime(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> pTimeStamp)
{
cellPamf->Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr());
// always returns CELL_OK
pTimeStamp->upper = (u32)(u16)pSelf->pAddr->start_pts_high;
pTimeStamp->lower = pSelf->pAddr->start_pts_low;
return CELL_OK;
}
s32 cellPamfReaderGetPresentationEndTime(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodecTimeStamp> pTimeStamp)
{
cellPamf->Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr());
// always returns CELL_OK
pTimeStamp->upper = (u32)(u16)pSelf->pAddr->end_pts_high;
pTimeStamp->lower = pSelf->pAddr->end_pts_low;
return CELL_OK;
}
u32 cellPamfReaderGetMuxRateBound(vm::ptr<CellPamfReader> pSelf)
{
cellPamf->Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.addr());
// cannot return error code
return pSelf->pAddr->mux_rate_max;
}
u8 cellPamfReaderGetNumberOfStreams(vm::ptr<CellPamfReader> pSelf)
{
cellPamf->Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.addr());
// cannot return error code
return pSelf->pAddr->stream_count;
}
u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr<CellPamfReader> pSelf, u8 streamType)
{
cellPamf->Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)", pSelf.addr(), streamType);
// cannot return error code
u8 counts[256] = {};
for (u8 i = 0; i < pSelf->pAddr->stream_count; i++)
{
counts[pamfGetStreamType(pSelf, i)]++;
}
switch (streamType)
{
case CELL_PAMF_STREAM_TYPE_AVC:
case CELL_PAMF_STREAM_TYPE_M2V:
case CELL_PAMF_STREAM_TYPE_ATRAC3PLUS:
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];
}
}
cellPamf->Todo("cellPamfReaderGetNumberOfSpecificStreams(): unsupported stream type (0x%x)", streamType);
Emu.Pause();
return 0;
}
s32 cellPamfReaderSetStreamWithIndex(vm::ptr<CellPamfReader> pSelf, u8 streamIndex)
{
cellPamf->Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)", pSelf.addr(), streamIndex);
if (streamIndex >= pSelf->pAddr->stream_count)
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
pSelf->stream = streamIndex;
return CELL_OK;
}
s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr<CellPamfReader> pSelf, u8 streamType, u8 ch)
{
cellPamf->Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)", pSelf.addr(), streamType, ch);
// it probably doesn't support "any audio" or "any video" argument
if (streamType > 5 || ch >= 16)
{
cellPamf->Error("cellPamfReaderSetStreamWithTypeAndChannel(): invalid arguments (streamType=%d, ch=%d)", streamType, ch);
Emu.Pause();
return CELL_PAMF_ERROR_INVALID_ARG;
}
for (u8 i = 0; i < pSelf->pAddr->stream_count; i++)
{
if (pamfGetStreamType(pSelf, i) == streamType)
{
if (pamfGetStreamChannel(pSelf, i) == ch)
{
pSelf->stream = i;
return i;
}
}
}
return CELL_PAMF_ERROR_STREAM_NOT_FOUND;
}
s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr<CellPamfReader> pSelf, u8 streamType, u8 streamIndex)
{
cellPamf->Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)", pSelf.addr(), streamType, streamIndex);
u32 found = 0;
for (u8 i = 0; i < pSelf->pAddr->stream_count; i++)
{
const u8 type = pamfGetStreamType(pSelf, i);
if (type == streamType)
{
found++;
}
else switch(streamType)
{
case CELL_PAMF_STREAM_TYPE_VIDEO:
{
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)
{
pSelf->stream = i;
return i;
}
}
return CELL_PAMF_ERROR_STREAM_NOT_FOUND;
}
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);
}
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;
}
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;
}
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());
// always returns CELL_OK
assert((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count);
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;
}
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);
assert((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count);
auto& header = pSelf->pAddr->stream_headers[pSelf->stream];
const u8 type = pamfGetStreamType(pSelf, pSelf->stream);
const u8 ch = pamfGetStreamChannel(pSelf, pSelf->stream);
switch (type)
{
case CELL_PAMF_STREAM_TYPE_AVC:
{
if (size < sizeof(CellPamfAvcInfo))
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
auto info = vm::ptr<CellPamfAvcInfo>::make(pInfo_addr);
info->profileIdc = header.AVC.profileIdc;
info->levelIdc = header.AVC.levelIdc;
info->frameMbsOnlyFlag = (header.AVC.x2 & 0x80) >> 7;
info->videoSignalInfoFlag = (header.AVC.x2 & 0x40) >> 6;
info->frameRateInfo = (header.AVC.x2 & 0x0f) - 1;
info->aspectRatioIdc = header.AVC.aspectRatioIdc;
if (header.AVC.aspectRatioIdc == 0xff)
{
info->sarWidth = header.AVC.sarWidth;
info->sarHeight = header.AVC.sarHeight;
}
else
{
info->sarWidth = 0;
info->sarHeight = 0;
}
info->horizontalSize = ((u16)header.AVC.horizontalSize & 0xff) * 16;
info->verticalSize = ((u16)header.AVC.verticalSize & 0xff) * 16;
info->frameCropLeftOffset = header.AVC.frameCropLeftOffset;
info->frameCropRightOffset = header.AVC.frameCropRightOffset;
info->frameCropTopOffset = header.AVC.frameCropTopOffset;
info->frameCropBottomOffset = header.AVC.frameCropBottomOffset;
if (info->videoSignalInfoFlag)
{
info->videoFormat = header.AVC.x14 >> 5;
info->videoFullRangeFlag = (header.AVC.x14 & 0x10) >> 4;
info->colourPrimaries = header.AVC.colourPrimaries;
info->transferCharacteristics = header.AVC.transferCharacteristics;
info->matrixCoefficients = header.AVC.matrixCoefficients;
}
else
{
info->videoFormat = 0;
info->videoFullRangeFlag = 0;
info->colourPrimaries = 0;
info->transferCharacteristics = 0;
info->matrixCoefficients = 0;
}
info->entropyCodingModeFlag = (header.AVC.x18 & 0x80) >> 7;
info->deblockingFilterFlag = (header.AVC.x18 & 0x40) >> 6;
info->minNumSlicePerPictureIdc = (header.AVC.x18 & 0x30) >> 4;
info->nfwIdc = header.AVC.x18 & 0x03;
info->maxMeanBitrate = header.AVC.maxMeanBitrate;
cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_AVC");
break;
}
case CELL_PAMF_STREAM_TYPE_M2V:
{
if (size < sizeof(CellPamfM2vInfo))
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
auto info = vm::ptr<CellPamfM2vInfo>::make(pInfo_addr);
switch (header.M2V.x0)
{
case 0x44: info->profileAndLevelIndication = 3; break;
case 0x48: info->profileAndLevelIndication = 1; break;
default: info->profileAndLevelIndication = CELL_PAMF_M2V_UNKNOWN;
}
info->progressiveSequence = (header.M2V.x2 & 0x80) >> 7;
info->videoSignalInfoFlag = (header.M2V.x2 & 0x40) >> 6;
info->frameRateInfo = header.M2V.x2 & 0xf;
info->aspectRatioIdc = header.M2V.aspectRatioIdc;
if (header.M2V.aspectRatioIdc == 0xff)
{
info->sarWidth = header.M2V.sarWidth;
info->sarHeight = header.M2V.sarHeight;
}
else
{
info->sarWidth = 0;
info->sarHeight = 0;
}
info->horizontalSize = ((u16)header.M2V.horizontalSize & 0xff) * 16;
info->verticalSize = ((u16)header.M2V.verticalSize & 0xff) * 16;
info->horizontalSizeValue = header.M2V.horizontalSizeValue;
info->verticalSizeValue = header.M2V.verticalSizeValue;
if (info->videoSignalInfoFlag)
{
info->videoFormat = header.M2V.x14 >> 5;
info->videoFullRangeFlag = (header.M2V.x14 & 0x10) >> 4;
info->colourPrimaries = header.M2V.colourPrimaries;
info->transferCharacteristics = header.M2V.transferCharacteristics;
info->matrixCoefficients = header.M2V.matrixCoefficients;
}
else
{
info->videoFormat = 0;
info->videoFullRangeFlag = 0;
info->colourPrimaries = 0;
info->transferCharacteristics = 0;
info->matrixCoefficients = 0;
}
cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_M2V");
break;
}
case CELL_PAMF_STREAM_TYPE_ATRAC3PLUS:
{
if (size < sizeof(CellPamfAtrac3plusInfo))
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
auto info = vm::ptr<CellPamfAtrac3plusInfo>::make(pInfo_addr);
info->samplingFrequency = header.audio.freq & 0xf;
info->numberOfChannels = header.audio.channels & 0xf;
cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_ATRAC3PLUS");
break;
}
case CELL_PAMF_STREAM_TYPE_PAMF_LPCM:
{
if (size < sizeof(CellPamfLpcmInfo))
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
auto info = vm::ptr<CellPamfLpcmInfo>::make(pInfo_addr);
info->samplingFrequency = header.audio.freq & 0xf;
info->numberOfChannels = header.audio.channels & 0xf;
info->bitsPerSample = header.audio.bps >> 6;
cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_PAMF_LPCM");
break;
}
case CELL_PAMF_STREAM_TYPE_AC3:
{
if (size < sizeof(CellPamfAc3Info))
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
auto info = vm::ptr<CellPamfAc3Info>::make(pInfo_addr);
info->samplingFrequency = header.audio.freq & 0xf;
info->numberOfChannels = header.audio.channels & 0xf;
cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_AC3");
break;
}
case CELL_PAMF_STREAM_TYPE_USER_DATA:
{
cellPamf->Error("cellPamfReaderGetStreamInfo(): invalid type CELL_PAMF_STREAM_TYPE_USER_DATA");
return CELL_PAMF_ERROR_INVALID_ARG;
}
case 6:
{
if (size < 4)
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
cellPamf->Todo("cellPamfReaderGetStreamInfo(): type 6");
break;
}
case 7:
{
if (size < 2)
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
cellPamf->Todo("cellPamfReaderGetStreamInfo(): type 7");
break;
}
case 8:
{
if (size < 2)
{
return CELL_PAMF_ERROR_INVALID_ARG;
}
cellPamf->Todo("cellPamfReaderGetStreamInfo(): type 8");
break;
}
case 9:
{
cellPamf->Error("cellPamfReaderGetStreamInfo(): invalid type 9");
return CELL_PAMF_ERROR_INVALID_ARG;
}
default:
{
// invalid type or getting type/ch failed
cellPamf->Error("cellPamfReaderGetStreamInfo(): invalid type %d (ch=%d)", type, ch);
return CELL_PAMF_ERROR_INVALID_PAMF;
}
}
return CELL_OK;
}
u32 cellPamfReaderGetNumberOfEp(vm::ptr<CellPamfReader> pSelf)
{
cellPamf->Todo("cellPamfReaderGetNumberOfEp(pSelf=0x%x, stream=%d)", pSelf.addr(), pSelf->stream);
// cannot return error code
return 0; //pSelf->pAddr->stream_headers[pSelf->stream].ep_num;
}
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());
// TODO
return CELL_OK;
}
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());
// TODO
return CELL_OK;
}
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());
// always returns CELL_OK
// TODO
return CELL_OK;
}
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());
// cannot return error code
// TODO
return 0;
}
void cellPamf_init(Module *pxThis)
{
cellPamf = pxThis;
cellPamf->AddFunc(0xca8181c1, cellPamfGetHeaderSize);
cellPamf->AddFunc(0x90fc9a59, cellPamfGetHeaderSize2);
cellPamf->AddFunc(0x44f5c9e3, cellPamfGetStreamOffsetAndSize);
cellPamf->AddFunc(0xd1a40ef4, cellPamfVerify);
cellPamf->AddFunc(0xb8436ee5, cellPamfReaderInitialize);
cellPamf->AddFunc(0x4de501b1, cellPamfReaderGetPresentationStartTime);
cellPamf->AddFunc(0xf61609d6, cellPamfReaderGetPresentationEndTime);
cellPamf->AddFunc(0xdb70296c, cellPamfReaderGetMuxRateBound);
cellPamf->AddFunc(0x37f723f7, cellPamfReaderGetNumberOfStreams);
cellPamf->AddFunc(0xd0230671, cellPamfReaderGetNumberOfSpecificStreams);
cellPamf->AddFunc(0x461534b4, cellPamfReaderSetStreamWithIndex);
cellPamf->AddFunc(0x03fd2caa, cellPamfReaderSetStreamWithTypeAndChannel);
cellPamf->AddFunc(0x28b4e2c1, cellPamfReaderSetStreamWithTypeAndIndex);
cellPamf->AddFunc(0x01067e22, cellPamfStreamTypeToEsFilterId);
cellPamf->AddFunc(0x041cc708, cellPamfReaderGetStreamIndex);
cellPamf->AddFunc(0x9ab20793, cellPamfReaderGetStreamTypeAndChannel);
cellPamf->AddFunc(0x71df326a, cellPamfReaderGetEsFilterId);
cellPamf->AddFunc(0x67fd273b, cellPamfReaderGetStreamInfo);
cellPamf->AddFunc(0xd9ea3457, cellPamfReaderGetNumberOfEp);
cellPamf->AddFunc(0xe8586ec6, cellPamfReaderGetEpIteratorWithIndex);
cellPamf->AddFunc(0x439fba17, cellPamfReaderGetEpIteratorWithTimeStamp);
cellPamf->AddFunc(0x1abeb9d6, cellPamfEpIteratorGetEp);
cellPamf->AddFunc(0x50b83205, cellPamfEpIteratorMove);
}