New Upstream Release - vdr-plugin-dvd
Ready changes
Summary
Merged new upstream version: 0.3.7 (was: 0.3.6~b03+git20211216).
Resulting package
Built on 2022-11-30T06:18 (took 2m43s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases vdr-plugin-dvd-dbgsymapt install -t fresh-releases vdr-plugin-dvd
Lintian Result
Diff
diff --git a/HISTORY b/HISTORY
index 1160687..bf9dcf6 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,7 @@
VDR Plugin 'dvd' Revision History
---------------------------------
+2021-12-17 Version 0.3.7
- change i18n to gettext
- fix GetIndex return value, remove lcdproc workaround
- fix possible segfault's (thanks to Ioannis Petroglou)
diff --git a/Makefile b/Makefile
index 531ba0e..2f3a584 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,8 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri
### The directory environment:
-PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
+PKG_CONFIG ?= pkg-config
+PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell $(PKG_CONFIG) --variable=$(1) vdr || $(PKG_CONFIG) --variable=$(1) ../../../vdr.pc))
LIBDIR = $(DESTDIR)$(call PKGCFG,libdir)
LOCDIR = $(DESTDIR)$(call PKGCFG,locdir)
@@ -61,6 +62,10 @@ CXXFLAGS += -O3
LDFLAGS += -O3 -Wl,--retain-symbols-file,retain-sym
endif
+ifdef RESUMEDIR
+ DEFINES += -DRESUMEDIR=\"$(RESUMEDIR)\"
+endif
+
### The object files (add further files here):
OBJS = $(PLUGIN).o dvddev.o player-dvd.o control-dvd.o dvdspu.o \
diff --git a/debian/changelog b/debian/changelog
index 15908a3..dd5cd3b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+vdr-plugin-dvd (0.3.7-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+ * Drop patch 04_vdr-dvd_resume.patch, present upstream.
+ * Drop patch 10_dvd.c.patch, present upstream.
+ * Drop patch 12_dvd-fixed-german-spelling.patch, present upstream.
+ * Drop patch cross.patch, present upstream.
+
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 30 Nov 2022 06:16:39 -0000
+
vdr-plugin-dvd (0.3.6~b03+git20211216-2) unstable; urgency=medium
* Remove Thomas Günther and Thomas Schmidt from uploaders
diff --git a/debian/patches/04_vdr-dvd_resume.patch b/debian/patches/04_vdr-dvd_resume.patch
deleted file mode 100644
index b0b78a4..0000000
--- a/debian/patches/04_vdr-dvd_resume.patch
+++ /dev/null
@@ -1,545 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 04_vdr-dvd_resume.dpatch by Patrick Cernko <errror@errror.org>
-## http://www.vdrportal.de/board/thread.php?threadid=31685
-##
-## Thomas G�nther <tom@toms-cafe.de>:
-## - adapted to dvd plugin version cvs20070813
-## - adapted to dvd plugin version cvs20090426.0013
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Patch to resume a dvd where it was interrupted by the user.
-
-@DPATCH@
---- a/Makefile
-+++ b/Makefile
-@@ -61,6 +61,10 @@
- LDFLAGS += -O3 -Wl,--retain-symbols-file,retain-sym
- endif
-
-+ifdef RESUMEDIR
-+ DEFINES += -DRESUMEDIR=\"$(RESUMEDIR)\"
-+endif
-+
- ### The object files (add further files here):
-
- OBJS = $(PLUGIN).o dvddev.o player-dvd.o control-dvd.o dvdspu.o \
---- a/player-dvd.c
-+++ b/player-dvd.c
-@@ -21,6 +21,8 @@
- #include <vdr/thread.h>
- #include <vdr/device.h>
- #include <vdr/plugin.h>
-+// for VideoDirectory variable
-+#include <vdr/videodir.h>
-
- #ifdef HAVE_CONFIG_H
- #include "config.h"
-@@ -231,6 +233,220 @@
- }
-
-
-+// --- cResumeEntry ------------------------------------------------------------
-+
-+// borrowed from the mplayer plugin code and adapted to the dvd resume requirements
-+class cResumeEntry : public cListObject {
-+public:
-+ char *key;
-+ int title;
-+ int chapter;
-+ int64_t second;
-+ //
-+ cResumeEntry(void);
-+ ~cResumeEntry();
-+ };
-+
-+cResumeEntry::cResumeEntry(void)
-+{
-+ key=0;
-+}
-+
-+cResumeEntry::~cResumeEntry()
-+{
-+ free(key);
-+}
-+
-+// --- cDVDPlayerResume ----------------------------------------------------------
-+
-+// store resume database to this file ...
-+#define RESUME_FILE "dvdplayer.resume"
-+
-+// ... in this directory (default: /video)
-+#ifndef RESUMEDIR
-+#if APIVERSNUM > 20101
-+#define RESUMEDIR cVideoDirectory::Name()
-+#else
-+#define RESUMEDIR VideoDirectory
-+#endif
-+#endif
-+
-+
-+// borrowed from the mplayer plugin code and adapted to the dvd resume requirements
-+class cDVDPlayerResume : public cList<cResumeEntry> {
-+private:
-+ char* resfile; // the full pathname of resume file
-+ bool modified; // flag to indicate that memory database was modified and needs to be saved
-+ /**
-+ * LoadResume():
-+ * reads in the resume database file from resfile.
-+ */
-+ void LoadResume();
-+ /**
-+ * SaveResume():
-+ * saves the resume database to the file resfile.
-+ * returns true on successful save.
-+ */
-+ bool SaveResume(void);
-+ /**
-+ * search the (loaded) resume database for the given key.
-+ * returns the cResumeEntry* if the key was found
-+ * or NULL if no resume entry was found for the given key.
-+ */
-+ cResumeEntry *FindResume(const char* key);
-+public:
-+ cDVDPlayerResume(void);
-+ ~cDVDPlayerResume();
-+ /**
-+ * SetResume():
-+ * set the given resume values for the given key into the resume database.
-+ * the resume database is loaded from file if not yet loaded.
-+ */
-+ void SetResume(const char* key, int title, int chapter, int64_t second);
-+ /**
-+ * GetResume():
-+ * tries looking up the given key into the resume database.
-+ * the resume database is loaded from file if not yet loaded.
-+ * returns true if resume data could be found. In this case
-+ * the givven arguments are filled with the resume data. Otherwise
-+ * the arguments are not modified!
-+ */
-+ bool GetResume(const char* key, int& title, int& chapter, int64_t& second);
-+ };
-+
-+cDVDPlayerResume::cDVDPlayerResume(void)
-+{
-+ // initialize the resume filename string.
-+ asprintf(&resfile, "%s/%s", RESUMEDIR, RESUME_FILE);
-+}
-+
-+cDVDPlayerResume::~cDVDPlayerResume()
-+{
-+ // save resume data to disc before self-destruction.
-+ SaveResume();
-+ // free the resume filename string, allocated in C'tor by asprintf
-+ free(resfile);
-+}
-+
-+void cDVDPlayerResume::SetResume(const char* key, int title, int chapter, int64_t second)
-+{
-+ // (re)load resume data from file to be actual
-+ LoadResume();
-+ cResumeEntry* re = FindResume(key);
-+ if (re) {
-+ // found a resume entry, so we can update it.
-+ DEBUGDVD("resume: setting resume %d:%d:%lld (update)", title, chapter, second);
-+ } else {
-+ // no resume entry found yet, creating a new one
-+ re = new cResumeEntry;
-+ re->key = strdup(key);
-+ Add(re);
-+ DEBUGDVD("resume: setting resume %d:%d:%lld (new)", title, chapter, second);
-+ }
-+ // set the new resume data for the found/created entry
-+ re->title = title;
-+ re->chapter = chapter;
-+ re->second = second;
-+ // and mark memory database as modified to be saved.
-+ modified = true;
-+ // save it now (sync!)
-+ SaveResume();
-+}
-+
-+bool cDVDPlayerResume::GetResume(const char* key, int& title, int& chapter, int64_t& second)
-+{
-+ // (re)load the resume file to have actual values
-+ LoadResume();
-+ cResumeEntry* re = FindResume(key);
-+ if (re) {
-+ // found a resume entry, copy values
-+ title = re->title;
-+ chapter = re->chapter;
-+ second = re->second;
-+ // indicate successful search
-+ return true;
-+ }
-+ // no resume entry found in database
-+ return false;
-+}
-+
-+void cDVDPlayerResume::LoadResume()
-+{
-+ // we will load the file for sure and add all entries, clear all old entries.
-+ Clear();
-+ // no entries == no modifications
-+ modified = false;
-+ DEBUGDVD("resume: resume file is \"%s\"\n",resfile);
-+ FILE *f = fopen(resfile,"r");
-+ if (f) {
-+ DEBUGDVD("resume: successfully opened resume file\n");
-+ char line[768];
-+ // read file line by line
-+ while(fgets(line,sizeof(line),f)) {
-+ char key[512];
-+ int t, c;
-+ int64_t s;
-+ // parse line as "title:chapter:second:key"
-+ if(sscanf(line,"%d:%d:%lld:%511[^\n]",&t,&c,&s,key) == 4) {
-+ // successful parse, save in resume entry
-+ cResumeEntry *re = new cResumeEntry;
-+ re->key = strdup(key);
-+ re->title = t;
-+ re->chapter = c;
-+ re->second = s;
-+ // and add it to memory database
-+ Add(re);
-+ }
-+ }
-+ // don't forget to close what you have opened!
-+ fclose(f);
-+ }
-+ // unsuccessful open leads to empty database as the file does not exists
-+}
-+
-+bool cDVDPlayerResume::SaveResume(void)
-+{
-+ if(modified) {
-+ // modification indicated, save the database to the resume file
-+ DEBUGDVD("resume: saving resume file\n");
-+ cSafeFile f(resfile);
-+ if(f.Open()) {
-+ // forall resume entries in the memory database
-+ for (cResumeEntry *re=First(); re; re=Next(re)) {
-+ // save the as one line in the format "title:chapter:second:key"
-+ fprintf(f, "%d:%d:%lld:%s\n", re->title, re->chapter, re->second, re->key);
-+ }
-+ // don't forget to close what you have opened!
-+ f.Close();
-+ // signal successful save
-+ return true;
-+ } else {
-+ DEBUGDVD("resume: failed to save resume file\n");
-+ // saving did not succeed!!!!
-+ return false;
-+ }
-+ } else {
-+ // no modifications -> successful "save" :-)
-+ return true;
-+ }
-+}
-+
-+cResumeEntry *cDVDPlayerResume::FindResume(const char* key)
-+{
-+ DEBUGDVD("resume: searching resume position for \"%s\"\n", key);
-+ // iterate over all entries in the memory database
-+ for(cResumeEntry *re=First(); re; re=Next(re)) {
-+ if (!strcasecmp(re->key, key)) {
-+ // return the entry iff the keys match
-+ DEBUGDVD("resume: found resume position %d:%d:%lld\n",re->title, re->chapter, re->second);
-+ return re;
-+ }
-+ }
-+ DEBUGDVD("resume: no resume position found\n");
-+ return NULL;
-+}
-+
-+
- // --- cDvdPlayer ------------------------------------------------------------
-
- //XXX+ also used in recorder.c - find a better place???
-@@ -288,6 +504,9 @@
- skipPlayVideo=false;
- fastWindFactor=1;
-
-+ // resume
-+ resume = new cDVDPlayerResume;
-+
- clearSeenSubpStream();
- clearSeenAudioTrack();
-
-@@ -334,6 +553,8 @@
-
- if(aspect_str)
- free(aspect_str);
-+
-+ delete resume;
- }
-
- void cDvdPlayer::setController (cDvdPlayerControl *ctrl )
-@@ -570,6 +791,100 @@
- #endif
- }
-
-+char* cDvdPlayer::GetDVDResumeKey() const {
-+ // first we fetch the total number of titles of the current dvd
-+ int totalTitles;
-+ if (dvdnav_get_number_of_titles(nav, &totalTitles)) {
-+ // then we sum up the numbers of chapters for each title
-+ int totalChapters = 0;
-+ for (int t = 1; t <= totalTitles; t++) {
-+ int curChapters;
-+ dvdnav_get_number_of_parts(nav, t, &curChapters);
-+ totalChapters += curChapters;
-+ DEBUGDVD("resume: cDvdPlayer::Action() Title %d has %d chapters.\n", t, curChapters);
-+ }
-+ DEBUGDVD("resume: cDvdPlayer::Action() Titles: %d with %d chapters all together, Title: \"%s\"\n",
-+ totalTitles, totalChapters, title_str);
-+ // finally the key is build as "DVDName_TotalTitles_OverallChapters"
-+ char* key;
-+ asprintf(&key, "%s_%d_%d", title_str, totalTitles, totalChapters);
-+ // note: this is not completly unique. Maybe some other informations are more suitable, like:
-+ // - the "serial number" of the dvd as displayed in the libdvdnav debug output, but:
-+ // it is not available through the current libdvdnav api
-+ // - the total bytes of the dvd (quiet unique!!!), but:
-+ // also not available through the libdvdnav api and no idea how to get it for a media not mounted.
-+ // - any other ideas???
-+ return key;
-+ } else {
-+ // if we cannot fetch the total number of titles of the current disc, there must be something wrong!
-+ // Who needs a key for resuming then?
-+ return NULL;
-+ }
-+}
-+
-+void cDvdPlayer::SaveResume() {
-+ // make sure resume database is allocated (might be a possibility to completly disable resuming!)
-+ if (resume) {
-+ // fetch the current title and chapter number via libdvdnav api
-+ int currentTitle, currentChapter;
-+ if (dvdnav_current_title_info(nav, ¤tTitle, ¤tChapter) &&
-+ (0 != currentTitle)) {
-+ // fetch current time position through own class api
-+ int64_t currentSec, totalSec;
-+ GetPositionInSec(currentSec, totalSec);
-+ // compute the resume key for the current dvd
-+ char* key = GetDVDResumeKey();
-+ if (key) {
-+ // store computed/fetched resume data in database
-+ DEBUGDVD("resume->SetResume(\"%s\", %d, %d, %lld)\n", key, currentTitle, currentChapter, currentSec);
-+ resume->SetResume(key, currentTitle, currentChapter, currentSec);
-+ // free the key string memory allocated by GetDVDResumeKey()
-+ free(key);
-+ } else {
-+ DEBUGDVD("resume: ERROR computing resume key for this dvd!\n");
-+ }
-+ } else {
-+ // in a menu title and chapter seams to be always 0 -> no way to resume there!
-+ DEBUGDVD("resume: ERROR fetching current title and chapter (maybe in menus?).\n");
-+ }
-+ }
-+}
-+
-+bool cDvdPlayer::LoadResume(int& title, int& chapter, int64_t& second) {
-+ // helper variable for the return value
-+ bool retval = false;
-+ // make sure resume database is allocated (might be a possibility to completly disable resuming!)
-+ if(resume) {
-+ // compute the resume key for the current dvd
-+ char* key = GetDVDResumeKey();
-+ if (key) {
-+ DEBUGDVD("resume->GetResume(\"%s\", ...): ", key);
-+ // try loading the resume data for the computed key into the given arguments
-+ if (resume->GetResume(key, title, chapter, second)) {
-+ DEBUGDVD("%d:%d:%lld\n", title, chapter, second);
-+ // continuing at the very same position might be inappropriate (vdr's recordings also rewind some seconds)
-+ int ResumeRewind = 30; // rewind 30s if possible
-+ // note: I used a variable here to show up, that this value might be made
-+ // possible to configure (in the setup dialog). Doing so myself was
-+ // not yet nesseccary and is so left to the plugin maintainers.
-+ // make sure we do not rewind before the beginning
-+ if (second > ResumeRewind) {
-+ second -= ResumeRewind;
-+ }
-+ retval = true;
-+ } else {
-+ DEBUGDVD("<none>\n");
-+ retval = false;
-+ }
-+ // free the key string memory allocated by GetDVDResumeKey()
-+ free(key);
-+ } else {
-+ DEBUGDVD("resume: ERROR computing resume key for this dvd.\n");
-+ }
-+ }
-+ return retval;
-+}
-+
- void cDvdPlayer::Action(void) {
- memset(event_buf, 0, sizeof(uint8_t)*4096);
-
-@@ -641,6 +956,13 @@
-
- bool firstClear = true;
-
-+ // we need to know the very first VTS change to hook inthe resume call
-+ bool first_vts_change = true;
-+ // we cannot directly resume to the exact time, so we hook on the next cell change when resuming
-+ bool next_cell_change = false;
-+ // and seek the the exact time stored here
-+ int64_t resSecond = 0;
-+
- while(running && nav) {
-
- if (!pframe) {
-@@ -1119,6 +1441,22 @@
- SetTitleInfoString();
- SetTitleString();
- SetAspectString();
-+ if (first_vts_change) {
-+ first_vts_change = false;
-+
-+ // now all data for computing the resume key is available, so trying to resume
-+ int resTitle, resChapter;
-+ if (LoadResume(resTitle, resChapter, resSecond)) {
-+ // if resume data could be found seek to the found title and chapter NOW
-+ GotoTitle(resTitle, resChapter);
-+ // and wait for the next cell change (= title and chapter reached)
-+ // to seek to the exact time
-+ next_cell_change = true;
-+ // note: seeking to the exact time HERE leads to an error on the libdvdnav console:
-+ // "dvd error dvdnav_sector_search: New position not yet determined." and is
-+ // slightly ignored :-( .
-+ }
-+ }
- break;
- case DVDNAV_CELL_CHANGE: {
- DEBUG_NAV("%s:%d:NAV CELL CHANGE\n", __FILE__, __LINE__);
-@@ -1139,6 +1477,11 @@
- // cell change .. game over ..
- changeNavSubpStreamOnceInSameCell=false;
- SetTitleInfoString();
-+ if (next_cell_change) {
-+ next_cell_change = false;
-+ // we are resuming the current dvd. NOW its time to seek to the correct second.
-+ Goto(resSecond);
-+ }
- break;
- }
- case DVDNAV_NAV_PACKET: {
-@@ -1902,8 +2245,18 @@
- if (!DVDActiveAndRunning())
- return;
-
-- if (running && nav)
-+ if (running && nav) {
-+ // we will stop replay now. Its time to save the current possition
-+ // for later resuming.
-+ SaveResume();
-+
- dvdnav_stop(nav);
-+
-+ // don't know why Stop() is called twice, but this prevents from
-+ // twice save resume data and calling dvdnav_stop() twice.
-+ // Comments from maintainers are welcome.
-+ running = false;
-+ }
- }
-
- void cDvdPlayer::Play(void)
-@@ -2219,24 +2572,41 @@
- GotoAngle(++angleNumber);
- }
-
--int cDvdPlayer::GotoTitle(int Title)
-+// GotoTitle now optionally takes a chapter to seek to in the given title.
-+int cDvdPlayer::GotoTitle(int Title, int Chapter /*= 1*/)
- {
- int titleNumbers;
-+ int targetTitle = Title;
-+ int chapterNumber;
- if (!DVDActiveAndRunning())
- return -1;
- LOCK_THREAD;
- DEBUG_NAV("DVD NAV SPU clear & empty %s:%d\n", __FILE__, __LINE__);
- Empty();
-
-+ // check if the given title is in the title range of this dvd
- dvdnav_get_number_of_titles(nav, &titleNumbers);
-
- if (Title > titleNumbers)
-- Title = 1;
-+ targetTitle = 1;
- if (Title <= 0)
-- Title = titleNumbers;
-+ targetTitle = titleNumbers;
-+
-+ // if given title is in the bounds of this dvd's title range
-+ if (Title == targetTitle) {
-+ // check if the chapter is in the title's chapter range
-+ dvdnav_get_number_of_parts(nav, Title, &chapterNumber);
-+ if (Chapter > chapterNumber)
-+ Chapter = 1;
-+ if (Chapter <= 0)
-+ Chapter = chapterNumber;
-+ } else {
-+ // otherwise reset it to the first chapter.
-+ Chapter = 1;
-+ }
-
- if (stillTimer == 0) {
-- dvdnav_part_play(nav, Title, 1);
-+ dvdnav_part_play(nav, Title, Chapter);
- // dvdnav_title_play(nav, Title);
- }
-
---- a/player-dvd.h
-+++ b/player-dvd.h
-@@ -54,6 +54,7 @@
-
- class cDvdPlayerControl ;
- class cIframeAssembler;
-+class cDVDPlayerResume;
-
- class cDvdPlayer : public cPlayer, cThread {
- private:
-@@ -188,6 +189,32 @@
- int GetAudioStreamNumbers(void) const ;
- uint16_t GetSubtitleLanguageCode(int Channel) const;
- int GetSubtitleStreamNumbers(void) const ;
-+
-+ //resuming
-+ /**
-+ * the resume database
-+ */
-+ cDVDPlayerResume* resume;
-+ /**
-+ * GetDVDResumeKey():
-+ * computes a (hopefully) unique id for storing the resume data of the current disc.
-+ *
-+ * this get returns a new allocated memory area ..
-+ * must be freed by callee ..
-+ */
-+ char* GetDVDResumeKey() const;
-+ /**
-+ * SaveResume():
-+ * handles everything to save the current position on the disc for later resuming.
-+ */
-+ void SaveResume();
-+ /**
-+ * LoadResume():
-+ * loads the resume data for the current disc and stores it in the given arguments.
-+ * returns false if no resume data for the disc can be found or and error occured while loading.
-+ */
-+ bool LoadResume(int& title, int& chapter, int64_t& second);
-+
- protected: //Player
- virtual void Activate(bool On);
- virtual void Action(void);
-@@ -320,7 +347,8 @@
- *
- * return set title ..
- */
-- int GotoTitle(int Title);
-+ // GotoTitle now optionally takes a chapter to seek to in the given title
-+ int GotoTitle(int Title, int Chapter = 1);
-
- /**
- * jump to the previous Title (rotate)
diff --git a/debian/patches/05_stdint.patch b/debian/patches/05_stdint.patch
index 2dbd6a5..1772a33 100644
--- a/debian/patches/05_stdint.patch
+++ b/debian/patches/05_stdint.patch
@@ -6,9 +6,11 @@
## DP: C++ code.
@DPATCH@
---- a/Makefile
-+++ b/Makefile
-@@ -41,6 +41,7 @@
+Index: vdr-plugin-dvd.git/Makefile
+===================================================================
+--- vdr-plugin-dvd.git.orig/Makefile
++++ vdr-plugin-dvd.git/Makefile
+@@ -42,6 +42,7 @@ SOFILE = libvdr-$(PLUGIN).so
INCLUDES +=
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
diff --git a/debian/patches/10_dvd.c.patch b/debian/patches/10_dvd.c.patch
deleted file mode 100644
index d050e23..0000000
--- a/debian/patches/10_dvd.c.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## dvd.c patch
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Removes stderr output on correctly parsed -C parameter
-
-@DPATCH@
-Index: vdr-plugin-dvd-0.3.6~b03+cvs20090426.0013/dvd.c
-===================================================================
---- vdr-plugin-dvd-0.3.6~b03+cvs20090426.0013.orig/dvd.c 2007-09-16 18:31:50.000000000 +0200
-+++ vdr-plugin-dvd-0.3.6~b03+cvs20090426.0013/dvd.c 2011-04-09 17:23:43.000000000 +0200
-@@ -73,7 +73,7 @@
- #endif
- switch (c) {
- case 'C':
-- fprintf(stderr, "arg: %s\n", optarg);
-+ // fprintf(stderr, "arg: %s\n", optarg);
- cDVD::SetDeviceName(optarg);
- if (!cDVD::DriveExists()) {
- esyslog("vdr: DVD drive not found: %s", optarg);
diff --git a/debian/patches/11_allow-non-existing-dvd-drive.patch b/debian/patches/11_allow-non-existing-dvd-drive.patch
index 2c3f67e..0e42f6c 100644
--- a/debian/patches/11_allow-non-existing-dvd-drive.patch
+++ b/debian/patches/11_allow-non-existing-dvd-drive.patch
@@ -6,11 +6,11 @@
## DP: just log a warning and continue.
@DPATCH@
-Index: vdr-plugin-dvd-0.3.6~b03+cvs20090426.0013/dvd.c
+Index: vdr-plugin-dvd.git/dvd.c
===================================================================
---- vdr-plugin-dvd-0.3.6~b03+cvs20090426.0013.orig/dvd.c 2011-04-09 17:23:43.000000000 +0200
-+++ vdr-plugin-dvd-0.3.6~b03+cvs20090426.0013/dvd.c 2011-04-09 17:23:46.000000000 +0200
-@@ -76,8 +76,7 @@
+--- vdr-plugin-dvd.git.orig/dvd.c
++++ vdr-plugin-dvd.git/dvd.c
+@@ -76,8 +76,7 @@ bool cPluginDvd::ProcessArgs(int argc, c
// fprintf(stderr, "arg: %s\n", optarg);
cDVD::SetDeviceName(optarg);
if (!cDVD::DriveExists()) {
diff --git a/debian/patches/12_dvd-fixed-german-spelling.patch b/debian/patches/12_dvd-fixed-german-spelling.patch
deleted file mode 100644
index bc0dfbf..0000000
--- a/debian/patches/12_dvd-fixed-german-spelling.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 12_dvd-fixed-german-spelling.dpatch by Thomas G�nther <tom@toms-cafe.de>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Fixed spelling errors in german translation.
-
-@DPATCH@
---- a/i18n.c
-+++ b/i18n.c
-@@ -125,7 +125,7 @@
- },
- {
- "Setup.DVD$Preferred menu language", // English
-- "Bevorzugte Spache f�r Men�s", // Deutsch
-+ "Bevorzugte Sprache f�r Men�s", // Deutsch
- "Prednostni jezik za menije", // Slovenski
- "menu - linguaggio preferito", // Italiano
- "Taalkeuze voor menu", // Nederlands
-@@ -177,7 +177,7 @@
- },
- {
- "Setup.DVD$Preferred subtitle language", // English
-- "Bevorzugte Spache f�r Untertitel", // Deutsch
-+ "Bevorzugte Sprache f�r Untertitel", // Deutsch
- "Prednostni jezik za podnapise", // Slovenski
- "sottotitoli - linguaggio preferito", // Italiano
- "Taalkeuze voor ondertitels", // Nederlands
-@@ -333,7 +333,7 @@
- },
- {
- "Error.DVD$Error opening DVD!", // English
-- "Fehler beim �ffnen der DVD!", // Deutsch
-+ "Fehler beim �ffnen der DVD!", // Deutsch
- "Napaka pri odpiranju DVD-ja!", // Slovenski
- "", // Italiano
- "Fout bij het openen van de DVD!", // Nederlands
-@@ -359,7 +359,7 @@
- },
- {
- "Error.DVD$Error fetching data from DVD!", // English
-- "Fehler beim lesen von der DVD!", // Deutsch
-+ "Fehler beim Lesen von der DVD!", // Deutsch
- "Napaka pri branju podatkov iz DVD-ja!", // Slovenski
- "", // Italiano
- "Error bij het verkrijgen van data van de DVD!", // Nederlands
---- a/po/de_DE.po
-+++ b/po/de_DE.po
-@@ -26,19 +26,19 @@
- msgstr "DVD"
-
- msgid "Error.DVD$Error opening DVD!"
--msgstr "Fehler beim �ffnen der DVD!"
-+msgstr "Fehler beim �ffnen der DVD!"
-
- msgid "Error.DVD$Error fetching data from DVD!"
--msgstr "Fehler beim lesen von der DVD!"
-+msgstr "Fehler beim Lesen von der DVD!"
-
- msgid "Setup.DVD$Preferred menu language"
--msgstr "Bevorzugte Spache f�r Men�s"
-+msgstr "Bevorzugte Sprache f�r Men�s"
-
- msgid "Setup.DVD$Preferred audio language"
- msgstr "Bevorzugte Sprache f�r Dialog"
-
- msgid "Setup.DVD$Preferred subtitle language"
--msgstr "Bevorzugte Spache f�r Untertitel"
-+msgstr "Bevorzugte Sprache f�r Untertitel"
-
- msgid "Setup.DVD$Player region code"
- msgstr "Regionalkode f�r DVD Spieler"
diff --git a/debian/patches/cross.patch b/debian/patches/cross.patch
deleted file mode 100644
index 830cc22..0000000
--- a/debian/patches/cross.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -15,7 +15,8 @@
-
- ### The directory environment:
-
--PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell pkg-config --variable=$(1) vdr || pkg-config --variable=$(1) ../../../vdr.pc))
-+PKG_CONFIG ?= pkg-config
-+PKGCFG = $(if $(VDRDIR),$(shell $(PKG_CONFIG) --variable=$(1) $(VDRDIR)/vdr.pc),$(shell $(PKG_CONFIG) --variable=$(1) vdr || $(PKG_CONFIG) --variable=$(1) ../../../vdr.pc))
- LIBDIR = $(DESTDIR)$(call PKGCFG,libdir)
- LOCDIR = $(DESTDIR)$(call PKGCFG,locdir)
-
diff --git a/debian/patches/series b/debian/patches/series
index 92111fe..144f0d9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,6 +1,2 @@
-04_vdr-dvd_resume.patch
05_stdint.patch
-10_dvd.c.patch
11_allow-non-existing-dvd-drive.patch
-12_dvd-fixed-german-spelling.patch
-cross.patch
diff --git a/dvd.c b/dvd.c
index d87efad..8b22e6c 100644
--- a/dvd.c
+++ b/dvd.c
@@ -14,7 +14,7 @@
#include "dvd.h"
-static const char *VERSION = "0.3.6-b03";
+static const char *VERSION = "0.3.7";
#if VDRVERSNUM >= 10507
static const char *DESCRIPTION = trNOOP("Plugin.DVD$turn VDR into an (almost) full featured DVD player");
static const char *MAINMENUENTRY = trNOOP("Plugin.DVD$DVD");
@@ -73,7 +73,7 @@ bool cPluginDvd::ProcessArgs(int argc, char *argv[])
#endif
switch (c) {
case 'C':
- fprintf(stderr, "arg: %s\n", optarg);
+ // fprintf(stderr, "arg: %s\n", optarg);
cDVD::SetDeviceName(optarg);
if (!cDVD::DriveExists()) {
esyslog("vdr: DVD drive not found: %s", optarg);
diff --git a/i18n.c b/i18n.c
index 8381ed4..bf0d416 100644
--- a/i18n.c
+++ b/i18n.c
@@ -125,7 +125,7 @@ const tI18nPhrase DvdPhrases[] = {
},
{
"Setup.DVD$Preferred menu language", // English
- "Bevorzugte Spache f�r Men�s", // Deutsch
+ "Bevorzugte Sprache f�r Men�s", // Deutsch
"Prednostni jezik za menije", // Slovenski
"menu - linguaggio preferito", // Italiano
"Taalkeuze voor menu", // Nederlands
@@ -177,7 +177,7 @@ const tI18nPhrase DvdPhrases[] = {
},
{
"Setup.DVD$Preferred subtitle language", // English
- "Bevorzugte Spache f�r Untertitel", // Deutsch
+ "Bevorzugte Sprache f�r Untertitel", // Deutsch
"Prednostni jezik za podnapise", // Slovenski
"sottotitoli - linguaggio preferito", // Italiano
"Taalkeuze voor ondertitels", // Nederlands
@@ -333,7 +333,7 @@ const tI18nPhrase DvdPhrases[] = {
},
{
"Error.DVD$Error opening DVD!", // English
- "Fehler beim �ffnen der DVD!", // Deutsch
+ "Fehler beim �ffnen der DVD!", // Deutsch
"Napaka pri odpiranju DVD-ja!", // Slovenski
"", // Italiano
"Fout bij het openen van de DVD!", // Nederlands
@@ -359,7 +359,7 @@ const tI18nPhrase DvdPhrases[] = {
},
{
"Error.DVD$Error fetching data from DVD!", // English
- "Fehler beim lesen von der DVD!", // Deutsch
+ "Fehler beim Lesen von der DVD!", // Deutsch
"Napaka pri branju podatkov iz DVD-ja!", // Slovenski
"", // Italiano
"Error bij het verkrijgen van data van de DVD!", // Nederlands
diff --git a/player-dvd.c b/player-dvd.c
index ae03ce2..0d40696 100644
--- a/player-dvd.c
+++ b/player-dvd.c
@@ -21,6 +21,8 @@
#include <vdr/thread.h>
#include <vdr/device.h>
#include <vdr/plugin.h>
+// for VideoDirectory variable
+#include <vdr/videodir.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -231,6 +233,220 @@ void cIframeAssembler::Put(unsigned char *Data, int Length) {
}
+// --- cResumeEntry ------------------------------------------------------------
+
+// borrowed from the mplayer plugin code and adapted to the dvd resume requirements
+class cResumeEntry : public cListObject {
+public:
+ char *key;
+ int title;
+ int chapter;
+ int64_t second;
+ //
+ cResumeEntry(void);
+ ~cResumeEntry();
+ };
+
+cResumeEntry::cResumeEntry(void)
+{
+ key=0;
+}
+
+cResumeEntry::~cResumeEntry()
+{
+ free(key);
+}
+
+// --- cDVDPlayerResume ----------------------------------------------------------
+
+// store resume database to this file ...
+#define RESUME_FILE "dvdplayer.resume"
+
+// ... in this directory (default: /video)
+#ifndef RESUMEDIR
+#if APIVERSNUM > 20101
+#define RESUMEDIR cVideoDirectory::Name()
+#else
+#define RESUMEDIR VideoDirectory
+#endif
+#endif
+
+
+// borrowed from the mplayer plugin code and adapted to the dvd resume requirements
+class cDVDPlayerResume : public cList<cResumeEntry> {
+private:
+ char* resfile; // the full pathname of resume file
+ bool modified; // flag to indicate that memory database was modified and needs to be saved
+ /**
+ * LoadResume():
+ * reads in the resume database file from resfile.
+ */
+ void LoadResume();
+ /**
+ * SaveResume():
+ * saves the resume database to the file resfile.
+ * returns true on successful save.
+ */
+ bool SaveResume(void);
+ /**
+ * search the (loaded) resume database for the given key.
+ * returns the cResumeEntry* if the key was found
+ * or NULL if no resume entry was found for the given key.
+ */
+ cResumeEntry *FindResume(const char* key);
+public:
+ cDVDPlayerResume(void);
+ ~cDVDPlayerResume();
+ /**
+ * SetResume():
+ * set the given resume values for the given key into the resume database.
+ * the resume database is loaded from file if not yet loaded.
+ */
+ void SetResume(const char* key, int title, int chapter, int64_t second);
+ /**
+ * GetResume():
+ * tries looking up the given key into the resume database.
+ * the resume database is loaded from file if not yet loaded.
+ * returns true if resume data could be found. In this case
+ * the givven arguments are filled with the resume data. Otherwise
+ * the arguments are not modified!
+ */
+ bool GetResume(const char* key, int& title, int& chapter, int64_t& second);
+ };
+
+cDVDPlayerResume::cDVDPlayerResume(void)
+{
+ // initialize the resume filename string.
+ asprintf(&resfile, "%s/%s", RESUMEDIR, RESUME_FILE);
+}
+
+cDVDPlayerResume::~cDVDPlayerResume()
+{
+ // save resume data to disc before self-destruction.
+ SaveResume();
+ // free the resume filename string, allocated in C'tor by asprintf
+ free(resfile);
+}
+
+void cDVDPlayerResume::SetResume(const char* key, int title, int chapter, int64_t second)
+{
+ // (re)load resume data from file to be actual
+ LoadResume();
+ cResumeEntry* re = FindResume(key);
+ if (re) {
+ // found a resume entry, so we can update it.
+ DEBUGDVD("resume: setting resume %d:%d:%lld (update)", title, chapter, second);
+ } else {
+ // no resume entry found yet, creating a new one
+ re = new cResumeEntry;
+ re->key = strdup(key);
+ Add(re);
+ DEBUGDVD("resume: setting resume %d:%d:%lld (new)", title, chapter, second);
+ }
+ // set the new resume data for the found/created entry
+ re->title = title;
+ re->chapter = chapter;
+ re->second = second;
+ // and mark memory database as modified to be saved.
+ modified = true;
+ // save it now (sync!)
+ SaveResume();
+}
+
+bool cDVDPlayerResume::GetResume(const char* key, int& title, int& chapter, int64_t& second)
+{
+ // (re)load the resume file to have actual values
+ LoadResume();
+ cResumeEntry* re = FindResume(key);
+ if (re) {
+ // found a resume entry, copy values
+ title = re->title;
+ chapter = re->chapter;
+ second = re->second;
+ // indicate successful search
+ return true;
+ }
+ // no resume entry found in database
+ return false;
+}
+
+void cDVDPlayerResume::LoadResume()
+{
+ // we will load the file for sure and add all entries, clear all old entries.
+ Clear();
+ // no entries == no modifications
+ modified = false;
+ DEBUGDVD("resume: resume file is \"%s\"\n",resfile);
+ FILE *f = fopen(resfile,"r");
+ if (f) {
+ DEBUGDVD("resume: successfully opened resume file\n");
+ char line[768];
+ // read file line by line
+ while(fgets(line,sizeof(line),f)) {
+ char key[512];
+ int t, c;
+ int64_t s;
+ // parse line as "title:chapter:second:key"
+ if(sscanf(line,"%d:%d:%lld:%511[^\n]",&t,&c,&s,key) == 4) {
+ // successful parse, save in resume entry
+ cResumeEntry *re = new cResumeEntry;
+ re->key = strdup(key);
+ re->title = t;
+ re->chapter = c;
+ re->second = s;
+ // and add it to memory database
+ Add(re);
+ }
+ }
+ // don't forget to close what you have opened!
+ fclose(f);
+ }
+ // unsuccessful open leads to empty database as the file does not exists
+}
+
+bool cDVDPlayerResume::SaveResume(void)
+{
+ if(modified) {
+ // modification indicated, save the database to the resume file
+ DEBUGDVD("resume: saving resume file\n");
+ cSafeFile f(resfile);
+ if(f.Open()) {
+ // forall resume entries in the memory database
+ for (cResumeEntry *re=First(); re; re=Next(re)) {
+ // save the as one line in the format "title:chapter:second:key"
+ fprintf(f, "%d:%d:%lld:%s\n", re->title, re->chapter, re->second, re->key);
+ }
+ // don't forget to close what you have opened!
+ f.Close();
+ // signal successful save
+ return true;
+ } else {
+ DEBUGDVD("resume: failed to save resume file\n");
+ // saving did not succeed!!!!
+ return false;
+ }
+ } else {
+ // no modifications -> successful "save" :-)
+ return true;
+ }
+}
+
+cResumeEntry *cDVDPlayerResume::FindResume(const char* key)
+{
+ DEBUGDVD("resume: searching resume position for \"%s\"\n", key);
+ // iterate over all entries in the memory database
+ for(cResumeEntry *re=First(); re; re=Next(re)) {
+ if (!strcasecmp(re->key, key)) {
+ // return the entry iff the keys match
+ DEBUGDVD("resume: found resume position %d:%d:%lld\n",re->title, re->chapter, re->second);
+ return re;
+ }
+ }
+ DEBUGDVD("resume: no resume position found\n");
+ return NULL;
+}
+
+
// --- cDvdPlayer ------------------------------------------------------------
//XXX+ also used in recorder.c - find a better place???
@@ -288,6 +504,9 @@ cDvdPlayer::cDvdPlayer(void): cThread("dvd-plugin"), a52dec(*this) {
skipPlayVideo=false;
fastWindFactor=1;
+ // resume
+ resume = new cDVDPlayerResume;
+
clearSeenSubpStream();
clearSeenAudioTrack();
@@ -334,6 +553,8 @@ cDvdPlayer::~cDvdPlayer()
if(aspect_str)
free(aspect_str);
+
+ delete resume;
}
void cDvdPlayer::setController (cDvdPlayerControl *ctrl )
@@ -570,6 +791,100 @@ uint64_t cDvdPlayer::delay_ticks(uint64_t ticks)
#endif
}
+char* cDvdPlayer::GetDVDResumeKey() const {
+ // first we fetch the total number of titles of the current dvd
+ int totalTitles;
+ if (dvdnav_get_number_of_titles(nav, &totalTitles)) {
+ // then we sum up the numbers of chapters for each title
+ int totalChapters = 0;
+ for (int t = 1; t <= totalTitles; t++) {
+ int curChapters;
+ dvdnav_get_number_of_parts(nav, t, &curChapters);
+ totalChapters += curChapters;
+ DEBUGDVD("resume: cDvdPlayer::Action() Title %d has %d chapters.\n", t, curChapters);
+ }
+ DEBUGDVD("resume: cDvdPlayer::Action() Titles: %d with %d chapters all together, Title: \"%s\"\n",
+ totalTitles, totalChapters, title_str);
+ // finally the key is build as "DVDName_TotalTitles_OverallChapters"
+ char* key;
+ asprintf(&key, "%s_%d_%d", title_str, totalTitles, totalChapters);
+ // note: this is not completly unique. Maybe some other informations are more suitable, like:
+ // - the "serial number" of the dvd as displayed in the libdvdnav debug output, but:
+ // it is not available through the current libdvdnav api
+ // - the total bytes of the dvd (quiet unique!!!), but:
+ // also not available through the libdvdnav api and no idea how to get it for a media not mounted.
+ // - any other ideas???
+ return key;
+ } else {
+ // if we cannot fetch the total number of titles of the current disc, there must be something wrong!
+ // Who needs a key for resuming then?
+ return NULL;
+ }
+}
+
+void cDvdPlayer::SaveResume() {
+ // make sure resume database is allocated (might be a possibility to completly disable resuming!)
+ if (resume) {
+ // fetch the current title and chapter number via libdvdnav api
+ int currentTitle, currentChapter;
+ if (dvdnav_current_title_info(nav, ¤tTitle, ¤tChapter) &&
+ (0 != currentTitle)) {
+ // fetch current time position through own class api
+ int64_t currentSec, totalSec;
+ GetPositionInSec(currentSec, totalSec);
+ // compute the resume key for the current dvd
+ char* key = GetDVDResumeKey();
+ if (key) {
+ // store computed/fetched resume data in database
+ DEBUGDVD("resume->SetResume(\"%s\", %d, %d, %lld)\n", key, currentTitle, currentChapter, currentSec);
+ resume->SetResume(key, currentTitle, currentChapter, currentSec);
+ // free the key string memory allocated by GetDVDResumeKey()
+ free(key);
+ } else {
+ DEBUGDVD("resume: ERROR computing resume key for this dvd!\n");
+ }
+ } else {
+ // in a menu title and chapter seams to be always 0 -> no way to resume there!
+ DEBUGDVD("resume: ERROR fetching current title and chapter (maybe in menus?).\n");
+ }
+ }
+}
+
+bool cDvdPlayer::LoadResume(int& title, int& chapter, int64_t& second) {
+ // helper variable for the return value
+ bool retval = false;
+ // make sure resume database is allocated (might be a possibility to completly disable resuming!)
+ if(resume) {
+ // compute the resume key for the current dvd
+ char* key = GetDVDResumeKey();
+ if (key) {
+ DEBUGDVD("resume->GetResume(\"%s\", ...): ", key);
+ // try loading the resume data for the computed key into the given arguments
+ if (resume->GetResume(key, title, chapter, second)) {
+ DEBUGDVD("%d:%d:%lld\n", title, chapter, second);
+ // continuing at the very same position might be inappropriate (vdr's recordings also rewind some seconds)
+ int ResumeRewind = 30; // rewind 30s if possible
+ // note: I used a variable here to show up, that this value might be made
+ // possible to configure (in the setup dialog). Doing so myself was
+ // not yet nesseccary and is so left to the plugin maintainers.
+ // make sure we do not rewind before the beginning
+ if (second > ResumeRewind) {
+ second -= ResumeRewind;
+ }
+ retval = true;
+ } else {
+ DEBUGDVD("<none>\n");
+ retval = false;
+ }
+ // free the key string memory allocated by GetDVDResumeKey()
+ free(key);
+ } else {
+ DEBUGDVD("resume: ERROR computing resume key for this dvd.\n");
+ }
+ }
+ return retval;
+}
+
void cDvdPlayer::Action(void) {
memset(event_buf, 0, sizeof(uint8_t)*4096);
@@ -641,6 +956,13 @@ void cDvdPlayer::Action(void) {
bool firstClear = true;
+ // we need to know the very first VTS change to hook inthe resume call
+ bool first_vts_change = true;
+ // we cannot directly resume to the exact time, so we hook on the next cell change when resuming
+ bool next_cell_change = false;
+ // and seek the the exact time stored here
+ int64_t resSecond = 0;
+
while(running && nav) {
if (!pframe) {
@@ -1119,6 +1441,22 @@ void cDvdPlayer::Action(void) {
SetTitleInfoString();
SetTitleString();
SetAspectString();
+ if (first_vts_change) {
+ first_vts_change = false;
+
+ // now all data for computing the resume key is available, so trying to resume
+ int resTitle, resChapter;
+ if (LoadResume(resTitle, resChapter, resSecond)) {
+ // if resume data could be found seek to the found title and chapter NOW
+ GotoTitle(resTitle, resChapter);
+ // and wait for the next cell change (= title and chapter reached)
+ // to seek to the exact time
+ next_cell_change = true;
+ // note: seeking to the exact time HERE leads to an error on the libdvdnav console:
+ // "dvd error dvdnav_sector_search: New position not yet determined." and is
+ // slightly ignored :-( .
+ }
+ }
break;
case DVDNAV_CELL_CHANGE: {
DEBUG_NAV("%s:%d:NAV CELL CHANGE\n", __FILE__, __LINE__);
@@ -1139,6 +1477,11 @@ void cDvdPlayer::Action(void) {
// cell change .. game over ..
changeNavSubpStreamOnceInSameCell=false;
SetTitleInfoString();
+ if (next_cell_change) {
+ next_cell_change = false;
+ // we are resuming the current dvd. NOW its time to seek to the correct second.
+ Goto(resSecond);
+ }
break;
}
case DVDNAV_NAV_PACKET: {
@@ -1902,8 +2245,18 @@ void cDvdPlayer::Stop(void)
if (!DVDActiveAndRunning())
return;
- if (running && nav)
+ if (running && nav) {
+ // we will stop replay now. Its time to save the current possition
+ // for later resuming.
+ SaveResume();
+
dvdnav_stop(nav);
+
+ // don't know why Stop() is called twice, but this prevents from
+ // twice save resume data and calling dvdnav_stop() twice.
+ // Comments from maintainers are welcome.
+ running = false;
+ }
}
void cDvdPlayer::Play(void)
@@ -2219,24 +2572,41 @@ void cDvdPlayer::NextAngle(void)
GotoAngle(++angleNumber);
}
-int cDvdPlayer::GotoTitle(int Title)
+// GotoTitle now optionally takes a chapter to seek to in the given title.
+int cDvdPlayer::GotoTitle(int Title, int Chapter /*= 1*/)
{
int titleNumbers;
+ int targetTitle = Title;
+ int chapterNumber;
if (!DVDActiveAndRunning())
return -1;
LOCK_THREAD;
DEBUG_NAV("DVD NAV SPU clear & empty %s:%d\n", __FILE__, __LINE__);
Empty();
+ // check if the given title is in the title range of this dvd
dvdnav_get_number_of_titles(nav, &titleNumbers);
if (Title > titleNumbers)
- Title = 1;
+ targetTitle = 1;
if (Title <= 0)
- Title = titleNumbers;
+ targetTitle = titleNumbers;
+
+ // if given title is in the bounds of this dvd's title range
+ if (Title == targetTitle) {
+ // check if the chapter is in the title's chapter range
+ dvdnav_get_number_of_parts(nav, Title, &chapterNumber);
+ if (Chapter > chapterNumber)
+ Chapter = 1;
+ if (Chapter <= 0)
+ Chapter = chapterNumber;
+ } else {
+ // otherwise reset it to the first chapter.
+ Chapter = 1;
+ }
if (stillTimer == 0) {
- dvdnav_part_play(nav, Title, 1);
+ dvdnav_part_play(nav, Title, Chapter);
// dvdnav_title_play(nav, Title);
}
diff --git a/player-dvd.h b/player-dvd.h
index 319314a..8f9d5c8 100644
--- a/player-dvd.h
+++ b/player-dvd.h
@@ -54,6 +54,7 @@ class IntegerListObject : public cListObject {
class cDvdPlayerControl ;
class cIframeAssembler;
+class cDVDPlayerResume;
class cDvdPlayer : public cPlayer, cThread {
private:
@@ -188,6 +189,32 @@ class cDvdPlayer : public cPlayer, cThread {
int GetAudioStreamNumbers(void) const ;
uint16_t GetSubtitleLanguageCode(int Channel) const;
int GetSubtitleStreamNumbers(void) const ;
+
+ //resuming
+ /**
+ * the resume database
+ */
+ cDVDPlayerResume* resume;
+ /**
+ * GetDVDResumeKey():
+ * computes a (hopefully) unique id for storing the resume data of the current disc.
+ *
+ * this get returns a new allocated memory area ..
+ * must be freed by callee ..
+ */
+ char* GetDVDResumeKey() const;
+ /**
+ * SaveResume():
+ * handles everything to save the current position on the disc for later resuming.
+ */
+ void SaveResume();
+ /**
+ * LoadResume():
+ * loads the resume data for the current disc and stores it in the given arguments.
+ * returns false if no resume data for the disc can be found or and error occured while loading.
+ */
+ bool LoadResume(int& title, int& chapter, int64_t& second);
+
protected: //Player
virtual void Activate(bool On);
virtual void Action(void);
@@ -320,7 +347,8 @@ public:
*
* return set title ..
*/
- int GotoTitle(int Title);
+ // GotoTitle now optionally takes a chapter to seek to in the given title
+ int GotoTitle(int Title, int Chapter = 1);
/**
* jump to the previous Title (rotate)
diff --git a/po/de_DE.po b/po/de_DE.po
index 017e2e7..d59c68a 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -26,19 +26,19 @@ msgid "Plugin.DVD$DVD"
msgstr "DVD"
msgid "Error.DVD$Error opening DVD!"
-msgstr "Fehler beim �ffnen der DVD!"
+msgstr "Fehler beim �ffnen der DVD!"
msgid "Error.DVD$Error fetching data from DVD!"
-msgstr "Fehler beim lesen von der DVD!"
+msgstr "Fehler beim Lesen von der DVD!"
msgid "Setup.DVD$Preferred menu language"
-msgstr "Bevorzugte Spache f�r Men�s"
+msgstr "Bevorzugte Sprache f�r Men�s"
msgid "Setup.DVD$Preferred audio language"
msgstr "Bevorzugte Sprache f�r Dialog"
msgid "Setup.DVD$Preferred subtitle language"
-msgstr "Bevorzugte Spache f�r Untertitel"
+msgstr "Bevorzugte Sprache f�r Untertitel"
msgid "Setup.DVD$Player region code"
msgstr "Regionalkode f�r DVD Spieler"
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/lib/debug/.build-id/b3/18cad0522788200de6b43d9c9fd4a004f9fba7.debug -rw-r--r-- root/root /usr/lib/vdr/plugins/libvdr-dvd.so.2.6.1
Files in first set of .debs but not in second
-rw-r--r-- root/root /usr/lib/debug/.build-id/49/db97d3249a6c475c4ad6585d79723d9a2c7700.debug -rw-r--r-- root/root /usr/lib/vdr/plugins/libvdr-dvd.so.2.6.0
No differences were encountered between the control files of package vdr-plugin-dvd
Control files of package vdr-plugin-dvd-dbgsym: lines which differ (wdiff format)
Build-Ids: 49db97d3249a6c475c4ad6585d79723d9a2c7700 b318cad0522788200de6b43d9c9fd4a004f9fba7