20#define PTSINDEX_ENTRIES 1024
37 void Put(uint32_t Pts,
int Index,
bool Independent);
64 pi[
w].independent = Independent;
76 uint32_t Delta = 0xFFFFFFFF;
78 for (
int i =
w; i !=
r; ) {
81 uint32_t d =
pi[i].pts < Pts ? Pts -
pi[i].pts :
pi[i].pts - Pts;
101 int UnplayedIFrame = 2;
102 for (
int i =
r; i !=
w && UnplayedIFrame; ) {
107 if (
pi[i].independent) {
108 FrameNumber =
pi[i].index;
115 if (
pi[i].independent)
120 return Valid ? FrameNumber :
FindIndex(Pts);
147:
cThread(
"non blocking file reader")
233#define PLAYERBUFSIZE (MAXFRAMESIZE * 5)
235#define RESUMEBACKUP 10
236#define MAXSTUCKATEOF 3
266 bool NextFile(uint16_t FileNumber = 0, off_t FileOffset = -1);
271 virtual void Action(
void);
273 cDvbPlayer(
const char *FileName,
bool PauseLive);
283 void Goto(
int Position,
bool Still =
false);
287 virtual bool GetIndex(
int &Current,
int &Total,
bool SnapToIFrame =
false);
292#define MAX_VIDEO_SLOWMOTION 63
293#define NORMAL_SPEED 4
320 isyslog(
"replay %s", FileName);
329 esyslog(
"ERROR: can't allocate index");
330 else if (!
index->Ok()) {
404 int Index =
index->GetResume();
408 if (
index->Get(Index, &FileNumber, &FileOffset) &&
NextFile(FileNumber, FileOffset))
422 marks->Lock(StateKey);
429 Index =
index->GetNextIFrame(Index,
false);
433 return index->StoreResume(Index);
459 marks->Lock(StateKey);
461 int Index =
marks->First()->Position();
464 if (
index->Get(Index, &FileNumber, &FileOffset) &&
NextFile(FileNumber, FileOffset)) {
477 bool WaitingForData =
false;
478 time_t StuckAtEof = 0;
479 uint32_t LastStc = 0;
480 int LastReadFrame = -1;
481 int SwitchToPlayFrame = 0;
483 bool AtLastMark =
false;
508 bool TimeShiftMode =
index->IsStillRecording();
520 if (NewIndex <= 0 && readIndex > 0)
530 if (!
NextFile(FileNumber, FileOffset))
543 marks->Lock(StateKey);
545 if (m && (m->
Index() & 0x01) != 0) {
546 m =
marks->GetNextBegin(m);
550 else if (
Setup.PauseAtLastMark)
552 else if (
index->IsStillRecording())
583 WaitingForData =
false;
590 WaitingForData =
true;
659 w =
PlayTs(p, pc, VideoOnly);
677 if (
Setup.PauseAtLastMark) {
689 if (
eof || SwitchToPlayFrame) {
690 bool SwitchToPlay =
false;
694 else if (!StuckAtEof)
695 StuckAtEof = time(NULL);
702 int Index =
ptsIndex.FindIndex(Stc);
704 if (Index >= LastReadFrame)
707 else if (Index <= 0 || SwitchToPlayFrame && Index >= SwitchToPlayFrame)
710 if (!SwitchToPlayFrame)
715 SwitchToPlayFrame = 0;
766 if (
Setup.MultiSpeedMode) {
788 if (
Setup.MultiSpeedMode) {
806 default:
esyslog(
"ERROR: unknown playMode %d (%s)",
playMode, __FUNCTION__);
816 if (
Setup.MultiSpeedMode) {
837 if (
Setup.MultiSpeedMode) {
858 default:
esyslog(
"ERROR: unknown playMode %d (%s)",
playMode, __FUNCTION__);
865 if (
index && Frames) {
868 int OldCurrent = Current;
872 Current =
index->GetNextIFrame(Current + Frames + (Frames > 0 ? -1 : 1), Frames > 0);
873 return Current >= 0 ? Current : OldCurrent;
880 if (
index && Seconds) {
887 Index =
index->GetNextIFrame(Index,
false, NULL, NULL, NULL);
905 Index =
index->GetNextIFrame(Index,
false, &FileNumber, &FileOffset, &Length);
908 if (
NextFile(FileNumber, FileOffset)) {
947 return index->GetErrors();
956 int i1 =
index->GetNextIFrame(Current + 1,
false);
957 int i2 =
index->GetNextIFrame(Current,
true);
958 Current = (abs(Current - i1) <= abs(Current - i2)) ? i1 : i2;
960 Total =
index->Last();
963 Current = Total = -1;
971 Total =
index->Last();
974 Current = Total = -1;
1048 player->SkipSeconds(Seconds);
1054 return player->SkipFrames(Frames);
1061 return player->GetErrors();
1068 player->GetIndex(Current, Total, SnapToIFrame);
1077 player->GetFrameNumber(Current, Total);
1091 player->Goto(Position, Still);
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
void SetPlayer(cPlayer *Player)
cControl(cPlayer *Player, bool Hidden=false)
void SetMarks(const cMarks *Marks)
bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false)
virtual ~cDvbPlayerControl()
const cErrors * GetErrors(void)
void SkipSeconds(int Seconds)
cDvbPlayerControl(const char *FileName, bool PauseLive=false)
bool GetReplayMode(bool &Play, bool &Forward, int &Speed)
int SkipFrames(int Frames)
void Goto(int Index, bool Still=false)
bool GetFrameNumber(int &Current, int &Total)
cRingBufferFrame * ringBuffer
virtual void Activate(bool On)
void SetMarks(const cMarks *Marks)
virtual bool GetFrameNumber(int &Current, int &Total)
virtual const cErrors * GetErrors(void)
void SkipSeconds(int Seconds)
virtual double FramesPerSecond(void)
cDvbPlayer(const char *FileName, bool PauseLive)
cNonBlockingFileReader * nonBlockingFileReader
cUnbufferedFile * replayFile
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
void Goto(int Position, bool Still=false)
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed)
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false)
bool NextFile(uint16_t FileNumber=0, off_t FileOffset=-1)
virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId)
void TrickSpeed(int Increment)
int SkipFrames(int Frames)
void Request(cUnbufferedFile *File, int Length)
cNonBlockingFileReader(void)
void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
bool WaitForDataMs(int msToWait)
int Result(uchar **Buffer)
~cNonBlockingFileReader()
void DeviceStillPicture(const uchar *Data, int Length)
uint64_t DeviceGetSTC(void)
int PlayTs(const uchar *Data, int Length, bool VideoOnly=false)
int PlayPes(const uchar *Data, int Length, bool VideoOnly=false)
bool DevicePoll(cPoller &Poller, int TimeoutMs=0)
bool DeviceHasIBPTrickSpeed(void)
cPlayer(ePlayMode PlayMode=pmAudioVideo)
bool DeviceIsPlayingVideo(void)
void DeviceTrickSpeed(int Speed, bool Forward)
int FindIndex(uint32_t Pts)
tPtsIndex pi[PTSINDEX_ENTRIES]
void Put(uint32_t Pts, int Index, bool Independent)
int FindFrameNumber(uint32_t Pts)
double FramesPerSecond(void) const
bool IsPesRecording(void) const
static void SetBrokenLink(uchar *Data, int Length)
void Remove(bool IncState=true)
Removes this key from the lock it was previously used with.
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
cThread(const char *Description=NULL, bool LowPriority=false)
Creates a new thread.
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
static tThreadId IsMainThread(void)
cUnbufferedFile is used for large files that are mainly written or read in a streaming manner,...
#define MAX_VIDEO_SLOWMOTION
cString IndexToHMSF(int Index, bool WithFrame, double FramesPerSecond)
int SecondsToFrames(int Seconds, double FramesPerSecond)
int ReadFrame(cUnbufferedFile *f, uchar *b, int Length, int Max)
int64_t TsGetPts(const uchar *p, int l)
bool PesHasPts(const uchar *p)
int64_t PesGetPts(const uchar *p)