Merge pull request #6178 from unknownbrackets/audiocodec-fix

Cleanup sceAudiocodec some
This commit is contained in:
Henrik Rydgård 2014-05-29 20:04:25 +02:00
commit 770d0d7adb
5 changed files with 50 additions and 82 deletions

View File

@ -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");
}

View File

@ -59,5 +59,4 @@ typedef struct
void __AudioCodecInit();
void __AudioCodecShutdown();
void Register_sceAudiocodec();
void resetAudioList();
void __sceAudiocodecDoState(PointerWrap &p);

View File

@ -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();

View File

@ -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

View File

@ -418,7 +418,6 @@ void PSP_Shutdown() {
CPU_Shutdown();
}
GPU_Shutdown();
resetAudioList();
host->SetWindowTitle(0);
currentMIPS = 0;
pspIsInited = false;