mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Fixed switching into time shift mode when pausing live video
This commit is contained in:
parent
50e09d1232
commit
23ec57d822
@ -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
|
||||
|
4
HISTORY
4
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).
|
||||
|
18
dvbplayer.c
18
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))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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
11
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;
|
||||
|
4
menu.h
4
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);
|
||||
|
11
recording.c
11
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:
|
||||
|
@ -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
10
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)
|
||||
|
3
tools.h
3
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);
|
||||
|
3
vdr.c
3
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;
|
||||
|
Loading…
Reference in New Issue
Block a user