#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;
data[3] = type;
data[4] = data[5] = 0;
packetType = type;
+ pts = PTS_INVALID;
}
int Demuxer::PESPacket::write(UCHAR *buf, int len)
// 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
// 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
*/
-
#ifndef DEMUXER_H
#define DEMUXER_H
#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;
#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; }
#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();
}
// 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
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;
#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;
}
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();
+ }
+}
#ifndef DEMUXERVDR_H
#define DEMUXERVDR_H
+#include <deque>
#include "demuxer.h"
#include "defines.h"
class DemuxerVDR : public Demuxer
{
+ class PESPacketVDR : public PESPacket
+ {
+ void parseDetails();
+ };
+ friend class PESPacketVDR;
+
public:
DemuxerVDR();
void flush();
#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<PTSMapEntry> PTSMap;
};
#endif