summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Reufer <thomas@reufer.ch>2015-04-25 18:44:16 +0200
committerThomas Reufer <thomas@reufer.ch>2015-04-26 20:25:29 +0200
commit2a95cb122bff5922b0528281c0e6d07ed3e88ef7 (patch)
tree81b7275a66482abd140b536f1145be56f8b9802b
parent91e19b446a85a50fa94682c1387389e215d1644c (diff)
downloadvdr-plugin-rpihddevice-2a95cb122bff5922b0528281c0e6d07ed3e88ef7.tar.gz
vdr-plugin-rpihddevice-2a95cb122bff5922b0528281c0e6d07ed3e88ef7.tar.bz2
fixed PTS wrap around
-rw-r--r--HISTORY1
-rw-r--r--omxdevice.c48
-rw-r--r--omxdevice.h4
3 files changed, 33 insertions, 20 deletions
diff --git a/HISTORY b/HISTORY
index 7a22637..511ecb1 100644
--- a/HISTORY
+++ b/HISTORY
@@ -8,6 +8,7 @@ VDR Plugin 'rpihddevice' Revision History
- added font kerning
- support for GPU accelerated pixmaps
- fixed:
+ - fixed PTS wrap around (reported by Klaus Schmidinger)
- increased audio decoder thread priority
- don't depend on multi channel PCM support for digital audio pass-through
- improved video frame rate detection to be more tolerant to inaccurate values
diff --git a/omxdevice.c b/omxdevice.c
index 0201044..ba37446 100644
--- a/omxdevice.c
+++ b/omxdevice.c
@@ -18,6 +18,7 @@
#include <string.h>
#define S(x) ((int)(floor(x * pow(2, 16))))
+#define PTS_START_OFFSET (32 * (MAX33BIT + 1))
// trick speeds as defined in vdr/dvbplayer.c
const int cOmxDevice::s_playbackSpeeds[eNumDirections][eNumPlaybackSpeeds] = {
@@ -246,6 +247,8 @@ void cOmxDevice::StillPicture(const uchar *Data, int Length)
int cOmxDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
{
m_mutex->Lock();
+ int ret = Length;
+ int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : 0;
if (!m_hasAudio)
{
@@ -257,21 +260,22 @@ int cOmxDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
DBG("audio first");
m_omx->SetClockScale(s_playbackSpeeds[m_direction][m_playbackSpeed]);
m_omx->StartClock(m_hasVideo, m_hasAudio);
+ m_audioPts = PTS_START_OFFSET + pts;
}
+ else
+ m_audioPts = m_videoPts + PtsDiff(m_videoPts & MAX33BIT, pts);
}
- int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : 0;
-
- // keep track of direction in case of trick speed
- if (m_trickRequest && pts)
+ if (pts)
{
- if (m_audioPts)
- PtsTracker(PtsDiff(m_audioPts, pts));
+ int64_t ptsDiff = PtsDiff(m_audioPts & MAX33BIT, pts);
+ m_audioPts += ptsDiff;
- m_audioPts = pts;
+ // keep track of direction in case of trick speed
+ if (m_trickRequest && ptsDiff)
+ PtsTracker(ptsDiff);
}
- int ret = Length;
int length = Length - PesPayloadOffset(Data);
// ignore packets with invalid payload offset
@@ -287,7 +291,7 @@ int cOmxDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
data += 4;
length -= 4;
}
- if (!m_audio->WriteData(data, length, pts))
+ if (!m_audio->WriteData(data, length, pts ? m_audioPts : 0))
ret = 0;
}
m_mutex->Unlock();
@@ -305,8 +309,9 @@ int cOmxDevice::PlayVideo(const uchar *Data, int Length, bool EndOfFrame)
{
m_mutex->Lock();
int ret = Length;
+ int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : 0;
- if (!m_hasVideo && m_videoCodec == cVideoCodec::eInvalid)
+ if (!m_hasVideo && pts && m_videoCodec == cVideoCodec::eInvalid)
{
m_videoCodec = ParseVideoCodec(Data + PesPayloadOffset(Data),
Length - PesPayloadOffset(Data));
@@ -323,7 +328,7 @@ int cOmxDevice::PlayVideo(const uchar *Data, int Length, bool EndOfFrame)
}
}
- if (!m_hasVideo && cRpiSetup::IsVideoCodecSupported(m_videoCodec))
+ if (!m_hasVideo && pts && cRpiSetup::IsVideoCodecSupported(m_videoCodec))
{
m_hasVideo = true;
if (!m_hasAudio)
@@ -332,16 +337,23 @@ int cOmxDevice::PlayVideo(const uchar *Data, int Length, bool EndOfFrame)
m_omx->SetClockReference(cOmx::eClockRefVideo);
m_omx->SetClockScale(s_playbackSpeeds[m_direction][m_playbackSpeed]);
m_omx->StartClock(m_hasVideo, m_hasAudio);
+ m_videoPts = PTS_START_OFFSET + pts;
}
+ else
+ m_videoPts = m_audioPts + PtsDiff(m_audioPts & MAX33BIT, pts);
}
if (m_hasVideo)
{
- int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : 0;
+ if (pts)
+ {
+ int64_t ptsDiff = PtsDiff(m_videoPts & MAX33BIT, pts);
+ m_videoPts += ptsDiff;
- // keep track of direction in case of trick speed
- if (m_trickRequest && pts && m_videoPts)
- PtsTracker(PtsDiff(m_videoPts, pts));
+ // keep track of direction in case of trick speed
+ if (m_trickRequest && ptsDiff)
+ PtsTracker(ptsDiff);
+ }
// skip PES header, proceed with payload towards OMX
Length -= PesPayloadOffset(Data);
@@ -349,8 +361,8 @@ int cOmxDevice::PlayVideo(const uchar *Data, int Length, bool EndOfFrame)
while (Length > 0)
{
- OMX_BUFFERHEADERTYPE *buf = m_omx->GetVideoBuffer(pts);
- if (buf)
+ if (OMX_BUFFERHEADERTYPE *buf =
+ m_omx->GetVideoBuffer(pts ? m_videoPts : 0))
{
buf->nFilledLen = buf->nAllocLen < (unsigned)Length ?
buf->nAllocLen : Length;
@@ -400,7 +412,7 @@ bool cOmxDevice::SubmitEOS(void)
int64_t cOmxDevice::GetSTC(void)
{
- return m_omx->GetSTC();
+ return m_omx->GetSTC() & MAX33BIT;
}
uchar *cOmxDevice::GrabImage(int &Size, bool Jpeg, int Quality,
diff --git a/omxdevice.h b/omxdevice.h
index 22476d5..412bdf0 100644
--- a/omxdevice.h
+++ b/omxdevice.h
@@ -176,8 +176,8 @@ private:
int m_playDirection;
int m_trickRequest;
- int64_t m_audioPts;
- int64_t m_videoPts;
+ uint64_t m_audioPts;
+ uint64_t m_videoPts;
};
#endif