20#define PTSINDEX_ENTRIES 1024
37 void Put(uint32_t Pts,
int Index,
bool Independent);
64 pi[
w].independent = Independent;
74 if (
w ==
r || Pts == 0 && !Still)
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;
98 if (
w ==
r || Pts == 0 && !Still)
102 int UnplayedIFrame = 2;
103 for (
int i =
r; i !=
w && UnplayedIFrame; ) {
104 int32_t d = int32_t(Pts -
pi[i].pts);
106 if (
pi[i].independent) {
107 FrameNumber =
pi[i].index;
115 else if (
pi[i].independent)
151:
cThread(
"non blocking file reader")
237#define PLAYERBUFSIZE (MAXFRAMESIZE * 5)
239#define RESUMEBACKUP 10
240#define MAXSTUCKATEOF 3
270 bool NextFile(uint16_t FileNumber = 0, off_t FileOffset = -1);
274 virtual void Activate(
bool On)
override;
275 virtual void Action(
void)
override;
277 cDvbPlayer(
const char *FileName,
bool PauseLive);
287 void Goto(
int Position,
bool Still =
false);
291 virtual bool GetIndex(
int &Current,
int &Total,
bool SnapToIFrame =
false)
override;
296#define MAX_VIDEO_SLOWMOTION 63
297#define NORMAL_SPEED 4
324 isyslog(
"replay %s", FileName);
333 esyslog(
"ERROR: can't allocate index");
334 else if (!
index->Ok()) {
408 int Index =
index->GetResume();
410 index->StoreResume(0);
414 if (
index->Get(Index, &FileNumber, &FileOffset) &&
NextFile(FileNumber, FileOffset)) {
415 index->StoreResume(Index);
430 marks->Lock(StateKey);
437 Index =
index->GetNextIFrame(Index,
false);
441 return index->StoreResume(Index);
467 marks->Lock(StateKey);
469 int Index =
marks->First()->Position();
472 if (
index->Get(Index, &FileNumber, &FileOffset) &&
NextFile(FileNumber, FileOffset)) {
485 bool WaitingForData =
false;
486 time_t StuckAtEof = 0;
487 uint32_t LastStc = 0;
488 int LastReadFrame = -1;
489 int SwitchToPlayFrame = 0;
491 bool AtLastMark =
false;
517 bool TimeShiftMode =
index->IsStillRecording();
529 if (NewIndex <= 0 && readIndex > 0)
539 if (!
NextFile(FileNumber, FileOffset))
552 marks->Lock(StateKey);
554 if (m && (m->
Index() & 0x01) != 0) {
555 m =
marks->GetNextBegin(m);
559 else if (
Setup.PauseAtLastMark)
561 else if (
index->IsStillRecording())
592 WaitingForData =
false;
603 WaitingForData =
true;
674 w =
PlayTs(p, pc, VideoOnly);
689 if ((
Setup.SkipEdited ||
Setup.PauseAtLastMark) && EndPts >= 0) {
691 if (
Setup.PauseAtLastMark) {
706 if (
eof || SwitchToPlayFrame) {
707 bool SwitchToPlay =
false;
711 else if (!StuckAtEof)
712 StuckAtEof = time(NULL);
721 if (Index >= LastReadFrame)
724 else if (Index <= 0 || SwitchToPlayFrame && Index >= SwitchToPlayFrame)
727 if (!SwitchToPlayFrame)
732 SwitchToPlayFrame = 0;
783 if (
Setup.MultiSpeedMode) {
805 if (
Setup.MultiSpeedMode) {
825 default:
esyslog(
"ERROR: unknown playMode %d (%s)",
playMode, __FUNCTION__);
835 if (
Setup.MultiSpeedMode) {
857 if (
Setup.MultiSpeedMode) {
877 default:
esyslog(
"ERROR: unknown playMode %d (%s)",
playMode, __FUNCTION__);
884 if (
index && Frames) {
887 int OldCurrent = Current;
891 Current =
index->GetNextIFrame(Current + Frames + (Frames > 0 ? -1 : 1), Frames > 0);
892 return Current >= 0 ? Current : OldCurrent;
899 if (
index && Seconds) {
906 Index =
index->GetNextIFrame(Index,
false, NULL, NULL, NULL);
924 Index =
index->GetNextIFrame(Index,
false, &FileNumber, &FileOffset, &Length);
927 if (
NextFile(FileNumber, FileOffset)) {
966 return index->GetErrors();
975 int i1 =
index->GetNextIFrame(Current + 1,
false);
976 int i2 =
index->GetNextIFrame(Current,
true);
977 Current = (abs(Current - i1) <= abs(Current - i2)) ? i1 : i2;
979 Total =
index->Last();
982 Current = Total = -1;
990 Total =
index->Last();
993 Current = Total = -1;
1067 player->SkipSeconds(Seconds);
1073 return player->SkipFrames(Frames);
1080 return player->GetErrors();
1087 player->GetIndex(Current, Total, SnapToIFrame);
1096 player->GetFrameNumber(Current, Total);
1110 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)
virtual ~cDvbPlayerControl() override
bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false)
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)
virtual const cErrors * GetErrors(void) override
cRingBufferFrame * ringBuffer
void SetMarks(const cMarks *Marks)
virtual void Action(void) override
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed) override
virtual void Activate(bool On) override
void SkipSeconds(int Seconds)
cDvbPlayer(const char *FileName, bool PauseLive)
cNonBlockingFileReader * nonBlockingFileReader
cUnbufferedFile * replayFile
virtual void SetAudioTrack(eTrackType Type, const tTrackId *TrackId) override
void Goto(int Position, bool Still=false)
bool NextFile(uint16_t FileNumber=0, off_t FileOffset=-1)
virtual ~cDvbPlayer() override
virtual bool GetFrameNumber(int &Current, int &Total) override
void TrickSpeed(int Increment)
virtual double FramesPerSecond(void) override
int SkipFrames(int Frames)
virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame=false) override
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)
void DeviceSetTempSubtitles(void)
bool DeviceHasIBPTrickSpeed(void)
cPlayer(ePlayMode PlayMode=pmAudioVideo)
bool DeviceIsPlayingVideo(void)
void DeviceTrickSpeed(int Speed, bool Forward)
int FindIndex(uint32_t Pts, bool Still)
int FindFrameNumber(uint32_t Pts, bool Forward, bool Still)
tPtsIndex pi[PTSINDEX_ENTRIES]
void Put(uint32_t Pts, int Index, bool Independent)
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 PtsDiff(int64_t Pts1, int64_t Pts2)
Returns the difference between two PTS values.
int64_t TsGetPts(const uchar *p, int l, int Pid)
bool PesHasPts(const uchar *p)
int64_t PesGetPts(const uchar *p)