]> git.vomp.tv Git - vompclient.git/commitdiff
Demuxer frame counting, second step
authorMark Calderbank <mark@vomp.tv>
Sun, 11 Jun 2006 19:55:08 +0000 (19:55 +0000)
committerMark Calderbank <mark@vomp.tv>
Sun, 11 Jun 2006 19:55:08 +0000 (19:55 +0000)
demuxer.h
demuxervdr.cc
demuxervdr.h

index 188cb3735fd2f90e97a78738de3fdc495ed6caa9..a30ad52f751ff2c27c3cb2214290b19c5bc6e0e1 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -86,6 +86,7 @@ protected:
     virtual int put(UCHAR* buf, int len,ULLONG cur_pos) = 0;
 #endif
     virtual void setFrameNum(ULONG frame) {}
+    virtual ULONG getFrameNumFromPTS(ULLONG pts) {return 0;}
 
     int getHorizontalSize() { return horizontal_size; }
     int getVerticalSize() { return vertical_size; }
index ba9278e7e3ec063ad84cd1baa11f2a32f65ebc9e..9bdf7bace8e8d4f636c7ebbe97e54e0f52a683ad 100644 (file)
@@ -34,6 +34,8 @@
 #endif
 
 #define PTSMAP_MAXENTRIES 300
+#define PTSMAP_THRESHOLD 90000 // One second
+          // ISO standard demands at least one PTS every 0.7 seconds
 
 DemuxerVDR::DemuxerVDR()
 {
@@ -118,6 +120,7 @@ void DemuxerVDR::setFrameNum(ULONG frame)
 {
   frameCounting = true;
   frameNumber = frame;
+  Log::getInstance()->log("Demuxer", Log::DEBUG, "setFrameNum %d", frame);
 }
 
 #ifndef NEW_DEMUXER
@@ -244,16 +247,59 @@ int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos)
   return ret;
 }
 
+ULONG DemuxerVDR::getFrameNumFromPTS(ULLONG pts)
+{
+  ULONG ret;
+  pthread_mutex_lock(&pts_map_mutex);
+  PTSMap::const_iterator iter = pts_map.begin();
+  bool onTarget = false;
+  while (iter != pts_map.end())
+  {
+    bool inRange;
+    if (pts < PTSMAP_THRESHOLD)
+      inRange = (iter->pts <= pts ||
+                 iter->pts >= (1LL<<33) - PTSMAP_THRESHOLD + pts);
+    else
+      inRange = (iter->pts <= pts &&
+                 iter->pts >= pts - PTSMAP_THRESHOLD);
+    if (onTarget)
+    {
+      if (!inRange) break; // We have hit the target
+    }
+    else
+    {
+      if (inRange) onTarget = true; // We are hot on the trail
+    }
+    ++iter;
+  }
+  --iter;
+  if (onTarget) ret = iter->frame;
+  pthread_mutex_unlock(&pts_map_mutex);
+  if (!onTarget)
+    return 0;
+  else
+    return ret;
+}
 void DemuxerVDR::PESPacketVDR::parseDetails()
 {
+  // TODO: Currently, we naïvely assume that a packet contains a new frame
+  // if and only if it contains a pts, and that no packet contains more
+  // than one new frame
+  
   DemuxerVDR* dx = (DemuxerVDR*)(DemuxerVDR::getInstance());
   PESPacket::parseDetails();
-  if (dx->frameCounting && pts != PTS_INVALID)
+  if (dx->frameCounting && pts != PTS_INVALID &&
+      packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
   {
     PTSMapEntry me;
     me.pts = pts;
     me.frame = dx->frameNumber;
-    dx->PTSMap.push_back(me);
-    if (dx->PTSMap.size() == PTSMAP_MAXENTRIES) dx->PTSMap.pop_front();
+    Log::getInstance()->log("Demuxer", Log::DEBUG, "Map %llu %u", me.pts, me.frame);
+    pthread_mutex_lock(&(dx->pts_map_mutex));
+    dx->pts_map.push_back(me);
+    if (dx->pts_map.size() == PTSMAP_MAXENTRIES) dx->pts_map.pop_front();
+    pthread_mutex_unlock(&(dx->pts_map_mutex));
+    ++(dx->frameNumber);
   }
 }
index e8e186ad674f326fba8e120174468a7655dffffb..4194fe06db811ec0ff7cb77042630897cf65395d 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef DEMUXERVDR_H
 #define DEMUXERVDR_H
 
+#include "pthread.h"
 #include <deque>
 #include "demuxer.h"
 #include "defines.h"
@@ -44,6 +45,7 @@ class DemuxerVDR : public Demuxer
     int put(UCHAR* buf, int len,ULLONG cur_pos);
 #endif
     void setFrameNum(ULONG frame);
+    ULONG getFrameNumFromPTS(ULLONG pts);
 
   private:
     int state;
@@ -54,7 +56,9 @@ class DemuxerVDR : public Demuxer
     ULONG frameNumber;
     bool frameCounting;
     typedef struct { ULLONG pts; ULONG frame; } PTSMapEntry;
-    std::deque<PTSMapEntry> PTSMap;
+    typedef std::deque<PTSMapEntry> PTSMap;
+    PTSMap pts_map;
+    pthread_mutex_t pts_map_mutex;
 };
 
 #endif