summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2012-02-19 11:50:20 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2012-02-19 11:50:20 +0100
commit23ec57d8229be5c0a2eaa12fa313ceb8b49fc962 (patch)
treedf01fdf5fe16d652783aec64320c7fcf98464dd9
parent50e09d1232c8d01a8a3f570aa8b3044f8d46a2e6 (diff)
downloadvdr-23ec57d8229be5c0a2eaa12fa313ceb8b49fc962.tar.gz
vdr-23ec57d8229be5c0a2eaa12fa313ceb8b49fc962.tar.bz2
Fixed switching into time shift mode when pausing live video1.7.24
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY4
-rw-r--r--dvbplayer.c18
-rw-r--r--dvbplayer.h7
-rw-r--r--menu.c11
-rw-r--r--menu.h4
-rw-r--r--recording.c11
-rw-r--r--recording.h4
-rw-r--r--tools.c10
-rw-r--r--tools.h3
-rw-r--r--vdr.c3
11 files changed, 49 insertions, 27 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index a7f9c5cd..72f4a44a 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -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
diff --git a/HISTORY b/HISTORY
index 82c02128..3ecb8c65 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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).
diff --git a/dvbplayer.c b/dvbplayer.c
index d644e203..b0adac40 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -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))
{
}
diff --git a/dvbplayer.h b/dvbplayer.h
index 41590257..e2f2082d 100644
--- a/dvbplayer.h
+++ b/dvbplayer.h
@@ -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);
diff --git a/menu.c b/menu.c
index 7acffe7a..61dcdfcb 100644
--- a/menu.c
+++ b/menu.c
@@ -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;
diff --git a/menu.h b/menu.h
index ec1c175b..c74d8c25 100644
--- a/menu.h
+++ b/menu.h
@@ -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);
diff --git a/recording.c b/recording.c
index ac1ff2c7..7617d734 100644
--- a/recording.c
+++ b/recording.c
@@ -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:
diff --git a/recording.h b/recording.h
index d3dbd1da..61ec2a64 100644
--- a/recording.h
+++ b/recording.h
@@ -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);
diff --git a/tools.c b/tools.c
index 145af7af..3296b540 100644
--- a/tools.c
+++ b/tools.c
@@ -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)
diff --git a/tools.h b/tools.h
index 86e8fb06..52bf8a7f 100644
--- a/tools.h
+++ b/tools.h
@@ -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);
diff --git a/vdr.c b/vdr.c
index 0913614f..417ee19d 100644
--- a/vdr.c
+++ b/vdr.c
@@ -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;