From 1127c721246e9a493a05a15c79f59df43cfa0829 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Mon, 12 Nov 2012 20:53:16 +0100 Subject: [PATCH] some initial mediaengine work --- Common/Log.h | 1 + Common/LogManager.cpp | 1 + Core/CMakeLists.txt | 1 + Core/Core.vcxproj | 2 + Core/Core.vcxproj.filters | 6 + Core/HLE/FunctionWrappers.h | 5 + Core/HLE/sceKernelThread.cpp | 2 +- Core/HLE/sceMpeg.cpp | 396 ++++++++++++++++++++++++++++------- Core/HW/MediaEngine.cpp | 18 ++ Core/HW/MediaEngine.h | 43 ++++ android/jni/Android.mk | 1 + 11 files changed, 403 insertions(+), 73 deletions(-) create mode 100644 Core/HW/MediaEngine.cpp create mode 100644 Core/HW/MediaEngine.h diff --git a/Common/Log.h b/Common/Log.h index 742a96d912..1ccd8f0bdb 100644 --- a/Common/Log.h +++ b/Common/Log.h @@ -46,6 +46,7 @@ enum LOG_TYPE { VIDEO, DYNA_REC, NETPLAY, + ME, NUMBER_OF_LOGS, // Must be last JIT = DYNA_REC, diff --git a/Common/LogManager.cpp b/Common/LogManager.cpp index 060ab25905..f5cbd0cf74 100644 --- a/Common/LogManager.cpp +++ b/Common/LogManager.cpp @@ -58,6 +58,7 @@ LogManager::LogManager() m_Log[LogTypes::VIDEO] = new LogContainer("VID", "Video"); m_Log[LogTypes::DYNA_REC] = new LogContainer("Jit", "JIT compiler"); m_Log[LogTypes::NETPLAY] = new LogContainer("NET", "Net play"); + m_Log[LogTypes::ME] = new LogContainer("ME", "Media Engine"); #ifndef ANDROID m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str()); diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index bbf5e38704..41bd09e3f0 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -49,6 +49,7 @@ set(SRCS HLE/sceUmd.cpp HLE/sceUtility.cpp HW/MemoryStick.cpp + HW/MediaEngine.cpp FileSystems/BlockDevices.cpp FileSystems/ISOFileSystem.cpp FileSystems/DirectoryFileSystem.cpp diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 426a12c298..1500e3c14d 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -160,6 +160,7 @@ + @@ -290,6 +291,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index a29237c2a8..f2c60896de 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -291,6 +291,9 @@ HLE\Libraries + + HW + @@ -530,6 +533,9 @@ HLE\Libraries + + HW + diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index 1a33383cf0..ca01975ff8 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -173,3 +173,8 @@ template void WrapU_UUUUUU() { u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5)); RETURN(retval); } + +template void WrapU_UUUUUUU() { + u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5), PARAM(6)); + RETURN(retval); +} \ No newline at end of file diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 8b2e6c3c6f..e0680ff971 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1075,7 +1075,7 @@ SceUID __KernelGetCurThread() void sceKernelGetThreadId() { u32 retVal = currentThread->GetUID(); - DEBUG_LOG(HLE,"%i = sceKernelGetThreadId()", retVal); + // DEBUG_LOG(HLE,"%i = sceKernelGetThreadId()", retVal); RETURN(retVal); } diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index e3c9723830..430939079a 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -15,28 +15,334 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +// This code is part shamelessly "inspired" from JPSCP. + + #include "sceMpeg.h" #include "HLE.h" +#include "../HW/MediaEngine.h" + + +struct StreamInfo { + int id; + int type; +}; + +static bool useMediaEngine; + +// MPEG statics. +static const int PSMF_MAGIC = 0x464D5350; +static const int PSMF_VERSION_0012 = 0x32313030; +static const int PSMF_VERSION_0013 = 0x33313030; +static const int PSMF_VERSION_0014 = 0x34313030; +static const int PSMF_VERSION_0015 = 0x35313030; +static const int PSMF_STREAM_VERSION_OFFSET = 0x4; +static const int PSMF_STREAM_OFFSET_OFFSET = 0x8; +static const int PSMF_STREAM_SIZE_OFFSET = 0xC; +static const int PSMF_FIRST_TIMESTAMP_OFFSET = 0x56; +static const int PSMF_LAST_TIMESTAMP_OFFSET = 0x5C; +// MPEG AVC elementary stream. +static const int MPEG_AVC_ES_SIZE = 2048; // MPEG packet size. +// MPEG ATRAC elementary stream. +static const int MPEG_ATRAC_ES_SIZE = 2112; +static const int MPEG_ATRAC_ES_OUTPUT_SIZE = 8192; +// MPEG PCM elementary stream. +static const int MPEG_PCM_ES_SIZE = 320; +static const int MPEG_PCM_ES_OUTPUT_SIZE = 320; +// MPEG analysis results. +static const int MPEG_VERSION_0012 = 0; +static const int MPEG_VERSION_0013 = 1; +static const int MPEG_VERSION_0014 = 2; +static const int MPEG_VERSION_0015 = 3; +// MPEG streams. +static const int MPEG_AVC_STREAM = 0; +static const int MPEG_ATRAC_STREAM = 1; +static const int MPEG_PCM_STREAM = 2; +static const int MPEG_DATA_STREAM = 3; // Arbitrary user defined type. Can represent audio or video. +static const int MPEG_AUDIO_STREAM = 15; +static const int MPEG_AU_MODE_DECODE = 0; +static const int MPEG_AU_MODE_SKIP = 1; +static const int MPEG_MEMSIZE = 0x10000; // 64k. + +static const int MPEG_AVC_DECODE_SUCCESS = 1; // Internal value. +static const int MPEG_AVC_DECODE_ERROR_FATAL = -8; + +static const int atracDecodeDelay = 3000; // Microseconds +static const int avcDecodeDelay = 5400; // Microseconds +static const int mpegDecodeErrorDelay = 100; // Delay in Microseconds in case of decode error +static const int mpegTimestampPerSecond = 90000; // How many MPEG Timestamp units in a second. +static const int videoTimestampStep = 3003; // Value based on pmfplayer (mpegTimestampPerSecond / 29.970 (fps)). +static const int audioTimestampStep = 4180; // For audio play at 44100 Hz (2048 samples / 44100 * mpegTimestampPerSecond == 4180) +//static const int audioFirstTimestamp = 89249; // The first MPEG audio AU has always this timestamp +static const int audioFirstTimestamp = 90000; // The first MPEG audio AU has always this timestamp +static const s64 UNKNOWN_TIMESTAMP = -1; + +// At least 2048 bytes of MPEG data is provided when analysing the MPEG header +static const int MPEG_HEADER_BUFFER_MINIMUM_SIZE = 2048; + +// As native in PSP ram +struct SceMpegRingBuffer { + // PSP info + int packets; + int packetsRead; + int packetsWritten; + int packetsFree; // pspsdk: unk2, noxa: iUnk0 + int packetSize; // 2048 + int data; // address, ring buffer + u32 callback_addr; // see sceMpegRingbufferPut + int callback_args; + int dataUpperBound; + int semaID; // unused? + u32 mpeg; // pointer to mpeg struct, fixed up in sceMpegCreate +}; + +struct SceMpegAu { + s64 pts; // presentation time stamp + s64 dts; // decode time stamp + u32 esBuffer; + u32 esSize; +}; + +void InitRingbuffer(SceMpegRingBuffer *buf, int packets, int data, int size, int callback_addr, int callback_args) { + buf->packets = packets; + buf->packetsRead = 0; + buf->packetsWritten = 0; + buf->packetsFree = 0; // set later + buf->packetSize = 2048; + buf->data = data; + buf->callback_addr = callback_addr; + buf->callback_args = callback_args; + buf->dataUpperBound = data + packets * 2048; + buf->semaID = -1; + buf->mpeg = 0; +} + + +SceMpegRingBuffer mpegRingbuffer; +SceMpegAu mpegAtracAu; +SceMpegAu mpegAvcAu; + +bool isCurrentMpegAnalyzed; +static int mpegHandle; + +u32 mpegRingbufferAddr; +u32 mpegStreamAddr; + +u32 mpegMagic; +u32 mpegVersion; +u32 mpegRawVersion; +u32 mpegOffset; +u32 mpegStreamSize; +u32 mpegFirstTimestamp; +u32 mpegLastTimestamp; +u32 mpegFirstDate; +u32 mpegLastDate; +int avcDetailFrameWidth; +int avcDetailFrameHeight; +int avcDecodeResult; +int avcFrameStatus; +u32 defaultFrameWidth; +int videoFrameCount = 0; +int audioFrameCount = 0; +bool endOfAudioReached = false; +bool endOfVideoReached = false; + + +MediaEngine me; + +u32 endianSwap32(u32 x) { + return x; // TODO +} + +u32 convertTimestampToDate(u32 ts) { + return ts; // TODO +} + +void AnalyzeMpeg(u32 buffer_addr) { + mpegStreamAddr = buffer_addr; + mpegMagic = Memory::Read_U32(buffer_addr); + mpegRawVersion = Memory::Read_U32(buffer_addr + PSMF_STREAM_VERSION_OFFSET); + switch (mpegRawVersion) { + case PSMF_VERSION_0012: + mpegVersion = MPEG_VERSION_0012; + break; + case PSMF_VERSION_0013: + mpegVersion = MPEG_VERSION_0013; + break; + case PSMF_VERSION_0014: + mpegVersion = MPEG_VERSION_0014; + break; + case PSMF_VERSION_0015: + mpegVersion = MPEG_VERSION_0015; + break; + default: + mpegVersion = -1; + break; + } + mpegOffset = endianSwap32(Memory::Read_U32(buffer_addr + PSMF_STREAM_OFFSET_OFFSET)); + mpegStreamSize = endianSwap32(Memory::Read_U32(buffer_addr + PSMF_STREAM_SIZE_OFFSET)); + mpegFirstTimestamp = endianSwap32(Memory::Read_U32(buffer_addr + PSMF_FIRST_TIMESTAMP_OFFSET)); + mpegLastTimestamp = endianSwap32(Memory::Read_U32(buffer_addr + PSMF_LAST_TIMESTAMP_OFFSET)); + mpegFirstDate = convertTimestampToDate(mpegFirstTimestamp); + mpegLastDate = convertTimestampToDate(mpegLastTimestamp); + avcDetailFrameWidth = (Memory::Read_U8(buffer_addr + 142) * 0x10); + avcDetailFrameHeight = (Memory::Read_U8(buffer_addr + 143) * 0x10); + avcDecodeResult = MPEG_AVC_DECODE_SUCCESS; + avcFrameStatus = 0; + if (!isCurrentMpegAnalyzed) { + InitRingbuffer(&mpegRingbuffer, 0, 0, 0, 0, 0); + // ???? + Memory::WriteStruct(mpegRingbufferAddr, &mpegRingbuffer); + } + + mpegAtracAu.dts = UNKNOWN_TIMESTAMP; + mpegAtracAu.pts = 0; + mpegAvcAu.dts = 0; + mpegAvcAu.pts = 0; + videoFrameCount = 0; + audioFrameCount = 0; + endOfAudioReached = false; + endOfVideoReached = false; + + if ((mpegStreamSize > 0) && !isCurrentMpegAnalyzed) { + me.init(buffer_addr, mpegStreamSize, mpegOffset); + //meChannel = new PacketChannel(); + //meChannel.write(buffer_addr, mpegOffset); + } + // When used with scePsmf, some applications attempt to use sceMpegQueryStreamOffset + // and sceMpegQueryStreamSize, which forces a packet overwrite in the Media Engine and in + // the MPEG ringbuffer. + // Mark the current MPEG as analyzed to filter this, and restore it at sceMpegFinish. + isCurrentMpegAnalyzed = true; + + INFO_LOG(ME, "Stream offset: %d, Stream size: 0x%X", mpegOffset, mpegStreamSize); + INFO_LOG(ME, "First timestamp: %d, Last timestamp: %d", mpegFirstTimestamp, mpegLastTimestamp); +} + + +void __MpegInit(bool useMediaEngine_) { + +} + + +void __MpegFinish() { + +} void sceMpegInit() { - WARN_LOG(HLE, "HACK sceMpegInit(...)"); + WARN_LOG(HLE, "sceMpegInit()"); + RETURN(0); } -void sceMpegCreate() + +u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr, u32 frameWidth, u32 mode, u32 ddrTop) { - WARN_LOG(HLE, "HACK sceMpegCreate(...)"); + INFO_LOG(HLE, "sceMpegCreate(%i, %08x, %i, %08x, %i, %i, %i)", + mpegAddr, dataPtr, size, ringbufferAddr, frameWidth, mode, ddrTop); + if (size < MPEG_MEMSIZE) { + return -1; + //return ERROR_MPEG_NO_MEMORY; + } + + SceMpegRingBuffer ringbuffer; + Memory::ReadStruct(ringbufferAddr, &ringbuffer); + if (ringbuffer.packetSize == 0) { + ringbuffer.packetsFree = 0; + } else { + ringbuffer.packetsFree = (ringbuffer.dataUpperBound - ringbuffer.data) / ringbuffer.packetSize; + } + ringbuffer.mpeg = mpegAddr; + Memory::WriteStruct(ringbufferAddr, &ringbuffer); + + // Generate, and write mpeg handle into mpeg data, for some reason + mpegHandle = dataPtr + 0x30; + Memory::Write_U32(mpegAddr, mpegHandle); + + Memory::Memcpy(mpegHandle, "LIBMPEG.001", 12); + Memory::Write_U32(-1, mpegHandle + 12); + Memory::Write_U32(ringbufferAddr, mpegHandle + 16); + Memory::Write_U32(ringbuffer.dataUpperBound, mpegHandle + 20); + + mpegRingbufferAddr = ringbufferAddr; + mpegRingbuffer = ringbuffer; + videoFrameCount = 0; + audioFrameCount = 0; + defaultFrameWidth = frameWidth; + + return 0; +} + +u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr, u32 initAddr) +{ + WARN_LOG(HLE, "sceMpegAvcDecode(%08x, %08x, %i, %08x, %08x)", mpeg, auAddr, frameWidth, bufferAddr, initAddr); + + // TODO + + return 0; +} + +u32 sceMpegAvcDecodeStop(u32 mpeg, u32 frameWidth, u32 bufferAddr, u32 statusAddr) +{ + WARN_LOG(HLE, "HACK sceMpegAvcDecodeStop(%08x, %08x, %08x, statusAddr=%08x)", + mpeg, frameWidth, bufferAddr, statusAddr); + + return 0; +} + +void sceMpegAvcDecodeMode() +{ + WARN_LOG(HLE, "HACK sceMpegAvcDecodeMode(...)"); RETURN(0); } + +void sceMpegAvcDecodeStopYCbCr() +{ + WARN_LOG(HLE, "HACK sceMpegAvcDecodeStopYCbCr(...)"); + RETURN(0); +} + +void sceMpegAvcDecodeYCbCr() +{ + WARN_LOG(HLE, "HACK sceMpegAvcDecodeYCbCr(...)"); + RETURN(0); +} + +void sceMpegAvcDecodeDetail() +{ + WARN_LOG(HLE, "HACK sceMpegAvcDecodeDetail(...)"); + RETURN(0); +} + +u32 sceMpegAvcDecodeFlush(u32 mpeg) +{ + ERROR_LOG(HLE, "UNIMPL sceMpegAvcDecodeFlush(%08x)", mpeg); + return 0; +} + void sceMpegInitAu() { WARN_LOG(HLE, "HACK sceMpegInitAu(...)"); RETURN(0); } +void sceMpegFinish() +{ + WARN_LOG(HLE, "sceMpegFinish(...)"); + __MpegFinish(); + RETURN(0); +} + +void sceMpegDelete() +{ + WARN_LOG(HLE, "HACK sceMpegDelete(...)"); + RETURN(0); +} + void sceMpegQueryMemSize() { - WARN_LOG(HLE, "HACK sceMpegQueryMemSize(...)"); + DEBUG_LOG(HLE, "sceMpegQueryMemSize()"); RETURN(0x10000); // 64K } @@ -137,48 +443,18 @@ void sceMpegAtracDecode() RETURN(0); } -void sceMpegAvcDecodeStop() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecodeStop(...)"); - RETURN(0); -} - -void sceMpegAvcDecodeMode() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecodeMode(...)"); - RETURN(0); -} - -void sceMpegAvcDecode() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecode(...)"); - RETURN(0); -} - void sceMpegAvcCsc() { WARN_LOG(HLE, "HACK sceMpegAvcCsc(...)"); RETURN(0); } -void sceMpegAvcDecodeStopYCbCr() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecodeStopYCbCr(...)"); - RETURN(0); -} - void sceMpegRingbufferDestruct() { WARN_LOG(HLE, "HACK sceMpegRingbufferDestruct(...)"); RETURN(0); } -void sceMpegAvcDecodeYCbCr() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecodeYCbCr(...)"); - RETURN(0); -} - void sceMpegRingbufferPut() { WARN_LOG(HLE, "HACK sceMpegRingbufferPut(...)"); @@ -203,30 +479,6 @@ void sceMpegRingbufferAvailableSize() RETURN(0); } -void sceMpegAvcDecodeDetail() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecodeDetail(...)"); - RETURN(0); -} - -void sceMpegAvcDecodeFlush() -{ - WARN_LOG(HLE, "HACK sceMpegAvcDecodeFlush(...)"); - RETURN(0); -} - -void sceMpegFinish() -{ - WARN_LOG(HLE, "HACK sceMpegFinish(...)"); - RETURN(0); -} - -void sceMpegDelete() -{ - WARN_LOG(HLE, "HACK sceMpegDelete(...)"); - RETURN(0); -} - void sceMpegGetAvcAu() { WARN_LOG(HLE, "HACK sceMpegDelete(...)"); @@ -243,7 +495,7 @@ const HLEFunction sceMpeg[] = { {0xe1ce83a7,sceMpegGetAtracAu,"sceMpegGetAtracAu"}, {0xfe246728,sceMpegGetAvcAu,"sceMpegGetAvcAu"}, - {0xd8c5f121,sceMpegCreate,"sceMpegCreate"}, + {0xd8c5f121,&WrapU_UUUUUUU,"sceMpegCreate"}, {0xf8dcb679,sceMpegQueryAtracEsSize,"sceMpegQueryAtracEsSize"}, {0xc132e22f,sceMpegQueryMemSize,"sceMpegQueryMemSize"}, {0x21ff80e4,sceMpegQueryStreamOffset,"sceMpegQueryStreamOffset"}, @@ -255,28 +507,28 @@ const HLEFunction sceMpeg[] = {0xceb870b1,sceMpegFreeAvcEsBuf,"sceMpegFreeAvcEsBuf"}, {0x167afd9e,sceMpegInitAu,"sceMpegInitAu"}, {0x682a619b,sceMpegInit,"sceMpegInit"}, + {0x606a4649,sceMpegDelete,"sceMpegDelete"}, + {0x874624d6,sceMpegFinish,"sceMpegFinish"}, {0x800c44df,sceMpegAtracDecode,"sceMpegAtracDecode"}, - {0x740fccd1,sceMpegAvcDecodeStop,"sceMpegAvcDecodeStop"}, - {0x0e3c2e9d,sceMpegAvcDecode,"sceMpegAvcDecode"}, - {0xd7a29f46,sceMpegRingbufferQueryMemSize,"sceMpegRingbufferQueryMemSize"}, + {0x0e3c2e9d,&WrapU_UUUUU,"sceMpegAvcDecode"}, + {0x740fccd1,&WrapU_UUUU,"sceMpegAvcDecodeStop"}, + {0x4571cc64,&WrapU_U,"sceMpegAvcDecodeFlush"}, + {0x0f6c18d7,sceMpegAvcDecodeDetail,"sceMpegAvcDecodeDetail"}, + {0xf0eb1125,sceMpegAvcDecodeYCbCr,"sceMpegAvcDecodeYCbCr"}, + {0xf2930c9c,sceMpegAvcDecodeStopYCbCr,"sceMpegAvcDecodeStopYCbCr"}, + {0xa11c7026,sceMpegAvcDecodeMode,"sceMpegAvcDecodeMode"}, {0x37295ed8,sceMpegRingbufferConstruct,"sceMpegRingbufferConstruct"}, {0x13407f13,sceMpegRingbufferDestruct,"sceMpegRingbufferDestruct"}, {0xb240a59e,sceMpegRingbufferPut,"sceMpegRingbufferPut"}, {0xb5f6dc87,sceMpegRingbufferAvailableSize,"sceMpegRingbufferAvailableSize"}, - {0x606a4649,sceMpegDelete,"sceMpegDelete"}, - {0x874624d6,sceMpegFinish,"sceMpegFinish"}, - {0x4571cc64,sceMpegAvcDecodeFlush,"sceMpegAvcDecodeFlush"}, - {0x0f6c18d7,sceMpegAvcDecodeDetail,"sceMpegAvcDecodeDetail"}, + {0xd7a29f46,sceMpegRingbufferQueryMemSize,"sceMpegRingbufferQueryMemSize"}, + {0x769BEBB6,sceMpegRingbufferQueryPackNum,"sceMpegRingbufferQueryPackNum"}, + {0x31bd0272,sceMpegAvcCsc,"sceMpegAvcCsc"}, {0x211a057c,sceMpegAvcQueryYCbCrSize,"sceMpegAvcQueryYCbCrSize"}, {0x67179b1b,sceMpegAvcInitYCbCr,"sceMpegAvcInitYCbCr"}, - {0xf0eb1125,sceMpegAvcDecodeYCbCr,"sceMpegAvcDecodeYCbCr"}, - {0xf2930c9c,sceMpegAvcDecodeStopYCbCr,"sceMpegAvcDecodeStopYCbCr"}, - {0x31bd0272,sceMpegAvcCsc,"sceMpegAvcCsc"}, - {0xa11c7026,sceMpegAvcDecodeMode,"sceMpegAvcDecodeMode"}, {0x0558B075,sceMpegAvcCopyYCbCr,"sceMpegAvcCopyYCbCr"}, - {0x769BEBB6,sceMpegRingbufferQueryPackNum,"sceMpegRingbufferQueryPackNum"}, - {0x8C1E027D,sceMpegGetPcmAu,"sceMpegGetPcmAu"}, {0x9DCFB7EA,sceMpegChangeGetAuMode,"sceMpegChangeGetAuMode"}, + {0x8C1E027D,sceMpegGetPcmAu,"sceMpegGetPcmAu"}, {0xC02CF6B5,sceMpegQueryPcmEsSize,"sceMpegQueryPcmEsSize"}, }; diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp new file mode 100644 index 0000000000..8243398391 --- /dev/null +++ b/Core/HW/MediaEngine.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "MediaEngine.h" \ No newline at end of file diff --git a/Core/HW/MediaEngine.h b/Core/HW/MediaEngine.h new file mode 100644 index 0000000000..393505b881 --- /dev/null +++ b/Core/HW/MediaEngine.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + + + +// Simulation of the hardware video/audio decoders. +// The idea is high level emulation where we simply use FFMPEG. + +#pragma once + +// An approximation of what the interface will look like. Similar to JPCSP's. + +#include "../../Globals.h" + +class MediaEngine +{ +public: + void init(u32 bufferAddr, u32 mpegStreamSize, u32 mpegOffset) { + bufferAddr_ = bufferAddr; + mpegStreamSize_ = mpegStreamSize; + mpegOffset_ = mpegOffset; + } + void finish(); + +private: + u32 bufferAddr_; + u32 mpegStreamSize_; + u32 mpegOffset_; +}; diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 5b0680bccf..ea81e6ba1f 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -80,6 +80,7 @@ LOCAL_SRC_FILES := \ $(SRC)/Core/ELF/ElfReader.cpp \ $(SRC)/Core/ELF/PrxDecrypter.cpp \ $(SRC)/Core/HW/MemoryStick.cpp \ + $(SRC)/Core/HW/MediaEngine.cpp \ $(SRC)/Core/Core.cpp \ $(SRC)/Core/Config.cpp \ $(SRC)/Core/CoreTiming.cpp \