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
// 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/MIPS/MIPS.h"
@ -25,6 +22,7 @@
#include "Core/Reporting.h"
#include "Core/Config.h"
#include "Core/HW/MediaEngine.h"
#include "Core/HW/BufferQueue.h"
#include "Common/ChunkFile.h"
#include "sceKernel.h"
@ -250,7 +248,7 @@ struct Atrac {
InputBuffer first;
InputBuffer second;
Atrac3plus_Decoder::BufferQueue sampleQueue;
BufferQueue sampleQueue;
void* decoder_context;
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_audiopts = 0;
m_ringbuffersize = RingbufferSize;
m_pdata = new Atrac3plus_Decoder::BufferQueue(RingbufferSize + 2048);
m_pdata = new BufferQueue(RingbufferSize + 2048);
if (!m_pdata)
return false;
m_pdata->push(buffer, readSize);

View File

@ -53,7 +53,8 @@ public:
bool loadStream(u8* buffer, int readSize, int RingbufferSize);
// open the mpeg context
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);
void setVideoStream(int streamNum) { m_videoStream = streamNum; }
@ -64,7 +65,7 @@ public:
bool stepVideo(int videoPixelMode);
int writeVideoImage(u8* buffer, int frameWidth = 512, int videoPixelMode = 3);
int writeVideoImageWithRange(u8* buffer, int frameWidth, int videoPixelMode,
int writeVideoImageWithRange(u8* buffer, int frameWidth, int videoPixelMode,
int xpos, int ypos, int width, int height);
int getAudioSamples(u8* buffer);
@ -81,8 +82,9 @@ public:
private:
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;
AVCodecContext *m_pCodecCtx;
AVFrame *m_pFrame;
@ -92,17 +94,19 @@ public:
int m_sws_fmt;
u8 *m_buffer;
int m_videoStream;
// Used by the demuxer.
int m_audioStream;
int m_desWidth;
int m_desHeight;
int m_desWidth;
int m_desHeight;
int m_decodingsize;
int m_bufSize;
s64 m_videopts;
Atrac3plus_Decoder::BufferQueue *m_pdata;
BufferQueue *m_pdata;
MpegDemux *m_demux;
void* m_audioContext;
void *m_audioContext;
s64 m_audiopts;
s64 m_firstTimeStamp;
@ -112,6 +116,6 @@ public:
bool m_noAudioData;
int m_ringbuffersize;
u8 m_mpegheader[0x10000];
u8 m_mpegheader[0x10000]; // TODO: Allocate separately
int m_mpegheaderReadPos;
};

View File

@ -18,8 +18,7 @@ const int PRIVATE_STREAM_1 = 0x000001bd;
const int PADDING_STREAM = 0x000001be;
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_len = size;
@ -28,9 +27,21 @@ MpegDemux::MpegDemux(int size, int offset) : m_audioStream(size)
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) {

View File

@ -4,7 +4,7 @@
#pragma once
#include "../../Globals.h"
#include "Core/HW/atrac3plus.h"
#include "Core/HW/BufferQueue.h"
#include "Common/ChunkFile.h"
class MpegDemux
@ -18,6 +18,9 @@ public:
// return its framesize
int getNextaudioFrame(u8** buf, int *headerCode1, int *headerCode2);
void DoState(PointerWrap &p);
private:
struct PesHeader {
long pts;
@ -30,6 +33,7 @@ private:
channel = chan;
}
};
int read8() {
return m_buf[m_index++] & 0xFF;
}
@ -52,25 +56,11 @@ private:
}
int readPesHeader(PesHeader &pesHeader, int length, int startCode);
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_len;
u8* m_buf;
Atrac3plus_Decoder::BufferQueue m_audioStream;
BufferQueue m_audioStream;
u8 m_audioFrame[0x2000];
int m_audioChannel;
int m_readSize;

View File

@ -163,7 +163,7 @@ int SasAtrac3::setContext(u32 context) {
contextAddr = context;
atracID = _AtracGetIDByContext(context);
if (!sampleQueue)
sampleQueue = new Atrac3plus_Decoder::BufferQueue;
sampleQueue = new BufferQueue();
sampleQueue->clear();
return 0;
}
@ -180,7 +180,7 @@ int SasAtrac3::getNextSamples(s16* outbuf, int wantedSamples) {
_AtracDecodeData(atracID, (u8*)buf, &numSamples, &finish, &remains);
if (numSamples > 0)
sampleQueue->push((u8*)buf, numSamples * sizeof(s16));
else
else
finish = 1;
}
sampleQueue->pop_front((u8*)outbuf, wantedbytes);
@ -202,7 +202,7 @@ void SasAtrac3::DoState(PointerWrap &p) {
p.Do(contextAddr);
p.Do(atracID);
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 "ChunkFile.h"
#include "Core/HW/atrac3plus.h"
#include "Core/HW/BufferQueue.h"
enum {
PSP_SAS_VOICES_MAX = 32,
@ -109,16 +109,17 @@ private:
class SasAtrac3 {
public:
SasAtrac3() : contextAddr(0), atracID(-1), sampleQueue(0){}
SasAtrac3() : contextAddr(0), atracID(-1), sampleQueue(0) {}
~SasAtrac3() { if (sampleQueue) delete sampleQueue; }
int setContext(u32 context);
int getNextSamples(s16* outbuf, int wantedSamples);
int addStreamData(u8* buf, u32 addbytes);
void DoState(PointerWrap &p);
private:
u32 contextAddr;
int atracID;
Atrac3plus_Decoder::BufferQueue *sampleQueue;
BufferQueue *sampleQueue;
};
// Max height: 0x40000000 I think
@ -175,7 +176,7 @@ struct SasVoice
{
SasVoice()
: playing(false),
paused(false),
paused(false),
on(false),
type(VOICETYPE_OFF),
vagAddr(0),

View File

@ -1,7 +1,7 @@
#ifndef _ATRAC3PLUS_DECODER_
#define _ATRAC3PLUS_DECODER_
#include "Common/ChunkFile.h"
#include "Core/HW/BufferQueue.h"
namespace Atrac3plus_Decoder {
bool IsSupported();
@ -18,106 +18,6 @@ namespace Atrac3plus_Decoder {
Context OpenContext();
int CloseContext(Context *context);
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_