21 #define PTSINDEX_ENTRIES 500
37 void Put(uint32_t Pts,
int Index);
74 uint32_t Delta = 0xFFFFFFFF;
76 for (
int i =
w; i !=
r; ) {
115 :
cThread(
"non blocking file reader")
201 #define PLAYERBUFSIZE MEGABYTE(1)
203 #define RESUMEBACKUP 10 // number of seconds to back up when resuming an interrupted replay session
204 #define MAXSTUCKATEOF 3 // max. number of seconds to wait in case the device doesn't play the last frame
234 bool NextFile(uint16_t FileNumber = 0, off_t FileOffset = -1);
239 virtual void Action(
void);
241 cDvbPlayer(
const char *FileName,
bool PauseLive);
250 void Goto(
int Position,
bool Still =
false);
253 virtual bool GetIndex(
int &Current,
int &Total,
bool SnapToIFrame =
false);
257 #define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct?
258 #define NORMAL_SPEED 4 // the index of the '1' entry in the following array
259 #define MAX_SPEEDS 3 // the offset of the maximum speed from normal speed in either direction
260 #define SPEED_MULT 12 // the speed multiplier
284 isyslog(
"replay %s", FileName);
293 esyslog(
"ERROR: can't allocate index");
367 if (
index->
Get(Index, &FileNumber, &FileOffset) &&
NextFile(FileNumber, FileOffset))
383 int backup = int(round(
RESUMEBACKUP * framesPerSecond));
425 if (
index->
Get(Index, &FileNumber, &FileOffset) &&
427 isyslog(
"PlayJump: start replay at first mark %d (%s)",
433 bool LastMarkPause =
false;
437 bool WaitingForData =
false;
438 time_t StuckAtEof = 0;
439 uint32_t LastStc = 0;
440 int LastReadIFrame = -1;
441 int SwitchToPlayFrame = 0;
478 if (NewIndex <= 0 && readIndex > 0)
488 if (!
NextFile(FileNumber, FileOffset))
502 if (m && (m->
Index() & 0x01) != 0) {
509 isyslog(
"PauseLastMark: pause at position %d (%s)",
511 LastMarkPause =
true;
523 isyslog(
"PlayJump: %d frames to %d (%s)",
555 WaitingForData =
false;
565 WaitingForData =
true;
636 w =
PlayTs(p, pc, VideoOnly);
654 LastMarkPause =
false;
662 if (
eof || SwitchToPlayFrame) {
663 bool SwitchToPlay =
false;
667 else if (!StuckAtEof)
668 StuckAtEof = time(NULL);
677 if (Index >= LastReadIFrame)
680 else if (Index <= 0 || SwitchToPlayFrame && Index >= SwitchToPlayFrame)
683 if (!SwitchToPlayFrame)
688 SwitchToPlayFrame = 0;
779 default:
esyslog(
"ERROR: unknown playMode %d (%s)",
playMode, __FUNCTION__);
831 default:
esyslog(
"ERROR: unknown playMode %d (%s)",
playMode, __FUNCTION__);
838 if (
index && Frames) {
841 int OldCurrent = Current;
846 return Current >= 0 ? Current : OldCurrent;
853 if (
index && Seconds) {
879 if (Index >= 0 &&
NextFile(FileNumber, FileOffset) && Still) {
916 Current = (abs(Current - i1) <= abs(Current - i2)) ? i1 : i2;
921 Current = Total = -1;
int FindIndex(uint32_t Pts)
cRingBufferFrame * ringBuffer
virtual void Activate(bool On)
double FramesPerSecond(void) const
ssize_t Read(void *Data, size_t Size)
cUnbufferedFile * SetOffset(int Number, off_t Offset=0)
void Signal(void)
Signals a caller of Wait() that the condition it is waiting for is met.
int64_t PesGetPts(const uchar *p)
int GetNextIFrame(int Index, bool Forward, uint16_t *FileNumber=NULL, off_t *FileOffset=NULL, int *Length=NULL)
cNonBlockingFileReader * nonBlockingFileReader
void Goto(int Position, bool Still=false)
void SkipSeconds(int Seconds)
static tThreadId IsMainThread(void)
cUnbufferedFile * NextFile(void)
int ReadFrame(cUnbufferedFile *f, uchar *b, int Length, int Max)
tPtsIndex pi[PTSINDEX_ENTRIES]
int Last(void)
Returns the index of the last entry in this file, or -1 if the file is empty.
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false)
cNonBlockingFileReader(void)
int PlayPes(const uchar *Data, int Length, bool VideoOnly=false)
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
cUnbufferedFile is used for large files that are mainly written or read in a streaming manner...
bool DeviceHasIBPTrickSpeed(void)
void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
cString IndexToHMSF(int Index, bool WithFrame, double FramesPerSecond)
virtual double FramesPerSecond(void)
virtual ~cDvbPlayerControl()
cDvbPlayerControl(const char *FileName, bool PauseLive=false)
T * Next(const T *object) const
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed)
int Result(uchar **Buffer)
bool NextFile(uint16_t FileNumber=0, off_t FileOffset=-1)
void DeviceStillPicture(const uchar *Data, int Length)
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
void bool Start(void)
Actually starts the thread.
cDvbPlayer(const char *FileName, bool PauseLive)
cUnbufferedFile * Open(void)
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
bool Wait(int TimeoutMs=0)
Waits at most TimeoutMs milliseconds for a call to Signal(), or forever if TimeoutMs is 0...
bool TimedWait(cMutex &Mutex, int TimeoutMs)
void Request(cUnbufferedFile *File, int Length)
bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false)
virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
bool StoreResume(int Index)
bool DevicePoll(cPoller &Poller, int TimeoutMs=0)
bool GetReplayMode(bool &Play, bool &Forward, int &Speed)
static void SetBrokenLink(uchar *Data, int Length)
bool DeviceIsPlayingVideo(void)
void Put(uint32_t Pts, int Index)
void DeviceTrickSpeed(int Speed)
int PlayTs(const uchar *Data, int Length, bool VideoOnly=false)
uint64_t DeviceGetSTC(void)
cMark * Get(int Position)
int64_t TsGetPts(const uchar *p, int l)
int SecondsToFrames(int Seconds, double FramesPerSecond)
bool Load(const char *RecordingFileName, double FramesPerSecond=DEFAULTFRAMESPERSECOND, bool IsPesRecording=false)
bool WaitForDataMs(int msToWait)
bool Get(int Index, uint16_t *FileNumber, off_t *FileOffset, bool *Independent=NULL, int *Length=NULL)
bool IsStillRecording(void)
void Goto(int Index, bool Still=false)
int SkipFrames(int Frames)
#define MAX_VIDEO_SLOWMOTION
~cNonBlockingFileReader()
int SkipFrames(int Frames)
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
void SkipSeconds(int Seconds)
void TrickSpeed(int Increment)
bool IsPesRecording(void) const
cUnbufferedFile * replayFile