mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-27 04:08:37 +01:00
Add MpegDemux for demuxing audios.
This commit is contained in:
1 parent
c85add4ede
commit
e0e8b2ec81
4 files changed
+264
-1
No files matched your search
@@ -233,6 +233,7 @@
|
||||
<ClCompile Include="HW\atrac3plus.cpp" />
|
||||
<ClCompile Include="HW\MediaEngine.cpp" />
|
||||
<ClCompile Include="HW\MemoryStick.cpp" />
|
||||
<ClCompile Include="HW\MpegDemux.cpp" />
|
||||
<ClCompile Include="HW\OMAConvert.cpp" />
|
||||
<ClCompile Include="HW\SasAudio.cpp" />
|
||||
<ClCompile Include="Loaders.cpp" />
|
||||
@@ -411,6 +412,7 @@
|
||||
<ClInclude Include="Host.h" />
|
||||
<ClInclude Include="HW\atrac3plus.h" />
|
||||
<ClInclude Include="HW\MediaEngine.h" />
|
||||
<ClInclude Include="HW\MpegDemux.h" />
|
||||
<ClInclude Include="HW\OMAConvert.h" />
|
||||
<ClInclude Include="HW\SasAudio.h" />
|
||||
<ClInclude Include="HW\MemoryStick.h" />
|
||||
|
||||
@@ -430,6 +430,9 @@
|
||||
<ClCompile Include="HW\atrac3plus.cpp">
|
||||
<Filter>HW</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="HW\MpegDemux.cpp">
|
||||
<Filter>HW</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ELF\ElfReader.h">
|
||||
@@ -795,6 +798,9 @@
|
||||
<ClInclude Include="HW\atrac3plus.h">
|
||||
<Filter>HW</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HW\MpegDemux.h">
|
||||
<Filter>HW</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="CMakeLists.txt" />
|
||||
@@ -802,4 +808,4 @@
|
||||
<None Include="..\android\jni\Android.mk" />
|
||||
<None Include="GameLogNotes.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -0,0 +1,192 @@
|
||||
#include "MpegDemux.h"
|
||||
|
||||
const int PACKET_START_CODE_MASK = 0xffffff00;
|
||||
const int PACKET_START_CODE_PREFIX = 0x00000100;
|
||||
|
||||
const int SEQUENCE_START_CODE = 0x000001b3;
|
||||
const int EXT_START_CODE = 0x000001b5;
|
||||
const int SEQUENCE_END_CODE = 0x000001b7;
|
||||
const int GOP_START_CODE = 0x000001b8;
|
||||
const int ISO_11172_END_CODE = 0x000001b9;
|
||||
const int PACK_START_CODE = 0x000001ba;
|
||||
const int SYSTEM_HEADER_START_CODE = 0x000001bb;
|
||||
const int PROGRAM_STREAM_MAP = 0x000001bc;
|
||||
const int PRIVATE_STREAM_1 = 0x000001bd;
|
||||
const int PADDING_STREAM = 0x000001be;
|
||||
const int PRIVATE_STREAM_2 = 0x000001bf;
|
||||
|
||||
MpegDemux::MpegDemux(u8* buffer, int size, int offset)
|
||||
{
|
||||
m_buf = buffer;
|
||||
m_len = size;
|
||||
m_index = offset;
|
||||
m_audioStream = 0;
|
||||
m_audiopos = 0;
|
||||
m_audioChannel = -1;
|
||||
m_readSize = 0;
|
||||
}
|
||||
|
||||
|
||||
MpegDemux::~MpegDemux(void)
|
||||
{
|
||||
if (m_audioStream)
|
||||
delete [] m_audioStream;
|
||||
}
|
||||
|
||||
void MpegDemux::setReadSize(int readSize)
|
||||
{
|
||||
m_readSize = readSize;
|
||||
}
|
||||
|
||||
int MpegDemux::readPesHeader(PesHeader &pesHeader, int length, int startCode) {
|
||||
int c = 0;
|
||||
while (length > 0) {
|
||||
c = read8();
|
||||
length--;
|
||||
if (c != 0xFF) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((c & 0xC0) == 0x40) {
|
||||
read8();
|
||||
c = read8();
|
||||
length -= 2;
|
||||
}
|
||||
pesHeader.pts = 0;
|
||||
pesHeader.dts = 0;
|
||||
if ((c & 0xE0) == 0x20) {
|
||||
pesHeader.dts = pesHeader.pts = readPts(c);
|
||||
length -= 4;
|
||||
if ((c & 0x10) != 0) {
|
||||
pesHeader.dts = readPts();
|
||||
length -= 5;
|
||||
}
|
||||
} else if ((c & 0xC0) == 0x80) {
|
||||
int flags = read8();
|
||||
int headerLength = read8();
|
||||
length -= 2;
|
||||
length -= headerLength;
|
||||
if ((flags & 0x80) != 0) {
|
||||
pesHeader.dts = pesHeader.pts = readPts();
|
||||
headerLength -= 5;
|
||||
if ((flags & 0x40) != 0) {
|
||||
pesHeader.dts = readPts();
|
||||
headerLength -= 5;
|
||||
}
|
||||
}
|
||||
if ((flags & 0x3F) != 0 && headerLength == 0) {
|
||||
flags &= 0xC0;
|
||||
}
|
||||
if ((flags & 0x01) != 0) {
|
||||
int pesExt = read8();
|
||||
headerLength--;
|
||||
int skip = (pesExt >> 4) & 0x0B;
|
||||
skip += skip & 0x09;
|
||||
if ((pesExt & 0x40) != 0 || skip > headerLength) {
|
||||
pesExt = skip = 0;
|
||||
}
|
||||
this->skip(skip);
|
||||
headerLength -= skip;
|
||||
if ((pesExt & 0x01) != 0) {
|
||||
int ext2Length = read8();
|
||||
headerLength--;
|
||||
if ((ext2Length & 0x7F) != 0) {
|
||||
int idExt = read8();
|
||||
headerLength--;
|
||||
if ((idExt & 0x80) == 0) {
|
||||
startCode = ((startCode & 0xFF) << 8) | idExt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
skip(headerLength);
|
||||
}
|
||||
if (startCode == PRIVATE_STREAM_1) {
|
||||
int channel = read8();
|
||||
pesHeader.channel = channel;
|
||||
length--;
|
||||
if (channel >= 0x80 && channel <= 0xCF) {
|
||||
// Skip audio header
|
||||
skip(3);
|
||||
length -= 3;
|
||||
if (channel >= 0xB0 && channel <= 0xBF) {
|
||||
skip(1);
|
||||
length--;
|
||||
}
|
||||
} else {
|
||||
// PSP audio has additional 3 bytes in header
|
||||
skip(3);
|
||||
length -= 3;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
int MpegDemux::demuxStream(bool bdemux, int startCode, int channel)
|
||||
{
|
||||
int length = read16();
|
||||
if (bdemux) {
|
||||
PesHeader pesHeader(channel);
|
||||
length = readPesHeader(pesHeader, length, startCode);
|
||||
if (pesHeader.channel == channel || channel < 0) {
|
||||
channel = pesHeader.channel;
|
||||
memcpy(m_audioStream + m_audiopos, m_buf + m_index, length);
|
||||
m_audiopos += length;
|
||||
}
|
||||
skip(length);
|
||||
} else {
|
||||
skip(length);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
void MpegDemux::demux()
|
||||
{
|
||||
if (!m_audioStream)
|
||||
m_audioStream = new u8[m_len - m_index];
|
||||
while (m_index < m_len)
|
||||
{
|
||||
if (m_readSize != m_len && m_index + 2048 > m_readSize)
|
||||
return;
|
||||
// Search for start code
|
||||
int startCode = 0xFF;
|
||||
while ((startCode & PACKET_START_CODE_MASK) != PACKET_START_CODE_PREFIX && !isEOF()) {
|
||||
startCode = (startCode << 8) | read8();
|
||||
}
|
||||
switch (startCode) {
|
||||
case PACK_START_CODE: {
|
||||
skip(10);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_HEADER_START_CODE: {
|
||||
skip(14);
|
||||
break;
|
||||
}
|
||||
case PADDING_STREAM:
|
||||
case PRIVATE_STREAM_2: {
|
||||
int length = read16();
|
||||
skip(length);
|
||||
break;
|
||||
}
|
||||
case PRIVATE_STREAM_1: {
|
||||
// Audio stream
|
||||
m_audioChannel = demuxStream(true, startCode, m_audioChannel);
|
||||
break;
|
||||
}
|
||||
case 0x1E0: case 0x1E1: case 0x1E2: case 0x1E3:
|
||||
case 0x1E4: case 0x1E5: case 0x1E6: case 0x1E7:
|
||||
case 0x1E8: case 0x1E9: case 0x1EA: case 0x1EB:
|
||||
case 0x1EC: case 0x1ED: case 0x1EE: case 0x1EF: {
|
||||
// Video Stream
|
||||
demuxStream(false, startCode, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MpegDemux::getaudioStream(u8** audioStream)
|
||||
{
|
||||
*audioStream = m_audioStream;
|
||||
return m_audiopos;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// This is a simple version MpegDemux that can get media's audio stream.
|
||||
// Thanks to JPCSP project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../Globals.h"
|
||||
|
||||
class MpegDemux
|
||||
{
|
||||
public:
|
||||
MpegDemux(u8* buffer, int size, int offset);
|
||||
~MpegDemux(void);
|
||||
|
||||
void setReadSize(int readSize);
|
||||
|
||||
void demux();
|
||||
|
||||
// return it's size
|
||||
int getaudioStream(u8 **audioStream);
|
||||
private:
|
||||
struct PesHeader {
|
||||
long pts;
|
||||
long dts;
|
||||
int channel;
|
||||
|
||||
PesHeader(int chan) {
|
||||
pts = 0;
|
||||
dts = 0;
|
||||
channel = chan;
|
||||
}
|
||||
};
|
||||
int read8() {
|
||||
return m_buf[m_index++] & 0xFF;
|
||||
}
|
||||
int read16() {
|
||||
return (read8() << 8) | read8();
|
||||
}
|
||||
long readPts() {
|
||||
return readPts(read8());
|
||||
}
|
||||
long readPts(int c) {
|
||||
return (((long) (c & 0x0E)) << 29) | ((read16() >> 1) << 15) | (read16() >> 1);
|
||||
}
|
||||
bool isEOF() {
|
||||
return m_index >= m_len;
|
||||
}
|
||||
void skip(int n) {
|
||||
if (n > 0) {
|
||||
m_index += n;
|
||||
}
|
||||
}
|
||||
int readPesHeader(PesHeader &pesHeader, int length, int startCode);
|
||||
int demuxStream(bool bdemux, int startCode, int channel);
|
||||
private:
|
||||
int m_index;
|
||||
int m_len;
|
||||
u8* m_buf;
|
||||
u8* m_audioStream;
|
||||
int m_audiopos;
|
||||
int m_audioChannel;
|
||||
int m_readSize;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user