diff options
author | jstebbins <[email protected]> | 2015-06-29 16:05:38 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2015-06-29 16:05:38 +0000 |
commit | 10f6690cfa1ebbd5a837e03f70d011b51ea7690a (patch) | |
tree | 7cbd3196b1367cade621ae14fe932778bc4d86bd | |
parent | af9de404779378e28af413d18291975dedd68861 (diff) |
libhb: detect read errors and propagate
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@7332 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/bd.c | 34 | ||||
-rw-r--r-- | libhb/common.h | 11 | ||||
-rw-r--r-- | libhb/dvd.c | 13 | ||||
-rw-r--r-- | libhb/dvd.h | 4 | ||||
-rw-r--r-- | libhb/dvdnav.c | 12 | ||||
-rw-r--r-- | libhb/hb.c | 5 | ||||
-rw-r--r-- | libhb/internal.h | 3 | ||||
-rw-r--r-- | libhb/reader.c | 2 | ||||
-rw-r--r-- | libhb/scan.c | 2 | ||||
-rw-r--r-- | libhb/stream.c | 32 |
10 files changed, 92 insertions, 26 deletions
diff --git a/libhb/bd.c b/libhb/bd.c index 44b8a2e26..7da108c50 100644 --- a/libhb/bd.c +++ b/libhb/bd.c @@ -719,13 +719,14 @@ hb_buffer_t * hb_bd_read( hb_bd_t * d ) if (error_count > 10) { hb_error("bd: Error, too many consecutive read errors"); - return 0; + hb_set_work_error(d->h, HB_ERROR_READ); + return NULL; } continue; } else if ( result == 0 ) { - return 0; + return NULL; } error_count = 0; @@ -827,7 +828,8 @@ static int have_ts_sync(const uint8_t *buf, int psize) static uint64_t align_to_next_packet(BLURAY *bd, uint8_t *pkt) { - uint8_t buf[MAX_HOLE]; + int result; + uint8_t buf[MAX_HOLE]; uint64_t pos = 0; uint64_t start = bd_tell(bd); uint64_t orig; @@ -841,7 +843,8 @@ static uint64_t align_to_next_packet(BLURAY *bd, uint8_t *pkt) while (1) { - if (bd_read(bd, buf+off, sizeof(buf)-off) == sizeof(buf)-off) + result = bd_read(bd, buf + off, sizeof(buf) - off); + if (result == sizeof(buf) - off) { const uint8_t *bp = buf; int i; @@ -862,6 +865,10 @@ static uint64_t align_to_next_packet(BLURAY *bd, uint8_t *pkt) memcpy(buf, buf + sizeof(buf) - off, off); start += sizeof(buf) - off; } + else if (result < 0) + { + return -1; + } else { return 0; @@ -874,9 +881,14 @@ static uint64_t align_to_next_packet(BLURAY *bd, uint8_t *pkt) bd_seek(bd, off); while (off > bd_tell(bd)) { - if (bd_read(bd, buf, 192) != 192) + result = bd_read(bd, buf, 192); + if (result < 0) { - break; + return -1; + } + else if (result != 192) + { + return 0; } } return start - orig + pos; @@ -905,12 +917,16 @@ static int next_packet( BLURAY *bd, uint8_t *pkt ) // lost sync - back up to where we started then try to re-establish. uint64_t pos = bd_tell(bd); uint64_t pos2 = align_to_next_packet(bd, pkt); - if ( pos2 == 0 ) + if (pos2 < 0) + { + return -1; + } + else if (pos2 == 0) { - hb_log( "next_packet: eof while re-establishing sync @ %"PRIu64"", pos ); + hb_log("next_packet: eof while re-establishing sync @ %"PRIu64"", pos ); return 0; } - hb_log( "next_packet: sync lost @ %"PRIu64", regained after %"PRIu64" bytes", + hb_log("next_packet: sync lost @ %"PRIu64", regained after %"PRIu64" bytes", pos, pos2 ); } } diff --git a/libhb/common.h b/libhb/common.h index d088ad8fd..d1fe73335 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -108,11 +108,12 @@ typedef struct hb_fifo_s hb_fifo_t; typedef struct hb_lock_s hb_lock_t; typedef enum { - HB_ERROR_NONE = 0, - HB_ERROR_CANCELED , - HB_ERROR_WRONG_INPUT, - HB_ERROR_INIT , - HB_ERROR_UNKNOWN + HB_ERROR_NONE = 0, + HB_ERROR_CANCELED = 1, + HB_ERROR_WRONG_INPUT = 2, + HB_ERROR_INIT = 3, + HB_ERROR_UNKNOWN = 4, + HB_ERROR_READ = 5 } hb_error_code; #include "ports.h" diff --git a/libhb/dvd.c b/libhb/dvd.c index 99e8a142e..082057bad 100644 --- a/libhb/dvd.c +++ b/libhb/dvd.c @@ -15,7 +15,7 @@ #include "dvdread/ifo_print.h" #include "dvdread/nav_read.h" -static hb_dvd_t * hb_dvdread_init( char * path ); +static hb_dvd_t * hb_dvdread_init( hb_handle_t * h, char * path ); static void hb_dvdread_close( hb_dvd_t ** _d ); static char * hb_dvdread_name( char * path ); static int hb_dvdread_title_count( hb_dvd_t * d ); @@ -106,7 +106,7 @@ static char * hb_dvdread_name( char * path ) *********************************************************************** * **********************************************************************/ -hb_dvd_t * hb_dvdread_init( char * path ) +hb_dvd_t * hb_dvdread_init( hb_handle_t * h, char * path ) { hb_dvd_t * e; hb_dvdread_t * d; @@ -115,6 +115,7 @@ hb_dvd_t * hb_dvdread_init( char * path ) e = calloc( sizeof( hb_dvd_t ), 1 ); d = &(e->dvdread); + d->h = h; /* * Convert UTF-8 path to current code page on Windows @@ -890,6 +891,7 @@ static hb_buffer_t * hb_dvdread_read( hb_dvd_t * e ) if ( d->cell_cur > d->cell_end ) { hb_buffer_close( &b ); + hb_set_work_error(d->h, HB_ERROR_READ); return NULL; } d->in_cell = 0; @@ -988,8 +990,9 @@ static hb_buffer_t * hb_dvdread_read( hb_dvd_t * e ) /* Wasn't a valid VOBU, try next block */ if( ++error > 1024 ) { - hb_log( "dvd: couldn't find a VOBU after 1024 blocks" ); + hb_error( "dvd: couldn't find a VOBU after 1024 blocks" ); hb_buffer_close( &b ); + hb_set_work_error(d->h, HB_ERROR_READ); return NULL; } @@ -1269,9 +1272,9 @@ char * hb_dvd_name( char * path ) return dvd_methods->name(path); } -hb_dvd_t * hb_dvd_init( char * path ) +hb_dvd_t * hb_dvd_init( hb_handle_t * h, char * path ) { - return dvd_methods->init(path); + return dvd_methods->init(h, path); } int hb_dvd_title_count( hb_dvd_t * d ) diff --git a/libhb/dvd.h b/libhb/dvd.h index 24f4f1e30..55153381f 100644 --- a/libhb/dvd.h +++ b/libhb/dvd.h @@ -42,6 +42,7 @@ struct hb_dvdread_s int in_sync; uint16_t cur_vob_id; uint8_t cur_cell_id; + hb_handle_t * h; }; struct hb_dvdnav_s @@ -57,6 +58,7 @@ struct hb_dvdnav_s int cell; hb_list_t * list_chapter; int stopped; + hb_handle_t * h; }; typedef struct hb_dvdnav_s hb_dvdnav_t; @@ -71,7 +73,7 @@ union hb_dvd_s struct hb_dvd_func_s { - hb_dvd_t * (* init) ( char * ); + hb_dvd_t * (* init) ( hb_handle_t *, char * ); void (* close) ( hb_dvd_t ** ); char * (* name) ( char * ); int (* title_count) ( hb_dvd_t * ); diff --git a/libhb/dvdnav.c b/libhb/dvdnav.c index 1999f6f9d..09dc411f8 100644 --- a/libhb/dvdnav.c +++ b/libhb/dvdnav.c @@ -19,7 +19,7 @@ #define DVD_READ_CACHE 1 static char * hb_dvdnav_name( char * path ); -static hb_dvd_t * hb_dvdnav_init( char * path ); +static hb_dvd_t * hb_dvdnav_init( hb_handle_t * h, char * path ); static int hb_dvdnav_title_count( hb_dvd_t * d ); static hb_title_t * hb_dvdnav_title_scan( hb_dvd_t * d, int t, uint64_t min_duration ); static int hb_dvdnav_start( hb_dvd_t * d, hb_title_t *title, int chapter ); @@ -148,7 +148,7 @@ fail: *********************************************************************** * **********************************************************************/ -static hb_dvd_t * hb_dvdnav_init( char * path ) +static hb_dvd_t * hb_dvdnav_init( hb_handle_t * h, char * path ) { hb_dvd_t * e; hb_dvdnav_t * d; @@ -157,6 +157,7 @@ static hb_dvd_t * hb_dvdnav_init( char * path ) e = calloc( sizeof( hb_dvd_t ), 1 ); d = &(e->dvdnav); + d->h = h; /* * Convert UTF-8 path to current code page on Windows @@ -1627,6 +1628,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) hb_error( "dvd: dvdnav_sector_search failed - %s", dvdnav_err_to_string(d->dvdnav) ); hb_buffer_close( &b ); + hb_set_work_error(d->h, HB_ERROR_READ); return NULL; } error_count++; @@ -1634,6 +1636,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) { hb_error("dvdnav: Error, too many consecutive read errors"); hb_buffer_close( &b ); + hb_set_work_error(d->h, HB_ERROR_READ); return NULL; } continue; @@ -1726,6 +1729,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) { // Transition to another title signals that we are done. hb_buffer_close( &b ); + hb_deep_log(2, "dvdnav: vts change, found next title"); return NULL; } } @@ -1749,6 +1753,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) { // Transition to another title signals that we are done. hb_buffer_close( &b ); + hb_deep_log(2, "dvdnav: cell change, found next title"); return NULL; } c = FindChapterIndex(d->list_chapter, pgcn, pgn); @@ -1759,6 +1764,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) // Some titles end with a 'link' back to the beginning so // a transition to an earlier chapter means we're done. hb_buffer_close( &b ); + hb_deep_log(2, "dvdnav: cell change, previous chapter"); return NULL; } chapter = d->chapter = c; @@ -1766,6 +1772,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) else if ( cell_event->cellN <= d->cell ) { hb_buffer_close( &b ); + hb_deep_log(2, "dvdnav: cell change, previous cell"); return NULL; } d->cell = cell_event->cellN; @@ -1808,6 +1815,7 @@ static hb_buffer_t * hb_dvdnav_read( hb_dvd_t * e ) */ d->stopped = 1; hb_buffer_close( &b ); + hb_deep_log(2, "dvdnav: stop"); return NULL; default: diff --git a/libhb/hb.c b/libhb/hb.c index 513c27e62..a3e373b0f 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -1819,6 +1819,11 @@ void hb_set_state( hb_handle_t * h, hb_state_t * s ) hb_unlock( h->pause_lock ); } +void hb_set_work_error( hb_handle_t * h, hb_error_code err ) +{ + h->work_error = err; +} + void hb_system_sleep_allow(hb_handle_t *h) { hb_system_sleep_private_enable(h->system_sleep_opaque); diff --git a/libhb/internal.h b/libhb/internal.h index 30d8c24c8..4be0dffc3 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -48,6 +48,7 @@ void hb_title_close( hb_title_t ** ); **********************************************************************/ int hb_get_pid( hb_handle_t * ); void hb_set_state( hb_handle_t *, hb_state_t * ); +void hb_set_work_error( hb_handle_t * h, hb_error_code err ); void hb_job_setup_passes(hb_handle_t *h, hb_job_t *job, hb_list_t *list_pass); /*********************************************************************** @@ -327,7 +328,7 @@ typedef struct hb_bd_s hb_bd_t; typedef union hb_dvd_s hb_dvd_t; typedef struct hb_stream_s hb_stream_t; -hb_dvd_t * hb_dvd_init( char * path ); +hb_dvd_t * hb_dvd_init( hb_handle_t * h, char * path ); int hb_dvd_title_count( hb_dvd_t * ); hb_title_t * hb_dvd_title_scan( hb_dvd_t *, int title, uint64_t min_duration ); int hb_dvd_start( hb_dvd_t *, hb_title_t *title, int chapter ); diff --git a/libhb/reader.c b/libhb/reader.c index d730c1f09..9c742e6fd 100644 --- a/libhb/reader.c +++ b/libhb/reader.c @@ -81,7 +81,7 @@ static int hb_reader_open( hb_work_private_t * r ) } else if ( r->title->type == HB_DVD_TYPE ) { - if ( !( r->dvd = hb_dvd_init( r->title->path ) ) ) + if ( !( r->dvd = hb_dvd_init( r->h, r->title->path ) ) ) return 1; } else if ( r->title->type == HB_STREAM_TYPE || diff --git a/libhb/scan.c b/libhb/scan.c index a446344cd..56a256f8b 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -126,7 +126,7 @@ static void ScanFunc( void * _data ) data->title_set->list_title ); } } - else if( ( data->dvd = hb_dvd_init( data->path ) ) ) + else if( ( data->dvd = hb_dvd_init( data->h, data->path ) ) ) { hb_log( "scan: DVD has %d title(s)", hb_dvd_title_count( data->dvd ) ); diff --git a/libhb/stream.c b/libhb/stream.c index cb669e52f..e404513e0 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -1125,6 +1125,12 @@ static const uint8_t *next_packet( hb_stream_t *stream ) if ( fread(stream->ts.packet, 1, stream->packetsize, stream->file_handle) != stream->packetsize ) { + int err; + if ((err = ferror(stream->file_handle)) != 0) + { + hb_error("next_packet: error (%d)", err); + hb_set_work_error(stream->h, HB_ERROR_READ); + } return NULL; } if (buf[0] == 0x47) @@ -2408,6 +2414,12 @@ static off_t align_to_next_packet(hb_stream_t *stream) } else { + int err; + if ((err = ferror(stream->file_handle)) != 0) + { + hb_error("align_to_next_packet: error (%d)", err); + hb_set_work_error(stream->h, HB_ERROR_READ); + } return 0; } } @@ -3352,9 +3364,18 @@ static int hb_ps_read_packet( hb_stream_t * stream, hb_buffer_t *b ) pos -= 4; fseeko( stream->file_handle, -4, SEEK_CUR ); } + done: // Parse packet for information we might need funlockfile( stream->file_handle ); + + int err; + if ((err = ferror(stream->file_handle)) != 0) + { + hb_error("hb_ps_read_packet: error (%d)", err); + hb_set_work_error(stream->h, HB_ERROR_READ); + } + int len = pos - b->size; b->size = pos; #undef cp @@ -5657,8 +5678,17 @@ hb_buffer_t * hb_ffmpeg_read( hb_stream_t *stream ) // use M$ 'packed b-frames' and occasionally have negative // sizes for the null frames these require. if ( err != AVERROR(ENOMEM) || stream->ffmpeg_pkt->size >= 0 ) - // eof + { + // error or eof + if (err != AVERROR_EOF) + { + char errstr[80]; + av_strerror(err, errstr, 80); + hb_error("av_read_frame error (%d): %s", err, errstr); + hb_set_work_error(stream->h, HB_ERROR_READ); + } return NULL; + } } if ( stream->ffmpeg_pkt->stream_index == stream->ffmpeg_video_id ) { |