mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #4308 from unknownbrackets/mp3-minor
Fix mp3 savestates and savestate backwards compat
This commit is contained in:
commit
00ee8847e8
4 files changed
+110
-56
No files matched your search
+13
-2
@@ -25,6 +25,10 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
|
||||
#ifndef _XBOX
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#endif
|
||||
|
||||
#include "Common/Thread.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
@@ -179,7 +183,7 @@ void __DisplayInit() {
|
||||
}
|
||||
|
||||
void __DisplayDoState(PointerWrap &p) {
|
||||
auto s = p.Section("sceDisplay", 1);
|
||||
auto s = p.Section("sceDisplay", 1, 2);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
@@ -205,10 +209,17 @@ void __DisplayDoState(PointerWrap &p) {
|
||||
p.Do(leaveVblankEvent);
|
||||
CoreTiming::RestoreRegisterEvent(leaveVblankEvent, "LeaveVBlank", &hleLeaveVblank);
|
||||
p.Do(afterFlipEvent);
|
||||
CoreTiming::RestoreRegisterEvent(afterFlipEvent, "AfterFlipEVent", &hleAfterFlip);
|
||||
CoreTiming::RestoreRegisterEvent(afterFlipEvent, "AfterFlip", &hleAfterFlip);
|
||||
|
||||
p.Do(gstate);
|
||||
p.Do(gstate_c);
|
||||
#ifndef _XBOX
|
||||
if (s < 2) {
|
||||
// This shouldn't have been savestated anyway, but it was.
|
||||
// It's unlikely to overlap with the first value in gpuStats.
|
||||
p.ExpectVoid(&gl_extensions.gpuVendor, sizeof(gl_extensions.gpuVendor));
|
||||
}
|
||||
#endif
|
||||
p.Do(gpuStats);
|
||||
gpu->DoState(p);
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "sceKernelEventFlag.h"
|
||||
#include "sceKernelVTimer.h"
|
||||
#include "sceKernelTime.h"
|
||||
#include "sceMp3.h"
|
||||
#include "sceMpeg.h"
|
||||
#include "sceNet.h"
|
||||
#include "sceNetAdhoc.h"
|
||||
@@ -157,6 +158,7 @@ void __KernelShutdown()
|
||||
__NetAdhocShutdown();
|
||||
__FontShutdown();
|
||||
|
||||
__Mp3Shutdown();
|
||||
__MpegShutdown();
|
||||
__PsmfShutdown();
|
||||
__PPGeShutdown();
|
||||
@@ -231,6 +233,7 @@ void __KernelDoState(PointerWrap &p)
|
||||
__ImposeDoState(p);
|
||||
__IoDoState(p);
|
||||
__JpegDoState(p);
|
||||
__Mp3DoState(p);
|
||||
__MpegDoState(p);
|
||||
__NetDoState(p);
|
||||
__NetAdhocDoState(p);
|
||||
|
||||
+88
-53
@@ -22,7 +22,6 @@
|
||||
#include "Core/HLE/sceMp3.h"
|
||||
#include "Core/HW/MediaEngine.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/HW/MediaEngine.h"
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
#ifndef PRId64
|
||||
@@ -40,11 +39,37 @@ extern "C" {
|
||||
|
||||
static const int MP3_BITRATES[] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320};
|
||||
|
||||
struct Mp3Context;
|
||||
int __Mp3InitContext(Mp3Context *ctx);
|
||||
|
||||
struct Mp3Context {
|
||||
Mp3Context()
|
||||
#ifdef USE_FFMPEG
|
||||
: avformat_context(NULL), avio_context(NULL), resampler_context(NULL) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
}
|
||||
|
||||
~Mp3Context() {
|
||||
#ifdef USE_FFMPEG
|
||||
if (avio_context != NULL) {
|
||||
av_free(avio_context->buffer);
|
||||
av_free(avio_context);
|
||||
}
|
||||
if (avformat_context != NULL) {
|
||||
avformat_free_context(avformat_context);
|
||||
}
|
||||
if (resampler_context != NULL) {
|
||||
swr_free(&resampler_context);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DoState(PointerWrap &p) {
|
||||
auto s = p.Section("Mp3Context", 1, 2);
|
||||
if (!s)
|
||||
return;
|
||||
auto s = p.Section("Mp3Context", 1);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
p.Do(mp3StreamStart);
|
||||
p.Do(mp3StreamEnd);
|
||||
@@ -52,18 +77,20 @@ struct Mp3Context {
|
||||
p.Do(mp3BufSize);
|
||||
p.Do(mp3PcmBuf);
|
||||
p.Do(mp3PcmBufSize);
|
||||
p.Do(readPosition);
|
||||
p.Do(bufferRead);
|
||||
p.Do(bufferWrite);
|
||||
p.Do(bufferAvailable);
|
||||
p.Do(mp3DecodedBytes);
|
||||
if (s >= 2)
|
||||
p.Do(mp3SumDecodedSamples);
|
||||
else
|
||||
mp3SumDecodedSamples = 0;
|
||||
p.Do(mp3LoopNum);
|
||||
p.Do(mp3MaxSamples);
|
||||
p.Do(mp3Bitrate);
|
||||
p.Do(mp3SumDecodedSamples);
|
||||
p.Do(mp3Channels);
|
||||
p.Do(mp3Bitrate);
|
||||
p.Do(mp3SamplingRate);
|
||||
p.Do(mp3Version);
|
||||
p.DoClass(mediaengine);
|
||||
|
||||
__Mp3InitContext(this);
|
||||
}
|
||||
|
||||
int mp3StreamStart;
|
||||
@@ -83,7 +110,6 @@ struct Mp3Context {
|
||||
int mp3LoopNum;
|
||||
int mp3MaxSamples;
|
||||
int mp3SumDecodedSamples;
|
||||
MediaEngine *mediaengine;
|
||||
|
||||
int mp3Channels;
|
||||
int mp3Bitrate;
|
||||
@@ -99,19 +125,28 @@ struct Mp3Context {
|
||||
};
|
||||
|
||||
static std::map<u32, Mp3Context *> mp3Map;
|
||||
static u32 lastMp3Handle = 0;
|
||||
|
||||
Mp3Context *getMp3Ctx(u32 mp3) {
|
||||
if (mp3Map.find(mp3) == mp3Map.end()) {
|
||||
ERROR_LOG(ME, "Bad mp3 handle %08x - using last one (%08x) instead", mp3, lastMp3Handle);
|
||||
mp3 = lastMp3Handle;
|
||||
}
|
||||
|
||||
if (mp3Map.find(mp3) == mp3Map.end())
|
||||
return NULL;
|
||||
return mp3Map[mp3];
|
||||
}
|
||||
|
||||
void __Mp3Shutdown() {
|
||||
for (auto it = mp3Map.begin(), end = mp3Map.end(); it != end; ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
mp3Map.clear();
|
||||
}
|
||||
|
||||
void __Mp3DoState(PointerWrap &p) {
|
||||
auto s = p.Section("sceMp3", 0, 1);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
p.Do(mp3Map);
|
||||
}
|
||||
|
||||
/* MP3 */
|
||||
int sceMp3Decode(u32 mp3, u32 outPcmPtr) {
|
||||
DEBUG_LOG(ME, "sceMp3Decode(%08x,%08x)", mp3, outPcmPtr);
|
||||
@@ -236,7 +271,7 @@ int sceMp3CheckStreamDataNeeded(u32 mp3) {
|
||||
return ctx->bufferAvailable != ctx->mp3BufSize && ctx->readPosition < ctx->mp3StreamEnd;
|
||||
}
|
||||
|
||||
int readFunc(void *opaque, uint8_t *buf, int buf_size) {
|
||||
static int readFunc(void *opaque, uint8_t *buf, int buf_size) {
|
||||
Mp3Context *ctx = static_cast<Mp3Context*>(opaque);
|
||||
|
||||
int res = 0;
|
||||
@@ -300,11 +335,6 @@ u32 sceMp3ReserveMp3Handle(u32 mp3Addr) {
|
||||
ctx->mp3Bitrate = 128;
|
||||
ctx->mp3SamplingRate = 44100;
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
ctx->avformat_context = NULL;
|
||||
ctx->avio_context = NULL;
|
||||
#endif
|
||||
|
||||
mp3Map[mp3Addr] = ctx;
|
||||
return mp3Addr;
|
||||
}
|
||||
@@ -321,28 +351,10 @@ int sceMp3TermResource() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceMp3Init(u32 mp3) {
|
||||
DEBUG_LOG(ME, "sceMp3Init(%08x)", mp3);
|
||||
|
||||
Mp3Context *ctx = getMp3Ctx(mp3);
|
||||
if (!ctx) {
|
||||
ERROR_LOG(ME, "%s: bad mp3 handle %08x", __FUNCTION__, mp3);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read in the header and swap the endian
|
||||
int header = Memory::Read_U32(ctx->mp3Buf);
|
||||
header = (header >> 24) |
|
||||
((header<<8) & 0x00FF0000) |
|
||||
((header>>8) & 0x0000FF00) |
|
||||
(header << 24);
|
||||
|
||||
ctx->mp3Version = ((header >> 19) & 0x3);
|
||||
|
||||
int __Mp3InitContext(Mp3Context *ctx) {
|
||||
#ifdef USE_FFMPEG
|
||||
InitFFmpeg();
|
||||
|
||||
u8* avio_buffer = static_cast<u8*>(av_malloc(ctx->mp3BufSize));
|
||||
u8 *avio_buffer = static_cast<u8*>(av_malloc(ctx->mp3BufSize));
|
||||
ctx->avio_context = avio_alloc_context(avio_buffer, ctx->mp3BufSize, 0, ctx, readFunc, NULL, NULL);
|
||||
ctx->avformat_context = avformat_alloc_context();
|
||||
ctx->avformat_context->pb = ctx->avio_context;
|
||||
@@ -384,12 +396,6 @@ int sceMp3Init(u32 mp3) {
|
||||
ctx->decoder_context->sample_rate,
|
||||
0, NULL);
|
||||
|
||||
// Let's just grab this info from FFMPEG, it seems more reliable than the code above.
|
||||
|
||||
ctx->mp3SamplingRate = ctx->decoder_context->sample_rate;
|
||||
ctx->mp3Channels = ctx->decoder_context->channels;
|
||||
ctx->mp3Bitrate = ctx->decoder_context->bit_rate / 1000;
|
||||
|
||||
if (!ctx->resampler_context) {
|
||||
ERROR_LOG(ME, "Could not allocate resampler context %d", ret);
|
||||
return -1;
|
||||
@@ -400,6 +406,39 @@ int sceMp3Init(u32 mp3) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int sceMp3Init(u32 mp3) {
|
||||
DEBUG_LOG(ME, "sceMp3Init(%08x)", mp3);
|
||||
|
||||
Mp3Context *ctx = getMp3Ctx(mp3);
|
||||
if (!ctx) {
|
||||
ERROR_LOG(ME, "%s: bad mp3 handle %08x", __FUNCTION__, mp3);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read in the header and swap the endian
|
||||
int header = Memory::Read_U32(ctx->mp3Buf);
|
||||
header = (header >> 24) |
|
||||
((header<<8) & 0x00FF0000) |
|
||||
((header>>8) & 0x0000FF00) |
|
||||
(header << 24);
|
||||
|
||||
ctx->mp3Version = ((header >> 19) & 0x3);
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
int ret = __Mp3InitContext(ctx);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
// Let's just grab this info from FFMPEG, it seems more reliable than the code above.
|
||||
|
||||
ctx->mp3SamplingRate = ctx->decoder_context->sample_rate;
|
||||
ctx->mp3Channels = ctx->decoder_context->channels;
|
||||
ctx->mp3Bitrate = ctx->decoder_context->bit_rate / 1000;
|
||||
|
||||
av_dump_format(ctx->avformat_context, 0, "mp3", 0);
|
||||
#endif
|
||||
|
||||
@@ -549,10 +588,6 @@ int sceMp3ReleaseMp3Handle(u32 mp3) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
av_free(ctx->avio_context->buffer);
|
||||
av_free(ctx->avio_context);
|
||||
#endif
|
||||
mp3Map.erase(mp3Map.find(mp3));
|
||||
|
||||
delete ctx;
|
||||
|
||||
+6
-1
@@ -19,4 +19,9 @@
|
||||
|
||||
#include "HLE.h"
|
||||
|
||||
void Register_sceMp3();
|
||||
class PointerWrap;
|
||||
|
||||
void Register_sceMp3();
|
||||
|
||||
void __Mp3Shutdown();
|
||||
void __Mp3DoState(PointerWrap &p);
|
||||
Reference in new issue
Block a user