Index: libhb/stream.c =================================================================== --- libhb/stream.c (revision 1129) +++ libhb/stream.c (working copy) @@ -108,22 +108,75 @@ static void hb_ps_stream_find_audio_ids(hb_stream_t *stream, hb_title_t *title); static off_t align_to_next_packet(FILE* f); -int hb_stream_is_stream_type( char * path ) + +static inline int check_ps_sync(const uint8_t *buf) { - if ((strstr(path,".mpg") != NULL) || - (strstr(path,".vob") != NULL) || - (strstr(path, ".VOB") != NULL) || - (strstr(path, ".mpeg") != NULL) || - (strstr(path,".ts") != NULL) || - (strstr(path, ".m2t") != NULL) || - (strstr(path, ".TS") != NULL)) - { - return 1; - } - else + // must have a Pack header + // (note: the operator '&' instead of '&&' is used deliberately for better + // performance with a multi-issue pipeline.) + return (buf[0] == 0x00) & (buf[1] == 0x00) & (buf[2] == 0x01) & (buf[3] == 0xba); +} + +static inline int check_ts_sync(const uint8_t *buf) +{ + // must have initial sync byte, no scrambling & a legal adaptation ctrl + return (buf[0] == 0x47) & ((buf[3] >> 6) == 0) & ((buf[3] >> 4) > 0); +} + +static inline int have_ts_sync(const uint8_t *buf) +{ + return check_ts_sync(&buf[0*188]) & check_ts_sync(&buf[1*188]) & + check_ts_sync(&buf[2*188]) & check_ts_sync(&buf[3*188]) & + check_ts_sync(&buf[4*188]) & check_ts_sync(&buf[5*188]) & + check_ts_sync(&buf[6*188]) & check_ts_sync(&buf[7*188]); +} + +static int hb_stream_check_for_ts(const uint8_t *buf) +{ + // transport streams should have a sync byte every 188 bytes. + // search the first KB of buf looking for at least 8 consecutive + // correctly located sync patterns. + int offset = 0; + + for ( offset = 0; offset < 1024; ++offset ) + { + if ( have_ts_sync( &buf[offset]) ) + return 1; + } return 0; } +static int hb_stream_check_for_ps(const uint8_t *buf) +{ + // program streams should have a Pack header every 2048 bytes. + // check that we have 4 of these. + return check_ps_sync(&buf[0*2048]) & check_ps_sync(&buf[1*2048]) & + check_ps_sync(&buf[2*2048]) & check_ps_sync(&buf[3*2048]); +} + +static int hb_stream_get_type(hb_stream_t *stream) +{ + uint8_t buf[2048*4]; + + if ( fread(buf, 1, sizeof(buf), stream->file_handle) == sizeof(buf) ) + { + if ( hb_stream_check_for_ts(buf) != 0 ) + { + hb_log("file is MPEG Transport Stream"); + stream->stream_type = hb_stream_type_transport; + hb_ts_stream_init(stream); + return 1; + } + if ( hb_stream_check_for_ps(buf) != 0 ) + { + hb_log("file is MPEG Program Stream"); + stream->stream_type = hb_stream_type_program; + return 1; + } + } + return 0; +} + /*********************************************************************** * hb_stream_open *********************************************************************** @@ -136,27 +189,20 @@ d = calloc( sizeof( hb_stream_t ), 1 ); /* Open device */ - if( !( d->file_handle = fopen( path, "rb" ) ) ) + if( ( d->file_handle = fopen( path, "rb" ) ) ) { + d->path = strdup( path ); + if ( hb_stream_get_type( d ) != 0 ) + { + return d; + } + fclose( d->file_handle ); + free( d->path ); + } + else + { hb_log( "hb_stream_open: fopen failed (%s)", path ); - goto fail; } - - d->path = strdup( path ); - - if ( ( strstr(d->path,".ts") != NULL) || ( strstr(d->path,".m2t") != NULL) || ( strstr(d->path,".TS") != NULL) ) - { - d->stream_type = hb_stream_type_transport; - hb_ts_stream_init(d); - } - else if (( strstr(d->path,".mpg") != NULL) || ( strstr(d->path,".vob") != NULL) || ( strstr(d->path,".mpeg") != NULL) || ( strstr(d->path,".VOB") != NULL)) - { - d->stream_type = hb_stream_type_program; - } - - return d; - -fail: free( d ); return NULL; } @@ -194,7 +240,7 @@ d->ts_packetbuf[i] = NULL; } } - + free( d->path ); free( d ); *_d = NULL; } Index: libhb/internal.h =================================================================== --- libhb/internal.h (revision 1129) +++ libhb/internal.h (working copy) @@ -133,14 +133,12 @@ int hb_dvd_is_break( hb_dvd_t * d ); void hb_dvd_close( hb_dvd_t ** ); -int hb_stream_is_stream_type( char * path); hb_stream_t * hb_stream_open( char * path ); void hb_stream_close( hb_stream_t ** ); hb_title_t * hb_stream_title_scan( hb_stream_t *); int hb_stream_read( hb_stream_t *, hb_buffer_t *); int hb_stream_seek( hb_stream_t *, float ); void hb_stream_update_audio( hb_stream_t *, hb_audio_t *); -void hb_stream_set_selected_audio_pid_index(hb_stream_t *, int); /*********************************************************************** * Work objects Index: libhb/scan.c =================================================================== --- libhb/scan.c (revision 1129) +++ libhb/scan.c (working copy) @@ -70,19 +70,14 @@ } } } + else if ( (data->stream = hb_stream_open (data->path)) != NULL ) + { + hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) ); + } else { - if ( hb_stream_is_stream_type(data->path) ) - { - hb_log( "scan: trying to open as MPEG-2 Stream"); - data->stream = hb_stream_open (data->path); - hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) ); - } - else - { - hb_log( "scan: unrecognized file type" ); - return; - } + hb_log( "scan: unrecognized file type" ); + return; } for( i = 0; i < hb_list_count( data->list_title ); )