#endif
#define PTSMAP_MAXENTRIES 300
+#define PTSMAP_THRESHOLD 90000 // One second
+ // ISO standard demands at least one PTS every 0.7 seconds
DemuxerVDR::DemuxerVDR()
{
{
frameCounting = true;
frameNumber = frame;
+ Log::getInstance()->log("Demuxer", Log::DEBUG, "setFrameNum %d", frame);
}
#ifndef NEW_DEMUXER
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);
}
}
#ifndef DEMUXERVDR_H
#define DEMUXERVDR_H
+#include "pthread.h"
#include <deque>
#include "demuxer.h"
#include "defines.h"
int put(UCHAR* buf, int len,ULLONG cur_pos);
#endif
void setFrameNum(ULONG frame);
+ ULONG getFrameNumFromPTS(ULLONG pts);
private:
int state;
ULONG frameNumber;
bool frameCounting;
typedef struct { ULLONG pts; ULONG frame; } PTSMapEntry;
- std::deque<PTSMapEntry> PTSMap;
+ typedef std::deque<PTSMapEntry> PTSMap;
+ PTSMap pts_map;
+ pthread_mutex_t pts_map_mutex;
};
#endif