From 1bd6e826db76d298b79ff644c2042d6e8d6acb35 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Tue, 23 Dec 2008 17:25:46 +0000 Subject: [PATCH] Vogel Media Player 2008-11-28 --- audioplayer.cc | 144 +++-- audioplayer.h | 22 +- boxx.cc | 6 + boxx.h | 2 + demuxermedia.cc | 348 +++++++++++ demuxermedia.h | 67 ++ imagereader.cc | 322 ++++++++++ imagereader.h | 120 ++++ localmediafile.cc | 57 ++ localmediafile.h | 52 ++ media.cc | 418 ++++++++++--- media.h | 205 ++++++- mediafile.cc | 222 +++++++ mediafile.h | 129 ++++ mediaoptions.cc | 178 ++++++ mediaoptions.h | 60 ++ mediaplayer.cc | 197 ++++++ mediaplayer.h | 116 ++++ mediaprovider.h | 129 ++++ mediaproviderids.h | 59 ++ objects.mk | 50 +- playermedia.cc | 780 ++++++++++++++++++++++++ playermedia.h | 205 +++++++ readme_media.txt | 241 +++++--- recman.cc | 1 + serialize.cc | 441 ++++++++++++++ serialize.h | 238 ++++++++ surface.h | 2 + surfacemvp.cc | 84 +-- surfacemvp.h | 38 +- surfacewin.cc | 8 + surfacewin.h | 1 + vaudioplayer.cc | 633 ------------------- vaudioplayer.h | 107 ---- vcolourtuner.cc | 277 +++++++++ vcolourtuner.h | 63 ++ vdr.cc | 310 ++++++---- vdr.h | 58 +- vdrcommand.h | 163 +++++ vepg.cc | 1 + vmedialist.cc | 796 +++++++++++++++++++----- vmedialist.h | 86 ++- vmediaview.cc | 1450 ++++++++++++++++++++++++++++++++++++++++++++ vmediaview.h | 197 ++++++ vopts.cc | 3 + vpicture.cc | 439 -------------- vpicture.h | 98 --- vpicturebanner.cc | 16 +- vpicturebanner.h | 5 +- vradiorec.cc | 1 + vrecordinglist.cc | 1 + vrecordingmenu.cc | 1 + vtimerlist.cc | 1 + vvideolivetv.cc | 1 + vvideomedia.cc | 779 ++++++++++++++++++++++++ vvideomedia.h | 104 ++++ vvideorec.cc | 4 +- wjpeg.cc | 943 ++++++++++++++++------------ wjpeg.h | 226 +++++-- 59 files changed, 9341 insertions(+), 2364 deletions(-) create mode 100644 demuxermedia.cc create mode 100644 demuxermedia.h create mode 100644 imagereader.cc create mode 100644 imagereader.h create mode 100644 localmediafile.cc create mode 100644 localmediafile.h create mode 100644 mediafile.cc create mode 100644 mediafile.h create mode 100644 mediaoptions.cc create mode 100644 mediaoptions.h create mode 100644 mediaplayer.cc create mode 100644 mediaplayer.h create mode 100644 mediaprovider.h create mode 100644 mediaproviderids.h create mode 100644 playermedia.cc create mode 100644 playermedia.h create mode 100644 serialize.cc create mode 100644 serialize.h delete mode 100644 vaudioplayer.cc delete mode 100644 vaudioplayer.h create mode 100644 vcolourtuner.cc create mode 100644 vcolourtuner.h create mode 100644 vdrcommand.h create mode 100644 vmediaview.cc create mode 100644 vmediaview.h delete mode 100644 vpicture.cc delete mode 100644 vpicture.h create mode 100644 vvideomedia.cc create mode 100644 vvideomedia.h diff --git a/audioplayer.cc b/audioplayer.cc index 85a8a7b..a982437 100644 --- a/audioplayer.cc +++ b/audioplayer.cc @@ -19,13 +19,18 @@ */ #include "audioplayer.h" -#include "vaudioplayer.h" #include "demuxeraudio.h" #include "timers.h" #include "video.h" #include "command.h" #include "i18n.h" #include "boxx.h" +#include "log.h" +#include "media.h" +#include "mediaplayer.h" + +//how often do we retry if there is no data in stream +#define MAXTRY 50 AudioPlayer * AudioPlayer::instance=NULL; @@ -66,7 +71,7 @@ AudioPlayer::AudioPlayer(Boxx *parent) : afeed(this) sequence=0; playSequence=0; currentPlaySequence=-1; - filename=NULL; + uri=NULL; demuxer=new DemuxerAudio(); logger->log("AudioPlayer", Log::DEBUG, "Audio player ctorII"); if (!demuxer->init(this, audio, NULL, 0, DemuxerAudio::PACKET_SIZE+200)) @@ -80,6 +85,7 @@ AudioPlayer::AudioPlayer(Boxx *parent) : afeed(this) audio->reset(); lenInBytes=0; logger->log("AudioPlayer", Log::DEBUG, "Audio player created"); + canPosition=false; } AudioPlayer::~AudioPlayer() @@ -91,7 +97,7 @@ AudioPlayer::~AudioPlayer() audio->setStreamType(Audio::MPEG2_PES); delete demuxer; demuxer=NULL; - delete filename; + delete uri; } void AudioPlayer::controlFeeder(int feederAction) { @@ -171,14 +177,13 @@ void AudioPlayer::setState(UCHAR s) { } //------------------- externally called functions -------------------------- -int AudioPlayer::play(const char * fn) +int AudioPlayer::play(const MediaURI * u) { - logger->log("AudioPlayer", Log::DEBUG, "play request for %s", fn); + logger->log("AudioPlayer", Log::DEBUG, "play request for %s", u->getName()); int rt=0; threadLock(); - if (filename) delete filename; - filename=new char[strlen(fn)+1]; - strcpy(filename,fn); + if (uri) delete uri; + uri=new MediaURI(u); requestState=S_PLAY; requestedSequence++; rt=requestedSequence; @@ -209,17 +214,20 @@ int AudioPlayer::unpause() } int AudioPlayer::fastForward(){ + if (! canPosition) return 1; int rt=setRequestedState(S_FF); threadSignalNoLock(); return rt; } int AudioPlayer::fastBackward(){ + if (! canPosition) return 1; int rt=setRequestedState(S_BACK); threadSignalNoLock(); return rt; } int AudioPlayer::jumpToPercent(double percent){ + if (! canPosition) return 1; threadLock(); ULONG fsec=demuxer->getSecondsFromLen(lenInBytes); ULONG npos=streampos; @@ -243,6 +251,7 @@ int AudioPlayer::jumpToPercent(double percent){ } int AudioPlayer::skipForward(int seconds) { + if (! canPosition) return 1; threadLock(); ULONG curr=demuxer->getSecondsFromLen(streampos); ULONG dest=demuxer->positionFromSeconds(curr+(UINT)seconds); @@ -256,6 +265,7 @@ int AudioPlayer::skipForward(int seconds) { return 0; } int AudioPlayer::skipBackward(int seconds) { + if (! canPosition) return 1; threadLock(); ULONG curr=demuxer->getSecondsFromLen(streampos); if (curr > (UINT)seconds) { @@ -289,39 +299,35 @@ void AudioPlayer::sendFrontendMessage(ULONG para) Command::getInstance()->postMessageFromOuterSpace(m); } -void AudioPlayer::handleVDRerror(){ - if (!vdr->isConnected()) - { - logger->log("AudioPlayer", Log::ERR, "disconnect"); - sendFrontendMessage(CONNECTION_LOST); - setState(S_ERROR); - } -} //open a new file //called within the thread! int AudioPlayer::openFile() { - char * fn=NULL; threadLock(); - if (filename) { - fn=new char[strlen(filename)+1]; - strcpy(fn,filename); - } + MediaURI fn(uri); threadUnlock(); demuxer->reset(); streampos=0; bytesWritten=0; - lenInBytes=vdr->loadImage(fn,0,0); - Log::getInstance()->log("Audioplayer", Log::DEBUG, "request file rt=%d file=%s",lenInBytes,fn); - handleVDRerror(); - if (lenInBytes <= 0) { + MediaPlayer::getInstance()->closeMediaChannel(2); + int rt=MediaPlayer::getInstance()->openMedium(2,&fn,&lenInBytes,0,0); + Log::getInstance()->log("Audioplayer", Log::DEBUG, "request file rt=%d file=%s",rt,fn.getDisplayName()); + if (rt != 0) { return 1; } - UINT rsize=0; - UCHAR *idbuf=vdr->getImageBlock(0,demuxer->headerBytes(),&rsize); - handleVDRerror(); - if (rsize < demuxer->headerBytes() || idbuf == NULL) { + MediaInfo mi; + rt=MediaPlayer::getInstance()->getMediaInfo(2,&mi); + canPosition=mi.canPosition; + ULONG rsize=0; + UCHAR *idbuf=NULL; + if (canPosition) { + rt=MediaPlayer::getInstance()->getMediaBlock(2,0,demuxer->headerBytes(),&rsize,&idbuf); + } + else { + rt=-1; + } + if (rsize < demuxer->headerBytes() || rt != 0 ) { if (idbuf) free(idbuf); - Log::getInstance()->log("VAudioplayer", Log::DEBUG, "unable to get header for file %s",fn); + Log::getInstance()->log("Audioplayer", Log::DEBUG, "unable to get header for file %s",fn.getName()); return 0; } threadLock(); @@ -332,20 +338,19 @@ int AudioPlayer::openFile() { } if (idbuf) free(idbuf); idbuf=NULL; - if (demuxer->getId3Tag() == NULL) { + if (demuxer->getId3Tag() == NULL && canPosition) { //OK - look at the end - idbuf=vdr->getImageBlock(lenInBytes-demuxer->footerBytes(),demuxer->footerBytes(),&rsize); - handleVDRerror(); - if (rsize < demuxer->footerBytes() || idbuf == NULL) { + rt=MediaPlayer::getInstance()->getMediaBlock(2,lenInBytes-demuxer->footerBytes(),demuxer->footerBytes(),&rsize,&idbuf); + if (rsize < demuxer->footerBytes() || rt != 0) { if (idbuf) free(idbuf); - Log::getInstance()->log("VAudioplayer", Log::DEBUG, "unable to get footer for file %s",fn); + Log::getInstance()->log("Audioplayer", Log::DEBUG, "unable to get footer for file %s",fn.getName()); return 0; } threadLock(); hdrpos=demuxer->checkID3(idbuf,rsize); threadUnlock(); if (hdrpos < 0) { - Log::getInstance()->log("VAudioplayer", Log::DEBUG, "no ID3 in footer for file %s",fn); + Log::getInstance()->log("Audioplayer", Log::DEBUG, "no ID3 in footer for file %s",fn.getName()); } free(idbuf); } @@ -371,14 +376,21 @@ UCHAR AudioPlayer::checkState() switch(rstate) { case S_PAUSE: - if (cstate != S_PLAY && cstate != S_FF) rstate=cstate; //ignore request + if (cstate != S_PLAY && cstate != S_FF && cstate != S_PAUSE) { + rstate=cstate; //ignore request + break; + } else { - skipfactor=0; - demuxer->setSkipFactor(0); - audio->mute(); - audio->pause(); + if (cstate != S_PAUSE) { + skipfactor=0; + demuxer->setSkipFactor(0); + audio->mute(); + audio->pause(); + break; + } } - break; + //if cstate==S_PAUSE fallthrough to S_PLAY + rstate=S_PLAY; case S_PLAY: // to S_PLAY skipfactor=0; demuxer->setSkipFactor(0); @@ -492,7 +504,7 @@ UCHAR AudioPlayer::checkState() //any change after done cancels the "done" timer Timers::getInstance()->cancelTimer(this,1); } - logger->log("AudioPlayer", Log::DEBUG, "Switch state from %u to %u completed nf=%s", cstate, rstate,newFile?"true":"false"); + logger->log("AudioPlayer", Log::DEBUG, "Switch state from %u to %u completed seq=%d, nf=%s", cstate, rstate,rseq,newFile?"true":"false"); //we return the newly set state return rstate; } @@ -529,6 +541,7 @@ void AudioPlayer::threadMethod() logger->log("AudioPlayer", Log::DEBUG, "player thread started"); thisWrite=0; thisRead=0; + int retrycount=0; while(1) { UCHAR cstate=checkState(); @@ -545,15 +558,31 @@ void AudioPlayer::threadMethod() //TODO: use normal blocks... thisRead=0; thisWrite=0; - threadBuffer = vdr->getImageBlock(streampos, BUFLEN , &thisRead); - handleVDRerror(); - if (!threadBuffer || thisRead == 0) { + threadBuffer=NULL; + int rt=MediaPlayer::getInstance()->getMediaBlock(2,streampos,BUFLEN,&thisRead,&threadBuffer); + if (thisRead == 0 && threadBuffer) { + free(threadBuffer); + threadBuffer=NULL; + } + if ((!threadBuffer || thisRead == 0 ) && rt == 0) { + retrycount++; + if (retrycount > MAXTRY) rt=-1; + else { + logger->log("AudioPlayer", Log::DEBUG, "no data read, retrying"); + continue; + } + } + + if (!threadBuffer || thisRead == 0 || rt != 0) { //OK we count this as end of stream //hmm --- we should be able to detect if the audio has gone... logger->log("AudioPlayer", Log::DEBUG, "stream end"); setRequestedState(S_DONE); + MediaPlayer::getInstance()->closeMediaChannel(2); + retrycount=0; continue; } + retrycount=0; //logger->log("AudioPlayer", Log::DEBUG, "read %ld bytes at pos %ld",thisRead,streampos); streampos+=thisRead; } @@ -593,6 +622,7 @@ void AudioPlayer::threadMethod() } logger->log("AudioPlayer", Log::DEBUG, "finished"); + MediaPlayer::getInstance()->closeMediaChannel(2); playerRunnig=false; return; } @@ -601,12 +631,18 @@ int AudioPlayer::waitForSequence(int timeout, int seq) { time_t starttime=time(NULL)+timeout; time_t curtime=0; logger->log("AudioPlayer", Log::DEBUG, "waiting for sequence %d",seq); + int rt=-1; while ((curtime=time(NULL)) < starttime) { int cseq=getSequence(); - if (cseq >= seq) return cseq; - MILLISLEEP(10); + if (cseq >= seq) { + rt=cseq; + break; + } + //logger->log("AudioPlayer", Log::DEBUG, "waiting for sequence loop"); + MILLISLEEP(100); } - return -1; + logger->log("AudioPlayer", Log::DEBUG, "waiting for sequence %d returns %d",seq,rt); + return rt; } int AudioPlayer::getSequence() { @@ -677,17 +713,19 @@ char * AudioPlayer::getID3Info() { if (info && info->avrBitrate != info->bitRate) bitrateType='V'; rt=new char[len]; if (!tag && info) { - SNPRINTF(rt,len-1,"%s: %s/L%d %cBR,SR=%dk,%s\n",tr("MpegInfo"), - info->mpegVersion,info->mpegLayer,bitrateType,info->sampleRate/1000, + int sr=info->sampleRate/1000; + SNPRINTF(rt,len-1,"%s: %s/L%d %cBR,SR=%d.%02dkBit/s,%s\n",tr("MpegInfo"), + info->mpegVersion,info->mpegLayer,bitrateType,sr,(info->sampleRate/10-sr*100), info->info); } else if (tag && info){ + int sr=info->sampleRate/1000; char *tmp=new char[taglen+1]; SNPRINTF(rt,len-1,"%s\n" - "%s: %s/L%d %cBR,SR=%dk,%s\n", + "%s: %s/L%d %cBR,SR=%d.%02dkBit/s,%s\n", tag->toString(tmp,taglen,false), tr("MpegInfo"), - info->mpegVersion,info->mpegLayer,bitrateType,info->sampleRate/1000, + info->mpegVersion,info->mpegLayer,bitrateType,sr,(info->sampleRate/10-sr*100), info->info); delete [] tmp; } diff --git a/audioplayer.h b/audioplayer.h index 43c4a31..86aa712 100644 --- a/audioplayer.h +++ b/audioplayer.h @@ -48,6 +48,7 @@ class Boxx; class DemuxerAudio; +class MediaURI; class AudioPlayer : public Thread_TYPE, public Callback, public TimerReceiver @@ -71,7 +72,7 @@ class AudioPlayer : public Thread_TYPE, public Callback, public TimerReceiver //each of the commands works as a request //only after getSequence returned the same sequence as those commands this is //handled by the player and getError is valid - int play(const char * filename); + int play(const MediaURI *uri); //stop the player without shutting it down int stop(); int pause(); @@ -126,6 +127,7 @@ class AudioPlayer : public Thread_TYPE, public Callback, public TimerReceiver const static ULONG STATUS_CHANGE=4; //some info has been changed const static ULONG NEW_SONG=5; //some info has been changed const static ULONG SHORT_UPDATE=6; //timer info update + const static ULONG EXTERN1=7; //for other users as parameter to player event virtual void timercall(int reference); @@ -163,17 +165,17 @@ class AudioPlayer : public Thread_TYPE, public Callback, public TimerReceiver UCHAR checkState(); //variables used by the thread - UINT thisWrite; - UINT thisRead; + ULONG thisWrite; + ULONG thisRead; bool running; UCHAR *threadBuffer; UCHAR state; UCHAR requestState; - ULONG streampos; - ULONG lenInBytes; - ULONG bytesWritten; - ULONG requestedStreampos; + ULLONG streampos; + ULLONG lenInBytes; + ULLONG bytesWritten; + ULLONG requestedStreampos; int skipfactor; //the buffer len in bytes @@ -187,10 +189,12 @@ class AudioPlayer : public Thread_TYPE, public Callback, public TimerReceiver int currentPlaySequence; //sequence that is changed for each new filename int playSequence; + //can we position? + bool canPosition; - char * filename; + + MediaURI *uri; int openFile(); - void handleVDRerror(); void sendFrontendMessage(ULONG para); diff --git a/boxx.cc b/boxx.cc index af6ce48..1a26213 100644 --- a/boxx.cc +++ b/boxx.cc @@ -390,3 +390,9 @@ int Boxx::charWidth(char c) if (parent) return parent->charWidth(c); else return surface->getCharWidth(c); } + +Surface * Boxx::getSurface() { + if (parent) return parent->getSurface(); + return surface; +} + diff --git a/boxx.h b/boxx.h index 439fa54..d5eb7c1 100644 --- a/boxx.h +++ b/boxx.h @@ -126,6 +126,8 @@ class Boxx friend class BoxStack; protected: + //get the surface this box is drawing to + Surface *getSurface(); Boxx* parent; Region area; vector children; diff --git a/demuxermedia.cc b/demuxermedia.cc new file mode 100644 index 0000000..777a96c --- /dev/null +++ b/demuxermedia.cc @@ -0,0 +1,348 @@ +/* + Copyright 2005-2007 Mark Calderbank + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "demuxermedia.h" +#include "callback.h" + +#include "video.h" +#include "log.h" + +#ifndef WIN32 +#include +#else +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __BYTE_ORDER __LITTLE_ENDIAN +#endif + +#define PTS_JUMP_MARGIN 10000 +#define PTS_ALLOWANCE 90000 + +// TODO: PTS class to handle wrapping arithmetic & comparisons? +static ULLONG PTSDistance(ULLONG pts1, ULLONG pts2) +{ + // Assume pts1, pts2 < 2^33; calculate shortest distance between + ULLONG ret = (pts1 > pts2) ? pts1 - pts2 : pts2 - pts1; + if (ret > (1LL<<32)) ret = (1LL<<33) - ret; + return ret; +} + +DemuxerMedia::DemuxerMedia() +{ + frameCounting = false; + packetCounting = false; +} + +void DemuxerMedia::reset() +{ + frameCounting = false; + packetCounting = false; + pts_map.clear(); + Demuxer::reset(); + firstPTS=0; + lastPTS=0; + currentPTS=0; + last_horizontal_size=-1; + last_vertical_size=-1; +} + +void DemuxerMedia::flush() +{ + state = 0; + submitting = false; + Demuxer::flush(); +} + +int DemuxerMedia::scan(UCHAR *buf, int len) +{ + int ret = 0; + int astate=0; //hdrbyte + + while ((len + astate)> 3) + { + switch (astate) { + case 0: //1st hdr byte + if (*buf != 0) break; + astate++; + break; + case 1: //2nd hdrbyte + if (*buf != 0) { + astate=0; + break; + } + astate++; + break; + case 2: //3rd header byte + if (*buf != 1) { + astate=0; + break; + } + astate++; + break; + case 3: //4th header byte + if ((*buf PESTYPE_AUDMAX) && *buf != PESTYPE_PRIVATE_1) { + astate=0; + break; + } + if (*buf != PESTYPE_PRIVATE_1) { + //found audio + ret=*buf; + return ret; + } + //AC3 - TODO + astate=0; + default: + astate=0; + break; + } + buf++; + len--; + } + return ret; +} + +int DemuxerMedia::findPTS(UCHAR* buf, int len, ULLONG* dest) +{ + // nobody uses this + // No PTS found. + return 0; +} + +void DemuxerMedia::setFrameNum(ULONG frame) +{ + frameCounting = true; + frameNumber = frame; + Log::getInstance()->log("Demuxer", Log::DEBUG, "setFrameNum %d", frame); +} + +void DemuxerMedia::setPacketNum(ULONG npacket) +{ + packetCounting = true; + packetNumber = npacket; + Log::getInstance()->log("Demuxer", Log::DEBUG, "setPacketNum %d", npacket); +} + +int DemuxerMedia::put(UCHAR* buf, int len) +{ + int ret = 0; // return number of bytes consumed + if (submitting) + { + if (submitPacket(packet) == 0) // Still full! + return ret; + else + submitting = false; + } + + if (state > 0) // We are half way through a PES packet. + { + if (len >= state) // The remainder of the packet is available. + { + packet.write(buf, state); + buf += state; len -= state; ret += state; + state = 0; + parseVDRPacketDetails(); + if (submitPacket(packet) == 0) // Stream is full + { + submitting = true; + return ret; + } + } + else // Write what we have, then exit. + { + packet.write(buf, len); + state -= len; + return len; + } + } + + while (len > 0) + { + switch (state) + { + case 0: + case -1: + if (*buf == 0x00) state--; else state = 0; + buf++; len--; ret++; + break; + case -2: + if (*buf == 0x01) state--; else if (*buf != 0x00) state = 0; + buf++; len--; ret++; + break; + case -3: + if ((*buf >= PESTYPE_VID0 && *buf <= PESTYPE_VIDMAX) || + (*buf >= PESTYPE_AUD0 && *buf <= PESTYPE_AUDMAX) || + (*buf == PESTYPE_PRIVATE_1)) + { + packet.init(*buf); + state--; + } + else if (*buf == 0x00) + state = -1; + else + state = 0; + buf++; len--; ret++; + break; + case -4: + packetLength = ((UINT)*buf) << 8; + state--; + buf++; len--; ret++; + break; + case -5: + packetLength += *buf; + state--; + buf++; len--; ret++; + break; + } + + if (state == -6) // Packet header complete + { + if (len >= packetLength) // The entire packet is available. + { + packet.write(buf, packetLength); + buf += packetLength; len -= packetLength; ret += packetLength; + state = 0; + parseVDRPacketDetails(); + if (submitPacket(packet) == 0) // Stream is full + { + submitting = true; + return ret; + } + } + else // Write what we have. + { + packet.write(buf, len); + state = packetLength - len; + ret += len; + len = 0; + } + } + } + return ret; +} + +ULONG DemuxerMedia::getPacketNum() +{ + return packetNumber; +} + +void DemuxerMedia::parseVDRPacketDetails() +{ + parsePacketDetails(packet); + + if (packetCounting && packet.getPacketType() >= PESTYPE_AUD0 && + packet.getPacketType() <= PESTYPE_AUDMAX) + { + packetNumber++; + } + + if (frameCounting && packet.findPictureHeader() && + packet.getPacketType() >= PESTYPE_VID0 && + packet.getPacketType() <= PESTYPE_VIDMAX) + { + ULLONG pts=packet.getPTS(); + if (packet.findSeqHeader() > 1 && pts != PESPacket::PTS_INVALID) + { + if (firstPTS == 0) firstPTS=pts; + currentPTS=pts; + + } + } + if (packet.getPacketType() >= PESTYPE_VID0 && + packet.getPacketType() <= PESTYPE_VIDMAX && + packet.findSeqHeader()) { + //check video size + if (horizontal_size != last_horizontal_size || + vertical_size != last_vertical_size) { + last_horizontal_size=horizontal_size; + last_vertical_size=vertical_size; + Log::getInstance()->log("Demux", Log::DEBUG,"signal size change, new x %d, y %d", + horizontal_size,vertical_size); + if (callback) callback->call(this); + } + } + +} + +//find a sequence header backward +//search for 00 00 01