From 686d80d4a39053d28772848cf97845e8a0368d67 Mon Sep 17 00:00:00 2001 From: Mark Calderbank Date: Sun, 11 Jun 2006 17:04:37 +0000 Subject: [PATCH] Demuxer frame counting: first step --- demuxer.cc | 22 ++++++++++++---------- demuxer.h | 9 ++++++--- demuxervdr.cc | 38 ++++++++++++++++++++++++++++++++------ demuxervdr.h | 18 +++++++++++++++--- 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index e90d4f0..b29b398 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -36,6 +36,7 @@ #define SEEK_THRESHOLD 150000 // About 1.5 seconds const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 }; +const ULLONG Demuxer::PESPacket::PTS_INVALID = (1LL << 33); Demuxer* Demuxer::instance = NULL; @@ -167,6 +168,7 @@ void Demuxer::PESPacket::init(UCHAR type) data[3] = type; data[4] = data[5] = 0; packetType = type; + pts = PTS_INVALID; } int Demuxer::PESPacket::write(UCHAR *buf, int len) @@ -236,11 +238,11 @@ void Demuxer::PESPacket::parseDetails() // Extract audio PTS if it exists if ( data[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present { - dx->audio_pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) | - ( (ULLONG)(data[10]) << 22 ) | - ( (ULLONG)(data[11] & 0xFE) << 14 ) | - ( (ULLONG)(data[12]) << 7 ) | - ( (ULLONG)(data[13] & 0xFE) >> 1 ); + dx->audio_pts = pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) | + ( (ULLONG)(data[10]) << 22 ) | + ( (ULLONG)(data[11] & 0xFE) << 14 ) | + ( (ULLONG)(data[12]) << 7 ) | + ( (ULLONG)(data[13] & 0xFE) >> 1 ); // We continue to seek on the audio if the video PTS that we // are trying to match is ahead of the audio PTS by at most @@ -264,11 +266,11 @@ void Demuxer::PESPacket::parseDetails() // Extract video PTS if it exists if ( data[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present { - dx->video_pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) | - ( (ULLONG)(data[10]) << 22 ) | - ( (ULLONG)(data[11] & 0xFE) << 14 ) | - ( (ULLONG)(data[12]) << 7 ) | - ( (ULLONG)(data[13] & 0xFE) >> 1 ); + dx->video_pts = pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) | + ( (ULLONG)(data[10]) << 22 ) | + ( (ULLONG)(data[11] & 0xFE) << 14 ) | + ( (ULLONG)(data[12]) << 7 ) | + ( (ULLONG)(data[13] & 0xFE) >> 1 ); } // Now, scan for a sequence header and extract information diff --git a/demuxer.h b/demuxer.h index 7487c38..188cb37 100644 --- a/demuxer.h +++ b/demuxer.h @@ -26,7 +26,6 @@ however, no code was copied verbatim. */ - #ifndef DEMUXER_H #define DEMUXER_H @@ -52,13 +51,16 @@ protected: #else int submit(ULLONG cur_pos); #endif - private: + protected: UCHAR data[0x10000]; UINT length, size; bool closed; UCHAR packetType; + ULLONG pts; UINT submitted; - void parseDetails(); + virtual void parseDetails(); + + static const ULLONG PTS_INVALID; }; friend class PESPacket; @@ -83,6 +85,7 @@ protected: #else virtual int put(UCHAR* buf, int len,ULLONG cur_pos) = 0; #endif + virtual void setFrameNum(ULONG frame) {} int getHorizontalSize() { return horizontal_size; } int getVerticalSize() { return vertical_size; } diff --git a/demuxervdr.cc b/demuxervdr.cc index 28668c3..ba9278e 100644 --- a/demuxervdr.cc +++ b/demuxervdr.cc @@ -33,13 +33,18 @@ #define DEMUXER_SEQ_HEAD 0xB3010000 #endif -DemuxerVDR::DemuxerVDR() { -} //MS Visual C++ needs the Bracket after the first line other it ignores the line +#define PTSMAP_MAXENTRIES 300 + +DemuxerVDR::DemuxerVDR() +{ + frameCounting = false; +} void DemuxerVDR::flush() { state = 0; submitting = false; + frameCounting = false; Demuxer::flush(); } @@ -108,6 +113,13 @@ int DemuxerVDR::findVideoPTS(UCHAR* buf, int len, ULLONG* dest) // No PTS found. return 0; } + +void DemuxerVDR::setFrameNum(ULONG frame) +{ + frameCounting = true; + frameNumber = frame; +} + #ifndef NEW_DEMUXER int DemuxerVDR::put(UCHAR* buf, int len) #else @@ -140,9 +152,9 @@ int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos) buf += state; len -= state; ret += state; state = 0; #ifndef NEW_DEMUXER - if (packet.submit() == 0) // Still full! + if (packet.submit() == 0) // Stream is full #else - if (packet.submit(current_position) == 0) // Still full! + if (packet.submit(current_position) == 0) // Stream is full #endif { submitting = true; @@ -211,9 +223,9 @@ int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos) #endif state = 0; #ifndef NEW_DEMUXER - if (packet.submit() == 0) // Still full! + if (packet.submit() == 0) // Stream is full #else - if (packet.submit(current_position) == 0) // Still full! + if (packet.submit(current_position) == 0) // Stream is full #endif { submitting = true; @@ -231,3 +243,17 @@ int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos) } return ret; } + +void DemuxerVDR::PESPacketVDR::parseDetails() +{ + DemuxerVDR* dx = (DemuxerVDR*)(DemuxerVDR::getInstance()); + PESPacket::parseDetails(); + if (dx->frameCounting && pts != PTS_INVALID) + { + PTSMapEntry me; + me.pts = pts; + me.frame = dx->frameNumber; + dx->PTSMap.push_back(me); + if (dx->PTSMap.size() == PTSMAP_MAXENTRIES) dx->PTSMap.pop_front(); + } +} diff --git a/demuxervdr.h b/demuxervdr.h index 410a23a..e8e186a 100644 --- a/demuxervdr.h +++ b/demuxervdr.h @@ -21,11 +21,18 @@ #ifndef DEMUXERVDR_H #define DEMUXERVDR_H +#include #include "demuxer.h" #include "defines.h" class DemuxerVDR : public Demuxer { + class PESPacketVDR : public PESPacket + { + void parseDetails(); + }; + friend class PESPacketVDR; + public: DemuxerVDR(); void flush(); @@ -34,15 +41,20 @@ class DemuxerVDR : public Demuxer #ifndef NEW_DEMUXER int put(UCHAR* buf, int len); #else - int put(UCHAR* buf, int len,ULLONG cur_pos); + int put(UCHAR* buf, int len,ULLONG cur_pos); #endif - + void setFrameNum(ULONG frame); private: int state; bool submitting; int packetLength; - PESPacket packet; + PESPacketVDR packet; + + ULONG frameNumber; + bool frameCounting; + typedef struct { ULLONG pts; ULONG frame; } PTSMapEntry; + std::deque PTSMap; }; #endif -- 2.39.2