Skip to content

Commit

Permalink
libmythdvdnav: Resync dvdnav and dvdread.
Browse files Browse the repository at this point in the history
This covers upstream SVN revisions 1216-1226.  Covers the following changes:

libdvdnav:

* Prevent abort if a menu doesn't exist.
* Fix typos
* Fix grammar in dvdnav.h
* Fix typos in comments

libdvdread:

* Provide BUP file support for more issues.
* Mark a large number of functions not used outside of the file as static.
* Fix some spelling issues
* Move UDFReadBlocksRaw declaration to dvdread_internal.h.
* Inhibit double free of parental management information
* Replaces the hard-coded values (in parental management)
* Report which index failed reading

Fixes #9828.  The ticket contained a patch which purports to fix additional memory leaks in the upstream copy, but I'm going to insist that that patch be applied upstream first for my sanity's sake.  Given the slow rate of change in libdvdnav and libdvdread, I am willing to perform a resync when pinged on this after it's committed there.

Tested this resync with local, disc, and myth:// playback of ISOs and DVDs.
  • Loading branch information
Robert McNamara committed Jun 6, 2011
1 parent aac2eee commit bfdbc77
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 38 deletions.
30 changes: 15 additions & 15 deletions mythtv/libs/libmythdvdnav/dvdnav/dvdnav.h
Expand Up @@ -183,7 +183,7 @@ dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int32_t *pgc_bas
*********************************************************************/

/*
* These functions are used to poll the playback enginge and actually get data
* These functions are used to poll the playback engine and actually get data
* off the DVD.
*/

Expand All @@ -207,7 +207,7 @@ dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, uint8_t *buf,
/*
* This basically does the same as dvdnav_get_next_block. The only difference is
* that it avoids a memcopy, when the requested block was found in the cache.
* I such a case (cache hit) this function will return a different pointer than
* In such a case (cache hit) this function will return a different pointer than
* the one handed in, pointing directly into the relevant block in the cache.
* Those pointers must _never_ be freed but instead returned to the library via
* dvdnav_free_cache_block().
Expand Down Expand Up @@ -326,7 +326,7 @@ dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu);

/*
* Return the title number and part currently being played.
* A title of 0 indicates, we are in a menu. In this case, part
* A title of 0 indicates we are in a menu. In this case, part
* is set to the current menu's ID.
*/
dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int32_t *title,
Expand Down Expand Up @@ -368,7 +368,7 @@ dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int32_t part);
* VOBU boundary before the given sector. The sector number is not
* meant to be an absolute physical DVD sector, but a relative sector
* in the current program. This function cannot leave the current
* program and will fail, if asked to do so.
* program and will fail if asked to do so.
*
* If program chain based positioning is enabled
* (see dvdnav_set_PGC_positioning_flag()), this will seek to the relative
Expand Down Expand Up @@ -402,7 +402,7 @@ int dvdnav_relative_time_search(dvdnav_t *self,

/*
* Stop playing current position and play the "GoUp"-program chain.
* (which generally leads to the title menu or a higer-level menu).
* (which generally leads to the title menu or a higher-level menu).
*/
dvdnav_status_t dvdnav_go_up(dvdnav_t *self);

Expand Down Expand Up @@ -442,12 +442,12 @@ dvdnav_status_t dvdnav_get_position(dvdnav_t *self, uint32_t *pos,

/*
* Most functions related to highlights take a NAV PCI packet as a parameter.
* While you can get the such a packet from libdvdnav, for players with internal
* FIFOs, this will result in errors, because due to the FIFO length, libdvdnav will
* be ahead in the stream compared to what the user is seeing on screen.
* Therefore, player applications who have a NAV packet available, which is
* better in sync with the actual playback should always pass this one to these
* functions.
* While you can get such a packet from libdvdnav, this will result in
* errors for players with internal FIFOs because due to the FIFO length,
* libdvdnav will be ahead in the stream compared to what the user is
* seeing on screen. Therefore, player applications who have a NAV
* packet available, which is better in sync with the actual playback,
* should always pass this one to these functions.
*/

/*
Expand Down Expand Up @@ -504,7 +504,7 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int32_t button)
dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int32_t button);

/*
* Activate (press) a button and execute specified command.
* Activate ("press") a button and execute specified command.
*/
dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd);

Expand Down Expand Up @@ -554,7 +554,7 @@ dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *self,
/*
* Return a string describing the title of the DVD.
* This is an ID string encoded on the disc by the author. In many cases
* this is a descriptive string such as `THE_MATRIX' but sometimes is sigularly
* this is a descriptive string such as `THE_MATRIX' but sometimes is singularly
* uninformative such as `PDVD-011421'. Some DVD authors even forget to set this,
* so you may also read the default of the authoring software they used, like
* `DVDVolume'.
Expand Down Expand Up @@ -610,7 +610,7 @@ uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream);
uint16_t dvdnav_audio_stream_format(dvdnav_t *self, uint8_t stream);

/*
* Returns number of channelsn in *logical* audio stream 'stream'
* Returns number of channels in *logical* audio stream 'stream'
* (returns 0xffff if no such stream).
*/
uint16_t dvdnav_audio_stream_channels(dvdnav_t *self, uint8_t stream);
Expand Down Expand Up @@ -684,7 +684,7 @@ user_ops_t dvdnav_get_restrictions(dvdnav_t *self);
*/

/*
* Sets the current angle. If you try to follow a non existant angle
* Sets the current angle. If you try to follow a non existent angle
* the call fails.
*/
dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int32_t angle);
Expand Down
4 changes: 2 additions & 2 deletions mythtv/libs/libmythdvdnav/dvdnav/highlight.c
Expand Up @@ -368,7 +368,7 @@ dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) {

button_ptr = get_current_button(this, pci);
/* Finally, make the VM execute the appropriate code and probably
* scedule a jump */
* schedule a jump */
#ifdef BUTTON_TESTING
fprintf(MSG_OUT, "libdvdnav: Evaluating Button Activation commands.\n");
#endif
Expand Down Expand Up @@ -425,7 +425,7 @@ dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int32_t button)
}

this->vm->state.HL_BTNN_REG = (button << 10);
this->position_current.button = -1; /* Force Highligh change */
this->position_current.button = -1; /* Force Highlight change */

return DVDNAV_STATUS_OK;
}
Expand Down
59 changes: 48 additions & 11 deletions mythtv/libs/libmythdvdnav/dvdnav/vm/vm.c
Expand Up @@ -610,19 +610,23 @@ int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) {
switch(menuid) {
case DVD_MENU_Title:
case DVD_MENU_Escape:
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
return 0;
}
(vm->state).domain = VMGM_DOMAIN;
break;
case DVD_MENU_Root:
case DVD_MENU_Subpicture:
case DVD_MENU_Audio:
case DVD_MENU_Angle:
case DVD_MENU_Part:
if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
return 0;
}
(vm->state).domain = VTSM_DOMAIN;
break;
}
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL)
return 0;
else if(get_PGCIT(vm) && set_MENU(vm, menuid)) {
if(get_PGCIT(vm) && set_MENU(vm, menuid)) {
process_command(vm, play_PGC(vm));
return 1; /* Jump */
} else {
Expand Down Expand Up @@ -1469,8 +1473,9 @@ static int process_command(vm_t *vm, link_t link_values) {
if(link_values.data2 != 0)
(vm->state).HL_BTNN_REG = link_values.data2 << 10;
if(!set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1))
assert(0);
link_values = play_PG(vm);
link_values.command = Exit;
else
link_values = play_PG(vm);
break;
case LinkPGN:
/* Link to Program Number:data1 */
Expand Down Expand Up @@ -1515,8 +1520,9 @@ static int process_command(vm_t *vm, link_t link_values) {
/* Set SPRM1 and SPRM2 */
assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1))
assert(0);
link_values = play_PGC(vm);
link_values.command = Exit;
else
link_values = play_PGC(vm);
break;
case JumpVTS_PTT:
/* Jump to Part:data2 of Title:data1 in same VTS Title Domain */
Expand All @@ -1526,8 +1532,9 @@ static int process_command(vm_t *vm, link_t link_values) {
/* Set SPRM1 and SPRM2 */
assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */
if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2))
assert(0);
link_values = play_PGC_PG(vm, (vm->state).pgN);
link_values.command = Exit;
else
link_values = play_PGC_PG(vm, (vm->state).pgN);
break;

case JumpSS_FP:
Expand All @@ -1545,6 +1552,10 @@ static int process_command(vm_t *vm, link_t link_values) {
/* Allowed from anywhere except the VTS Title domain */
/* Stop SPRM9 Timer and any GPRM counters */
assert((vm->state).domain != VTS_DOMAIN); /* ?? */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
(vm->state).domain = VMGM_DOMAIN;
if(!set_MENU(vm, link_values.data1))
assert(0);
Expand All @@ -1561,14 +1572,22 @@ static int process_command(vm_t *vm, link_t link_values) {
if (link_values.data1 != (vm->state).vtsN) {
/* the normal case */
assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
(vm->state).domain = VTSM_DOMAIN;
if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1)) /* Also sets (vm->state).vtsN */
assert(0);
if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
(vm->state).domain = VTSM_DOMAIN;
} else {
/* This happens on some discs like "Captain Scarlet & the Mysterons" or
* the German RC2 of "Anatomie" in VTSM. */
assert((vm->state).domain == VTSM_DOMAIN ||
(vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */
if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
(vm->state).domain = VTSM_DOMAIN;
}
} else {
Expand All @@ -1590,6 +1609,10 @@ static int process_command(vm_t *vm, link_t link_values) {
/* set_PGCN:data1 */
/* Stop SPRM9 Timer and any GPRM counters */
assert((vm->state).domain != VTS_DOMAIN); /* ?? */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
(vm->state).domain = VMGM_DOMAIN;
if(!set_PGCN(vm, link_values.data1))
assert(0);
Expand All @@ -1609,6 +1632,10 @@ static int process_command(vm_t *vm, link_t link_values) {
/* set_RSMinfo:data2 */
assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
(vm->state).domain = VMGM_DOMAIN;
if(!set_MENU(vm, link_values.data1))
Expand All @@ -1620,6 +1647,10 @@ static int process_command(vm_t *vm, link_t link_values) {
/* set_RSMinfo:data2 */
assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
if(vm->vtsi == NULL || vm->vtsi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
(vm->state).domain = VTSM_DOMAIN;
if(!set_MENU(vm, link_values.data1))
Expand All @@ -1631,6 +1662,10 @@ static int process_command(vm_t *vm, link_t link_values) {
/* set_RSMinfo:data2 */
assert((vm->state).domain == VTS_DOMAIN); /* ?? */
/* Must be called before domain is changed */
if(vm->vmgi == NULL || vm->vmgi->pgci_ut == NULL) {
link_values.command = Exit;
break;
}
set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0);
(vm->state).domain = VMGM_DOMAIN;
if(!set_PGCN(vm, link_values.data1))
Expand Down Expand Up @@ -1691,7 +1726,9 @@ static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) {
(vm->state).TT_PGCN_REG = pgcN;
(vm->state).PTTN_REG = part;
(vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn);
assert( (vm->state.TTN_REG) != 0 );
if( (vm->state.TTN_REG) == 0 )
return 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? */
Expand Down
6 changes: 1 addition & 5 deletions mythtv/libs/libmythdvdnav/dvdread/dvd_udf.c
Expand Up @@ -37,14 +37,10 @@
#include <unistd.h>
#include <inttypes.h>

#include "dvdread_internal.h"
#include "dvdread/dvd_reader.h"
#include "dvdread/dvd_udf.h"

/* Private but located in/shared with dvd_reader.c */
extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
int encrypted );

/* It's required to either fail or deliver all the blocks asked for. */
static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data,
Expand Down
8 changes: 8 additions & 0 deletions mythtv/libs/libmythdvdnav/dvdread/dvdread_internal.h
Expand Up @@ -19,15 +19,23 @@
#ifndef LIBDVDREAD_DVDREAD_INTERNAL_H
#define LIBDVDREAD_DVDREAD_INTERNAL_H

#include <stdint.h>
#include <sys/types.h>

#ifdef _WIN32
#include <unistd.h>
#endif /* _WIN32 */

#include "dvdread/dvd_reader.h"

#define CHECK_VALUE(arg) \
if(!(arg)) { \
fprintf(stderr, "\n*** libdvdread: CHECK_VALUE failed in %s:%i ***" \
"\n*** for %s ***\n\n", \
__FILE__, __LINE__, # arg ); \
}

int UDFReadBlocksRaw(dvd_reader_t *device, uint32_t lb_number,
size_t block_count, unsigned char *data, int encrypted);

#endif /* LIBDVDREAD_DVDREAD_INTERNAL_H */
15 changes: 11 additions & 4 deletions mythtv/libs/libmythdvdnav/dvdread/ifo_read.c
Expand Up @@ -1325,6 +1325,9 @@ int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
ifofile->ptl_mait = 0;
return 0;
}
for(i = 0; i < ptl_mait->nr_of_countries; i++) {
ptl_mait->countries[i].pf_ptl_mai = NULL;
}

for(i = 0; i < ptl_mait->nr_of_countries; i++) {
if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_COUNTRY_SIZE))) {
Expand All @@ -1345,7 +1348,7 @@ int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
CHECK_ZERO(ptl_mait->countries[i].zero_1);
CHECK_ZERO(ptl_mait->countries[i].zero_2);
CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte
+ 8*2 * (ptl_mait->nr_of_vtss + 1) <= ptl_mait->last_byte + 1);
+ sizeof(pf_level_t) * (ptl_mait->nr_of_vtss + 1) <= ptl_mait->last_byte + 1);
}

for(i = 0; i < ptl_mait->nr_of_countries; i++) {
Expand All @@ -1354,21 +1357,24 @@ int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
if(!DVDFileSeek_(ifofile->file,
ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN
+ ptl_mait->countries[i].pf_ptl_mai_start_byte)) {
fprintf(stderr, "libdvdread: Unable to seek PTL_MAIT table.\n");
fprintf(stderr, "libdvdread: Unable to seek PTL_MAIT table at index %d.\n",i);
free(ptl_mait->countries);
free(ptl_mait);
ifofile->ptl_mait = NULL;
return 0;
}
info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t);
pf_temp = (uint16_t *)malloc(info_length);
if(!pf_temp) {
free_ptl_mait(ptl_mait, i);
ifofile->ptl_mait = NULL;
return 0;
}
if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table at index %d.\n",i);
free(pf_temp);
free_ptl_mait(ptl_mait, i);
ifofile->ptl_mait = NULL;
return 0;
}
for (j = 0; j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) {
Expand All @@ -1378,11 +1384,12 @@ int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) {
if(!ptl_mait->countries[i].pf_ptl_mai) {
free(pf_temp);
free_ptl_mait(ptl_mait, i);
ifofile->ptl_mait = NULL;
return 0;
}
{ /* Transpose the array so we can use C indexing. */
int level, vts;
for(level = 0; level < 8; level++) {
for(level = 0; level < PTL_MAIT_NUM_LEVEL; level++) {
for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) {
ptl_mait->countries[i].pf_ptl_mai[vts][level] =
pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts];
Expand Down
3 changes: 2 additions & 1 deletion mythtv/libs/libmythdvdnav/dvdread/ifo_types.h
Expand Up @@ -475,7 +475,8 @@ typedef struct {
* Parental Management Information Unit Table.
* Level 1 (US: G), ..., 7 (US: NC-17), 8
*/
typedef uint16_t pf_level_t[8];
#define PTL_MAIT_NUM_LEVEL 8
typedef uint16_t pf_level_t[PTL_MAIT_NUM_LEVEL];

/**
* Parental Management Information Unit Table.
Expand Down

0 comments on commit bfdbc77

Please sign in to comment.