From cbbf7675610653ccb8c752516c151c39d6075fe9 Mon Sep 17 00:00:00 2001 From: Mark Calderbank Date: Sun, 11 Jun 2006 19:55:08 +0000 Subject: [PATCH] Demuxer frame counting, second step --- demuxer.h | 1 + demuxervdr.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++--- demuxervdr.h | 6 +++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/demuxer.h b/demuxer.h index 188cb37..a30ad52 100644 --- 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; } diff --git a/demuxervdr.cc b/demuxervdr.cc index ba9278e..9bdf7ba 100644 --- a/demuxervdr.cc +++ b/demuxervdr.cc @@ -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); } } diff --git a/demuxervdr.h b/demuxervdr.h index e8e186a..4194fe0 100644 --- a/demuxervdr.h +++ b/demuxervdr.h @@ -21,6 +21,7 @@ #ifndef DEMUXERVDR_H #define DEMUXERVDR_H +#include "pthread.h" #include #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 PTSMap; + typedef std::deque PTSMap; + PTSMap pts_map; + pthread_mutex_t pts_map_mutex; }; #endif -- 2.39.5