/*
- Copyright 2005-2006 Mark Calderbank
+ Copyright 2005-2007 Mark Calderbank
+ Copyright 2007 Marten Richter (AC3 support)
This file is part of VOMP.
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
#define DEMUXER_SEQ_HEAD 0x000001B3
-#else
-#define DEMUXER_SEQ_HEAD 0xB3010000
-#endif
-
#define DEMUXER_PIC_HEAD 0x00000101
#define SEEK_THRESHOLD 150000 // About 1.5 seconds
+// Statics
const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
-const ULLONG Demuxer::PESPacket::PTS_INVALID = (1LL << 33);
-
+const ULLONG PESPacket::PTS_INVALID = (1LL << 33);
Demuxer* Demuxer::instance = NULL;
+// PESPacket methods
+PESPacket::PESPacket()
+{
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x01;
+ init(0);
+}
+
+void PESPacket::init(UCHAR type)
+{
+ length = 0; size = 6;
+ data[3] = type;
+ data[4] = data[5] = 0;
+ packetType = type;
+ pts = PTS_INVALID;
+ seq_header = 1; // Unknown seq_header status
+}
+
+void PESPacket::truncate()
+{
+ init(packetType);
+}
+
+int PESPacket::write(UCHAR *buf, int len)
+{
+ if (length + len > 0xFFFA) return 0;
+ memcpy(data+length+6, buf, len);
+ length += len;
+ size += len;
+ data[4] = (length >> 8);
+ data[5] = (length & 0xFF);
+ // We have added data - reset seq_header indicator if necessary
+ if (seq_header == 0) seq_header = 1; // Reset to 'unknown'
+ // Extract PTS if this is the first write to reach 14 bytes
+ if (size - len < 14 && size >= 14 && data[7] & 0x80 &&
+ ( (packetType >= Demuxer::PESTYPE_AUD0 &&
+ packetType <= Demuxer::PESTYPE_AUDMAX)
+ ||
+ (packetType >= Demuxer::PESTYPE_VID0 &&
+ packetType <= Demuxer::PESTYPE_VIDMAX)
+ ))
+ {
+ // 14 bytes are now in, and PTS_DTS_flags indicate 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 );
+ }
+ return 1;
+}
+
+UCHAR PESPacket::operator[] (UINT index)
+{
+ if (index >= size)
+ return 0;
+ else
+ return data[index];
+}
+
+UINT PESPacket::findPictureHeader()
+{
+ if (size < 12) return 0;
+ UINT pattern = ( ((UINT)data[ 8] << 24) |
+ ((UINT)data[ 9] << 16) |
+ ((UINT)data[10] << 8) |
+ (UINT)data[11] );
+ UINT pos = 11;
+ while (pattern != DEMUXER_PIC_HEAD)
+ {
+ if (++pos >= size) return 0;
+ pattern = (pattern << 8) | data[pos];
+ }
+ return pos-3;
+}
+
+UINT PESPacket::findSeqHeader()
+{
+ if (seq_header != 1) return seq_header;
+ if (size < 12) return 0;
+ UINT pattern = ( ((UINT)data[ 8] << 24) |
+ ((UINT)data[ 9] << 16) |
+ ((UINT)data[10] << 8) |
+ (UINT)data[11] );
+ UINT pos = 11;
+ while (pattern != DEMUXER_SEQ_HEAD)
+ {
+ if (++pos >= size)
+ {
+ seq_header = 0;
+ return 0;
+ }
+ pattern = (pattern << 8) | data[pos];
+ }
+ seq_header = pos - 3;
+ return seq_header;
+}
+
+// Demuxer methods
Demuxer::Demuxer()
{
if (instance) return;
return videostream.drain();
}
-Demuxer::PESPacket::PESPacket()
-{
- data[0] = 0x00;
- data[1] = 0x00;
- data[2] = 0x01;
- init(0);
-}
-
-void Demuxer::PESPacket::init(UCHAR type)
-{
- length = submitted = 0;
- size = 6; closed = false;
- data[3] = type;
- data[4] = data[5] = 0;
- packetType = type;
- pts = PTS_INVALID;
- seq_header = false;
-}
-
-void Demuxer::PESPacket::truncate()
-{
- init(packetType);
-}
-
-int Demuxer::PESPacket::write(UCHAR *buf, int len)
-{
- if (closed) return 0;
- if (length + len > 0xFFFA) return 0;
- memcpy(data+length+6, buf, len);
- length += len;
- size += len;
- data[4] = (length >> 8);
- data[5] = (length & 0xFF);
- return 1;
-}
-
-int Demuxer::PESPacket::submit()
+bool Demuxer::submitPacket(PESPacket& packet)
{
- if (submitted >= size) return 0;
- if (!closed) parseDetails();
+ UINT sent = 0;
+ UCHAR packet_type = packet.getPacketType();
- closed = true;
- Demuxer* dx = Demuxer::getInstance();
- int sent = 0;
- if (packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
+ if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
{
- if (dx->video_current == -1) dx->video_current = packetType;
- if (dx->video_current == packetType && !dx->vid_seeking)
- sent = dx->videostream.put(data+submitted, size-submitted, MPTYPE_VIDEO);
+ if (video_current == -1) video_current = packet_type;
+ if (video_current == packet_type && !vid_seeking)
+ sent = videostream.put(packet.getData(), packet.getSize(), MPTYPE_VIDEO);
else
- sent = size-submitted;
+ sent = packet.getSize();
}
- else if (packetType >= PESTYPE_AUD0 && packetType <= PESTYPE_AUDMAX)
+ else if (packet_type >= PESTYPE_AUD0 && packet_type <= PESTYPE_AUDMAX)
{
- if (dx->audio_current == -1) dx->audio_current = packetType;
-
- dx->avail_mpaudchan[packetType-PESTYPE_AUD0]=true;
-
- if (dx->audio_current == packetType && !dx->aud_seeking)
- sent = dx->audiostream.put(data+submitted, size-submitted, MPTYPE_MPEG_AUDIO);
+ if (audio_current == -1) audio_current = packet_type;
+ avail_mpaudchan[packet_type - PESTYPE_AUD0] = true;
+ if (audio_current == packet_type && !aud_seeking)
+ sent = audiostream.put(packet.getData(), packet.getSize(), MPTYPE_MPEG_AUDIO);
else
- sent = size-submitted;
+ sent = packet.getSize();
}
- else if (packetType == PESTYPE_PRIVATE_1)
+ else if (packet_type == PESTYPE_PRIVATE_1)
{
- if (substream >= PESTYPE_SUBSTREAM_AC30 && substream <= PESTYPE_SUBSTREAM_AC3MAX)
+ if (packet.getSubstream() >= PESTYPE_SUBSTREAM_AC30 &&
+ packet.getSubstream() <= PESTYPE_SUBSTREAM_AC3MAX)
{
- dx->avail_ac3audchan[substream-PESTYPE_SUBSTREAM_AC30]=true;
- if (substream == dx->audio_current)
+ avail_ac3audchan[packet.getSubstream() - PESTYPE_SUBSTREAM_AC30] = true;
+ if (packet.getSubstream() == audio_current)
{
- sent = dx->audiostream.put(data+submitted,size-submitted,(dx->ispre_1_3_19)?MPTYPE_AC3_PRE13:MPTYPE_AC3);
+ sent = audiostream.put(packet.getData(), packet.getSize(), (ispre_1_3_19)? MPTYPE_AC3_PRE13 : MPTYPE_AC3);
}
else
{
- sent = size-submitted;
+ sent = packet.getSize();
}
}
}
else
{
- sent = size-submitted;
+ sent = packet.getSize();
}
- submitted += sent;
- if (submitted < size) // Stream is full.
- return 0;
+ if (sent < packet.getSize()) // Stream is full.
+ return false;
else
- return 1;
+ return true;
}
-void Demuxer::PESPacket::parseDetails()
+void Demuxer::parsePacketDetails(PESPacket& packet)
{
- Demuxer* dx = Demuxer::getInstance();
- if (packetType >= PESTYPE_AUD0 && packetType <= PESTYPE_AUDMAX)
+ if (packet.getPacketType() >= PESTYPE_AUD0 &&
+ packet.getPacketType() <= PESTYPE_AUDMAX)
{
// Extract audio PTS if it exists
- if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS
+ if (packet.hasPTS())
{
- 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 );
-
+ audio_pts = packet.getPTS();
// 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
// SEEK_THRESHOLD. We consider the possibility of PTS wrap.
- if (dx->aud_seeking && !dx->vid_seeking &&
- !( (dx->video_pts_seek > dx->audio_pts &&
- dx->video_pts_seek - dx->audio_pts < SEEK_THRESHOLD)
+ if (aud_seeking && !vid_seeking &&
+ !( (video_pts_seek > audio_pts &&
+ video_pts_seek - audio_pts < SEEK_THRESHOLD)
||
- (dx->video_pts_seek < dx->audio_pts &&
- dx->video_pts_seek + (1LL<<33) -
- dx->audio_pts < SEEK_THRESHOLD) ))
+ (video_pts_seek < audio_pts &&
+ video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
{
- dx->aud_seeking = 0;
+ aud_seeking = 0;
Log::getInstance()->log("Demuxer", Log::DEBUG,
- "Leaving audio sync: Audio PTS = %llu", dx->audio_pts);
+ "Leaving audio sync: Audio PTS = %llu", audio_pts);
}
}
}
- else if (packetType == PESTYPE_PRIVATE_1) //Private Stream
+ else if (packet.getPacketType() == PESTYPE_PRIVATE_1) // Private stream
{
//Inspired by vdr's device.c
- int payload_begin = data[8]+9;
- unsigned char substream_id = data[payload_begin];
+ int payload_begin = packet[8]+9;
+ unsigned char substream_id = packet[payload_begin];
unsigned char substream_type = substream_id & 0xF0;
unsigned char substream_index = substream_id & 0x1F;
pre_1_3_19_Recording: //This is for old recordings stuff
- if (dx->ispre_1_3_19)
+ if (ispre_1_3_19)
{
substream_id = PESTYPE_PRIVATE_1;
substream_type = 0x80;
case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
break;
case 0x80: //ac3, currently only one ac3 track per recording supported
- substream=substream_type+substream_index;
+ packet.setSubstream(substream_type+substream_index);
// Extract audio PTS if it exists
- if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS
+ if (packet.hasPTS())
{
- 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 );
+ audio_pts = packet.getPTS();
// 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
// SEEK_THRESHOLD. We consider the possibility of PTS wrap.
- if (dx->aud_seeking && !dx->vid_seeking &&
- !( (dx->video_pts_seek > dx->audio_pts &&
- dx->video_pts_seek - dx->audio_pts < SEEK_THRESHOLD)
+ if (aud_seeking && !vid_seeking &&
+ !( (video_pts_seek > audio_pts &&
+ video_pts_seek - audio_pts < SEEK_THRESHOLD)
||
- (dx->video_pts_seek < dx->audio_pts &&
- dx->video_pts_seek + (1LL<<33) -
- dx->audio_pts < SEEK_THRESHOLD) ))
+ (video_pts_seek < audio_pts &&
+ video_pts_seek + (1LL<<33) - audio_pts < SEEK_THRESHOLD) ))
{
- dx->aud_seeking = 0;
- Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", dx->audio_pts);
+ aud_seeking = 0;
+ Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", audio_pts);
}
}
break;
default:
- if (!dx->ispre_1_3_19)
+ if (!ispre_1_3_19)
{
- dx->ispre_1_3_19=true; //switching to compat mode
+ ispre_1_3_19=true; //switching to compat mode
goto pre_1_3_19_Recording;
}
else
{
- substream=0;
+ packet.setSubstream(0);
}
break;
}
}
- else if (packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
+ else if (packet.getPacketType() >= PESTYPE_VID0 &&
+ packet.getPacketType() <= PESTYPE_VIDMAX)
{
// Extract video PTS if it exists
- if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS
- {
- 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 );
- }
+ if (packet.hasPTS()) video_pts = packet.getPTS();
- // Now, scan for a sequence header and extract information
- UINT pos = 9; // Start searching from byte 9
- while (pos < size - 5)
+ // If there is a sequence header, extract information
+ UINT pos = packet.findSeqHeader();
+ if (pos > 1)
{
- UINT pattern = *(UINT*)(data+pos);
- if (pattern == DEMUXER_SEQ_HEAD)
+ pos += 4;
+ if (pos+6 >= packet.getSize()) return;
+ horizontal_size = ((int)packet[pos] << 4) | ((int)packet[pos+1] >> 4);
+ vertical_size = (((int)packet[pos+1] & 0xf) << 8) | (int)packet[pos+2];
+ setAspectRatio((enum AspectRatio)(packet[pos+3] >> 4));
+ frame_rate = packet[pos+3] & 0x0f;
+ if (frame_rate >= 1 && frame_rate <= 8)
+ frame_rate = FrameRates[frame_rate];
+ else
+ frame_rate = 0;
+ bit_rate = ((int)packet[pos+4] << 10) |
+ ((int)packet[pos+5] << 2) |
+ ((int)packet[pos+6] >> 6);
+ if (vid_seeking)
{
- seq_header = true;
- pos += 4;
- if (pos+6 >= size) return;
- dx->horizontal_size = ((int)data[pos] << 4) | ((int)data[pos+1] >> 4);
- dx->vertical_size = (((int)data[pos+1] & 0xf) << 8) | (int)data[pos+2];
- dx->setAspectRatio((enum AspectRatio)(data[pos+3] >> 4));
- dx->frame_rate = data[pos+3] & 0x0f;
- if (dx->frame_rate >= 1 && dx->frame_rate <= 8)
- dx->frame_rate = FrameRates[dx->frame_rate];
- else
- dx->frame_rate = 0;
- dx->bit_rate = ((int)data[pos+4] << 10) |
- ((int)data[pos+5] << 2) |
- ((int)data[pos+6] >> 6);
- if (dx->vid_seeking)
- {
- dx->vid_seeking = 0;
- dx->video_pts_seek = dx->video_pts;
- Log::getInstance()->log("Demuxer", Log::DEBUG,
- "Entering audio sync: Video PTS = %llu", dx->video_pts);
- Log::getInstance()->log("Demuxer", Log::DEBUG,
- "Entering audio sync: Audio PTS = %llu", dx->audio_pts);
- }
- return;
+ vid_seeking = 0;
+ video_pts_seek = video_pts;
+ Log::getInstance()->log("Demuxer", Log::DEBUG,
+ "Entering audio sync: Video PTS = %llu", video_pts);
+ Log::getInstance()->log("Demuxer", Log::DEBUG,
+ "Entering audio sync: Audio PTS = %llu", audio_pts);
}
- else pos++;
+ return;
}
}
}
-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;
-}
-
UINT Demuxer::stripAudio(UCHAR* buf, UINT len)
{
UINT read_pos = 0, write_pos = 0;
/*
- Copyright 2005-2006 Mark Calderbank
+ Copyright 2005-2007 Mark Calderbank
+ Copyright 2007 Marten Richter (AC3 support)
This file is part of VOMP.
/*
-Thanks goes to Jon Gettler of the MVPMC project and Stephen Rice for
-the demuxer in mvpmc. It was used in the creation of this Demuxer,
+Thanks go to Jon Gettler of the MVPMC project and Stephen Rice for
+the demuxer in mvpmc. It was used in the creation of this demuxer;
however, no code was copied verbatim.
*/
#include "callback.h"
#include "draintarget.h"
-#define PES_AUDIO_START 0xc0
-#define PES_AUDIO_END 0xcf
+class PESPacket
+{
+ public:
+ PESPacket();
+ void init(UCHAR type);
+ void truncate();
+ int write(UCHAR* buf, int len);
+
+ UCHAR operator[] (UINT index); // return data[index] if in bounds, else 0
+ // so no proper error condition but never mind for now
+ const UCHAR* getData() { return data; }
+ UINT getLength() { return length; }
+ UINT getSize() { return size; }
+ UCHAR getPacketType() { return packetType; }
+ void setSubstream(UCHAR s) { substream = s; }
+ UCHAR getSubstream() { return substream; }
+ bool hasPTS() { return (pts != PTS_INVALID); }
+ ULLONG getPTS() { return pts; }
+
+ UINT findPictureHeader();
+ UINT findSeqHeader();
+ static const ULLONG PTS_INVALID;
+ protected:
+ UCHAR data[0x10000];
+ UINT length, size;
+ UCHAR packetType;
+ UCHAR substream;
+ ULLONG pts;
+ UINT seq_header; // 0 = no, 1 = unknown, else = header offset
+};
class Demuxer
{
-protected:
- class PESPacket
- {
- public:
- PESPacket();
- void init(UCHAR type);
- void truncate();
- int write(UCHAR* buf, int len);
- int submit();
- protected:
- UCHAR data[0x10000];
- UINT length, size;
- bool closed;
- UCHAR packetType;
- UCHAR substream; //for ac3
- ULLONG pts;
- bool seq_header;
- UINT submitted;
- virtual void parseDetails();
- UINT findPictureHeader();
-
-
- static const ULLONG PTS_INVALID;
- };
- friend class PESPacket;
-
public:
Demuxer();
virtual ~Demuxer();
// *static function*
static bool scanForVideo(UCHAR* buf, UINT len);
- protected:
- // General demuxer objects and status indicators
- static Demuxer* instance;
- Stream videostream;
- Stream audiostream;
- int shutdown();
- bool initted;
- bool vid_seeking;
- bool aud_seeking;
- int video_current, audio_current;
-
- // Video stream information
- void setAspectRatio(enum AspectRatio);
- Callback* callback;
-
- int horizontal_size;
- int vertical_size;
- enum AspectRatio aspect_ratio;
- int arcnt;
- int frame_rate;
- int bit_rate;
- ULLONG video_pts;
- ULLONG video_pts_seek;
- ULLONG audio_pts;
-
- // Constants
- static const int FrameRates[9];
-
enum PESTYPE
{
PESTYPE_PRIVATE_1 = 0xBD,
PESTYPE_SUBSTREAM_AC3MAX = PESTYPE_SUBSTREAM_AC37
};
+ protected:
+ // Operations on PES packets
+ bool submitPacket(PESPacket&);
+ void parsePacketDetails(PESPacket&);
+
+ // General demuxer objects and status indicators
+ static Demuxer* instance;
+ Stream videostream;
+ Stream audiostream;
+ int shutdown();
+ bool initted;
+ bool vid_seeking;
+ bool aud_seeking;
+ int video_current, audio_current;
+
+ // Video stream information
+ void setAspectRatio(enum AspectRatio);
+ Callback* callback;
+
+ int horizontal_size;
+ int vertical_size;
+ enum AspectRatio aspect_ratio;
+ int arcnt;
+ int frame_rate;
+ int bit_rate;
+ ULLONG video_pts;
+ ULLONG video_pts_seek;
+ ULLONG audio_pts;
+
+ // Constants
+ static const int FrameRates[9];
+
bool ispre_1_3_19;
bool avail_mpaudchan[PESTYPE_AUDMAX-PESTYPE_AUD0+1];
bool avail_ac3audchan[PESTYPE_SUBSTREAM_AC3MAX-PESTYPE_SUBSTREAM_AC30+1];
/*
- Copyright 2005-2006 Mark Calderbank
+ Copyright 2005-2007 Mark Calderbank
This file is part of VOMP.
int ret = 0; // return number of bytes consumed
if (submitting)
{
- if (packet.submit() == 0) // Still full!
+ if (submitPacket(packet) == 0) // Still full!
return ret;
else
submitting = false;
packet.write(buf, state);
buf += state; len -= state; ret += state;
state = 0;
- if (packet.submit() == 0) // Stream is full
+ parseVDRPacketDetails();
+ if (submitPacket(packet) == 0) // Stream is full
{
submitting = true;
return ret;
packet.write(buf, packetLength);
buf += packetLength; len -= packetLength; ret += packetLength;
state = 0;
- if (packet.submit() == 0) // Stream is full
+ parseVDRPacketDetails();
+ if (submitPacket(packet) == 0) // Stream is full
{
submitting = true;
return ret;
return ref_frame + difference * Video::getInstance()->getFPS() / 90000;
}
-void DemuxerVDR::PESPacketVDR::parseDetails()
+void DemuxerVDR::parseVDRPacketDetails()
{
- DemuxerVDR* dx = (DemuxerVDR*)(DemuxerVDR::getInstance());
- PESPacket::parseDetails();
+ parsePacketDetails(packet);
- if (dx->packetCounting &&
- packetType >= PESTYPE_AUD0 && packetType <= PESTYPE_AUDMAX)
+ if (packetCounting && packet.getPacketType() >= PESTYPE_AUD0 &&
+ packet.getPacketType() <= PESTYPE_AUDMAX)
{
- dx->packetNumber++;
+ packetNumber++;
}
- if (dx->frameCounting && findPictureHeader() &&
- packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
+ if (frameCounting && packet.findPictureHeader() &&
+ packet.getPacketType() >= PESTYPE_VID0 &&
+ packet.getPacketType() <= PESTYPE_VIDMAX)
{
- ULONG frame_num = (dx->frameNumber)++;
- if (seq_header && pts != PTS_INVALID)
+ ULONG frame_num = (frameNumber)++;
+ if (packet.findSeqHeader() > 1 && packet.hasPTS())
{
PTSMapEntry me;
- dx->pts_map_mutex.Lock();
- if (dx->pts_map.empty())
+ pts_map_mutex.Lock();
+ if (pts_map.empty())
{
- me.pts = pts;
+ me.pts = packet.getPTS();
me.frame = frame_num;
- dx->pts_map_mutex.Unlock();
+ pts_map_mutex.Unlock();
Log::getInstance()->log("Demuxer", Log::DEBUG, "+* PTS INIT *+ %llu %u", me.pts, me.frame);
- dx->pts_map_mutex.Lock();
- dx->pts_map.push_front(me);
+ pts_map_mutex.Lock();
+ pts_map.push_front(me);
}
- me = dx->pts_map.front();
- dx->pts_map_mutex.Unlock();
+ me = pts_map.front();
+ pts_map_mutex.Unlock();
UINT fps = Video::getInstance()->getFPS();
ULLONG pts_expected = me.pts + 90000*(frame_num - me.frame) / fps;
while (pts_expected > (1LL<<33)) pts_expected -= (1LL<<33);
- if (PTSDistance(pts_expected, pts) > PTS_JUMP_MARGIN) // PTS jump!
+ if (PTSDistance(pts_expected, packet.getPTS()) > PTS_JUMP_MARGIN) // PTS jump!
{
-Log::getInstance()->log("Demuxer", Log::DEBUG, "+* PTS JUMP *+ %llu %u", pts, frame_num);
- me.pts = pts;
+Log::getInstance()->log("Demuxer", Log::DEBUG, "+* PTS JUMP *+ %llu %u", packet.getPTS(), frame_num);
+ me.pts = packet.getPTS();
me.frame = frame_num;
- dx->pts_map_mutex.Lock();
- dx->pts_map.push_front(me);
- dx->pts_map_mutex.Unlock();
+ pts_map_mutex.Lock();
+ pts_map.push_front(me);
+ pts_map_mutex.Unlock();
}
}
}