summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY12
-rw-r--r--Makefile4
-rw-r--r--README24
-rw-r--r--contrib/README14
-rw-r--r--contrib/getlength.c (renamed from tools/getlength.c)0
-rw-r--r--contrib/isodetect.c (renamed from tools/isodetect.c)0
-rw-r--r--contrib/vdr-1.3.43-extrecmenu.diff (renamed from patches/vdr-1.3.43-extrecmenu.diff)0
-rw-r--r--extrecmenu.c44
-rw-r--r--extrecmenu.h2
-rw-r--r--i18n.c78
-rw-r--r--mydvbplayer.c824
-rw-r--r--mydvbplayer.h45
-rw-r--r--mymenumoverecording.h75
-rw-r--r--mymenurecordingdetails.c48
-rw-r--r--mymenurecordings.c163
-rw-r--r--mymenurecordings.h14
-rw-r--r--mymenurenamerecording.c25
-rw-r--r--mymenusetup.c26
-rw-r--r--mymenusetup.h6
-rw-r--r--myreplaycontrol.c48
-rw-r--r--myreplaycontrol.h8
-rw-r--r--patchfont.c2
-rwxr-xr-xscripts/dvdarchive.sh26
-rw-r--r--tools.c65
-rw-r--r--tools.h18
25 files changed, 452 insertions, 1119 deletions
diff --git a/HISTORY b/HISTORY
index 34861d4..2585985 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,18 @@
VDR Plugin 'extrecmenu' Revision History
----------------------------------------
+2006-04-10: Version 0.9
+- removed myDvbPlayer, use VDR's cDvbPlayer instead
+- made adjustments to work with BigPatch-VDRs (JumpPlay-patch)
+- added option for sort recordings
+- moved editing of priority and lifetime to its own submenu
+- removed option to select alternative dvd marker, the icon is now default
+- added default values for setup options
+- moved content of patches/ and tools/ to contrib/ and added a small README
+- new version of 'dvdarchive.sh'; thanks to vejoun from vdr-portal.de
+- fixed problem with archive dvd recordings at the base dir; thanks to Mase
+ from vdr-portal.de for reporting
+
2006-03-31: Version 0.8a
- fixed problem when open the plugin while replaying a archive dvd; thanks to
Monroe from vdr-portal.de for reporting
diff --git a/Makefile b/Makefile
index fbec955..e2318df 100644
--- a/Makefile
+++ b/Makefile
@@ -47,8 +47,8 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
OBJS = $(PLUGIN).o mymenurecordings.o myreplaycontrol.o mymenurenamerecording.o \
- mymenumoverecording.o i18n.o mydvbplayer.o mymenurecordinginfo.o mymenusetup.o \
- mymenucommands.o patchfont.o tools.o
+ mymenumoverecording.o i18n.o mymenurecordinginfo.o mymenusetup.o \
+ mymenucommands.o patchfont.o tools.o mymenurecordingdetails.o
### Implicit rules:
diff --git a/README b/README
index 9ef17ec..495ce2f 100644
--- a/README
+++ b/README
@@ -6,7 +6,7 @@ Project's homepage: http://martins-kabuff.de/extrecmenu.html
See the file COPYING for license information. See top of *.c for additional
copyright information. The script 'dvdarchive.sh' is provided by vejoun from
-vdr-portal.de
+vdr-portal.de.
Description
-------------------------------------------------------------------------------
@@ -25,7 +25,19 @@ base directory of the /video-directory-hierarchy. 'Ok' opens sub-directories,
with 'Yellow' you can create new dirs. 'Blue' moves the recording to the
selected directory.
-DVDArchive-patch functionality
+Sort recordings
+-------------------------------------------------------------------------------
+There are four options for sorting at the setup menu:
+Sort recordings by:
+- alphabet for main-, flexible for subdirectories
+- date for main-, flexible for subdirectories
+- alphabet for all directories
+- date for all directories
+Flexible means, if the directory name ends with "-",".","$" or "ª", the
+recordings in this directory are sorted by name, else by date.
+
+
+DVD-archive functionality
-------------------------------------------------------------------------------
Burn the entire directory, that contains the recording, to a dvd and label it
with an indentifier (a number or anything else). You can of cource burn more
@@ -59,3 +71,11 @@ Check the options at the setup menu of the plugin. They are self-explaining.
There is a patch for VDR in patches/ for replacing VDR's recordings menu with
this plugin. You have to set the corresponding option at the setup menu of the
plugin!
+
+There ist a patched TTF-Font for Enigma containing the dvd and alternative new
+symbols. See this post at vdr-portal.de:
+http://www.vdr-portal.de/board/thread.php?postid=447376#post447376
+
+
+Do you like this plugin? Support the developer! Go to the project homepage and
+make a donation over the PayPal donation button.
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 0000000..3ec797d
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,14 @@
+getlength.c
+-------------------------------------------------------------------------------
+Creates a length.vdr from an index.vdr
+Compile with 'gcc getlength.c -o getlength'
+
+isodetect.c
+-------------------------------------------------------------------------------
+Checks, if a dvd is in the drive. Used optionally by dvdarchive.sh
+Compile with 'gcc isodetect.c -o isodetect'
+
+vdr-1.3.43-extrecmenu.diff
+-------------------------------------------------------------------------------
+A patch to replace VDR's recordings menu with the plugin
+Apply with 'patch < vdr-1.3.43.extrecmenu.diff'
diff --git a/tools/getlength.c b/contrib/getlength.c
index 946e01c..946e01c 100644
--- a/tools/getlength.c
+++ b/contrib/getlength.c
diff --git a/tools/isodetect.c b/contrib/isodetect.c
index 25c4c68..25c4c68 100644
--- a/tools/isodetect.c
+++ b/contrib/isodetect.c
diff --git a/patches/vdr-1.3.43-extrecmenu.diff b/contrib/vdr-1.3.43-extrecmenu.diff
index 6e980f0..6e980f0 100644
--- a/patches/vdr-1.3.43-extrecmenu.diff
+++ b/contrib/vdr-1.3.43-extrecmenu.diff
diff --git a/extrecmenu.c b/extrecmenu.c
index 622042b..c37ea64 100644
--- a/extrecmenu.c
+++ b/extrecmenu.c
@@ -10,63 +10,50 @@
cPluginExtrecmenu::cPluginExtrecmenu(void)
{
- // Initialize any member variables here.
- // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
- // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
}
cPluginExtrecmenu::~cPluginExtrecmenu()
{
- // Clean up after yourself!
}
const char *cPluginExtrecmenu::CommandLineHelp(void)
{
- // Return a string that describes all known command line options.
- return NULL;
+ return NULL;
}
bool cPluginExtrecmenu::ProcessArgs(int argc, char *argv[])
{
- // Implement command line argument processing here if applicable.
- return true;
+ return true;
}
bool cPluginExtrecmenu::Initialize(void)
{
RegisterI18n(Phrases);
- mysetup.wasdvd=false;
-
return true;
}
bool cPluginExtrecmenu::Start(void)
{
- // Start any background activities the plugin shall perform.
- return true;
+ return true;
}
void cPluginExtrecmenu::Stop(void)
{
- // Stop any background activities the plugin shall perform.
}
void cPluginExtrecmenu::Housekeeping(void)
{
- // Perform any cleanup or other regular tasks.
}
cOsdObject *cPluginExtrecmenu::MainMenuAction(void)
{
- // Perform the action when selected from the main VDR menu.
- return new myMenuRecordings();
+ return new myMenuRecordings();
}
cMenuSetupPage *cPluginExtrecmenu::SetupMenu(void)
{
- // Return a setup menu in case the plugin supports one.
- return new myMenuSetup();
+ return new myMenuSetup();
}
bool cPluginExtrecmenu::SetupParse(const char *Name, const char *Value)
@@ -92,14 +79,14 @@ bool cPluginExtrecmenu::SetupParse(const char *Name, const char *Value)
if(!strcasecmp(Name,"PatchNew"))
mysetup.PatchNew=atoi(Value);
else
- if(!strcasecmp(Name,"PatchDvd"))
- mysetup.PatchDvd=atoi(Value);
+ if(!strcasecmp(Name,"ShowDvdNr"))
+ mysetup.ShowDvdNr=atoi(Value);
else
- if(!strcasecmp(Name,"ShowDvdNr"))
- mysetup.ShowDvdNr=atoi(Value);
+ if(!strcasecmp(Name,"ShowNewRecs"))
+ mysetup.ShowNewRecs=atoi(Value);
else
- if(!strcasecmp(Name,"ShowNewRecs"))
- mysetup.ShowNewRecs=atoi(Value);
+ if(!strcasecmp(Name,"SortRecords"))
+ mysetup.SortRecords=atoi(Value);
else
return false;
return true;
@@ -107,20 +94,17 @@ bool cPluginExtrecmenu::SetupParse(const char *Name, const char *Value)
bool cPluginExtrecmenu::Service(const char *Id, void *Data)
{
- // Handle custom service requests from other plugins
- return false;
+ return false;
}
const char **cPluginExtrecmenu::SVDRPHelpPages(void)
{
- // Return help text for SVDRP commands this plugin implements
- return NULL;
+ return NULL;
}
cString cPluginExtrecmenu::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
{
- // Process SVDRP commands this plugin implements
- return NULL;
+ return NULL;
}
VDRPLUGINCREATOR(cPluginExtrecmenu); // Don't touch this!
diff --git a/extrecmenu.h b/extrecmenu.h
index 687c445..d504ace 100644
--- a/extrecmenu.h
+++ b/extrecmenu.h
@@ -1,6 +1,6 @@
#include <vdr/plugin.h>
-static const char *VERSION = "0.8a";
+static const char *VERSION = "0.9";
static const char *DESCRIPTION = "Extended recordings menu";
static const char *MAINMENUENTRY = "ExtRecMenu";
diff --git a/i18n.c b/i18n.c
index a458750..c78bd70 100644
--- a/i18n.c
+++ b/i18n.c
@@ -205,16 +205,6 @@ const tI18nPhrase Phrases[] = {
"",
"",
},
- { "Show alternative dvd marker",
- "Alternativen DVD-Marker anzeigen",
- "",
- "",
- "",
- "",
- "Afficher les symbole DVD",
- "",
- "Näytä vaihtoehtoinen DVD:n merkintä",
- },
{ "Please insert DVD %s",
"Bitte DVD %s einlegen",
"",
@@ -271,7 +261,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "[rép. parent]",
+ "[Dossier racine]",
"",
"[juurihakemisto]",
},
@@ -281,7 +271,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "",
+ "Pas de DVD dans le lecteur!",
"",
"Asemassa ei ole DVD-levyä!",
},
@@ -291,7 +281,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "",
+ "Erreur lors de la création des racourcis [0-9]*.vdr!",
"",
"Tiedostojen [0-9]*.vdr linkittäminen epäonnistui!",
},
@@ -301,9 +291,69 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "",
+ "\"Colone nouveaux enregistrements\" Afficher",
"",
"Näytä \"uudet tallenteet\"-sarake",
},
+ { "Sort recordings by",
+ "Aufnahme sortieren nach",
+ "",
+ "",
+ "",
+ "",
+ "Trier enregistrements par",
+ "",
+ "Järjestä tallenteet",
+ },
+ { "alphabet for main-, flexible for subdirectories",
+ "Alphabet für Haupt-, flexibel für Unterverzeichnisse",
+ "",
+ "",
+ "",
+ "",
+ "Alphabet pour les dossiers, flexible pour les sous-dossiers",
+ "",
+ "juurihakemisto aakkosittain",
+ },
+ { "date for main-, flexible for subdirectories",
+ "Datum für Haupt, flexibel für Unterverzeichnisse",
+ "",
+ "",
+ "",
+ "",
+ "Date pour les dossiers, flexible pour les sous-dossiers",
+ "",
+ "juurihakemisto päivämäärän mukaan",
+ },
+ { "alphabet for all directories",
+ "Alphabet für alle Verzeichnisse",
+ "",
+ "",
+ "",
+ "",
+ "Alphabet pour tous les dossiers",
+ "",
+ "kaikki aakkosittain",
+ },
+ { "date for all directories",
+ "Datum für alle Verzeichnisse",
+ "",
+ "",
+ "",
+ "",
+ "Date pour tous les dossiers",
+ "",
+ "kaikki päivämäärän mukaan",
+ },
+ { "Details",
+ "Details",
+ "",
+ "",
+ "",
+ "",
+ "Détails",
+ "",
+ "Lisätiedot",
+ },
{ NULL }
};
diff --git a/mydvbplayer.c b/mydvbplayer.c
deleted file mode 100644
index 2ef2b28..0000000
--- a/mydvbplayer.c
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * See the README file for copyright information and how to reach the author.
- *
- * This code is directly taken from VDR with some changes by me to work with this plugin
- */
-
-#include "mydvbplayer.h"
-#include <stdlib.h>
-#include <vdr/recording.h>
-#include <vdr/remux.h>
-#include <vdr/ringbuffer.h>
-#include <vdr/thread.h>
-#include <vdr/tools.h>
-
-// --- myBackTrace ----------------------------------------------------------
-
-#define AVG_FRAME_SIZE 15000 // an assumption about the average frame size
-#define DVB_BUF_SIZE (256 * 1024) // an assumption about the dvb firmware buffer size
-#define BACKTRACE_ENTRIES (DVB_BUF_SIZE / AVG_FRAME_SIZE + 20) // how many entries are needed to backtrace buffer contents
-
-class myBackTrace {
-private:
- int index[BACKTRACE_ENTRIES];
- int length[BACKTRACE_ENTRIES];
- int pos, num;
-public:
- myBackTrace(void);
- void Clear(void);
- void Add(int Index, int Length);
- int Get(bool Forward);
- };
-
-myBackTrace::myBackTrace(void)
-{
- Clear();
-}
-
-void myBackTrace::Clear(void)
-{
- pos = num = 0;
-}
-
-void myBackTrace::Add(int Index, int Length)
-{
- index[pos] = Index;
- length[pos] = Length;
- if (++pos >= BACKTRACE_ENTRIES)
- pos = 0;
- if (num < BACKTRACE_ENTRIES)
- num++;
-}
-
-int myBackTrace::Get(bool Forward)
-{
- int p = pos;
- int n = num;
- int l = DVB_BUF_SIZE + (Forward ? 0 : 256 * 1024); //XXX (256 * 1024) == DVB_BUF_SIZE ???
- int i = -1;
-
- while (n && l > 0) {
- if (--p < 0)
- p = BACKTRACE_ENTRIES - 1;
- i = index[p] - 1;
- l -= length[p];
- n--;
- }
- return i;
-}
-
-// --- myNonBlockingFileReader ------------------------------------------------
-
-class myNonBlockingFileReader : public cThread {
-private:
- cUnbufferedFile *f;
- uchar *buffer;
- int wanted;
- int length;
- bool hasData;
- cCondWait newSet;
- cCondVar newDataCond;
- cMutex newDataMutex;
-protected:
- void Action(void);
-public:
- myNonBlockingFileReader(void);
- ~myNonBlockingFileReader();
- void Clear(void);
- int Read(cUnbufferedFile *File, uchar *Buffer, int Length);
- bool Reading(void) { return buffer; }
- bool WaitForDataMs(int msToWait);
- };
-
-myNonBlockingFileReader::myNonBlockingFileReader(void)
-:cThread("non blocking file reader")
-{
- f = NULL;
- buffer = NULL;
- wanted = length = 0;
- hasData = false;
- Start();
-}
-
-myNonBlockingFileReader::~myNonBlockingFileReader()
-{
- newSet.Signal();
- Cancel(3);
- free(buffer);
-}
-
-void myNonBlockingFileReader::Clear(void)
-{
- Lock();
- f = NULL;
- free(buffer);
- buffer = NULL;
- wanted = length = 0;
- hasData = false;
- Unlock();
- newSet.Signal();
-}
-
-int myNonBlockingFileReader::Read(cUnbufferedFile *File, uchar *Buffer, int Length)
-{
- if (hasData && buffer) {
- if (buffer != Buffer) {
- esyslog("ERROR: myNonBlockingFileReader::Read() called with different buffer!");
- errno = EINVAL;
- return -1;
- }
- buffer = NULL;
- return length;
- }
- if (!buffer) {
- f = File;
- buffer = Buffer;
- wanted = Length;
- length = 0;
- hasData = false;
- newSet.Signal();
- }
- errno = EAGAIN;
- return -1;
-}
-
-void myNonBlockingFileReader::Action(void)
-{
- while (Running()) {
- Lock();
- if (!hasData && f && buffer) {
- int r = f->Read(buffer + length, wanted - length);
- if (r >= 0) {
- length += r;
- if (!r || length == wanted) { // r == 0 means EOF
- cMutexLock NewDataLock(&newDataMutex);
- hasData = true;
- newDataCond.Broadcast();
- }
- }
- else if (r < 0 && FATALERRNO) {
- LOG_ERROR;
- length = r; // this will forward the error status to the caller
- hasData = true;
- }
- }
- Unlock();
- newSet.Wait(1000);
- }
-}
-
-bool myNonBlockingFileReader::WaitForDataMs(int msToWait)
-{
- cMutexLock NewDataLock(&newDataMutex);
- if (hasData)
- return true;
- return newDataCond.TimedWait(newDataMutex, msToWait);
-}
-
-// --- myDvbPlayer ------------------------------------------------------------
-
-#define PLAYERBUFSIZE MEGABYTE(1)
-
-// The number of frames to back up when resuming an interrupted replay session:
-#define RESUMEBACKUP (10 * FRAMESPERSEC)
-
-class myDvbPlayer : public cPlayer, cThread {
-private:
- enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill };
- enum ePlayDirs { pdForward, pdBackward };
- static int Speeds[];
- myNonBlockingFileReader *nonBlockingFileReader;
- cRingBufferFrame *ringBuffer;
- myBackTrace *backTrace;
- cFileName *fileName;
- cIndexFile *index;
- cUnbufferedFile *replayFile;
- bool eof;
- bool firstPacket;
- ePlayModes playMode;
- ePlayDirs playDir;
- int trickSpeed;
- int readIndex, writeIndex;
- cFrame *readFrame;
- cFrame *playFrame;
- void TrickSpeed(int Increment);
- void Empty(void);
- bool NextFile(uchar FileNumber = 0, int FileOffset = -1);
- int Resume(void);
- bool Save(void);
-protected:
- virtual void Activate(bool On);
- virtual void Action(void);
-public:
- myDvbPlayer(const char *FileName);
- virtual ~myDvbPlayer();
- bool Active(void) { return cThread::Running(); }
- void Pause(void);
- void Play(void);
- void Forward(void);
- void Backward(void);
- int SkipFrames(int Frames);
- void SkipSeconds(int Seconds);
- void Goto(int Position, bool Still = false);
- virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
- virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
- };
-
-#define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct?
-#define NORMAL_SPEED 4 // the index of the '1' entry in the following array
-#define MAX_SPEEDS 3 // the offset of the maximum speed from normal speed in either direction
-#define SPEED_MULT 12 // the speed multiplier
-int myDvbPlayer::Speeds[] = { 0, -2, -4, -8, 1, 2, 4, 12, 0 };
-
-myDvbPlayer::myDvbPlayer(const char *FileName)
-:cThread("dvbplayer")
-{
- nonBlockingFileReader = NULL;
- ringBuffer = NULL;
- backTrace = NULL;
- index = NULL;
- eof = false;
- firstPacket = true;
- playMode = pmPlay;
- playDir = pdForward;
- trickSpeed = NORMAL_SPEED;
- readIndex = writeIndex = -1;
- readFrame = NULL;
- playFrame = NULL;
- isyslog("replay %s", FileName);
- fileName = new cFileName(FileName, false);
- replayFile = fileName->Open();
- if (!replayFile)
- return;
- ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE);
- // Create the index file:
- index = new cIndexFile(FileName, false);
- if (!index)
- esyslog("ERROR: can't allocate index");
- else if (!index->Ok()) {
- delete index;
- index = NULL;
- }
- backTrace = new myBackTrace;
-}
-
-myDvbPlayer::~myDvbPlayer()
-{
- Detach();
- Save();
- delete readFrame; // might not have been stored in the buffer in Action()
- delete index;
- delete fileName;
- delete backTrace;
- delete ringBuffer;
-}
-
-void myDvbPlayer::TrickSpeed(int Increment)
-{
- int nts = trickSpeed + Increment;
- if (Speeds[nts] == 1) {
- trickSpeed = nts;
- if (playMode == pmFast)
- Play();
- else
- Pause();
- }
- else if (Speeds[nts]) {
- trickSpeed = nts;
- int Mult = (playMode == pmSlow && playDir == pdForward) ? 1 : SPEED_MULT;
- int sp = (Speeds[nts] > 0) ? Mult / Speeds[nts] : -Speeds[nts] * Mult;
- if (sp > MAX_VIDEO_SLOWMOTION)
- sp = MAX_VIDEO_SLOWMOTION;
- DeviceTrickSpeed(sp);
- }
-}
-
-void myDvbPlayer::Empty(void)
-{
- LOCK_THREAD;
- if (nonBlockingFileReader)
- nonBlockingFileReader->Clear();
- if ((readIndex = backTrace->Get(playDir == pdForward)) < 0)
- readIndex = writeIndex;
- delete readFrame; // might not have been stored in the buffer in Action()
- readFrame = NULL;
- playFrame = NULL;
- ringBuffer->Clear();
- backTrace->Clear();
- DeviceClear();
- firstPacket = true;
-}
-
-bool myDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
-{
- if (FileNumber > 0)
- replayFile = fileName->SetOffset(FileNumber, FileOffset);
- else if (replayFile && eof)
- replayFile = fileName->NextFile();
- eof = false;
- return replayFile != NULL;
-}
-
-int myDvbPlayer::Resume(void)
-{
- if (index) {
- int Index = index->GetResume();
- if (Index >= 0) {
- uchar FileNumber;
- int FileOffset;
- if (index->Get(Index, &FileNumber, &FileOffset) && NextFile(FileNumber, FileOffset))
- return Index;
- }
- }
- return -1;
-}
-
-bool myDvbPlayer::Save(void)
-{
- if (index) {
- int Index = writeIndex;
- if (Index >= 0) {
- Index -= RESUMEBACKUP;
- if (Index > 0)
- Index = index->GetNextIFrame(Index, false);
- else
- Index = 0;
- if (Index >= 0)
- return index->StoreResume(Index);
- }
- }
- return false;
-}
-
-void myDvbPlayer::Activate(bool On)
-{
- if (On) {
- if (replayFile)
- Start();
- }
- else
- Cancel(9);
-}
-
-void myDvbPlayer::Action(void)
-{
- uchar *b = NULL;
- uchar *p = NULL;
- int pc = 0;
-
- readIndex = Resume();
- if (readIndex >= 0)
- isyslog("resuming replay at index %d (%s)", readIndex, *IndexToHMSF(readIndex, true));
-
- nonBlockingFileReader = new myNonBlockingFileReader;
- int Length = 0;
- bool Sleep = false;
- bool WaitingForData = false;
-
- while (Running() && (NextFile() || readIndex >= 0 || ringBuffer->Available() || !DeviceFlush(100))) {
- if (Sleep) {
- if (WaitingForData)
- nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data
- else
- cCondWait::SleepMs(3); // this keeps the CPU load low
- Sleep = false;
- }
- cPoller Poller;
- if (DevicePoll(Poller, 100)) {
-
- LOCK_THREAD;
-
- // Read the next frame from the file:
-
- if (playMode != pmStill && playMode != pmPause) {
- if (!readFrame && (replayFile || readIndex >= 0)) {
- if (!nonBlockingFileReader->Reading()) {
- if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
- uchar FileNumber;
- int FileOffset;
- int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
- if (Index >= 0) {
- if (!NextFile(FileNumber, FileOffset))
- continue;
- }
- else {
- // hit begin of recording: wait for device buffers to drain
- // before changing play mode:
- if (!DeviceFlush(100))
- continue;
- // can't call Play() here, because those functions may only be
- // called from the foreground thread - and we also don't need
- // to empty the buffer here
- DevicePlay();
- playMode = pmPlay;
- playDir = pdForward;
- continue;
- }
- readIndex = Index;
- }
- else if (index) {
- uchar FileNumber;
- int FileOffset;
- readIndex++;
- if (!(index->Get(readIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset))) {
- readIndex = -1;
- eof = true;
- continue;
- }
- }
- else // allows replay even if the index file is missing
- Length = MAXFRAMESIZE;
- if (Length == -1)
- Length = MAXFRAMESIZE; // this means we read up to EOF (see cIndex)
- else if (Length > MAXFRAMESIZE) {
- esyslog("ERROR: frame larger than buffer (%d > %d)", Length, MAXFRAMESIZE);
- Length = MAXFRAMESIZE;
- }
- b = MALLOC(uchar, Length);
- }
- int r = nonBlockingFileReader->Read(replayFile, b, Length);
- if (r > 0) {
- WaitingForData = false;
- readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
- b = NULL;
- }
- else if (r == 0)
- eof = true;
- else if (r < 0 && errno == EAGAIN)
- WaitingForData = true;
- else if (r < 0 && FATALERRNO) {
- LOG_ERROR;
- break;
- }
- }
-
- // Store the frame in the buffer:
-
- if (readFrame) {
- if (ringBuffer->Put(readFrame))
- readFrame = NULL;
- }
- }
- else
- Sleep = true;
-
- // Get the next frame from the buffer:
-
- if (!playFrame) {
- playFrame = ringBuffer->Get();
- p = NULL;
- pc = 0;
- }
-
- // Play the frame:
-
- if (playFrame) {
- if (!p) {
- p = playFrame->Data();
- pc = playFrame->Count();
- if (p) {
- if (firstPacket) {
- PlayPes(NULL, 0);
- cRemux::SetBrokenLink(p, pc);
- firstPacket = false;
- }
- }
- }
- if (p) {
- int w = PlayPes(p, pc, playMode != pmPlay);
- if (w > 0) {
- p += w;
- pc -= w;
- }
- else if (w < 0 && FATALERRNO) {
- LOG_ERROR;
- break;
- }
- }
- if (pc == 0) {
- writeIndex = playFrame->Index();
- backTrace->Add(playFrame->Index(), playFrame->Count());
- ringBuffer->Drop(playFrame);
- playFrame = NULL;
- p = NULL;
- }
- }
- else
- Sleep = true;
- }
- }
-
- myNonBlockingFileReader *nbfr = nonBlockingFileReader;
- nonBlockingFileReader = NULL;
- delete nbfr;
-}
-
-void myDvbPlayer::Pause(void)
-{
- if (playMode == pmPause || playMode == pmStill)
- Play();
- else {
- LOCK_THREAD;
- if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))
- Empty();
- DeviceFreeze();
- playMode = pmPause;
- }
-}
-
-void myDvbPlayer::Play(void)
-{
- if (playMode != pmPlay) {
- LOCK_THREAD;
- if (playMode == pmStill || playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))
- Empty();
- DevicePlay();
- playMode = pmPlay;
- playDir = pdForward;
- }
-}
-
-void myDvbPlayer::Forward(void)
-{
- if (index) {
- switch (playMode) {
- case pmFast:
- if (Setup.MultiSpeedMode) {
- TrickSpeed(playDir == pdForward ? 1 : -1);
- break;
- }
- else if (playDir == pdForward) {
- Play();
- break;
- }
- // run into pmPlay
- case pmPlay: {
- LOCK_THREAD;
- Empty();
- DeviceMute();
- playMode = pmFast;
- playDir = pdForward;
- trickSpeed = NORMAL_SPEED;
- TrickSpeed(Setup.MultiSpeedMode ? 1 : MAX_SPEEDS);
- }
- break;
- case pmSlow:
- if (Setup.MultiSpeedMode) {
- TrickSpeed(playDir == pdForward ? -1 : 1);
- break;
- }
- else if (playDir == pdForward) {
- Pause();
- break;
- }
- // run into pmPause
- case pmStill:
- case pmPause:
- DeviceMute();
- playMode = pmSlow;
- playDir = pdForward;
- trickSpeed = NORMAL_SPEED;
- TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS);
- break;
- }
- }
-}
-
-void myDvbPlayer::Backward(void)
-{
- if (index) {
- switch (playMode) {
- case pmFast:
- if (Setup.MultiSpeedMode) {
- TrickSpeed(playDir == pdBackward ? 1 : -1);
- break;
- }
- else if (playDir == pdBackward) {
- Play();
- break;
- }
- // run into pmPlay
- case pmPlay: {
- LOCK_THREAD;
- Empty();
- DeviceMute();
- playMode = pmFast;
- playDir = pdBackward;
- trickSpeed = NORMAL_SPEED;
- TrickSpeed(Setup.MultiSpeedMode ? 1 : MAX_SPEEDS);
- }
- break;
- case pmSlow:
- if (Setup.MultiSpeedMode) {
- TrickSpeed(playDir == pdBackward ? -1 : 1);
- break;
- }
- else if (playDir == pdBackward) {
- Pause();
- break;
- }
- // run into pmPause
- case pmStill:
- case pmPause: {
- LOCK_THREAD;
- Empty();
- DeviceMute();
- playMode = pmSlow;
- playDir = pdBackward;
- trickSpeed = NORMAL_SPEED;
- TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS);
- }
- break;
- }
- }
-}
-
-int myDvbPlayer::SkipFrames(int Frames)
-{
- if (index && Frames) {
- int Current, Total;
- GetIndex(Current, Total, true);
- int OldCurrent = Current;
- // As GetNextIFrame() increments/decrements at least once, the
- // destination frame (= Current + Frames) must be adjusted by
- // -1/+1 respectively.
- Current = index->GetNextIFrame(Current + Frames + (Frames > 0 ? -1 : 1), Frames > 0);
- return Current >= 0 ? Current : OldCurrent;
- }
- return -1;
-}
-
-void myDvbPlayer::SkipSeconds(int Seconds)
-{
- if (index && Seconds) {
- LOCK_THREAD;
- Empty();
- int Index = writeIndex;
- if (Index >= 0) {
- Index = max(Index + Seconds * FRAMESPERSEC, 0);
- if (Index > 0)
- Index = index->GetNextIFrame(Index, false, NULL, NULL, NULL, true);
- if (Index >= 0)
- readIndex = writeIndex = Index - 1; // Action() will first increment it!
- }
- Play();
- }
-}
-
-void myDvbPlayer::Goto(int Index, bool Still)
-{
- if (index) {
- LOCK_THREAD;
- Empty();
- if (++Index <= 0)
- Index = 1; // not '0', to allow GetNextIFrame() below to work!
- uchar FileNumber;
- int FileOffset, Length;
- Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length);
- if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) {
- uchar b[MAXFRAMESIZE + 4 + 5 + 4];
- int r = ReadFrame(replayFile, b, Length, sizeof(b));
- if (r > 0) {
- if (playMode == pmPause)
- DevicePlay();
- // append sequence end code to get the image shown immediately with softdevices
- if (r > 6 && (b[3] & 0xF0) == 0xE0) { // make sure to append it only to a video packet
- b[r++] = 0x00;
- b[r++] = 0x00;
- b[r++] = 0x01;
- b[r++] = b[3];
- if (b[6] & 0x80) { // MPEG 2
- b[r++] = 0x00;
- b[r++] = 0x07;
- b[r++] = 0x80;
- b[r++] = 0x00;
- b[r++] = 0x00;
- }
- else { // MPEG 1
- b[r++] = 0x00;
- b[r++] = 0x05;
- b[r++] = 0x0F;
- }
- b[r++] = 0x00;
- b[r++] = 0x00;
- b[r++] = 0x01;
- b[r++] = 0xB7;
- }
- DeviceStillPicture(b, r);
- }
- playMode = pmStill;
- }
- readIndex = writeIndex = Index;
- }
-}
-
-bool myDvbPlayer::GetIndex(int &Current, int &Total, bool SnapToIFrame)
-{
- if (index) {
- if (playMode == pmStill)
- Current = max(readIndex, 0);
- else {
- Current = max(writeIndex, 0);
- if (SnapToIFrame) {
- int i1 = index->GetNextIFrame(Current + 1, false);
- int i2 = index->GetNextIFrame(Current, true);
- Current = (abs(Current - i1) <= abs(Current - i2)) ? i1 : i2;
- }
- }
- Total = index->Last();
- return true;
- }
- Current = Total = -1;
- return false;
-}
-
-bool myDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
-{
- Play = (playMode == pmPlay || playMode == pmFast);
- Forward = (playDir == pdForward);
- if (playMode == pmFast || playMode == pmSlow)
- Speed = Setup.MultiSpeedMode ? abs(trickSpeed - NORMAL_SPEED) : 0;
- else
- Speed = -1;
- return true;
-}
-
-// --- myDvbPlayerControl -----------------------------------------------------
-
-myDvbPlayerControl::myDvbPlayerControl(const char *FileName)
-:cControl(player = new myDvbPlayer(FileName))
-{
-}
-
-myDvbPlayerControl::~myDvbPlayerControl()
-{
- Stop();
-}
-
-bool myDvbPlayerControl::Active(void)
-{
- return player && player->Active();
-}
-
-void myDvbPlayerControl::Stop(void)
-{
- delete player;
- player = NULL;
-}
-
-void myDvbPlayerControl::Pause(void)
-{
- if (player)
- player->Pause();
-}
-
-void myDvbPlayerControl::Play(void)
-{
- if (player)
- player->Play();
-}
-
-void myDvbPlayerControl::Forward(void)
-{
- if (player)
- player->Forward();
-}
-
-void myDvbPlayerControl::Backward(void)
-{
- if (player)
- player->Backward();
-}
-
-void myDvbPlayerControl::SkipSeconds(int Seconds)
-{
- if (player)
- player->SkipSeconds(Seconds);
-}
-
-int myDvbPlayerControl::SkipFrames(int Frames)
-{
- if (player)
- return player->SkipFrames(Frames);
- return -1;
-}
-
-bool myDvbPlayerControl::GetIndex(int &Current, int &Total, bool SnapToIFrame)
-{
- if (player) {
- player->GetIndex(Current, Total, SnapToIFrame);
- return true;
- }
- return false;
-}
-
-bool myDvbPlayerControl::GetReplayMode(bool &Play, bool &Forward, int &Speed)
-{
- return player && player->GetReplayMode(Play, Forward, Speed);
-}
-
-void myDvbPlayerControl::Goto(int Position, bool Still)
-{
- if (player)
- player->Goto(Position, Still);
-}
diff --git a/mydvbplayer.h b/mydvbplayer.h
deleted file mode 100644
index 989ec5d..0000000
--- a/mydvbplayer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <vdr/player.h>
-#include <vdr/thread.h>
-
-class myDvbPlayer;
-
-class myDvbPlayerControl : public cControl {
-private:
- myDvbPlayer *player;
-public:
- myDvbPlayerControl(const char *FileName);
- // Sets up a player for the given file.
- virtual ~myDvbPlayerControl();
- bool Active(void);
- void Stop(void);
- // Stops the current replay session (if any).
- void Pause(void);
- // Pauses the current replay session, or resumes a paused session.
- void Play(void);
- // Resumes normal replay mode.
- void Forward(void);
- // Runs the current replay session forward at a higher speed.
- void Backward(void);
- // Runs the current replay session backwards at a higher speed.
- int SkipFrames(int Frames);
- // Returns the new index into the current replay session after skipping
- // the given number of frames (no actual repositioning is done!).
- // The sign of 'Frames' determines the direction in which to skip.
- void SkipSeconds(int Seconds);
- // Skips the given number of seconds in the current replay session.
- // The sign of 'Seconds' determines the direction in which to skip.
- // Use a very large negative value to go all the way back to the
- // beginning of the recording.
- bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
- // Returns the current and total frame index, optionally snapped to the
- // nearest I-frame.
- bool GetReplayMode(bool &Play, bool &Forward, int &Speed);
- // Returns the current replay mode (if applicable).
- // 'Play' tells whether we are playing or pausing, 'Forward' tells whether
- // we are going forward or backward and 'Speed' is -1 if this is normal
- // play/pause mode, 0 if it is single speed fast/slow forward/back mode
- // and >0 if this is multi speed mode.
- void Goto(int Index, bool Still = false);
- // Positions to the given index and displays that frame as a still picture
- // if Still is true.
- };
diff --git a/mymenumoverecording.h b/mymenumoverecording.h
deleted file mode 100644
index bc7b389..0000000
--- a/mymenumoverecording.h
+++ /dev/null
@@ -1,75 +0,0 @@
-extern bool clearall; // needed for myMenuMoveRecording
-
-// --- myMenuRecordingsItem ---------------------------------------------------
-class myMenuRecordingsItem:public cOsdItem
-{
- private:
- int level,isdirectory;
- int totalentries,newentries;
- char *title;
- char *name;
- const char *filename;
- public:
- myMenuRecordingsItem(cRecording *Recording,int Level);
- ~myMenuRecordingsItem();
- const char *FileName(){return filename;}
- const char *Name(){return name;}
- bool IsDirectory(){return name!=NULL;}
- void IncrementCounter(bool IsNew);
-};
-
-// --- myMenuRecordings -------------------------------------------------------
-class myMenuRecordings:public cOsdMenu
-{
- private:
- bool edit;
- int level,helpkeys;
- int recordingsstate;
- char *base;
- bool Open();
- void SetHelpKeys();
- cRecording *GetRecording(myMenuRecordingsItem *Item);
- eOSState Play();
- eOSState Rewind();
- eOSState Delete();
- eOSState Rename();
- eOSState MoveRec();
- eOSState Info();
- eOSState Commands(eKeys Key=kNone);
- public:
- myMenuRecordings(const char *Base=NULL,int Level=0);
- ~myMenuRecordings();
- void Set(bool Refresh=false);
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-// --- myMenuRenameRecording --------------------------------------------------
-class myMenuRenameRecording:public cOsdMenu
-{
- private:
- char name[MaxFileName];
- char path[MaxFileName];
- cRecording *recording;
- myMenuRecordings *menurecordings;
- public:
- myMenuRenameRecording(cRecording *Recording,myMenuRecordings *MenuRecordings);
- virtual eOSState ProcessKey(eKeys Key);
-};
-
-// --- myMenuMoveRecording ----------------------------------------------------
-class myMenuMoveRecording:public cOsdMenu
-{
- private:
- int level;
- char *base;
- cRecording *recording;
- myMenuRecordings *menurecordings;
- void Set();
- eOSState Open();
- eOSState MoveRec();
- eOSState Create();
- public:
- myMenuMoveRecording(cRecording *Recording,myMenuRecordings *MenuRecordings,const char *Base=NULL,int Level=0);
- myMenuMoveRecording::~myMenuMoveRecording();
- virtual eOSState ProcessKey(eKeys Key);
-};
diff --git a/mymenurecordingdetails.c b/mymenurecordingdetails.c
new file mode 100644
index 0000000..def9a57
--- /dev/null
+++ b/mymenurecordingdetails.c
@@ -0,0 +1,48 @@
+/*
+ * See the README file for copyright information and how to reach the author.
+ *
+ */
+
+#include <vdr/videodir.h>
+#include <vdr/menu.h>
+#include "mymenurecordings.h"
+#include "tools.h"
+
+myMenuRecordingDetails::myMenuRecordingDetails(cRecording *Recording,myMenuRecordings *MenuRecordings):cOsdMenu(tr("Details"),12)
+{
+ recording=Recording;
+ menurecordings=MenuRecordings;
+ priority=recording->priority;
+ lifetime=recording->lifetime;
+
+ Add(new cMenuEditIntItem(tr("Priority"),&priority,0,MAXPRIORITY));
+ Add(new cMenuEditIntItem(tr("Lifetime"),&lifetime,0,MAXLIFETIME));
+}
+
+eOSState myMenuRecordingDetails::ProcessKey(eKeys Key)
+{
+ eOSState state=cOsdMenu::ProcessKey(Key);
+ if(state==osUnknown)
+ {
+ if(Key==kOk)
+ {
+ char *newfilename=strdup(recording->FileName());
+
+ sprintf(newfilename+strlen(newfilename)-9,"%02d.%02d.rec",priority,lifetime);
+
+ if(MoveVideoFile(recording,newfilename))
+ {
+ menurecordings->Set(true);
+ state=osBack;
+ }
+ else
+ {
+ Skins.Message(mtError,tr("Error while accessing recording!"));
+ state=osContinue;
+ }
+
+ free(newfilename);
+ }
+ }
+ return state;
+}
diff --git a/mymenurecordings.c b/mymenurecordings.c
index 1a9f860..bbdb4da 100644
--- a/mymenurecordings.c
+++ b/mymenurecordings.c
@@ -10,6 +10,7 @@
#include "mymenusetup.h"
#include "mymenucommands.h"
#include "patchfont.h"
+#include "tools.h"
// --- myMenuRecordingsItem ---------------------------------------------------
myMenuRecordingsItem::myMenuRecordingsItem(cRecording *Recording,int Level)
@@ -51,7 +52,6 @@ myMenuRecordingsItem::myMenuRecordingsItem(cRecording *Recording,int Level)
*title='\t';
*(title+1)='\t';
strn0cpy(title+2,p,s-p+1);
-
name=strdup(title+2);
}
else
@@ -121,7 +121,7 @@ myMenuRecordingsItem::myMenuRecordingsItem(cRecording *Recording,int Level)
char RecDate[9],RecTime[6],RecDelimiter[2]={'\t',0};
char New[2]={0,0};
if(isdvd)
- New[0]=mysetup.PatchDvd?char(129):'~';
+ New[0]=char(129);
else
if(isnew&&!mysetup.PatchNew)
New[0]='*';
@@ -142,7 +142,7 @@ myMenuRecordingsItem::myMenuRecordingsItem(cRecording *Recording,int Level)
(mysetup.ShowDvdNr?dvdnr:""), // show dvd nummber
((isdvd&&mysetup.ShowDvdNr)?" ":""), // space for fancy looking
s?s+1:Recording->Name()); // recording name
-
+
asprintf(&id,"%s %s %s",RecDate,RecTime,Recording->Name());
}
else
@@ -172,6 +172,10 @@ void myMenuRecordingsItem::IncrementCounter(bool IsNew)
else
asprintf(&buffer,"%d\t%s",totalentries,name);
+ // don't show '-', '.', '$', 'ª' or '·' if the directory name ends with one of it
+ if(buffer[strlen(buffer)-1]=='.'||buffer[strlen(buffer)-1]=='-'||buffer[strlen(buffer)-1]=='$'||buffer[strlen(buffer)-1]==char(170)||buffer[strlen(buffer)-1]==char(183))
+ buffer[strlen(buffer)-1]=0;
+
SetText(buffer,false);
}
@@ -179,7 +183,7 @@ void myMenuRecordingsItem::IncrementCounter(bool IsNew)
myMenuRecordings::myMenuRecordings(const char *Base,int Level):cOsdMenu(Base?Base:tr("Extended recordings menu"))
{
// patch font
- if(Level==0&&(mysetup.PatchNew||mysetup.PatchDvd))
+ if(Level==0)
{
if(Setup.UseSmallFont==2)
PatchFont(fontSml);
@@ -209,31 +213,28 @@ myMenuRecordings::myMenuRecordings(const char *Base,int Level):cOsdMenu(Base?Bas
Recordings.StateChanged(recordingsstate);
Display();
- Set();
- if(Current()<0)
- SetCurrent(First());
- else
- if(myReplayControl::LastReplayed())
+
+ if(mysetup.wasdvd&&!cControl::Control())
+ {
+ char *cmd;
+ asprintf(&cmd,"dvdarchive.sh umount \"%s\"",myReplayControl::LastReplayed());
+ isyslog("[extrecmenu] calling %s to unmount dvd",cmd);
+ int result=SystemExec(cmd);
+ if(result)
{
- if(mysetup.wasdvd&&!cControl::Control())
- {
- char *cmd;
- asprintf(&cmd,"dvdarchive.sh umount \"%s\"",myReplayControl::LastReplayed());
- isyslog("[extrecmenu] calling %s to unmount dvd",cmd);
- int result=SystemExec(cmd);
- if(result)
- {
- result=result/256;
- if(result==1)
- Skins.Message(mtError,tr("Error while mounting DVD!"));
- }
- isyslog("[extrecmenu] dvdarchive.sh returns %d",result);
- free(cmd);
-
- mysetup.wasdvd=false;
- }
- Open();
+ result=result/256;
+ if(result==1)
+ Skins.Message(mtError,tr("Error while mounting DVD!"));
}
+ isyslog("[extrecmenu] dvdarchive.sh returns %d",result);
+ free(cmd);
+
+ mysetup.wasdvd=false;
+ }
+
+ Set();
+ if(myReplayControl::LastReplayed())
+ Open();
Display();
SetHelpKeys();
@@ -243,7 +244,7 @@ myMenuRecordings::~myMenuRecordings()
{
free(base);
- if(level==0&&(mysetup.PatchNew||mysetup.PatchDvd))
+ if(level==0)
{
if(Setup.UseSmallFont==2)
cFont::SetFont(fontSml);
@@ -291,90 +292,49 @@ void myMenuRecordings::Set(bool Refresh)
cThreadLock RecordingsLock(&Recordings);
Clear();
+ // create my own recordings list from VDR's
+ myRecList *list=new myRecList();
+ for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
+ list->Add(new myRecListItem(recording));
+ // sort my recordings list
+ list->Sort();
+
+ // needed for move recording menu
Recordings.Sort();
char *lastitemtext=NULL;
myMenuRecordingsItem *lastitem=NULL;
- bool inlist=false;
- // add first the directories
- for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
+ for(myRecListItem *listitem=list->First();listitem;listitem=list->Next(listitem))
{
- if(!base||(strstr(recording->Name(),base)==recording->Name()&&recording->Name()[strlen(base)]=='~'))
+ cRecording *recording=listitem->recording;
+ if(!base||(strstr(listitem->recording->Name(),base)==listitem->recording->Name()&&listitem->recording->Name()[strlen(base)]=='~'))
{
- myMenuRecordingsItem *item=new myMenuRecordingsItem(recording,level);
- if(*item->Text()&&(!lastitem||strcmp(item->Text(),lastitemtext)))
+ myMenuRecordingsItem *recitem=new myMenuRecordingsItem(listitem->recording,level);
+ if(*recitem->Text()&&(!lastitem||strcmp(recitem->Text(),lastitemtext)))
{
- if(item->IsDirectory())
- {
- Add(item);
- inlist=true;
- }
- lastitem=item;
+ Add(recitem);
+ lastitem=recitem;
free(lastitemtext);
lastitemtext=strdup(lastitem->Text());
}
else
- delete item;
-
+ delete recitem;
+
if(lastitem)
{
if(lastitem->IsDirectory())
- {
- lastitem->IncrementCounter(recording->IsNew()); // counts the number of entries in a directory
- if(lastreplayed&&!strcmp(lastreplayed,recording->FileName()))
- SetCurrent(lastitem);
- }
- // delete items that are not in the list
- if(!inlist)
- {
- delete lastitem;
- lastitem=NULL;
- inlist=false;
- }
- }
- }
- }
- inlist=false;
- lastitem=NULL;
- // and now the recordings
- for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
- {
- if(!base||(strstr(recording->Name(),base)==recording->Name()&&recording->Name()[strlen(base)]=='~'))
- {
- myMenuRecordingsItem *item=new myMenuRecordingsItem(recording,level);
- if(item->ID()&&(!lastitem||strcmp(lastitemtext,item->ID())))
- {
- if(!item->IsDirectory())
- {
- Add(item);
- inlist=true;
- }
- lastitem=item;
- free(lastitemtext);
- lastitemtext=strdup(lastitem->ID());
- }
- else
- delete item;
-
- if(lastitem)
- {
- if(!item->IsDirectory()&&lastreplayed&&!strcmp(lastreplayed,recording->FileName()))
+ lastitem->IncrementCounter(recording->IsNew());
+ if(lastreplayed&&!strcmp(lastreplayed,recording->FileName()))
{
SetCurrent(lastitem);
- if(!cControl::Control())
+ if(recitem&&!recitem->IsDirectory()&&!cControl::Control())
myReplayControl::ClearLastReplayed(recording->FileName());
}
- // delete items that are not in the list
- if(!inlist)
- {
- delete lastitem;
- lastitem=NULL;
- inlist=false;
- }
}
}
- }
+ }
free(lastitemtext);
+ delete list;
if(Refresh)
Display();
}
@@ -559,6 +519,22 @@ eOSState myMenuRecordings::Rename()
return osContinue;
}
+// edit details of a recording
+eOSState myMenuRecordings::Details()
+{
+ if(HasSubMenu()||Count()==0)
+ return osContinue;
+
+ myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ if(item&&!item->IsDirectory())
+ {
+ cRecording *recording=GetRecording(item);
+ if(recording)
+ return AddSubMenu(new myMenuRecordingDetails(recording,this));
+ }
+ return osContinue;
+}
+
// moves a recording
eOSState myMenuRecordings::MoveRec()
{
@@ -635,6 +611,9 @@ eOSState myMenuRecordings::ProcessKey(eKeys Key)
case kYellow: edit=false;
helpkeys=-1;
return Delete();
+ case kBlue: edit=false;
+ helpkeys=-1;
+ return Details();
case kBack: edit=false;
helpkeys=-1;
SetHelpKeys();
@@ -658,7 +637,7 @@ eOSState myMenuRecordings::ProcessKey(eKeys Key)
if(item&&!item->IsDirectory())
{
edit=true;
- SetHelp(tr("Button$Rename"),tr("Button$Move"),tr("Button$Delete"));
+ SetHelp(tr("Button$Rename"),tr("Button$Move"),tr("Button$Delete"),tr("Details"));
}
break;
}
diff --git a/mymenurecordings.h b/mymenurecordings.h
index ebbf644..36e3f17 100644
--- a/mymenurecordings.h
+++ b/mymenurecordings.h
@@ -41,6 +41,7 @@ class myMenuRecordings:public cOsdMenu
eOSState Rename();
eOSState MoveRec();
eOSState Info();
+ eOSState Details();
eOSState Commands(eKeys Key=kNone);
public:
myMenuRecordings(const char *Base=NULL,int Level=0);
@@ -53,7 +54,6 @@ class myMenuRecordings:public cOsdMenu
class myMenuRenameRecording:public cOsdMenu
{
private:
- int priority,lifetime;
char name[MaxFileName];
char path[MaxFileName];
cRecording *recording;
@@ -80,3 +80,15 @@ class myMenuMoveRecording:public cOsdMenu
myMenuMoveRecording::~myMenuMoveRecording();
virtual eOSState ProcessKey(eKeys Key);
};
+
+// --- myMenuRenameRecording --------------------------------------------------
+class myMenuRecordingDetails:public cOsdMenu
+{
+ private:
+ int priority,lifetime;
+ cRecording *recording;
+ myMenuRecordings *menurecordings;
+ public:
+ myMenuRecordingDetails(cRecording *Recording,myMenuRecordings *MenuRecordings);
+ virtual eOSState ProcessKey(eKeys Key);
+};
diff --git a/mymenurenamerecording.c b/mymenurenamerecording.c
index 646813e..5259f3d 100644
--- a/mymenurenamerecording.c
+++ b/mymenurenamerecording.c
@@ -12,8 +12,6 @@
myMenuRenameRecording::myMenuRenameRecording(cRecording *Recording,myMenuRecordings *MenuRecordings):cOsdMenu(tr("Rename recording"),12)
{
recording=Recording;
- priority=recording->priority;
- lifetime=recording->lifetime;
menurecordings=MenuRecordings;
char *p=strrchr(recording->Name(),'~');
@@ -32,15 +30,13 @@ myMenuRenameRecording::myMenuRenameRecording(cRecording *Recording,myMenuRecordi
strn0cpy(path,"",sizeof(path));
}
Add(new cMenuEditStrItem(tr("Name"),name,sizeof(name),tr(FileNameChars)));
- Add(new cMenuEditIntItem(tr("Priority"),&priority,0,MAXPRIORITY));
- Add(new cMenuEditIntItem(tr("Lifetime"),&lifetime,0,MAXLIFETIME));
-// cRemote::Put(kRight);
+ cRemote::Put(kRight);
}
eOSState myMenuRenameRecording::ProcessKey(eKeys Key)
{
eOSState state=cOsdMenu::ProcessKey(Key);
- if(state==osUnknown) // ==osContinue)
+ if(state==osContinue)
{
if(Key==kOk)
{
@@ -52,18 +48,7 @@ eOSState myMenuRenameRecording::ProcessKey(eKeys Key)
else
asprintf(&buffer,"%s",name);
-// asprintf(&newfilename,"%s/%s/%s",VideoDirectory,ExchangeChars(buffer,true),strrchr(recording->FileName(),'/')+1);
- struct tm tm_r;
- struct tm *t=localtime_r(&recording->start, &tm_r);
- asprintf(&newfilename,"%s/%s/%d-%02d-%02d.%02d.%02d.%02d.%02d.rec",
- VideoDirectory,
- ExchangeChars(buffer,true),
- t->tm_year+1900,
- t->tm_mon+1,
- t->tm_mday,
- t->tm_hour,
- t->tm_min,
- priority,lifetime);
+ asprintf(&newfilename,"%s/%s/%s",VideoDirectory,ExchangeChars(buffer,true),strrchr(recording->FileName(),'/')+1);
if(MoveVideoFile(recording,newfilename))
{
@@ -78,8 +63,8 @@ eOSState myMenuRenameRecording::ProcessKey(eKeys Key)
free(buffer);
free(newfilename);
}
-// if(Key==kBack)
-// return osBack;
+ if(Key==kBack)
+ return osBack;
}
return state;
}
diff --git a/mymenusetup.c b/mymenusetup.c
index 2a3cc18..e5dec57 100644
--- a/mymenusetup.c
+++ b/mymenusetup.c
@@ -1,25 +1,45 @@
+#include <vdr/menu.h>
#include "mymenusetup.h"
+mySetup::mySetup()
+{
+ mysetup.HideMainMenuEntry=0;
+ mysetup.PatchNew=0;
+ mysetup.ShowDvdNr=0;
+ mysetup.ReplaceOrgRecMenu=0;
+ mysetup.ShowRecDate=1;
+ mysetup.ShowRecTime=1;
+ mysetup.ShowRecLength=0;
+ mysetup.ShowNewRecs=1;
+ mysetup.SortRecords=0;
+ mysetup.wasdvd=false;
+}
+
mySetup mysetup;
myMenuSetup::myMenuSetup()
{
+ sortrecordstext[0]=tr("alphabet for main-, flexible for subdirectories");
+ sortrecordstext[1]=tr("date for main-, flexible for subdirectories");
+ sortrecordstext[2]=tr("alphabet for all directories");
+ sortrecordstext[3]=tr("date for all directories");
+
hidemainmenuentry=mysetup.HideMainMenuEntry;
patchnew=mysetup.PatchNew;
- patchdvd=mysetup.PatchDvd;
replaceorgrecmenu=mysetup.ReplaceOrgRecMenu;
showrecdate=mysetup.ShowRecDate;
showrectime=mysetup.ShowRecTime;
showreclength=mysetup.ShowRecLength;
showdvdnr=mysetup.ShowDvdNr;
shownewrecs=mysetup.ShowNewRecs;
+ sortrecords=mysetup.SortRecords;
Add(new cMenuEditBoolItem(tr("Show recording date"),&showrecdate));
Add(new cMenuEditBoolItem(tr("Show recording time"),&showrectime));
Add(new cMenuEditBoolItem(tr("Show recording length"),&showreclength));
Add(new cMenuEditBoolItem(tr("Show \"new recordings column\""),&shownewrecs));
+ Add(new cMenuEditStraItem(tr("Sort recordings by"),&sortrecords,4,sortrecordstext));
Add(new cMenuEditBoolItem(tr("Show alternative to new marker"),&patchnew));
- Add(new cMenuEditBoolItem(tr("Show alternative dvd marker"),&patchdvd));
Add(new cMenuEditBoolItem(tr("Show dvd number"),&showdvdnr));
Add(new cMenuEditBoolItem(tr("Hide main menu entry"),&hidemainmenuentry));
Add(new cMenuEditBoolItem(tr("Replace original recordings menu"),&replaceorgrecmenu));
@@ -29,11 +49,11 @@ void myMenuSetup::Store()
{
SetupStore("HideMainMenuEntry",mysetup.HideMainMenuEntry=hidemainmenuentry);
SetupStore("PatchNew",mysetup.PatchNew=patchnew);
- SetupStore("PatchDvd",mysetup.PatchDvd=patchdvd);
SetupStore("ShowDvdNr",mysetup.ShowDvdNr=showdvdnr);
SetupStore("ReplaceOrgRecMenu",mysetup.ReplaceOrgRecMenu=replaceorgrecmenu);
SetupStore("ShowRecDate",mysetup.ShowRecDate=showrecdate);
SetupStore("ShowRecTime",mysetup.ShowRecTime=showrectime);
SetupStore("ShowRecLength",mysetup.ShowRecLength=showreclength);
SetupStore("ShowNewRecs",mysetup.ShowNewRecs=shownewrecs);
+ SetupStore("SortRecords",mysetup.SortRecords=sortrecords);
}
diff --git a/mymenusetup.h b/mymenusetup.h
index bd6f1a1..8813ac9 100644
--- a/mymenusetup.h
+++ b/mymenusetup.h
@@ -3,15 +3,16 @@
class mySetup
{
public:
+ mySetup();
int ShowRecDate;
int ShowRecTime;
int ShowRecLength;
int HideMainMenuEntry;
int ReplaceOrgRecMenu;
int PatchNew;
- int PatchDvd;
int ShowDvdNr;
int ShowNewRecs;
+ int SortRecords;
bool wasdvd; // needed for dvdarchive-patch functionality
};
@@ -20,15 +21,16 @@ extern mySetup mysetup;
class myMenuSetup:public cMenuSetupPage
{
private:
+ const char *sortrecordstext[4];
int showrecdate;
int showrectime;
int showreclength;
int hidemainmenuentry;
int replaceorgrecmenu;
int patchnew;
- int patchdvd;
int showdvdnr;
int shownewrecs;
+ int sortrecords;
protected:
virtual void Store();
public:
diff --git a/myreplaycontrol.c b/myreplaycontrol.c
index fe5f2b6..fb7f50f 100644
--- a/myreplaycontrol.c
+++ b/myreplaycontrol.c
@@ -1,7 +1,8 @@
/*
* See the README file for copyright information and how to reach the author.
*
- * This code is directly taken from VDR with some changes by me to work with this plugin
+ * This code is directly taken from VDR with some changes by me to work with this plugin.
+ * Also to JumpPlay-Patch is integrated using #ifdef's.
*/
#include <vdr/interface.h>
@@ -13,7 +14,12 @@ char *myReplayControl::fileName = NULL;
char *myReplayControl::title = NULL;
myReplayControl::myReplayControl(void)
-:myDvbPlayerControl(fileName)
+#ifdef BIGPATCHVERSION
+:cDvbPlayerControl(fileName,&marks)
+#endif
+#ifndef BIGPATCHVERSION
+:cDvbPlayerControl(fileName)
+#endif
{
displayReplay = NULL;
visible = modeOnly = shown = displayFrames = false;
@@ -23,6 +29,9 @@ myReplayControl::myReplayControl(void)
timeoutShow = 0;
timeSearchActive = false;
marks.Load(fileName);
+#ifdef BIGPACKVERSION
+ lastLoadMarks = time(NULL);
+#endif
cRecording Recording(fileName);
cStatus::MsgReplaying(this, Recording.Name(), Recording.FileName(), true);
}
@@ -244,8 +253,16 @@ void myReplayControl::MarkToggle(void)
ShowTimed(2);
bool Play, Forward;
int Speed;
+#ifndef BIGPACKVERSION
if (GetReplayMode(Play, Forward, Speed) && !Play)
Goto(Current, true);
+#endif
+#ifdef BIGBACKVERSION
+ if (GetReplayMode(Play, Forward, Speed) && !Play) {
+ Goto(Current, true);
+ displayFrames = true;
+ }
+#endif
}
marks.Save();
@@ -259,8 +276,23 @@ void myReplayControl::MarkJump(bool Forward)
if (GetIndex(Current, Total)) {
cMark *m = Forward ? marks.GetNext(Current) : marks.GetPrev(Current);
if (m) {
+#ifndef BIGPACKVERSION
Goto(m->position, true);
displayFrames = true;
+#endif
+#ifdef BIGPACKVERSION
+ bool Play2, Forward2;
+ int Speed;
+ if (Setup.JumpPlay && GetReplayMode(Play2, Forward2, Speed) &&
+ Play2 && Forward && m->position < Total - SecondsToFrames(3)) {
+ Goto(m->position);
+ Play();
+ }
+ else {
+ Goto(m->position, true);
+ displayFrames = true;
+ }
+#endif
}
}
}
@@ -315,7 +347,12 @@ void myReplayControl::EditTest(void)
if (!m)
m = marks.GetNext(Current);
if (m) {
+#ifndef BIGPACKVERSION
if ((m->Index() & 0x01) != 0)
+#endif
+#ifdef BIGPACKVERSION
+ if ((m->Index() & 0x01) != 0 && !Setup.PlayJump)
+#endif
m = marks.Next(m);
if (m) {
Goto(m->position - SecondsToFrames(3));
@@ -337,6 +374,13 @@ eOSState myReplayControl::ProcessKey(eKeys Key)
{
if (!Active())
return osEnd;
+#ifdef BIGPACKVERSION
+ if (Setup.LoadMarksInterval &&
+ time(NULL) >= lastLoadMarks + Setup.LoadMarksInterval) {
+ marks.Load(fileName, true);
+ lastLoadMarks = time(NULL);
+ }
+#endif
if (visible) {
if (timeoutShow && time(NULL) > timeoutShow) {
Hide();
diff --git a/myreplaycontrol.h b/myreplaycontrol.h
index cd14c96..274737e 100644
--- a/myreplaycontrol.h
+++ b/myreplaycontrol.h
@@ -1,9 +1,8 @@
-#include "mydvbplayer.h"
-
+#include <vdr/dvbplayer.h>
#define MODETIMEOUT 3 // seconds
// --- myReplayControls -------------------------------------------------------
-class myReplayControl : public myDvbPlayerControl {
+class myReplayControl : public cDvbPlayerControl {
private:
cSkinDisplayReplay *displayReplay;
cMarks marks;
@@ -12,6 +11,9 @@ private:
bool lastPlay, lastForward;
int lastSpeed;
time_t timeoutShow;
+#ifdef BIGPACKVERSION
+ time_t lastLoadMarks;
+#endif
bool timeSearchActive, timeSearchHide;
int timeSearchTime, timeSearchPos;
void TimeSearchDisplay(void);
diff --git a/patchfont.c b/patchfont.c
index 4f2ad2a..0a4c7db 100644
--- a/patchfont.c
+++ b/patchfont.c
@@ -87,7 +87,7 @@ void PatchFont(eDvbFont DvbFont)
}
}
// dvd marker
- else if(num_char==129&&mysetup.PatchDvd)
+ else if(num_char==129)
{
if(DvbFont==fontOsd)
{
diff --git a/scripts/dvdarchive.sh b/scripts/dvdarchive.sh
index 3dc0c71..7f5b72b 100755
--- a/scripts/dvdarchive.sh
+++ b/scripts/dvdarchive.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Version 1.2 2006-03-30
+# Version 1.4 2006-04-07
#
# Exitcodes:
#
@@ -15,20 +15,35 @@
# For dvd-in-drive detection download isodetect.c, compile it and put it into the PATH,
# usually /usr/local/bin/
#
+# Tools needed: mount, awk, find, test
+# Optional tools: isodetect
#<Configuration>
MOUNTCMD="/usr/bin/sudo /bin/mount"
UMOUNTCMD="/usr/bin/sudo /bin/umount"
+
MOUNTPOINT="/media/cdrom" # no trailing '/'!
+# Eject DVD for exit-codes 2 and 3 (no or wrong dvd). 1 = yes, 0 = no.
+EJECTWRONG=0
+# Eject DVD after unmounting. 1 = yes, 0 = no.
+EJECTUMOUNT=0
+
#</Configuration>
-DEVICE="$(awk '( $1 !~ /^#/ ) && ( $2 == "'$MOUNTPOINT'" ) { print $1; exit; }' /etc/fstab)" # dvd-device, used by isodetect if exists
+DEVICE="$(awk '( $1 !~ /^#/ ) && ( $2 == "'$MOUNTPOINT'" ) { printf("%s", $1); exit; }' /etc/fstab)" # dvd-device, used by isodetect if exists
REC="$2"
NAME="$3"
+call() {
+ echo -e "\nScript $0 needs three parameters. Action, rec and name. Action is mount or umount"
+ echo -e "Example: dvdarchive.sh mount '/video1.0/Music/%Riverdance/2004-06-06.00:10.50.99.rec' '2004-06-06.00:10.50.99.rec'\n"
+}
+
+[ $# -ne 3 ] && { call; exit 10; }
+
case "$1" in
mount)
# check if dvd is in drive, only if isodetect exists
@@ -36,6 +51,7 @@ mount)
isodetect -d "$DEVICE" >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "no dvd in drive"
+ [ $EJECTWRONG -eq 1 ] && { eject "$DEVICE"; }
exit 2
fi
fi
@@ -50,6 +66,7 @@ mount)
if [ -z "$DIR" ]; then
$UMOUNTCMD "$MOUNTPOINT" || { echo "dvd umount error"; exit 1; }
echo "wrong dvd in drive / recording not found on dvd"
+ [ $EJECTWRONG -eq 1 ] && { eject "$DEVICE"; }
exit 3
fi
# link index.vdr if not exist
@@ -84,7 +101,12 @@ umount)
rm "$LINK"
fi
done
+ [ $EJECTUMOUNT -eq 1 ] && { eject "$DEVICE"; }
;;
+ *)
+ echo -e "\nWrong action."
+ call
+ ;;
esac
exit 0
diff --git a/tools.c b/tools.c
index d685571..6c52a63 100644
--- a/tools.c
+++ b/tools.c
@@ -1,6 +1,14 @@
+/*
+ * See the README file for copyright information and how to reach the author.
+ *
+ * The code for sort recordings as adopted from the SortRecordings-patch
+ * copyright by FrankJepsen and FRank99 from vdr-portal.de
+ */
+
#include <vdr/videodir.h>
#include <vdr/recording.h>
#include "tools.h"
+#include "mymenusetup.h"
bool MoveVideoFile(cRecording *Recording,char *NewName)
{
@@ -23,3 +31,60 @@ bool MoveVideoFile(cRecording *Recording,char *NewName)
isyslog("[extrecmenu] moving failed");
return false;
}
+
+// --- myRecListItem ----------------------------------------------------------
+myRecListItem::myRecListItem(cRecording *Recording)
+{
+ recording=Recording;
+ filename=recording->FileName();
+ sortbuffer=NULL;
+}
+
+myRecListItem::~myRecListItem()
+{
+ free(sortbuffer);
+}
+
+char *myRecListItem::StripEpisodeName(char *s)
+{
+ char *t=s,*s1=NULL,*s2=NULL;
+ while(*t)
+ {
+ if(*t=='/')
+ {
+ if(s1)
+ {
+ if(s2)
+ s1=s2;
+ s2=t;
+ }
+ else
+ s1=t;
+ }
+ t++;
+ }
+ *s1=255;
+ if(s1&&s2&&(s1==s&&(mysetup.SortRecords&1)||s1!=s&&(mysetup.SortRecords==3||mysetup.SortRecords!=2&&!strchr(".-$ª·",*(s1-1)))))
+ memmove(s1+1,s2,t-s2+1);
+ return s;
+}
+
+char *myRecListItem::SortName()const
+{
+ if(!sortbuffer)
+ {
+ char *s=StripEpisodeName(strdup(filename+strlen(VideoDirectory)));
+ strreplace(s,'/','a');
+ int l=strxfrm(NULL,s,0)+1;
+ sortbuffer=MALLOC(char,l);
+ strxfrm(sortbuffer,s,l);
+ free(s);
+ }
+ return sortbuffer;
+}
+
+int myRecListItem::Compare(const cListObject &ListObject)const
+{
+ myRecListItem *item=(myRecListItem*)&ListObject;
+ return strcasecmp(SortName(),item->SortName());
+}
diff --git a/tools.h b/tools.h
index ab66085..527891b 100644
--- a/tools.h
+++ b/tools.h
@@ -1 +1,19 @@
bool MoveVideoFile(cRecording *Recording,char *NewName);
+
+class myRecListItem:public cListObject
+{
+ private:
+ const char *filename;
+ mutable char *sortbuffer;
+ static char *StripEpisodeName(char *s);
+ char *SortName()const;
+ public:
+ myRecListItem(cRecording *Recording);
+ ~myRecListItem();
+ virtual int Compare(const cListObject &ListObject)const;
+ cRecording *recording;
+};
+
+class myRecList:public cList<myRecListItem>
+{
+};