Move BufferQueue out of the at3 plugin header

This commit is contained in:
Henrik Rydgård 2013-10-17 12:27:04 +02:00
parent fa1858ffaf
commit ac2334386a
9 changed files with 166 additions and 142 deletions

View File

@ -15,9 +15,6 @@
// Official git repository and contact information can be found at // Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
// This is pretty much a stub implementation. Doesn't actually do anything, just tries to return values
// to keep games happy anyway. So, no ATRAC3 music until someone has reverse engineered Atrac3+.
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPS.h"
@ -25,6 +22,7 @@
#include "Core/Reporting.h" #include "Core/Reporting.h"
#include "Core/Config.h" #include "Core/Config.h"
#include "Core/HW/MediaEngine.h" #include "Core/HW/MediaEngine.h"
#include "Core/HW/BufferQueue.h"
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "sceKernel.h" #include "sceKernel.h"
@ -250,7 +248,7 @@ struct Atrac {
InputBuffer first; InputBuffer first;
InputBuffer second; InputBuffer second;
Atrac3plus_Decoder::BufferQueue sampleQueue; BufferQueue sampleQueue;
void* decoder_context; void* decoder_context;
PSPPointer<SceAtracId> atracContext; PSPPointer<SceAtracId> atracContext;

120
Core/HW/BufferQueue.h Normal file
View File

@ -0,0 +1,120 @@
// Copyright (c) 2013- 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/.
#pragma once
#include "Common/ChunkFile.h"
struct BufferQueue {
BufferQueue(int size = 0x20000) {
bufQueue = 0;
alloc(size);
}
~BufferQueue() {
if (bufQueue)
delete [] bufQueue;
}
bool alloc(int size) {
if (size < 0)
return false;
if (bufQueue)
delete [] bufQueue;
bufQueue = new unsigned char[size];
start = 0;
end = 0;
bufQueueSize = size;
return true;
}
void clear() {
start = 0;
end = 0;
}
inline int getQueueSize() {
return (end + bufQueueSize - start) % bufQueueSize;
}
inline int getRemainSize() {
return bufQueueSize - getQueueSize();
}
bool push(unsigned char *buf, int addsize) {
int queuesz = getQueueSize();
int space = bufQueueSize - queuesz;
if (space < addsize || addsize < 0)
return false;
if (end + addsize <= bufQueueSize) {
memcpy(bufQueue + end, buf, addsize);
} else {
int size = bufQueueSize - end;
memcpy(bufQueue + end, buf, size);
memcpy(bufQueue, buf + size, addsize - size);
}
end = (end + addsize) % bufQueueSize;
return true;
}
int pop_front(unsigned char *buf, int wantedsize) {
if (wantedsize <= 0)
return 0;
int bytesgot = getQueueSize();
if (wantedsize < bytesgot)
bytesgot = wantedsize;
if (buf) {
if (start + bytesgot <= bufQueueSize) {
memcpy(buf, bufQueue + start, bytesgot);
} else {
int size = bufQueueSize - start;
memcpy(buf, bufQueue + start, size);
memcpy(buf + size, bufQueue, bytesgot - size);
}
}
start = (start + bytesgot) % bufQueueSize;
return bytesgot;
}
int get_front(unsigned char *buf, int wantedsize) {
if (wantedsize <= 0)
return 0;
int bytesgot = getQueueSize();
if (wantedsize < bytesgot)
bytesgot = wantedsize;
if (start + bytesgot <= bufQueueSize) {
memcpy(buf, bufQueue + start, bytesgot);
} else {
int size = bufQueueSize - start;
memcpy(buf, bufQueue + start, size);
memcpy(buf + size, bufQueue, bytesgot - size);
}
return bytesgot;
}
void DoState(PointerWrap &p) {
p.Do(bufQueueSize);
p.Do(start);
p.Do(end);
if (bufQueue)
p.DoArray(bufQueue, bufQueueSize);
}
unsigned char* bufQueue;
int start, end;
int bufQueueSize;
};

View File

@ -298,7 +298,7 @@ bool MediaEngine::loadStream(u8* buffer, int readSize, int RingbufferSize)
m_videopts = 0; m_videopts = 0;
m_audiopts = 0; m_audiopts = 0;
m_ringbuffersize = RingbufferSize; m_ringbuffersize = RingbufferSize;
m_pdata = new Atrac3plus_Decoder::BufferQueue(RingbufferSize + 2048); m_pdata = new BufferQueue(RingbufferSize + 2048);
if (!m_pdata) if (!m_pdata)
return false; return false;
m_pdata->push(buffer, readSize); m_pdata->push(buffer, readSize);

View File

@ -53,7 +53,8 @@ public:
bool loadStream(u8* buffer, int readSize, int RingbufferSize); bool loadStream(u8* buffer, int readSize, int RingbufferSize);
// open the mpeg context // open the mpeg context
bool openContext(); bool openContext();
// Returns number of packets actually added.
// Returns number of packets actually added. I guess the buffer might be full.
int addStreamData(u8* buffer, int addSize); int addStreamData(u8* buffer, int addSize);
void setVideoStream(int streamNum) { m_videoStream = streamNum; } void setVideoStream(int streamNum) { m_videoStream = streamNum; }
@ -81,8 +82,9 @@ public:
private: private:
void updateSwsFormat(int videoPixelMode); void updateSwsFormat(int videoPixelMode);
public: public: // TODO: Very little of this below should be public.
// Video ffmpeg context - not used for audio
AVFormatContext *m_pFormatCtx; AVFormatContext *m_pFormatCtx;
AVCodecContext *m_pCodecCtx; AVCodecContext *m_pCodecCtx;
AVFrame *m_pFrame; AVFrame *m_pFrame;
@ -92,6 +94,8 @@ public:
int m_sws_fmt; int m_sws_fmt;
u8 *m_buffer; u8 *m_buffer;
int m_videoStream; int m_videoStream;
// Used by the demuxer.
int m_audioStream; int m_audioStream;
int m_desWidth; int m_desWidth;
@ -99,10 +103,10 @@ public:
int m_decodingsize; int m_decodingsize;
int m_bufSize; int m_bufSize;
s64 m_videopts; s64 m_videopts;
Atrac3plus_Decoder::BufferQueue *m_pdata; BufferQueue *m_pdata;
MpegDemux *m_demux; MpegDemux *m_demux;
void* m_audioContext; void *m_audioContext;
s64 m_audiopts; s64 m_audiopts;
s64 m_firstTimeStamp; s64 m_firstTimeStamp;
@ -112,6 +116,6 @@ public:
bool m_noAudioData; bool m_noAudioData;
int m_ringbuffersize; int m_ringbuffersize;
u8 m_mpegheader[0x10000]; u8 m_mpegheader[0x10000]; // TODO: Allocate separately
int m_mpegheaderReadPos; int m_mpegheaderReadPos;
}; };

View File

@ -18,8 +18,7 @@ const int PRIVATE_STREAM_1 = 0x000001bd;
const int PADDING_STREAM = 0x000001be; const int PADDING_STREAM = 0x000001be;
const int PRIVATE_STREAM_2 = 0x000001bf; const int PRIVATE_STREAM_2 = 0x000001bf;
MpegDemux::MpegDemux(int size, int offset) : m_audioStream(size) MpegDemux::MpegDemux(int size, int offset) : m_audioStream(size) {
{
m_buf = new u8[size]; m_buf = new u8[size];
m_len = size; m_len = size;
@ -28,9 +27,21 @@ MpegDemux::MpegDemux(int size, int offset) : m_audioStream(size)
m_readSize = 0; m_readSize = 0;
} }
MpegDemux::~MpegDemux(void) {
}
MpegDemux::~MpegDemux(void) void MpegDemux::DoState(PointerWrap &p) {
{ auto s = p.Section("MpegDemux", 1);
if (!s)
return;
p.Do(m_index);
p.Do(m_len);
p.Do(m_audioChannel);
p.Do(m_readSize);
if (m_buf)
p.DoArray(m_buf, m_len);
p.DoClass(m_audioStream);
} }
bool MpegDemux::addStreamData(u8* buf, int addSize) { bool MpegDemux::addStreamData(u8* buf, int addSize) {

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include "../../Globals.h" #include "../../Globals.h"
#include "Core/HW/atrac3plus.h" #include "Core/HW/BufferQueue.h"
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
class MpegDemux class MpegDemux
@ -18,6 +18,9 @@ public:
// return its framesize // return its framesize
int getNextaudioFrame(u8** buf, int *headerCode1, int *headerCode2); int getNextaudioFrame(u8** buf, int *headerCode1, int *headerCode2);
void DoState(PointerWrap &p);
private: private:
struct PesHeader { struct PesHeader {
long pts; long pts;
@ -30,6 +33,7 @@ private:
channel = chan; channel = chan;
} }
}; };
int read8() { int read8() {
return m_buf[m_index++] & 0xFF; return m_buf[m_index++] & 0xFF;
} }
@ -52,25 +56,11 @@ private:
} }
int readPesHeader(PesHeader &pesHeader, int length, int startCode); int readPesHeader(PesHeader &pesHeader, int length, int startCode);
int demuxStream(bool bdemux, int startCode, int channel); int demuxStream(bool bdemux, int startCode, int channel);
public:
void DoState(PointerWrap &p) {
auto s = p.Section("MpegDemux", 1);
if (!s)
return;
p.Do(m_index);
p.Do(m_len);
p.Do(m_audioChannel);
p.Do(m_readSize);
if (m_buf)
p.DoArray(m_buf, m_len);
p.DoClass(m_audioStream);
}
private:
int m_index; int m_index;
int m_len; int m_len;
u8* m_buf; u8* m_buf;
Atrac3plus_Decoder::BufferQueue m_audioStream; BufferQueue m_audioStream;
u8 m_audioFrame[0x2000]; u8 m_audioFrame[0x2000];
int m_audioChannel; int m_audioChannel;
int m_readSize; int m_readSize;

View File

@ -163,7 +163,7 @@ int SasAtrac3::setContext(u32 context) {
contextAddr = context; contextAddr = context;
atracID = _AtracGetIDByContext(context); atracID = _AtracGetIDByContext(context);
if (!sampleQueue) if (!sampleQueue)
sampleQueue = new Atrac3plus_Decoder::BufferQueue; sampleQueue = new BufferQueue();
sampleQueue->clear(); sampleQueue->clear();
return 0; return 0;
} }
@ -202,7 +202,7 @@ void SasAtrac3::DoState(PointerWrap &p) {
p.Do(contextAddr); p.Do(contextAddr);
p.Do(atracID); p.Do(atracID);
if (p.mode == p.MODE_READ && atracID >= 0 && !sampleQueue) { if (p.mode == p.MODE_READ && atracID >= 0 && !sampleQueue) {
sampleQueue = new Atrac3plus_Decoder::BufferQueue; sampleQueue = new BufferQueue();
} }
} }

View File

@ -25,7 +25,7 @@
#include "../Globals.h" #include "../Globals.h"
#include "ChunkFile.h" #include "ChunkFile.h"
#include "Core/HW/atrac3plus.h" #include "Core/HW/BufferQueue.h"
enum { enum {
PSP_SAS_VOICES_MAX = 32, PSP_SAS_VOICES_MAX = 32,
@ -109,16 +109,17 @@ private:
class SasAtrac3 { class SasAtrac3 {
public: public:
SasAtrac3() : contextAddr(0), atracID(-1), sampleQueue(0){} SasAtrac3() : contextAddr(0), atracID(-1), sampleQueue(0) {}
~SasAtrac3() { if (sampleQueue) delete sampleQueue; } ~SasAtrac3() { if (sampleQueue) delete sampleQueue; }
int setContext(u32 context); int setContext(u32 context);
int getNextSamples(s16* outbuf, int wantedSamples); int getNextSamples(s16* outbuf, int wantedSamples);
int addStreamData(u8* buf, u32 addbytes); int addStreamData(u8* buf, u32 addbytes);
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
private: private:
u32 contextAddr; u32 contextAddr;
int atracID; int atracID;
Atrac3plus_Decoder::BufferQueue *sampleQueue; BufferQueue *sampleQueue;
}; };
// Max height: 0x40000000 I think // Max height: 0x40000000 I think

View File

@ -1,7 +1,7 @@
#ifndef _ATRAC3PLUS_DECODER_ #ifndef _ATRAC3PLUS_DECODER_
#define _ATRAC3PLUS_DECODER_ #define _ATRAC3PLUS_DECODER_
#include "Common/ChunkFile.h" #include "Core/HW/BufferQueue.h"
namespace Atrac3plus_Decoder { namespace Atrac3plus_Decoder {
bool IsSupported(); bool IsSupported();
@ -18,106 +18,6 @@ namespace Atrac3plus_Decoder {
Context OpenContext(); Context OpenContext();
int CloseContext(Context *context); int CloseContext(Context *context);
bool Decode(Context context, void* inbuf, int inbytes, int *outbytes, void* outbuf); bool Decode(Context context, void* inbuf, int inbytes, int *outbytes, void* outbuf);
struct BufferQueue {
BufferQueue(int size = 0x20000) {
bufQueue = 0;
alloc(size);
}
~BufferQueue() {
if (bufQueue)
delete [] bufQueue;
}
bool alloc(int size) {
if (size < 0)
return false;
if (bufQueue)
delete [] bufQueue;
bufQueue = new unsigned char[size];
start = 0;
end = 0;
bufQueueSize = size;
return true;
}
void clear() {
start = 0;
end = 0;
}
inline int getQueueSize() {
return (end + bufQueueSize - start) % bufQueueSize;
}
inline int getRemainSize() {
return bufQueueSize - getQueueSize();
}
bool push(unsigned char *buf, int addsize) {
int queuesz = getQueueSize();
int space = bufQueueSize - queuesz;
if (space < addsize || addsize < 0)
return false;
if (end + addsize <= bufQueueSize) {
memcpy(bufQueue + end, buf, addsize);
} else {
int size = bufQueueSize - end;
memcpy(bufQueue + end, buf, size);
memcpy(bufQueue, buf + size, addsize - size);
}
end = (end + addsize) % bufQueueSize;
return true;
}
int pop_front(unsigned char *buf, int wantedsize) {
if (wantedsize <= 0)
return 0;
int bytesgot = getQueueSize();
if (wantedsize < bytesgot)
bytesgot = wantedsize;
if (buf) {
if (start + bytesgot <= bufQueueSize) {
memcpy(buf, bufQueue + start, bytesgot);
} else {
int size = bufQueueSize - start;
memcpy(buf, bufQueue + start, size);
memcpy(buf + size, bufQueue, bytesgot - size);
}
}
start = (start + bytesgot) % bufQueueSize;
return bytesgot;
}
int get_front(unsigned char *buf, int wantedsize) {
if (wantedsize <= 0)
return 0;
int bytesgot = getQueueSize();
if (wantedsize < bytesgot)
bytesgot = wantedsize;
if (start + bytesgot <= bufQueueSize) {
memcpy(buf, bufQueue + start, bytesgot);
} else {
int size = bufQueueSize - start;
memcpy(buf, bufQueue + start, size);
memcpy(buf + size, bufQueue, bytesgot - size);
}
return bytesgot;
}
void DoState(PointerWrap &p) {
p.Do(bufQueueSize);
p.Do(start);
p.Do(end);
if (bufQueue)
p.DoArray(bufQueue, bufQueueSize);
}
unsigned char* bufQueue;
int start, end;
int bufQueueSize;
};
} }
#endif // _ATRAC3PLUS_DECODER_ #endif // _ATRAC3PLUS_DECODER_