Skip to content

Commit

Permalink
Correct the audio pts from the actual stream data.
Browse files Browse the repository at this point in the history
Before, we would just increment it and hope we were right.  There's no
reason we'd be wrong, but with seeking we have to be more careful.
  • Loading branch information
unknownbrackets committed May 15, 2014
1 parent 2d12eb3 commit 2042672
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 13 deletions.
56 changes: 53 additions & 3 deletions Core/HW/BufferQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#pragma once

#include <map>
#include <cstring>
#include "Common/ChunkFile.h"

Expand Down Expand Up @@ -60,11 +61,12 @@ struct BufferQueue {
return bufQueueSize - getQueueSize();
}

bool push(unsigned char *buf, int addsize) {
bool push(const unsigned char *buf, int addsize, s64 pts = 0) {
int queuesz = getQueueSize();
int space = bufQueueSize - queuesz;
if (space < addsize || addsize < 0)
return false;
savePts(pts);
if (end + addsize <= bufQueueSize) {
memcpy(bufQueue + end, buf, addsize);
end += addsize;
Expand All @@ -77,12 +79,15 @@ struct BufferQueue {
return true;
}

int pop_front(unsigned char *buf, int wantedsize) {
int pop_front(unsigned char *buf, int wantedsize, s64 *pts = NULL) {
if (wantedsize <= 0)
return 0;
int bytesgot = getQueueSize();
if (wantedsize < bytesgot)
bytesgot = wantedsize;
if (pts != NULL) {
*pts = findPts(bytesgot);
}
if (buf) {
if (start + bytesgot <= bufQueueSize) {
memcpy(buf, bufQueue + start, bytesgot);
Expand Down Expand Up @@ -120,14 +125,59 @@ struct BufferQueue {
}

void DoState(PointerWrap &p) {
auto s = p.Section("BufferQueue", 0, 1);

p.Do(bufQueueSize);
p.Do(start);
p.Do(end);
if (bufQueue)
if (bufQueue) {
p.DoArray(bufQueue, bufQueueSize);
}

if (s >= 1) {
p.Do(ptsMarks);
}
}

private:
void savePts(u64 pts) {
if (pts != 0) {
ptsMarks[end] = pts;
}
}

u64 findPts(std::map<u32, s64>::iterator earliest, std::map<u32, s64>::iterator latest) {
u64 pts = 0;
// Take the first one, that is the pts of this packet.
if (earliest != latest) {
pts = earliest->second;
}
ptsMarks.erase(earliest, latest);
return pts;
}

u64 findPts(int packetSize) {
auto earliest = ptsMarks.lower_bound(start);
auto latest = ptsMarks.lower_bound(start + packetSize);

u64 pts = findPts(earliest, latest);

// If it wraps around, we have to look at the other half too.
if (start + packetSize > bufQueueSize) {
earliest = ptsMarks.begin();
latest = ptsMarks.lower_bound(start + packetSize - bufQueueSize);
u64 pts2 = findPts(earliest, latest);
if (pts2 != 0) {
pts = pts2;
}
}

return pts;
}

unsigned char* bufQueue;
int start, end;
int bufQueueSize;

std::map<u32, s64> ptsMarks;
};
12 changes: 9 additions & 3 deletions Core/HW/MediaEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ void MediaEngine::closeContext()
m_buffer = 0;
}

bool MediaEngine::loadStream(u8* buffer, int readSize, int RingbufferSize)
bool MediaEngine::loadStream(const u8 *buffer, int readSize, int RingbufferSize)
{
closeMedia();

Expand All @@ -336,7 +336,7 @@ bool MediaEngine::loadStream(u8* buffer, int readSize, int RingbufferSize)
return true;
}

int MediaEngine::addStreamData(u8* buffer, int addSize) {
int MediaEngine::addStreamData(const u8 *buffer, int addSize) {
int size = addSize;
if (size > 0 && m_pdata) {
if (!m_pdata->push(buffer, size))
Expand Down Expand Up @@ -762,7 +762,13 @@ int MediaEngine::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2)
// Demux now (rather than on add data) so that we select the right stream.
m_demux->demux(m_audioStream);

return m_demux->getNextAudioFrame(buf, headerCode1, headerCode2);
s64 pts = 0;
int result = m_demux->getNextAudioFrame(buf, headerCode1, headerCode2, &pts);
if (pts != 0) {
// m_audiopts is supposed to be after the returned frame.
m_audiopts = pts - m_firstTimeStamp + 4180;
}
return result;
}

int MediaEngine::getAudioSamples(u32 bufferPtr) {
Expand Down
6 changes: 3 additions & 3 deletions Core/HW/MediaEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct AVFormatContext;
struct AVCodecContext;
#endif

inline s64 getMpegTimeStamp(u8* buf) {
inline s64 getMpegTimeStamp(const u8 *buf) {
return (s64)buf[5] | ((s64)buf[4] << 8) | ((s64)buf[3] << 16) | ((s64)buf[2] << 24)
| ((s64)buf[1] << 32) | ((s64)buf[0] << 36);
}
Expand All @@ -59,13 +59,13 @@ class MediaEngine
~MediaEngine();

void closeMedia();
bool loadStream(u8* buffer, int readSize, int RingbufferSize);
bool loadStream(const u8 *buffer, int readSize, int RingbufferSize);
// open the mpeg context
bool openContext();
void closeContext();

// Returns number of packets actually added. I guess the buffer might be full.
int addStreamData(u8* buffer, int addSize);
int addStreamData(const u8 *buffer, int addSize);
bool seekTo(s64 timestamp, int videoPixelMode);

bool setVideoStream(int streamNum, bool force = false);
Expand Down
6 changes: 3 additions & 3 deletions Core/HW/MpegDemux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ int MpegDemux::demuxStream(bool bdemux, int startCode, int channel)
length = readPesHeader(pesHeader, length, startCode);
if (pesHeader.channel == channel || channel < 0) {
channel = pesHeader.channel;
m_audioStream.push(m_buf + m_index, length);
m_audioStream.push(m_buf + m_index, length, pesHeader.pts);
}
skip(length);
} else {
Expand Down Expand Up @@ -234,7 +234,7 @@ static int getNextHeaderPosition(u8* audioStream, int curpos, int limit, int fra
return -1;
}

int MpegDemux::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2)
int MpegDemux::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2, s64 *pts)
{
int gotsize;
int frameSize;
Expand All @@ -247,7 +247,7 @@ int MpegDemux::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2)
} else {
audioPos = gotsize;
}
m_audioStream.pop_front(0, audioPos);
m_audioStream.pop_front(0, audioPos, pts);
if (buf) {
*buf = m_audioFrame + 8;
}
Expand Down
2 changes: 1 addition & 1 deletion Core/HW/MpegDemux.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class MpegDemux
void demux(int audioChannel);

// return its framesize
int getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2);
int getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2, s64 *pts = NULL);
bool hasNextAudioFrame(int *gotsizeOut, int *frameSizeOut, int *headerCode1, int *headerCode2);

inline int getRemainSize() {
Expand Down

0 comments on commit 2042672

Please sign in to comment.