Fixed switching into time shift mode when pausing live video

This commit is contained in:
Klaus Schmidinger 2012-02-19 11:50:20 +01:00
parent 50e09d1232
commit 23ec57d822
11 changed files with 49 additions and 27 deletions

View File

@ -1298,6 +1298,7 @@ Reinhard Nissl <rnissl@gmx.de>
for making subtitle PIDs be decrypted
for making cEITScanner process new transponders before old ones, to make sure
transponder changes are recognized
for helping to debug switching into time shift mode when pausing live video
Richard Robson <richard_robson@beeb.net>
for reporting freezing replay if a timer starts while in Transfer Mode from the

View File

@ -6847,7 +6847,7 @@ Video Disk Recorder Revision History
- Fixed cRecordings::DelByName() to avoid compilation errors with gcc 4.4
(backport from version 1.7.9, thanks to Ralf Schueler).
2012-02-18: Version 1.7.24
2012-02-19: Version 1.7.24
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- Fixed a high load in case a transponder can't be received.
@ -6886,3 +6886,5 @@ Video Disk Recorder Revision History
device numbering.
- cReadDir::Next() now skips directory entries "." and "..".
- Fixed a possible deadlock in time shift mode.
- Fixed switching into time shift mode when pausing live video (thanks to Reinhard
Nissl for helping to debug this one).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbplayer.c 2.22 2012/02/17 15:36:41 kls Exp $
* $Id: dvbplayer.c 2.23 2012/02/19 10:48:02 kls Exp $
*/
#include "dvbplayer.h"
@ -216,6 +216,7 @@ private:
cUnbufferedFile *replayFile;
double framesPerSecond;
bool isPesRecording;
bool pauseLive;
bool eof;
bool firstPacket;
ePlayModes playMode;
@ -235,7 +236,7 @@ protected:
virtual void Activate(bool On);
virtual void Action(void);
public:
cDvbPlayer(const char *FileName);
cDvbPlayer(const char *FileName, bool PauseLive);
virtual ~cDvbPlayer();
bool Active(void) { return cThread::Running(); }
void Pause(void);
@ -256,7 +257,7 @@ public:
#define SPEED_MULT 12 // the speed multiplier
int cDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 };
cDvbPlayer::cDvbPlayer(const char *FileName)
cDvbPlayer::cDvbPlayer(const char *FileName, bool PauseLive)
:cThread("dvbplayer")
{
nonBlockingFileReader = NULL;
@ -265,6 +266,7 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
cRecording Recording(FileName);
framesPerSecond = Recording.FramesPerSecond();
isPesRecording = Recording.IsPesRecording();
pauseLive = PauseLive;
eof = false;
firstPacket = true;
playMode = pmPlay;
@ -282,7 +284,7 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
return;
ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE);
// Create the index file:
index = new cIndexFile(FileName, false, isPesRecording);
index = new cIndexFile(FileName, false, isPesRecording, pauseLive);
if (!index)
esyslog("ERROR: can't allocate index");
else if (!index->Ok()) {
@ -407,6 +409,8 @@ void cDvbPlayer::Action(void)
int LastReadIFrame = -1;
int SwitchToPlayFrame = 0;
if (pauseLive)
Goto(0, true);
while (Running()) {
if (WaitingForData)
nonBlockingFileReader->WaitForDataMs(10); // this keeps the CPU load low, but reacts immediately on new data
@ -414,7 +418,7 @@ void cDvbPlayer::Action(void)
cPoller Poller;
DevicePoll(Poller, 10);
Sleep = false;
if (playMode == pmStill || playMode==pmPause)
if (playMode == pmStill || playMode == pmPause)
cCondWait::SleepMs(10);
}
{
@ -836,8 +840,8 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
// --- cDvbPlayerControl -----------------------------------------------------
cDvbPlayerControl::cDvbPlayerControl(const char *FileName)
:cControl(player = new cDvbPlayer(FileName))
cDvbPlayerControl::cDvbPlayerControl(const char *FileName, bool PauseLive)
:cControl(player = new cDvbPlayer(FileName, PauseLive))
{
}

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: dvbplayer.h 1.2 2002/06/23 10:13:51 kls Exp $
* $Id: dvbplayer.h 2.1 2012/02/19 11:40:36 kls Exp $
*/
#ifndef __DVBPLAYER_H
@ -19,8 +19,11 @@ class cDvbPlayerControl : public cControl {
private:
cDvbPlayer *player;
public:
cDvbPlayerControl(const char *FileName);
cDvbPlayerControl(const char *FileName, bool PauseLive = false);
// Sets up a player for the given file.
// If PauseLive is true, special care is taken to make sure the index
// file of the recording is long enough to allow the player to display
// the first frame in still picture mode.
virtual ~cDvbPlayerControl();
bool Active(void);
void Stop(void);

11
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 2.36 2012/02/16 11:57:51 kls Exp $
* $Id: menu.c 2.37 2012/02/19 11:37:55 kls Exp $
*/
#include "menu.h"
@ -4329,13 +4329,10 @@ bool cRecordControls::PauseLiveVideo(void)
Skins.Message(mtStatus, tr("Pausing live video..."));
cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
if (Start(NULL, true)) {
cCondWait::SleepMs(2000); // allow recorded file to fill up enough to start replaying
cReplayControl *rc = new cReplayControl;
cReplayControl *rc = new cReplayControl(true);
cControl::Launch(rc);
cControl::Attach();
cCondWait::SleepMs(1000); // allow device to replay some frames, so we have a picture
Skins.Message(mtStatus, NULL);
rc->ProcessKey(kPause); // pause, allowing replay mode display
return true;
}
Skins.Message(mtStatus, NULL);
@ -4425,8 +4422,8 @@ cReplayControl *cReplayControl::currentReplayControl = NULL;
char *cReplayControl::fileName = NULL;
char *cReplayControl::title = NULL;
cReplayControl::cReplayControl(void)
:cDvbPlayerControl(fileName)
cReplayControl::cReplayControl(bool PauseLive)
:cDvbPlayerControl(fileName, PauseLive)
{
currentReplayControl = this;
displayReplay = NULL;

4
menu.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.h 2.3 2010/03/06 16:15:59 kls Exp $
* $Id: menu.h 2.4 2012/02/19 10:51:56 kls Exp $
*/
#ifndef __MENU_H
@ -276,7 +276,7 @@ private:
void EditCut(void);
void EditTest(void);
public:
cReplayControl(void);
cReplayControl(bool PauseLive = false);
virtual ~cReplayControl();
void Stop(void);
virtual cOsdObject *GetInfo(void);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.c 2.49 2012/02/17 13:57:05 kls Exp $
* $Id: recording.c 2.50 2012/02/19 10:44:45 kls Exp $
*/
#include "recording.h"
@ -1555,8 +1555,9 @@ struct tIndexTs {
#define MAXWAITFORINDEXFILE 10 // max. time to wait for the regenerated index file (seconds)
#define INDEXFILECHECKINTERVAL 500 // ms between checks for existence of the regenerated index file
#define INDEXFILETESTINTERVAL 10 // ms between tests for the size of the index file in case of pausing live video
cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording)
cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording, bool PauseLive)
:resumeFile(FileName, IsPesRecording)
{
f = -1;
@ -1567,6 +1568,12 @@ cIndexFile::cIndexFile(const char *FileName, bool Record, bool IsPesRecording)
indexFileGenerator = NULL;
if (FileName) {
fileName = IndexFileName(FileName, isPesRecording);
if (!Record && PauseLive) {
// Wait until the index file contains at least two frames:
time_t tmax = time(NULL) + MAXWAITFORINDEXFILE;
while (time(NULL) < tmax && FileSize(fileName) < 2 * sizeof(tIndexTs))
cCondWait::SleepMs(INDEXFILETESTINTERVAL);
}
int delta = 0;
if (!Record && access(fileName, R_OK) != 0) {
// Index file doesn't exist, so try to regenerate it:

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.h 2.26 2011/12/04 13:38:17 kls Exp $
* $Id: recording.h 2.27 2012/02/19 10:44:53 kls Exp $
*/
#ifndef __RECORDING_H
@ -279,7 +279,7 @@ private:
void ConvertToPes(tIndexTs *IndexTs, int Count);
bool CatchUp(int Index = -1);
public:
cIndexFile(const char *FileName, bool Record, bool IsPesRecording = false);
cIndexFile(const char *FileName, bool Record, bool IsPesRecording = false, bool PauseLive = false);
~cIndexFile();
bool Ok(void) { return index != NULL; }
bool Write(bool Independent, uint16_t FileNumber, off_t FileOffset);

10
tools.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.c 2.21 2012/02/17 13:58:49 kls Exp $
* $Id: tools.c 2.22 2012/02/18 15:30:35 kls Exp $
*/
#include "tools.h"
@ -563,6 +563,14 @@ time_t LastModifiedTime(const char *FileName)
return 0;
}
off_t FileSize(const char *FileName)
{
struct stat fs;
if (stat(FileName, &fs) == 0)
return fs.st_size;
return -1;
}
// --- cTimeMs ---------------------------------------------------------------
cTimeMs::cTimeMs(int Ms)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: tools.h 2.14 2011/12/04 14:48:03 kls Exp $
* $Id: tools.h 2.15 2012/02/18 15:29:50 kls Exp $
*/
#ifndef __TOOLS_H
@ -224,6 +224,7 @@ char *ReadLink(const char *FileName); ///< returns a new string allocated on the
bool SpinUpDisk(const char *FileName);
void TouchFile(const char *FileName);
time_t LastModifiedTime(const char *FileName);
off_t FileSize(const char *FileName); ///< returns the size of the given file, or -1 in case of an error (e.g. if the file doesn't exist)
cString WeekDayName(int WeekDay);
cString WeekDayName(time_t t);
cString WeekDayNameFull(int WeekDay);

3
vdr.c
View File

@ -22,7 +22,7 @@
*
* The project's page is at http://www.tvdr.de
*
* $Id: vdr.c 2.28 2012/02/11 12:34:01 kls Exp $
* $Id: vdr.c 2.29 2012/02/19 11:37:35 kls Exp $
*/
#include <getopt.h>
@ -1160,7 +1160,6 @@ int main(int argc, char *argv[])
}
switch (state) {
case osPause: DELETE_MENU;
cControl::Shutdown(); // just in case
if (!cRecordControls::PauseLiveVideo())
Skins.Message(mtError, tr("No free DVB device to record!"));
break;