mirror of
https://github.com/libretro/ppsspp.git
synced 2024-12-04 15:06:25 +00:00
Merge pull request #6178 from unknownbrackets/audiocodec-fix
Cleanup sceAudiocodec some
This commit is contained in:
commit
770d0d7adb
@ -35,50 +35,54 @@ struct AudioCodecContext {
|
||||
};
|
||||
|
||||
// audioList is to store current playing audios.
|
||||
// TODO: Why is this a list and not a map?
|
||||
static std::list<SimpleAudio *> audioList;
|
||||
static std::map<u32, SimpleAudio *> audioList;
|
||||
|
||||
static bool oldStateLoaded = false;
|
||||
|
||||
// find the audio decoder for corresponding ctxPtr in audioList
|
||||
SimpleAudio * findDecoder(u32 ctxPtr){
|
||||
for (std::list<SimpleAudio *>::iterator it = audioList.begin(); it != audioList.end(); it++){
|
||||
if ((*it)->ctxPtr == ctxPtr){
|
||||
return (*it);
|
||||
}
|
||||
static SimpleAudio *findDecoder(u32 ctxPtr) {
|
||||
auto it = audioList.find(ctxPtr);
|
||||
if (it != audioList.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// remove decoder from audioList
|
||||
bool removeDecoder(u32 ctxPtr){
|
||||
for (std::list<SimpleAudio *>::iterator it = audioList.begin(); it != audioList.end(); it++){
|
||||
if ((*it)->ctxPtr == ctxPtr){
|
||||
delete *it;
|
||||
audioList.erase(it);
|
||||
return true;
|
||||
}
|
||||
static bool removeDecoder(u32 ctxPtr) {
|
||||
auto it = audioList.find(ctxPtr);
|
||||
if (it != audioList.end()) {
|
||||
delete it->second;
|
||||
audioList.erase(it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void clearDecoders() {
|
||||
for (auto it = audioList.begin(), end = audioList.end(); it != end; it++) {
|
||||
delete it->second;
|
||||
}
|
||||
audioList.clear();
|
||||
}
|
||||
|
||||
void __AudioCodecInit() {
|
||||
oldStateLoaded = false;
|
||||
}
|
||||
|
||||
void __AudioCodecShutdown() {
|
||||
// We need to kill off any still opened codecs to not leak memory.
|
||||
for (std::list<SimpleAudio *>::iterator it = audioList.begin(); it != audioList.end(); it++){
|
||||
delete *it;
|
||||
}
|
||||
audioList.clear();
|
||||
clearDecoders();
|
||||
}
|
||||
|
||||
int sceAudiocodecInit(u32 ctxPtr, int codec) {
|
||||
if (isValidCodec(codec)){
|
||||
if (isValidCodec(codec)) {
|
||||
// Create audio decoder for given audio codec and push it into AudioList
|
||||
if (removeDecoder(ctxPtr)) {
|
||||
WARN_LOG_REPORT(HLE, "sceAudiocodecInit(%08x, %d): replacing existing context", ctxPtr, codec);
|
||||
}
|
||||
auto decoder = new SimpleAudio(ctxPtr, codec);
|
||||
audioList.push_front(decoder);
|
||||
audioList[ctxPtr] = decoder;
|
||||
INFO_LOG(ME, "sceAudiocodecInit(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
|
||||
DEBUG_LOG(ME, "Number of playing sceAudioCodec audios : %d", (int)audioList.size());
|
||||
return 0;
|
||||
@ -95,24 +99,23 @@ int sceAudiocodecDecode(u32 ctxPtr, int codec) {
|
||||
|
||||
if (isValidCodec(codec)){
|
||||
// Use SimpleAudioDec to decode audio
|
||||
AudioCodecContext ctx; // On stack, no need to allocate.
|
||||
Memory::ReadStruct(ctxPtr, &ctx);
|
||||
auto ctx = PSPPointer<AudioCodecContext>::Create(ctxPtr); // On stack, no need to allocate.
|
||||
int outbytes = 0;
|
||||
// find a decoder in audioList
|
||||
auto decoder = findDecoder(ctxPtr);
|
||||
|
||||
if (!decoder && oldStateLoaded) {
|
||||
// We must have loaded an old state that did not have sceAudioCodec information.
|
||||
// We must have loaded an old state that did not have sceAudiocodec information.
|
||||
// Fake it by creating the desired context.
|
||||
decoder = new SimpleAudio(ctxPtr, codec);
|
||||
audioList.push_front(decoder);
|
||||
audioList[ctxPtr] = decoder;
|
||||
}
|
||||
|
||||
if (decoder != NULL){
|
||||
if (decoder != NULL) {
|
||||
// Decode audio
|
||||
decoder->Decode(Memory::GetPointer(ctx.inDataPtr), ctx.inDataSize, Memory::GetPointer(ctx.outDataPtr), &outbytes);
|
||||
DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
|
||||
decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, Memory::GetPointer(ctx->outDataPtr), &outbytes);
|
||||
}
|
||||
DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
|
||||
return 0;
|
||||
}
|
||||
ERROR_LOG_REPORT(ME, "UNIMPL sceAudiocodecDecode(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
|
||||
@ -170,6 +173,8 @@ void __sceAudiocodecDoState(PointerWrap &p){
|
||||
|
||||
if (count > 0) {
|
||||
if (p.mode == PointerWrap::MODE_READ) {
|
||||
clearDecoders();
|
||||
|
||||
// loadstate if audioList is nonempty
|
||||
auto codec_ = new int[count];
|
||||
auto ctxPtr_ = new u32[count];
|
||||
@ -177,7 +182,7 @@ void __sceAudiocodecDoState(PointerWrap &p){
|
||||
p.DoArray(ctxPtr_, s >= 2 ? count : (int)ARRAY_SIZE(ctxPtr_));
|
||||
for (int i = 0; i < count; i++) {
|
||||
auto decoder = new SimpleAudio(ctxPtr_[i], codec_[i]);
|
||||
audioList.push_front(decoder);
|
||||
audioList[ctxPtr_[i]] = decoder;
|
||||
}
|
||||
delete[] codec_;
|
||||
delete[] ctxPtr_;
|
||||
@ -189,8 +194,8 @@ void __sceAudiocodecDoState(PointerWrap &p){
|
||||
auto codec_ = new int[count];
|
||||
auto ctxPtr_ = new u32[count];
|
||||
int i = 0;
|
||||
for (auto it = audioList.begin(); it != audioList.end(); it++) {
|
||||
const SimpleAudio *decoder = *it;
|
||||
for (auto it = audioList.begin(), end = audioList.end(); it != end; it++) {
|
||||
const SimpleAudio *decoder = it->second;
|
||||
codec_[i] = decoder->audioType;
|
||||
ctxPtr_[i] = decoder->ctxPtr;
|
||||
i++;
|
||||
@ -202,8 +207,3 @@ void __sceAudiocodecDoState(PointerWrap &p){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resetAudioList(){
|
||||
audioList.clear();
|
||||
INFO_LOG(ME, "Audio playing list is reset");
|
||||
}
|
||||
|
@ -59,5 +59,4 @@ typedef struct
|
||||
void __AudioCodecInit();
|
||||
void __AudioCodecShutdown();
|
||||
void Register_sceAudiocodec();
|
||||
void resetAudioList();
|
||||
void __sceAudiocodecDoState(PointerWrap &p);
|
@ -32,11 +32,10 @@ extern "C" {
|
||||
|
||||
#endif // USE_FFMPEG
|
||||
|
||||
bool SimpleAudio::GetAudioCodecID(int audioType){
|
||||
bool SimpleAudio::GetAudioCodecID(int audioType) {
|
||||
#ifdef USE_FFMPEG
|
||||
|
||||
switch (audioType)
|
||||
{
|
||||
switch (audioType) {
|
||||
case PSP_CODEC_AAC:
|
||||
audioCodecId = AV_CODEC_ID_AAC;
|
||||
break;
|
||||
@ -53,7 +52,7 @@ bool SimpleAudio::GetAudioCodecID(int audioType){
|
||||
audioType = 0;
|
||||
break;
|
||||
}
|
||||
if (audioType != 0){
|
||||
if (audioType != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -63,49 +62,17 @@ bool SimpleAudio::GetAudioCodecID(int audioType){
|
||||
}
|
||||
|
||||
SimpleAudio::SimpleAudio(int audioType)
|
||||
: codec_(0), codecCtx_(0), swrCtx_(0), audioType(audioType), outSamples(0), wanted_resample_freq(44100){
|
||||
#ifdef USE_FFMPEG
|
||||
avcodec_register_all();
|
||||
av_register_all();
|
||||
InitFFmpeg();
|
||||
|
||||
frame_ = av_frame_alloc();
|
||||
|
||||
// Get Audio Codec ID
|
||||
if (!GetAudioCodecID(audioType)){
|
||||
ERROR_LOG(ME, "This version of FFMPEG does not support Audio codec type: %08x. Update your submodule.", audioType);
|
||||
return;
|
||||
}
|
||||
// Find decoder
|
||||
codec_ = avcodec_find_decoder(audioCodecId);
|
||||
if (!codec_) {
|
||||
// Eh, we shouldn't even have managed to compile. But meh.
|
||||
ERROR_LOG(ME, "This version of FFMPEG does not support AV_CODEC_ID for audio (%s). Update your submodule.", GetCodecName(audioType));
|
||||
return;
|
||||
}
|
||||
// Allocate codec context
|
||||
codecCtx_ = avcodec_alloc_context3(codec_);
|
||||
if (!codecCtx_) {
|
||||
ERROR_LOG(ME, "Failed to allocate a codec context");
|
||||
return;
|
||||
}
|
||||
codecCtx_->channels = 2;
|
||||
codecCtx_->channel_layout = AV_CH_LAYOUT_STEREO;
|
||||
codecCtx_->sample_rate = 44100;
|
||||
// Open codec
|
||||
AVDictionary *opts = 0;
|
||||
if (avcodec_open2(codecCtx_, codec_, &opts) < 0) {
|
||||
ERROR_LOG(ME, "Failed to open codec");
|
||||
return;
|
||||
}
|
||||
|
||||
av_dict_free(&opts);
|
||||
#endif // USE_FFMPEG
|
||||
: codec_(0), codecCtx_(0), swrCtx_(0), audioType(audioType), outSamples(0), wanted_resample_freq(44100) {
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
SimpleAudio::SimpleAudio(u32 ctxPtr, int audioType)
|
||||
: codec_(0), codecCtx_(0), swrCtx_(0), ctxPtr(ctxPtr), audioType(audioType), outSamples(0), wanted_resample_freq(44100){
|
||||
: codec_(0), codecCtx_(0), swrCtx_(0), ctxPtr(ctxPtr), audioType(audioType), outSamples(0), wanted_resample_freq(44100) {
|
||||
Init();
|
||||
}
|
||||
|
||||
void SimpleAudio::Init() {
|
||||
#ifdef USE_FFMPEG
|
||||
avcodec_register_all();
|
||||
av_register_all();
|
||||
|
@ -46,8 +46,8 @@ extern "C" {
|
||||
|
||||
struct SimpleAudio {
|
||||
public:
|
||||
SimpleAudio(int);
|
||||
SimpleAudio(u32, int);
|
||||
SimpleAudio(int audioType);
|
||||
SimpleAudio(u32 ctxPtr, int audioType);
|
||||
~SimpleAudio();
|
||||
|
||||
bool Decode(void* inbuf, int inbytes, uint8_t *outbuf, int *outbytes);
|
||||
@ -72,6 +72,9 @@ public:
|
||||
|
||||
bool GetAudioCodecID(int audioType); // Get audioCodecId from audioType
|
||||
#endif // USE_FFMPEG
|
||||
|
||||
private:
|
||||
void Init();
|
||||
};
|
||||
|
||||
// audioType
|
||||
|
@ -418,7 +418,6 @@ void PSP_Shutdown() {
|
||||
CPU_Shutdown();
|
||||
}
|
||||
GPU_Shutdown();
|
||||
resetAudioList();
|
||||
host->SetWindowTitle(0);
|
||||
currentMIPS = 0;
|
||||
pspIsInited = false;
|
||||
|
Loading…
Reference in New Issue
Block a user