If you're in the mood for patches, I've got some more for you. Also,
please have a look at the patches I submitted on 4/24. When they were
submitted, there was very little discussion, so I don't know if that was
an implicit reject or nobody had the time to review them.
The attached patches are for some particular needs our project has, so
you may or may not have interest in them. Just thought I would pass
them by you.
1. Return fail status if nr_of_lus is invalid. We've encountered some
discs that cause libdvdread consume vast amounts of memory (gigabytes)
if allowed to proceed with titles that have this set to an invalid
value. I wish I could remember the particular disc I used for testing,
but it's been a while and it escapes me.
2. Add dvdnav_program_play and dvdnav_current_title_program analogs to
dvdnav_part_play and dvdnav_current_title_info.
We add chapter marks to the output mkv or mp4 files while encoding.
Using title parts is not reliable for this. The start of a part does
not necessarily fall strictly inside the main title. Parts can have an
intro sequence before getting into the title. So we use program
boundaries instead of part markers to test when we have reached a
chapter point during encoding of the title.
3. Eliminate "RANDOM or SHUFFLE titles not handled yet". The bit tested
here does not indicate
'random or shuffle' - it only says that the title uses multiple PGCs.
Since libdvdnav mostly deals correctly
with mult PGC titles (modulo some weirdness when seeking) we need the
state to get set correctly.
4. Prevent display of garbage volume label when the file being scanned
is not a dvd. This is a simple movement of the code that logs the volume
name to after the point that some basic validation of the disc has been
performed.
On 08/01/2009 01:44 AM, Nico Sabbi wrote:
Il giorno ven, 31/07/2009 alle 17.12 -0700, John Stebbins ha scritto:
dvd_reader.c and dvdread_internal.h use a mix of _WIN32 and _MSC_VER for
windows specific code. _WIN32 works for mingw, but _MSC_VER does not.
The practical effect of the incorrectly built code is that the dvd is
not opened as an image and thus the css keys are never obtained and
decryption doesn't happen.
Patch attached.
i'm not familiar with windows code, thus I'll commit this patch tomorrow
unless someone objects.
Thanks.
_______________________________________________
DVDnav-discuss mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/dvdnav-discuss
diff -Naur libdvdread.orig/src/ifo_read.c libdvdread/src/ifo_read.c
--- libdvdread.orig/src/ifo_read.c 2009-01-08 14:57:10.000000000 -0800
+++ libdvdread/src/ifo_read.c 2009-06-27 13:22:27.940241400 -0700
@@ -1914,6 +1914,13 @@
CHECK_VALUE(pgci_ut->nr_of_lus < 100); /* ?? 3-4 ? */
CHECK_VALUE((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE <
pgci_ut->last_byte);
+ if (pgci_ut->nr_of_lus == 0 || pgci_ut->nr_of_lus >= 100)
+ {
+ free(pgci_ut);
+ ifofile->pgci_ut = 0;
+ return 0;
+ }
+
info_length = pgci_ut->nr_of_lus * PGCI_LU_SIZE;
data = malloc(info_length);
if(!data) {
diff -Naur libdvdnav.orig/src/dvdnav/dvdnav.h libdvdnav/src/dvdnav/dvdnav.h
--- libdvdnav.orig/src/dvdnav/dvdnav.h 2009-03-13 18:28:22.000000000 -0700
+++ libdvdnav/src/dvdnav/dvdnav.h 2009-04-30 10:56:29.000000000 -0700
@@ -279,6 +279,11 @@
dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int32_t title, int32_t part);
/*
+ * Plays the specified title, starting from the specified program
+ */
+dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t
pgcn, int32_t pgn);
+
+/*
* Stores in *times an array (that the application *must* free) of
* dvdtimes corresponding to the chapter times for the chosen title.
* *duration will have the duration of the title
@@ -320,6 +325,13 @@
int32_t *part);
/*
+ * Return the title number, pgcn and pgn currently being played.
+ * A title of 0 indicates, we are in a menu.
+ */
+dvdnav_status_t dvdnav_current_title_program(dvdnav_t *self, int32_t *title,
+ int32_t *pgcn, int32_t *pgn);
+
+/*
* Return the current position (in blocks) within the current
* title and the length (in blocks) of said title.
*
diff -Naur libdvdnav.orig/src/navigation.c libdvdnav/src/navigation.c
--- libdvdnav.orig/src/navigation.c 2009-01-08 14:57:11.000000000 -0800
+++ libdvdnav/src/navigation.c 2009-04-30 10:55:47.000000000 -0700
@@ -122,10 +122,90 @@
return DVDNAV_STATUS_ERR;
}
+dvdnav_status_t dvdnav_current_title_program(dvdnav_t *this, int32_t *title,
int32_t *pgcn, int32_t *pgn) {
+ int32_t retval;
+ int32_t part;
+
+ pthread_mutex_lock(&this->vm_lock);
+ if (!this->vm->vtsi || !this->vm->vmgi) {
+ printerr("Bad VM state.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ if (!this->started) {
+ printerr("Virtual DVD machine not started.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ if (!this->vm->state.pgc) {
+ printerr("No current PGC.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ if ( (this->vm->state.domain == VTSM_DOMAIN)
+ || (this->vm->state.domain == VMGM_DOMAIN) ) {
+ /* Get current Menu ID: into *part. */
+ if(! vm_get_current_menu(this->vm, &part)) {
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ if (part > -1) {
+ *title = 0;
+ *pgcn = this->vm->state.pgcN;
+ *pgn = this->vm->state.pgN;
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_OK;
+ }
+ }
+ if (this->vm->state.domain == VTS_DOMAIN) {
+ retval = vm_get_current_title_part(this->vm, title, &part);
+ *pgcn = this->vm->state.pgcN;
+ *pgn = this->vm->state.pgN;
+ pthread_mutex_unlock(&this->vm_lock);
+ return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
+ }
+ printerr("Not in a title or menu.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+}
+
dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) {
return dvdnav_part_play(this, title, 1);
}
+dvdnav_status_t dvdnav_program_play(dvdnav_t *this, int32_t title, int32_t
pgcn, int32_t pgn) {
+ int32_t retval;
+
+ pthread_mutex_lock(&this->vm_lock);
+ if (!this->vm->vmgi) {
+ printerr("Bad VM state.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ if (!this->started) {
+ /* don't report an error but be nice */
+ vm_start(this->vm);
+ this->started = 1;
+ }
+ if (!this->vm->state.pgc) {
+ printerr("No current PGC.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+ if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) {
+ printerr("Title out of range.");
+ pthread_mutex_unlock(&this->vm_lock);
+ return DVDNAV_STATUS_ERR;
+ }
+
+ retval = vm_jump_title_program(this->vm, title, pgcn, pgn);
+ if (retval)
+ this->vm->hop_channel++;
+ pthread_mutex_unlock(&this->vm_lock);
+
+ return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR;
+}
+
dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) {
int32_t retval;
diff -Naur libdvdnav.orig/src/vm/vm.c libdvdnav/src/vm/vm.c
--- libdvdnav.orig/src/vm/vm.c 2009-03-13 18:28:22.000000000 -0700
+++ libdvdnav/src/vm/vm.c 2009-04-30 11:07:35.000000000 -0700
@@ -83,6 +83,8 @@
static int set_PTT(vm_t *vm, int tt, int ptt);
static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn);
static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part);
+static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn);
+static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn);
static int set_FP_PGC(vm_t *vm);
static int set_MENU(vm_t *vm, int menu);
static int set_PGCN(vm_t *vm, int pgcN);
@@ -516,6 +518,24 @@
return 1;
}
+int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn) {
+ link_t link;
+
+ if(!set_PROG(vm, title, pgcn, pgn))
+ return 0;
+ /* Some DVDs do not want us to jump directly into a title and have
+ * PGC pre commands taking us back to some menu. Since we do not like that,
+ * we do not execute PGC pre commands that would do a jump. */
+ /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */
+ link = play_PGC_PG(vm, (vm->state).pgN);
+ if (link.command != PlayThis)
+ /* jump occured -> ignore it and play the PG anyway */
+ process_command(vm, play_PG(vm));
+ else
+ process_command(vm, link);
+ return 1;
+}
+
int vm_jump_title_part(vm_t *vm, int title, int part) {
link_t link;
@@ -1644,6 +1664,42 @@
return res;
}
+static int set_PROG(vm_t *vm, int tt, int pgcn, int pgn) {
+ assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts);
+ return set_VTS_PROG(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr,
+ vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, pgcn, pgn);
+}
+
+static int set_VTS_PROG(vm_t *vm, int vtsN, int vts_ttn, int pgcn, int pgn) {
+ int pgcN, pgN, res, title, part;
+
+ (vm->state).domain = VTS_DOMAIN;
+
+ if (vtsN != (vm->state).vtsN)
+ if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */
+ return 0;
+
+ if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts)) {
+ return 0;
+ }
+
+ pgcN = pgcn;
+ pgN = pgn;
+
+ (vm->state).TT_PGCN_REG = pgcN;
+ (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
+ assert( (vm->state.TTN_REG) != 0 );
+ (vm->state).VTS_TTN_REG = vts_ttn;
+ (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to
it easily from TTN_REG */
+ /* Any other registers? */
+
+ res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but
we don't want clobbering here. */
+ (vm->state).pgN = pgN;
+ vm_get_current_title_part(vm, &title, &part);
+ (vm->state).PTTN_REG = part;
+ return res;
+}
+
static int set_FP_PGC(vm_t *vm) {
(vm->state).domain = FP_DOMAIN;
if (!vm->vmgi->first_play_pgc) {
diff -Naur libdvdnav.orig/src/vm/vm.h libdvdnav/src/vm/vm.h
--- libdvdnav.orig/src/vm/vm.h 2009-03-13 18:28:22.000000000 -0700
+++ libdvdnav/src/vm/vm.h 2009-04-30 10:57:02.000000000 -0700
@@ -139,6 +139,7 @@
int vm_jump_pg(vm_t *vm, int pg);
int vm_jump_cell_block(vm_t *vm, int cell, int block);
int vm_jump_title_part(vm_t *vm, int title, int part);
+int vm_jump_title_program(vm_t *vm, int title, int pgcn, int pgn);
int vm_jump_top_pg(vm_t *vm);
int vm_jump_next_pg(vm_t *vm);
int vm_jump_prev_pg(vm_t *vm);
# the bit tested here does not indicate 'random or shuffle' - it only says
# that the title uses multiple PGCs. Since libdvdnav mostly deals correctly
# with mult PGC titles (modulo some weirdness when seeking) we need the
# state to get set correctly.
--- libdvdnav/src/vm/vm.c.orig 2009-05-13 20:44:12.000000000 -0700
+++ libdvdnav/src/vm/vm.c 2009-05-13 20:46:02.000000000 -0700
@@ -1758,14 +1758,10 @@
if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts)
return 0; /* ?? */
pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty;
- if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) {
+
int dummy, part;
vm_get_current_title_part(vm, &dummy, &part);
(vm->state).PTTN_REG = part;
- } else {
- /* FIXME: Handle RANDOM or SHUFFLE titles. */
- fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled
yet.\n");
- }
}
return 1;
}
diff -Naur libdvdnav.orig/src/vm/vm.c libdvdnav/src/vm/vm.c
--- libdvdnav.orig/src/vm/vm.c 2009-03-13 18:28:22.000000000 -0700
+++ libdvdnav/src/vm/vm.c 2009-06-02 13:50:06.000000000 -0700
@@ -354,8 +354,6 @@
fprintf(MSG_OUT, "libdvdnav: vm: failed to open/read the DVD\n");
return 0;
}
- dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
- vm->map = remap_loadmap(vm->dvd_name);
vm->vmgi = ifoOpenVMGI(vm->dvd);
if(!vm->vmgi) {
fprintf(MSG_OUT, "libdvdnav: vm: failed to read VIDEO_TS.IFO\n");
@@ -386,6 +384,8 @@
/* return 0; Not really used for now.. */
}
/* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */
+ dvd_read_name(vm->dvd_name, vm->dvd_serial, dvdroot);
+ vm->map = remap_loadmap(vm->dvd_name);
}
if (vm->vmgi) {
int i, mask;
_______________________________________________
DVDnav-discuss mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/dvdnav-discuss