From 82b96d86d51ef44bad27322b87a24e9d5f3829da Mon Sep 17 00:00:00 2001 From: Mark Calderbank Date: Wed, 21 Jun 2006 20:53:25 +0000 Subject: [PATCH] Count frames properly in VDR demuxer --- demuxer.cc | 19 +++++++++++++++++-- demuxer.h | 1 + demuxervdr.cc | 18 +++--------------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index e2426d5..0b6f2cd 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -33,6 +33,8 @@ #define DEMUXER_SEQ_HEAD 0xB3010000 #endif +#define DEMUXER_PIC_HEAD 0x00000101 + #define SEEK_THRESHOLD 150000 // About 1.5 seconds const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 }; @@ -237,7 +239,7 @@ void Demuxer::PESPacket::parseDetails() if (packetType >= PESTYPE_AUD0 && packetType <= PESTYPE_AUDMAX) { // Extract audio PTS if it exists - if ( data[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present + if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS { dx->audio_pts = pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) | ( (ULLONG)(data[10]) << 22 ) | @@ -265,7 +267,7 @@ void Demuxer::PESPacket::parseDetails() else if (packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX) { // Extract video PTS if it exists - if ( data[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present + if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS { dx->video_pts = pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) | ( (ULLONG)(data[10]) << 22 ) | @@ -310,3 +312,16 @@ void Demuxer::PESPacket::parseDetails() } } } + +UINT Demuxer::PESPacket::findPictureHeader() +{ + if (size < 12) return 0; + UINT pattern = *(UINT*)(data+8); + UINT pos = 11; + while (pattern != DEMUXER_PIC_HEAD) + { + if (++pos >= size) return 0; + pattern = (pattern << 8) | data[pos]; + } + return pos-3; +} diff --git a/demuxer.h b/demuxer.h index 25b4b35..6447f0c 100644 --- a/demuxer.h +++ b/demuxer.h @@ -60,6 +60,7 @@ protected: bool seq_header; UINT submitted; virtual void parseDetails(); + UINT findPictureHeader(); static const ULLONG PTS_INVALID; }; diff --git a/demuxervdr.cc b/demuxervdr.cc index b22513e..cb0a4fd 100644 --- a/demuxervdr.cc +++ b/demuxervdr.cc @@ -28,17 +28,8 @@ #define __BYTE_ORDER __LITTLE_ENDIAN #endif -#if __BYTE_ORDER == __BIG_ENDIAN -#define DEMUXER_SEQ_HEAD 0x000001B3 -#else -#define DEMUXER_SEQ_HEAD 0xB3010000 -#endif - #define PTS_JUMP_MARGIN 10000 -#define PTS_ERASE_MARGIN 900000 // Erase PTS record if we get within 10 seconds #define PTS_ALLOWANCE 90000 -//#define PTS_UPDATE_FRAMES 2048 -//#define PTS_EXPIRE_FRAMES 2500 // TODO: PTS class to handle wrapping arithmetic & comparisons? static ULLONG PTSDistance(ULLONG pts1, ULLONG pts2) @@ -322,17 +313,14 @@ Log::getInstance()->log("Demuxer", Log::DEBUG, "STILL USING OLD REF"); 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 && findPictureHeader() && packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX) { ULONG frame_num = (dx->frameNumber)++; - if (seq_header) + if (seq_header && pts != PTS_INVALID) { PTSMapEntry me; pthread_mutex_lock(&(dx->pts_map_mutex)); -- 2.39.5