summaryrefslogtreecommitdiff
path: root/dvbplayer.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2016-12-22 11:33:12 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2016-12-22 11:33:12 +0100
commitbe4cdcf17027e2f6f5482fb13d273693145d11a1 (patch)
treeaa3877153e4640746b6833dae1a0891928907065 /dvbplayer.c
parentfd85701a84c976318afbb69e13d96c1ec44112fc (diff)
downloadvdr-be4cdcf17027e2f6f5482fb13d273693145d11a1.tar.gz
vdr-be4cdcf17027e2f6f5482fb13d273693145d11a1.tar.bz2
Improved handling frame numbers to have a smoother progress display during replay of recordings with B-frames
Diffstat (limited to 'dvbplayer.c')
-rw-r--r--dvbplayer.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/dvbplayer.c b/dvbplayer.c
index e5c9270b..6db497e3 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbplayer.c 4.2 2016/12/22 09:40:30 kls Exp $
+ * $Id: dvbplayer.c 4.3 2016/12/22 10:43:10 kls Exp $
*/
#include "dvbplayer.h"
@@ -17,13 +17,14 @@
// --- cPtsIndex -------------------------------------------------------------
-#define PTSINDEX_ENTRIES 500
+#define PTSINDEX_ENTRIES 1024
class cPtsIndex {
private:
struct tPtsIndex {
uint32_t pts; // no need for 33 bit - some devices don't even supply the msb
int index;
+ bool independent;
};
tPtsIndex pi[PTSINDEX_ENTRIES];
int w, r;
@@ -33,8 +34,9 @@ public:
cPtsIndex(void);
void Clear(void);
bool IsEmpty(void);
- void Put(uint32_t Pts, int Index);
+ void Put(uint32_t Pts, int Index, bool Independent);
int FindIndex(uint32_t Pts);
+ int FindFrameNumber(uint32_t Pts);
};
cPtsIndex::cPtsIndex(void)
@@ -55,10 +57,11 @@ bool cPtsIndex::IsEmpty(void)
return w == r;
}
-void cPtsIndex::Put(uint32_t Pts, int Index)
+void cPtsIndex::Put(uint32_t Pts, int Index, bool Independent)
{
cMutexLock MutexLock(&mutex);
pi[w].pts = Pts;
+ pi[w].independent = Independent;
pi[w].index = Index;
w = (w + 1) % PTSINDEX_ENTRIES;
if (w == r)
@@ -87,6 +90,36 @@ int cPtsIndex::FindIndex(uint32_t Pts)
return Index;
}
+int cPtsIndex::FindFrameNumber(uint32_t Pts)
+{
+ cMutexLock MutexLock(&mutex);
+ if (w == r)
+ return lastFound; // replay always starts at an I frame
+ bool Valid = false;
+ int d;
+ int FrameNumber = 0;
+ int UnplayedIFrame = 2; // GOPs may intersect, so we're looping until we found two unplayed I frames
+ for (int i = r; i != w && UnplayedIFrame; ) {
+ d = Pts - pi[i].pts;
+ if (d > 0x7FFFFFFF)
+ d = 0xFFFFFFFF - d; // handle rollover
+ if (d > 0) {
+ if (pi[i].independent) {
+ FrameNumber = pi[i].index; // an I frame's index represents its frame number
+ Valid = true;
+ }
+ else
+ FrameNumber++; // for every played non-I frame, increase frame number
+ }
+ else
+ if (pi[i].independent)
+ --UnplayedIFrame;
+ if (++i >= PTSINDEX_ENTRIES)
+ i = 0;
+ }
+ return Valid ? FrameNumber : FindIndex(Pts); // fall back during trick speeds
+}
+
// --- cNonBlockingFileReader ------------------------------------------------
class cNonBlockingFileReader : public cThread {
@@ -251,6 +284,7 @@ public:
virtual double FramesPerSecond(void) { return framesPerSecond; }
virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId);
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
+ virtual bool GetFrameNumber(int &Current, int &Total);
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
};
@@ -606,7 +640,7 @@ void cDvbPlayer::Action(void)
pc = playFrame->Count();
if (p) {
if (playFrame->Index() >= 0 && playFrame->Pts() != 0)
- ptsIndex.Put(playFrame->Pts(), playFrame->Index());
+ ptsIndex.Put(playFrame->Pts(), playFrame->Index(), playFrame->Independent());
if (firstPacket) {
if (isPesRecording) {
PlayPes(NULL, 0);
@@ -880,7 +914,7 @@ void cDvbPlayer::Goto(int Index, bool Still)
if (playMode == pmPause)
DevicePlay();
DeviceStillPicture(b, r);
- ptsIndex.Put(isPesRecording ? PesGetPts(b) : TsGetPts(b, r), Index);
+ ptsIndex.Put(isPesRecording ? PesGetPts(b) : TsGetPts(b, r), Index, true);
}
playMode = pmStill;
readIndex = Index;
@@ -925,6 +959,17 @@ bool cDvbPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
return false;
}
+bool cDvbPlayer::GetFrameNumber(int &Current, int &Total)
+{
+ if (index) {
+ Current = ptsIndex.FindFrameNumber(DeviceGetSTC());
+ Total = index->Last();
+ return true;
+ }
+ Current = Total = -1;
+ return false;
+}
+
bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
{
Play = (playMode == pmPlay || playMode == pmFast);
@@ -1011,6 +1056,15 @@ bool cDvbPlayerControl::GetIndex(int &Current, int &Total, bool SnapToIFrame)
return false;
}
+bool cDvbPlayerControl::GetFrameNumber(int &Current, int &Total)
+{
+ if (player) {
+ player->GetFrameNumber(Current, Total);
+ return true;
+ }
+ return false;
+}
+
bool cDvbPlayerControl::GetReplayMode(bool &Play, bool &Forward, int &Speed)
{
return player && player->GetReplayMode(Play, Forward, Speed);