*/
#include "demuxer.h"
+#ifndef WIN32
#include <endian.h>
+#else
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#define DEMUXER_SEQ_HEAD 0x000001B3
#define DEMUXER_SEQ_HEAD 0xB3010000
#endif
+
+
const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
Demuxer* Demuxer::instance = NULL;
initted = false;
callback = NULL;
arcnt = 0;
+ vid_seeking = aud_seeking = false;
+ video_pts = audio_pts = 0;
}
Demuxer::~Demuxer()
data[5] = (length & 0xFF);
return 1;
}
-
+#ifndef NEW_DEMUXER
int Demuxer::PESPacket::submit()
+#else
+int Demuxer::PESPacket::submit(ULLONG cur_pos)
+#endif
{
if (submitted >= size) return 0;
if (!closed) parseDetails();
{
if (dx->video_current == -1) dx->video_current = packetType;
if (dx->video_current == packetType && !dx->vid_seeking)
+#ifndef NEW_DEMUXER
sent = dx->videostream.put(data+submitted, size-submitted);
+#else
+ sent = dx->videostream.put(data+submitted, size-submitted,cur_pos);
+#endif
else
sent = size-submitted;
}
else if (packetType >= PESTYPE_AUD0 && packetType <= PESTYPE_AUDMAX)
{
if (dx->audio_current == -1) dx->audio_current = packetType;
- if (dx->audio_current == packetType & !dx->aud_seeking)
+ if (dx->audio_current == packetType && !dx->aud_seeking)
+#ifndef NEW_DEMUXER
sent = dx->audiostream.put(data+submitted, size-submitted);
+#else
+ sent = dx->audiostream.put(data+submitted, size-submitted,cur_pos);
+#endif
else
sent = size-submitted;
}
class Demuxer
{
+public: //MS Visual C++ need this, private does not work for DemuxerVDR, Marten
class PESPacket
{
public:
PESPacket();
void init(UCHAR type);
int write(UCHAR* buf, int len);
+#ifndef NEW_DEMUXER
int submit();
+#else
+ int submit(ULLONG cur_pos);
+#endif
private:
UCHAR data[0x10000];
UINT length, size;
virtual int scan(UCHAR* buf, int len) = 0;
virtual int findVideoPTS(UCHAR* buf, int len, ULLONG* dest) = 0;
+#ifndef NEW_DEMUXER
virtual int put(UCHAR* buf, int len) = 0;
+#else
+ virtual int put(UCHAR* buf, int len,ULLONG cur_pos) = 0;
+#endif
int getHorizontalSize() { return horizontal_size; }
int getVerticalSize() { return vertical_size; }
*/
#include "demuxervdr.h"
+#ifndef WIN32
#include <endian.h>
+#else
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define DEMUXER_SEQ_HEAD 0x000001B3
+#else
+#define DEMUXER_SEQ_HEAD 0xB3010000
+#endif
-DemuxerVDR::DemuxerVDR() {}
+DemuxerVDR::DemuxerVDR() {
+} //MS Visual C++ needs the Bracket after the first line other it ignores the line
void DemuxerVDR::flush()
{
// No PTS found.
return 0;
}
-
+#ifndef NEW_DEMUXER
int DemuxerVDR::put(UCHAR* buf, int len)
+#else
+int DemuxerVDR::put(UCHAR* buf, int len, ULLONG cur_pos)
+#endif
{
int ret = 0; // return number of bytes consumed
+#ifdef NEW_DEMUXER
+ ULLONG current_position = cur_pos;
+#endif
+
if (submitting)
{
+#ifndef NEW_DEMUXER
if (packet.submit() == 0) // Still full!
+#else
+ if (packet.submit(current_position) == 0) // Still full!
+#endif
return ret;
else
submitting = false;
packet.write(buf, state);
buf += state; len -= state; ret += state;
state = 0;
- if (packet.submit() == 0) // Stream is full.
+#ifndef NEW_DEMUXER
+ if (packet.submit() == 0) // Still full!
+#else
+ if (packet.submit(current_position) == 0) // Still full!
+#endif
{
submitting = true;
return ret;
}
buf++; len--; ret++;
+#ifdef NEW_DEMUXER
+ current_position++;
+#endif
if (state == -6) // Packet header complete
{
{
packet.write(buf, packetLength);
buf += packetLength; len -= packetLength; ret += packetLength;
+#ifdef NEW_DEMUXER
+ current_position+=(ULLONG)packetLength;
+#endif
state = 0;
- if (packet.submit() == 0) // Stream is full.
+#ifndef NEW_DEMUXER
+ if (packet.submit() == 0) // Still full!
+#else
+ if (packet.submit(current_position) == 0) // Still full!
+#endif
{
submitting = true;
return ret;
void flush();
int scan(UCHAR* buf, int len);
int findVideoPTS(UCHAR* buf, int len, ULLONG* dest);
+#ifndef NEW_DEMUXER
int put(UCHAR* buf, int len);
+#else
+ int put(UCHAR* buf, int len,ULLONG cur_pos);
+#endif
+
private:
int state;
bool submitting;
int packetLength;
- PESPacket packet;
+ PESPacket packet;
};
#endif
int Player::init()
{
if (initted) return 0;
-
+#ifndef WIN32
pthread_mutex_init(&mutex, NULL);
+#else
+ mutex=CreateMutex(NULL,FALSE,NULL);
+#endif
demuxer = new DemuxerVDR();
if (!demuxer) return 0;
delete demuxer;
demuxer = NULL;
+#ifdef WIN32
+ CloseHandle(mutex);
+#endif
return 1;
}
logger->log("Player", Log::DEBUG, "LOCKED");
#else
- // FIXME Marten
+ WaitForSingleObject(mutex, INFINITE );
#endif
}
logger->log("Player", Log::DEBUG, "UNLOCKING");
pthread_mutex_unlock(&mutex);
#else
- // FIXME Marten
+ ReleaseMutex(mutex);
#endif
}
void Player::setStartTS(UINT dataInBuffer)
{
+#ifndef NEW_DEMUXER
if (isRecording && feedPosition) // (feedPosition != 0)
{
// FIXME find out how much data need to get to find a TS
{
demuxer->findVideoPTS(threadBuffer, dataInBuffer, &startTS);
}
+#else
+ startTS=0;
+#endif
}
void Player::setEndTS()
{
logger->log("Player", Log::DEBUG, "Setting end TS");
-
+#ifndef NEW_DEMUXER
UINT thisRead;
UCHAR* tempBuffer = VDR::getInstance()->getBlock((streamLength - 100000), 100000, &thisRead);
if (!tempBuffer && !VDR::getInstance()->isConnected()) { doConnectionLost(); return; }
if (!tempBuffer) return;
if (thisRead) demuxer->findVideoPTS(tempBuffer, thisRead, &endTS);
free(tempBuffer);
+ #else //The replacement code relias completely on VDRs timecode and not the pts
+ endTS=video->frameNumberToTimecode(
+ VDR::getInstance()->frameNumberFromPosition((streamLength - 100000)));
+ #endif
logger->log("Player", Log::DEBUG, "Set end TS");
}
UINT thisRead;
UINT writeLength;
UINT thisWrite;
- UINT preBufferTotal;
+ UINT preBufferTotal = 0;
+#ifdef NEW_DEMUXER
+ ULLONG currentposition;
+#endif
VDR* vdr = VDR::getInstance();
}
threadBuffer = vdr->getBlock(feedPosition, askFor, &thisRead);
+#ifdef NEW_DEMUXER
+ currentposition=feedPosition;
+ #endif
if (!vdr->isConnected())
{
doConnectionLost();
while(writeLength < thisRead)
{
+#ifndef NEW_DEMUXER
thisWrite = demuxer->put(threadBuffer + writeLength, thisRead - writeLength);
+#else
+ thisWrite = demuxer->put(threadBuffer + writeLength, thisRead - writeLength,
+ currentposition+(ULLONG)writeLength);
+#endif
writeLength += thisWrite;
// logger->log("Player", Log::DEBUG, "Put %i to demuxer", thisWrite);
void Player::test1()
{
logger->log("Player", Log::DEBUG, "PLAYER TEST 1");
- video->play();
+ video->play();
// video->setAspectRatio(Video::ASPECT4X3);
}
#ifndef WIN32
pthread_mutex_t mutex;
#else
- // FIXME Marten
+ HANDLE mutex;
#endif
void lock();
void unLock();
{
if (initted) free(outbuf);
initted = 0;
+
}
int Stream::init(int bufsize)
{
#ifdef NEW_DEMUXER
mediapackets.clear();
+ if (draintarget) draintarget->ResetTimeOffsets();
#endif
bufferHead = 0;
bufferTail = 0;
return ret;
}
#else
-int Stream::put(UCHAR* inbuf, int len)
+int Stream::put(UCHAR* inbuf, int len,ULLONG curpos)
{
int ret = 0;
int tail = bufferTail;
MediaPacket newPacket;
newPacket.length=len;
newPacket.pos_buffer=0;
- newPacket.recording_byte_pos=0;
+ newPacket.recording_byte_pos=curpos;
newPacket.synched=false;
newPacket.disconti=false;
newPacket.pts=0;
if (cur_packet_pos==cur_mp.length) {
cur_packet_pos=0;
mediapackets.pop_back();
-// if ((int)(tail+cur_mp.length) < mark) {
- if ((((ULONG)tail)+cur_mp.length) < ((ULONG)mark))
- {
+ if ((((ULONG)tail)+cur_mp.length) < ((ULONG)mark)) {
bufferTail=tail+cur_mp.length;
} else {
bufferTail=0;
int init(int bufsize);
void shutdown();
void flush();
+#ifndef NEW_DEMUXER
int put(UCHAR* inbuf, int len);
+#else
+ int put(UCHAR* inbuf, int len,ULLONG curpos);
+#endif
+
#ifndef NEW_DEMUXER
int drain(int fd);
#else
int drain(DrainTarget* fd);
- void setDrainTarget(DrainTarget *dt) {draintarget=dt;};
+ void setDrainTarget(DrainTarget *dt) {if (dt) draintarget=dt;};
#endif
private:
ULLONG htonll(ULLONG a)
{
-/*
- #if BYTE_ORDER == BIG_ENDIAN
- return a;
- #else
- ULLONG b = 0;
-
- b = ((a << 56) & 0xFF00000000000000ULL)
- | ((a << 40) & 0x00FF000000000000ULL)
- | ((a << 24) & 0x0000FF0000000000ULL)
- | ((a << 8) & 0x000000FF00000000ULL)
- | ((a >> 8) & 0x00000000FF000000ULL)
- | ((a >> 24) & 0x0000000000FF0000ULL)
- | ((a >> 40) & 0x000000000000FF00ULL)
- | ((a >> 56) & 0x00000000000000FFULL) ;
-
- return b;
- #endif*///This macro switching does not work for windows, here is a implementation without
- // using BYTE_ORDER
- //#define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) |
- // (unsigned int)ntohl(((int)(x >> 32)))) //By Runner
-
return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32)
|(ULONG)htonl(((ULONG) (a >> 32))));
}