2013-09-28 04:36:57 +02:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Emu/SysCalls/SysCalls.h"
|
|
|
|
|
#include "Emu/SysCalls/SC_FUNC.h"
|
2014-03-03 00:02:42 +01:00
|
|
|
#include "cellPamf.h"
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
|
{
|
|
|
|
|
#include "libavcodec\avcodec.h"
|
|
|
|
|
#include "libavformat\avformat.h"
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 03:16:17 +01:00
|
|
|
#include "cellAdec.h"
|
2013-09-28 04:36:57 +02:00
|
|
|
|
|
|
|
|
void cellAdec_init();
|
|
|
|
|
Module cellAdec(0x0006, cellAdec_init);
|
|
|
|
|
|
2014-03-03 00:02:42 +01:00
|
|
|
u32 adecOpen(AudioDecoder* data)
|
|
|
|
|
{
|
|
|
|
|
AudioDecoder& adec = *data;
|
|
|
|
|
|
|
|
|
|
u32 adec_id = cellAdec.GetNewId(data);
|
|
|
|
|
|
|
|
|
|
adec.id = adec_id;
|
|
|
|
|
|
|
|
|
|
thread t("Audio Decoder[" + std::to_string(adec_id) + "] Thread", [&]()
|
|
|
|
|
{
|
|
|
|
|
ConLog.Write("Audio Decoder enter()");
|
|
|
|
|
|
|
|
|
|
AdecTask task;
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (Emu.IsStopped())
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (adec.job.IsEmpty() && adec.is_running)
|
|
|
|
|
{
|
|
|
|
|
Sleep(1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (adec.frames.GetCount() >= 50)
|
|
|
|
|
{
|
|
|
|
|
Sleep(1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!adec.job.Pop(task))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (task.type)
|
|
|
|
|
{
|
|
|
|
|
case adecStartSeq:
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case adecEndSeq:
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case adecDecodeAu:
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case adecClose:
|
|
|
|
|
{
|
|
|
|
|
adec.is_finished = true;
|
|
|
|
|
ConLog.Write("Audio Decoder exit");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
ConLog.Error("Audio Decoder error: unknown task(%d)", task.type);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ConLog.Warning("Audio Decoder aborted");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
t.detach();
|
|
|
|
|
|
|
|
|
|
return adec_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool adecCheckType(AudioCodecType type)
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case CELL_ADEC_TYPE_ATRACX: ConLog.Write("*** (???) type: ATRAC3plus"); break;
|
|
|
|
|
case CELL_ADEC_TYPE_ATRACX_2CH: ConLog.Write("*** type: ATRAC3plus 2ch"); break;
|
|
|
|
|
|
|
|
|
|
case CELL_ADEC_TYPE_ATRACX_6CH:
|
|
|
|
|
case CELL_ADEC_TYPE_ATRACX_8CH:
|
|
|
|
|
case CELL_ADEC_TYPE_LPCM_PAMF:
|
|
|
|
|
case CELL_ADEC_TYPE_AC3:
|
|
|
|
|
case CELL_ADEC_TYPE_MP3:
|
|
|
|
|
case CELL_ADEC_TYPE_ATRAC3:
|
|
|
|
|
case CELL_ADEC_TYPE_MPEG_L2:
|
|
|
|
|
case CELL_ADEC_TYPE_CELP:
|
|
|
|
|
case CELL_ADEC_TYPE_M4AAC:
|
|
|
|
|
case CELL_ADEC_TYPE_CELP8:
|
|
|
|
|
cellAdec.Error("Unimplemented audio codec type (%d)", type);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecQueryAttr(mem_ptr_t<CellAdecType> type, mem_ptr_t<CellAdecAttr> attr)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Warning("cellAdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.GetAddr(), attr.GetAddr());
|
|
|
|
|
|
|
|
|
|
if (!type.IsGood() || !attr.IsGood())
|
|
|
|
|
{
|
|
|
|
|
return CELL_ADEC_ERROR_FATAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
|
|
|
|
|
|
|
|
|
|
// TODO: check values
|
|
|
|
|
attr->adecVerLower = 0x280000; // from dmux
|
|
|
|
|
attr->adecVerUpper = 0x260000;
|
|
|
|
|
attr->workMemSize = 4 * 1024 * 1024;
|
|
|
|
|
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecOpen(mem_ptr_t<CellAdecType> type, mem_ptr_t<CellAdecResource> res, mem_ptr_t<CellAdecCb> cb, mem32_t handle)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Warning("cellAdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)",
|
2014-02-20 13:13:02 +01:00
|
|
|
type.GetAddr(), res.GetAddr(), cb.GetAddr(), handle.GetAddr());
|
2014-03-03 00:02:42 +01:00
|
|
|
|
|
|
|
|
if (!type.IsGood() || !res.IsGood() || !cb.IsGood() || !handle.IsGood())
|
|
|
|
|
{
|
|
|
|
|
return CELL_ADEC_ERROR_FATAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
|
|
|
|
|
|
|
|
|
|
handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg));
|
|
|
|
|
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecOpenEx(mem_ptr_t<CellAdecType> type, mem_ptr_t<CellAdecResourceEx> res, mem_ptr_t<CellAdecCb> cb, mem32_t handle)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Warning("cellAdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)",
|
2014-02-20 13:13:02 +01:00
|
|
|
type.GetAddr(), res.GetAddr(), cb.GetAddr(), handle.GetAddr());
|
2014-03-03 00:02:42 +01:00
|
|
|
|
|
|
|
|
if (!type.IsGood() || !res.IsGood() || !cb.IsGood() || !handle.IsGood())
|
|
|
|
|
{
|
|
|
|
|
return CELL_ADEC_ERROR_FATAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
|
|
|
|
|
|
|
|
|
|
handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg));
|
|
|
|
|
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecClose(u32 handle)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Warning("cellAdecClose(handle=%d)", handle);
|
|
|
|
|
|
|
|
|
|
AudioDecoder* adec;
|
|
|
|
|
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
|
|
|
|
{
|
|
|
|
|
return CELL_ADEC_ERROR_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adec->job.Push(AdecTask(adecClose));
|
|
|
|
|
|
|
|
|
|
while (!adec->is_finished || !adec->frames.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
if (Emu.IsStopped())
|
|
|
|
|
{
|
|
|
|
|
ConLog.Warning("cellAdecClose(%d) aborted", handle);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Sleep(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Emu.GetIdManager().RemoveID(handle);
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecStartSeq(u32 handle, u32 param_addr)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Error("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr);
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecEndSeq(u32 handle)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Error("cellAdecEndSeq(handle=%d)", handle);
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecDecodeAu(u32 handle, mem_ptr_t<CellAdecAuInfo> auInfo)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Error("cellAdecDecodeAu(handle=%d, auInfo_addr=0x%x)", handle, auInfo.GetAddr());
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecGetPcm(u32 handle, u32 outBuffer_addr)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Error("cellAdecGetPcm(handle=%d, outBuffer_addr=0x%x)", handle, outBuffer_addr);
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-20 13:13:02 +01:00
|
|
|
int cellAdecGetPcmItem(u32 handle, u32 pcmItem_ptr_addr)
|
2013-09-28 04:36:57 +02:00
|
|
|
{
|
2014-03-03 00:02:42 +01:00
|
|
|
cellAdec.Error("cellAdecGetPcmItem(handle=%d, pcmItem_ptr_addr=0x%x)", handle, pcmItem_ptr_addr);
|
2013-09-28 04:36:57 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cellAdec_init()
|
|
|
|
|
{
|
|
|
|
|
cellAdec.AddFunc(0x7e4a4a49, cellAdecQueryAttr);
|
|
|
|
|
cellAdec.AddFunc(0xd00a6988, cellAdecOpen);
|
|
|
|
|
cellAdec.AddFunc(0x8b5551a4, cellAdecOpenEx);
|
|
|
|
|
cellAdec.AddFunc(0x847d2380, cellAdecClose);
|
|
|
|
|
cellAdec.AddFunc(0x487b613e, cellAdecStartSeq);
|
|
|
|
|
cellAdec.AddFunc(0xe2ea549b, cellAdecEndSeq);
|
|
|
|
|
cellAdec.AddFunc(0x1529e506, cellAdecDecodeAu);
|
|
|
|
|
cellAdec.AddFunc(0x97ff2af1, cellAdecGetPcm);
|
|
|
|
|
cellAdec.AddFunc(0xbd75f78b, cellAdecGetPcmItem);
|
2014-03-03 00:02:42 +01:00
|
|
|
|
|
|
|
|
av_register_all();
|
|
|
|
|
avcodec_register_all();
|
2013-09-28 04:36:57 +02:00
|
|
|
}
|