summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/dvd.h1
-rw-r--r--libhb/dvdnav.c64
2 files changed, 65 insertions, 0 deletions
diff --git a/libhb/dvd.h b/libhb/dvd.h
index 8f89a82cc..811efe5b6 100644
--- a/libhb/dvd.h
+++ b/libhb/dvd.h
@@ -51,6 +51,7 @@ struct hb_dvdnav_s
int title;
int title_block_count;
int chapter;
+ int stopped;
};
typedef struct hb_dvdnav_s hb_dvdnav_t;
diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c
index c46d7faae..eee9d28b9 100644
--- a/libhb/dvdnav.c
+++ b/libhb/dvdnav.c
@@ -79,6 +79,54 @@ static char * hb_dvdnav_name( char * path )
}
/***********************************************************************
+ * hb_dvdnav_reset
+ ***********************************************************************
+ * Once dvdnav has entered the 'stopped' state, it can not be revived
+ * dvdnav_reset doesn't work because it doesn't remember the path
+ * So this function re-opens dvdnav
+ **********************************************************************/
+static int hb_dvdnav_reset( hb_dvdnav_t * d )
+{
+ if ( d->dvdnav )
+ dvdnav_close( d->dvdnav );
+
+ /* Open device */
+ if( dvdnav_open(&d->dvdnav, d->path) != DVDNAV_STATUS_OK )
+ {
+ /*
+ * Not an error, may be a stream - which we'll try in a moment.
+ */
+ hb_log( "dvd: not a dvd - trying as a stream/file instead" );
+ goto fail;
+ }
+
+ if (dvdnav_set_readahead_flag(d->dvdnav, DVD_READ_CACHE) !=
+ DVDNAV_STATUS_OK)
+ {
+ hb_error("Error: dvdnav_set_readahead_flag: %s\n",
+ dvdnav_err_to_string(d->dvdnav));
+ goto fail;
+ }
+
+ /*
+ ** set the PGC positioning flag to have position information
+ ** relatively to the whole feature instead of just relatively to the
+ ** current chapter
+ **/
+ if (dvdnav_set_PGC_positioning_flag(d->dvdnav, 1) != DVDNAV_STATUS_OK)
+ {
+ hb_error("Error: dvdnav_set_PGC_positioning_flag: %s\n",
+ dvdnav_err_to_string(d->dvdnav));
+ goto fail;
+ }
+ return 1;
+
+fail:
+ if( d->dvdnav ) dvdnav_close( d->dvdnav );
+ return 0;
+}
+
+/***********************************************************************
* hb_dvdnav_init
***********************************************************************
*
@@ -725,6 +773,10 @@ static int hb_dvdnav_start( hb_dvd_t * e, int title, int chapter )
}
ifoClose(ifo);
+ if ( d->stopped && !hb_dvdnav_reset(d) )
+ {
+ return 0;
+ }
if ( dvdnav_part_play(d->dvdnav, title, chapter) != DVDNAV_STATUS_OK )
{
hb_error( "dvd: dvdnav_title_play failed - %s",
@@ -732,6 +784,7 @@ static int hb_dvdnav_start( hb_dvd_t * e, int title, int chapter )
return 0;
}
d->title = title;
+ d->stopped = 0;
return 1;
}
@@ -742,6 +795,7 @@ static int hb_dvdnav_start( hb_dvd_t * e, int title, int chapter )
**********************************************************************/
static void hb_dvdnav_stop( hb_dvd_t * e )
{
+ hb_dvdnav_t * d = &(e->dvdnav);
}
/***********************************************************************
@@ -757,6 +811,10 @@ static int hb_dvdnav_seek( hb_dvd_t * e, float f )
uint8_t buf[HB_DVD_READ_BUFFER_SIZE];
int done = 0, ii;
+ if (d->stopped)
+ {
+ return 0;
+ }
// dvdnav will not let you seek or poll current position
// till it reaches a certain point in parsing. so we
// have to get blocks until we reach a cell
@@ -784,6 +842,7 @@ static int hb_dvdnav_seek( hb_dvd_t * e, float f )
break;
case DVDNAV_STOP:
+ d->stopped = 1;
return 0;
case DVDNAV_HOP_CHANNEL:
@@ -822,6 +881,10 @@ static int hb_dvdnav_read( hb_dvd_t * e, hb_buffer_t * b )
while ( 1 )
{
+ if (d->stopped)
+ {
+ return 0;
+ }
result = dvdnav_get_next_block( d->dvdnav, b->data, &event, &len );
if ( result == DVDNAV_STATUS_ERR )
{
@@ -964,6 +1027,7 @@ static int hb_dvdnav_read( hb_dvd_t * e, hb_buffer_t * b )
/*
* Playback should end here.
*/
+ d->stopped = 1;
return 0;
default: