rendered paste bodyIndex: libhb/reader.c===================================================================--- libhb/reader.c (revision 1345)+++ libhb/reader.c (working copy)@@ -68,7 +68,7 @@ if( !( r->dvd = hb_dvd_init( r->title->dvd ) ) ) {- if ( !(r->stream = hb_stream_open(r->title->dvd) ) )+ if ( !( r->stream = hb_stream_open( r->title->dvd, 1 ) ) ) { return; }Index: libhb/stream.c===================================================================--- libhb/stream.c (revision 1345)+++ libhb/stream.c (working copy)@@ -12,77 +12,92 @@ #define min(a, b) a < b ? a : b -typedef enum { hb_stream_type_unknown = 0, hb_stream_type_transport, hb_stream_type_program } hb_stream_type_t;+typedef enum {+ hb_stream_type_unknown = 0,+ hb_stream_type_transport,+ hb_stream_type_program+} hb_stream_type_t; #define kMaxNumberVideoPIDS 1-#define kMaxNumberAudioPIDS 16+#define kMaxNumberAudioPIDS 15 #define kMaxNumberDecodeStreams (kMaxNumberVideoPIDS+kMaxNumberAudioPIDS) #define kMaxNumberPMTStreams 32 struct hb_stream_s {- char * path;- FILE * file_handle;- hb_stream_type_t stream_type;+ int frames; /* video frames so far */+ int errors; /* total errors so far */+ int last_error_frame; /* frame # at last error message */+ int last_error_count; /* # errors at last error message */ - int frames; /* video frames so far */- int errors; /* total errors so far */- int last_error_frame; /* frame # at last error message */- int last_error_count; /* # errors at last error message */+ int64_t ts_lastpcr; /* the last pcr we found in the TS stream */+ int64_t ts_nextpcr; /* the next pcr to put in a PS packet */ - int64_t ts_lastpcr; /* the last pcr we found in the TS stream */- int64_t ts_nextpcr; /* the next pcr to put in a PS packet */+ uint8_t *ts_buf[kMaxNumberDecodeStreams];+ int ts_pos[kMaxNumberDecodeStreams];+ int8_t ts_foundfirst[kMaxNumberDecodeStreams];+ int8_t ts_skipbad[kMaxNumberDecodeStreams];+ int8_t ts_streamcont[kMaxNumberDecodeStreams];+ int8_t ts_start[kMaxNumberDecodeStreams]; - int ts_video_pids[kMaxNumberVideoPIDS];- int ts_audio_pids[kMaxNumberAudioPIDS];+ uint8_t *fwrite_buf; /* PS buffer (set by hb_ts_stream_decode) */+ uint8_t *fwrite_buf_orig; /* PS buffer start (set by hb_ts_stream_decode) */ - int ts_number_video_pids;- int ts_number_audio_pids;+ /*+ * Stuff before this point is dynamic state updated as we read the+ * stream. Stuff after this point is stream description state that+ * we learn during the initial scan but cache so it can be+ * reused during the conversion read.+ */+ int16_t ts_video_pids[kMaxNumberVideoPIDS];+ int16_t ts_audio_pids[kMaxNumberAudioPIDS]; - uint8_t *ts_buf[kMaxNumberDecodeStreams];- int ts_pos[kMaxNumberDecodeStreams];- int ts_streamid[kMaxNumberDecodeStreams];- int ts_audio_stream_type[kMaxNumberDecodeStreams];- int8_t ts_foundfirst[kMaxNumberDecodeStreams];- int8_t ts_skipbad[kMaxNumberDecodeStreams];- int8_t ts_streamcont[kMaxNumberDecodeStreams];- int8_t ts_start[kMaxNumberDecodeStreams];+ uint8_t ts_number_video_pids;+ uint8_t ts_number_audio_pids; - struct {- int lang_code;- int flags;- int rate;- int bitrate;- } a52_info[kMaxNumberAudioPIDS];+ uint8_t ts_streamid[kMaxNumberDecodeStreams];+ uint8_t ts_audio_stream_type[kMaxNumberDecodeStreams]; - struct- {- unsigned short program_number;- unsigned short program_map_PID;- } pat_info[kMaxNumberPMTStreams];- int ts_number_pat_entries;+ char *path;+ FILE *file_handle;+ hb_stream_type_t stream_type;+ int opentype; - struct- {- int reading;- unsigned char *tablebuf;- unsigned int tablepos;- unsigned char current_continuity_counter;+ struct {+ int lang_code;+ int flags;+ int rate;+ int bitrate;+ } a52_info[kMaxNumberAudioPIDS]; - int section_length;- int program_number;- unsigned int PCR_PID;- int program_info_length;- unsigned char *progam_info_descriptor_data;- struct- {- unsigned char stream_type;- unsigned short elementary_PID;- unsigned short ES_info_length;- unsigned char *es_info_descriptor_data;- } pmt_stream_info[kMaxNumberPMTStreams];- } pmt_info;+ struct+ {+ unsigned short program_number;+ unsigned short program_map_PID;+ } pat_info[kMaxNumberPMTStreams];+ int ts_number_pat_entries;++ struct+ {+ int reading;+ unsigned char *tablebuf;+ unsigned int tablepos;+ unsigned char current_continuity_counter;++ int section_length;+ int program_number;+ unsigned int PCR_PID;+ int program_info_length;+ unsigned char *progam_info_descriptor_data;+ struct+ {+ unsigned char stream_type;+ unsigned short elementary_PID;+ unsigned short ES_info_length;+ unsigned char *es_info_descriptor_data;+ } pmt_stream_info[kMaxNumberPMTStreams];+ } pmt_info; }; /***********************************************************************@@ -101,13 +116,36 @@ /* * streams have a bunch of state that's learned during the scan. We don't * want to throw away the state when scan does a close then relearn- * everything when reader does an open. So we basically ignore- * a stream close, remember the most recent stream we've opened and only- * delete it when a stream of a different name is opened.+ * everything when reader does an open. So we save the stream state on+ * the close following a scan and reuse it when 'reader' does an open. */-static hb_stream_t *current_stream;+static hb_list_t *stream_state_list; +static hb_stream_t *hb_stream_lookup( const char *path )+{+ if ( stream_state_list == NULL )+ return NULL; + hb_stream_t *ss;+ int i = 0;++ while ( ( ss = hb_list_item( stream_state_list, i++ ) ) != NULL )+ {+ if ( strcmp( path, ss->path ) == 0 )+ {+ break;+ }+ }+ return ss;+}++static void hb_stream_state_delete( hb_stream_t *ss )+{+ hb_list_rem( stream_state_list, ss );+ free( ss->path );+ free( ss );+}+ static inline int check_ps_sync(const uint8_t *buf) { // a legal MPEG program stream must start with a Pack header in the@@ -176,10 +214,8 @@ return 0; } -static void hb_stream_delete( hb_stream_t ** _d )+static void hb_stream_delete_dynamic( hb_stream_t *d ) {- hb_stream_t * d = *_d;- if( d->file_handle ) { fclose( d->file_handle );@@ -196,9 +232,13 @@ d->ts_buf[i] = NULL; } }+}++static void hb_stream_delete( hb_stream_t *d )+{+ hb_stream_delete_dynamic( d ); free( d->path ); free( d );- *_d = NULL; } /***********************************************************************@@ -206,33 +246,84 @@ *********************************************************************** * **********************************************************************/-hb_stream_t * hb_stream_open( char * path )+hb_stream_t * hb_stream_open( char *path, int opentype ) {- if (current_stream)++ FILE *f = fopen( path, "r" );+ if ( f == NULL ) {- if (strcmp( path, current_stream->path ) == 0 )- {- hb_stream_seek( current_stream, 0. );- return current_stream;- }- hb_stream_delete( ¤t_stream );+ hb_log( "hb_stream_open: open %s failed", path );+ return NULL; }+ hb_stream_t *d = calloc( sizeof( hb_stream_t ), 1 );+ if ( d == NULL )+ {+ fclose( f );+ hb_log( "hb_stream_open: can't allocate space for %s stream state", path );+ return NULL;+ } - /* open the file and see if it's a type we know about. return a stream- * reference structure if we can deal with it & NULL otherwise. */- if( ( d->file_handle = fopen( path, "rb" ) ) )+ /*+ * if we're opening the stream to read & convert, we need+ * the state we saved when we scanned the stream. if we're+ * opening the stream to scan it we want to rebuild the state+ * (even if we have saved state, the stream may have changed).+ */+ hb_stream_t *ss = hb_stream_lookup( path );+ if ( opentype == 1 ) {+ /* opening to read - we must have saved state */+ if ( ss == NULL )+ {+ hb_log( "hb_stream_open: error: re-opening %s but no scan state", path );+ fclose( f );+ free( d );+ return NULL;+ }+ /*+ * copy the saved state since we might be encoding the same stream+ * multiple times.+ */+ memcpy( d, ss, sizeof(*d) );+ d->file_handle = f;+ d->opentype = opentype; d->path = strdup( path );- if (d->path != NULL && hb_stream_get_type( d ) != 0 )++ if ( d->stream_type == hb_stream_type_transport ) {- current_stream = d;- return d;+ int i = 0;+ for ( ; i < d->ts_number_video_pids + d->ts_number_audio_pids; i++)+ {+ d->ts_buf[i] = malloc( HB_DVD_READ_BUFFER_SIZE );+ }+ hb_stream_seek( d, 0. ); }- fclose( d->file_handle );- if (d->path)- free( d->path );+ return d; }++ /*+ * opening for scan - delete any saved state then (re)scan the stream.+ * If it's something we can deal with (MPEG2 PS or TS) return a stream+ * reference structure & null otherwise.+ */++ if ( ss != NULL )+ {+ hb_stream_state_delete( ss );+ }+ d->file_handle = f;+ d->opentype = opentype;+ d->path = strdup( path );+ if (d->path != NULL && hb_stream_get_type( d ) != 0 )+ {+ return d;+ }+ fclose( d->file_handle );+ if (d->path)+ {+ free( d->path );+ } hb_log( "hb_stream_open: open %s failed", path ); free( d ); return NULL;@@ -252,6 +343,24 @@ stream->errors, (double)stream->errors * 100. / (double)stream->frames ); }+ /*+ * if the stream was opened for a scan, cache the result, otherwise delete+ * the state.+ */+ if ( stream->opentype == 0 )+ {+ hb_stream_delete_dynamic( stream );+ if ( stream_state_list == NULL )+ {+ stream_state_list = hb_list_init();+ }+ hb_list_add( stream_state_list, stream );+ }+ else+ {+ hb_stream_delete( stream );+ }+ *_d = NULL; } /* when the file was first opened we made entries for all the audio elementary@@ -960,77 +1069,57 @@ return pos; } -// ------------------------------------------------------------------------------------ -int bitpos = 0;-unsigned int bitval = 0;-unsigned char* bitbuf = NULL;-unsigned int bitmask[] = {+typedef struct {+ uint8_t *buf;+ uint32_t val;+ int pos;+} bitbuf_t;++static const unsigned int bitmask[] = { 0x0,0x1,0x3,0x7,0xf,0x1f,0x3f,0x7f,0xff, 0x1ff,0x3ff,0x7ff,0xfff,0x1fff,0x3fff,0x7fff,0xffff, 0x1ffff,0x3ffff,0x7ffff,0xfffff,0x1fffff,0x3fffff,0x7fffff,0xffffff, 0x1ffffff,0x3ffffff,0x7ffffff,0xfffffff,0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff}; -static inline void set_buf(unsigned char* buf, int bufsize, int clear)+static inline void set_buf(bitbuf_t *bb, uint8_t* buf, int bufsize, int clear) {- bitpos = 0;- bitbuf = buf;- bitval = (bitbuf[0] << 24) | (bitbuf[1] << 16) | (bitbuf[2] << 8) | bitbuf[3];+ bb->pos = 0;+ bb->buf = buf;+ bb->val = (bb->buf[0] << 24) | (bb->buf[1] << 16) |+ (bb->buf[2] << 8) | bb->buf[3]; if (clear)- memset(bitbuf, 0, bufsize);+ memset(bb->buf, 0, bufsize); } -static inline int buf_size()+static inline int buf_size(bitbuf_t *bb) {- return bitpos >> 3;+ return bb->pos >> 3; } -static inline void set_bits(unsigned int val, int bits)+static inline unsigned int get_bits(bitbuf_t *bb, int bits) {- val &= bitmask[bits];-- while (bits > 0)- {- int bitsleft = (8 - (bitpos & 7));- if (bits >= bitsleft)- {- bitbuf[bitpos >> 3] |= val >> (bits - bitsleft);- bitpos += bitsleft;- bits -= bitsleft;- val &= bitmask[bits];- }- else- {- bitbuf[bitpos >> 3] |= val << (bitsleft - bits);- bitpos += bits;- bits = 0;- }- }-}--static inline unsigned int get_bits(int bits)-{ unsigned int val;- int left = 32 - (bitpos & 31);+ int left = 32 - (bb->pos & 31); if (bits < left) {- val = (bitval >> (left - bits)) & bitmask[bits];- bitpos += bits;+ val = (bb->val >> (left - bits)) & bitmask[bits];+ bb->pos += bits; } else {- val = (bitval & bitmask[left]) << (bits - left);- bitpos += left;+ val = (bb->val & bitmask[left]) << (bits - left);+ bb->pos += left; bits -= left; - int pos = bitpos >> 3;- bitval = (bitbuf[pos] << 24) | (bitbuf[pos + 1] << 16) | (bitbuf[pos + 2] << 8) | bitbuf[pos + 3];+ int pos = bb->pos >> 3;+ bb->val = (bb->buf[pos] << 24) | (bb->buf[pos + 1] << 16) | (bb->buf[pos + 2] << 8) | bb->buf[pos + 3]; if (bits > 0) {- val |= (bitval >> (32 - bits)) & bitmask[bits];- bitpos += bits;+ val |= (bb->val >> (32 - bits)) & bitmask[bits];+ bb->pos += bits; } } @@ -1064,49 +1153,50 @@ int decode_program_map(hb_stream_t* stream) {- set_buf(stream->pmt_info.tablebuf, stream->pmt_info.tablepos, 0);+ bitbuf_t bb;+ set_buf(&bb, stream->pmt_info.tablebuf, stream->pmt_info.tablepos, 0); - get_bits(8); // table_id- get_bits(4);- unsigned int section_length = get_bits(12);+ get_bits(&bb, 8); // table_id+ get_bits(&bb, 4);+ unsigned int section_length = get_bits(&bb, 12); stream->pmt_info.section_length = section_length; - unsigned int program_number = get_bits(16);+ unsigned int program_number = get_bits(&bb, 16); stream->pmt_info.program_number = program_number;- get_bits(2);- get_bits(5); // version_number- get_bits(1);- get_bits(8); // section_number- get_bits(8); // last_section_number- get_bits(3);- unsigned int PCR_PID = get_bits(13);+ get_bits(&bb, 2);+ get_bits(&bb, 5); // version_number+ get_bits(&bb, 1);+ get_bits(&bb, 8); // section_number+ get_bits(&bb, 8); // last_section_number+ get_bits(&bb, 3);+ unsigned int PCR_PID = get_bits(&bb, 13); stream->pmt_info.PCR_PID = PCR_PID;- get_bits(4);- unsigned int program_info_length = get_bits(12);+ get_bits(&bb, 4);+ unsigned int program_info_length = get_bits(&bb, 12); stream->pmt_info.program_info_length = program_info_length; int i=0; unsigned char *descriptor_buf = (unsigned char *) malloc(program_info_length); for (i = 0; i < program_info_length; i++) {- descriptor_buf[i] = get_bits(8);+ descriptor_buf[i] = get_bits(&bb, 8); } int cur_pos = 9 /* data after the section length field*/ + program_info_length; int done_reading_stream_types = 0; while (!done_reading_stream_types) {- unsigned char stream_type = get_bits(8);- get_bits(3);- unsigned int elementary_PID = get_bits(13);- get_bits(4);- unsigned int ES_info_length = get_bits(12);+ unsigned char stream_type = get_bits(&bb, 8);+ get_bits(&bb, 3);+ unsigned int elementary_PID = get_bits(&bb, 13);+ get_bits(&bb, 4);+ unsigned int ES_info_length = get_bits(&bb, 12); int i=0; unsigned char *ES_info_buf = (unsigned char *) malloc(ES_info_length); for (i=0; i < ES_info_length; i++) {- ES_info_buf[i] = get_bits(8);+ ES_info_buf[i] = get_bits(&bb, 8); } if (stream_type == 0x02)@@ -1261,17 +1351,18 @@ unsigned int pos = 0; //while (pos < tablepos) {- set_buf(tablebuf + pos, tablepos - pos, 0);+ bitbuf_t bb;+ set_buf(&bb, tablebuf + pos, tablepos - pos, 0); - unsigned char section_id = get_bits(8);- get_bits(4);- unsigned int section_len = get_bits(12);- get_bits(16); // transport_id- get_bits(2);- get_bits(5); // version_num- get_bits(1); // current_next- get_bits(8); // section_num- get_bits(8); // last_section+ unsigned char section_id = get_bits(&bb, 8);+ get_bits(&bb, 4);+ unsigned int section_len = get_bits(&bb, 12);+ get_bits(&bb, 16); // transport_id+ get_bits(&bb, 2);+ get_bits(&bb, 5); // version_num+ get_bits(&bb, 1); // current_next+ get_bits(&bb, 8); // section_num+ get_bits(&bb, 8); // last_section switch (section_id) {@@ -1284,17 +1375,17 @@ stream->ts_number_pat_entries = 0; while ((curr_pos < section_len) && (stream->ts_number_pat_entries < kMaxNumberPMTStreams)) {- unsigned int pkt_program_num = get_bits(16);+ unsigned int pkt_program_num = get_bits(&bb, 16); stream->pat_info[stream->ts_number_pat_entries].program_number = pkt_program_num; - get_bits(3); // Reserved+ get_bits(&bb, 3); // Reserved if (pkt_program_num == 0) {- get_bits(13); // pkt_network_id+ get_bits(&bb, 13); // pkt_network_id } else {- unsigned int pkt_program_map_PID = get_bits(13);+ unsigned int pkt_program_map_PID = get_bits(&bb, 13); stream->pat_info[stream->ts_number_pat_entries].program_map_PID = pkt_program_map_PID; } curr_pos += 4;@@ -1414,55 +1505,53 @@ } -static uint8_t *fwrite_buf;-static uint8_t *fwrite_buf_orig;--static void set_fwrite_buf( uint8_t *obuf )+static void fwrite64( hb_stream_t *stream, void *buf, int size ) {- fwrite_buf = obuf;- fwrite_buf_orig = obuf;-}--static void fwrite64( void* buf, int size )-{- if ( (fwrite_buf - fwrite_buf_orig) + size > 2048 )+ if ( (stream->fwrite_buf - stream->fwrite_buf_orig) + size > 2048 ) { hb_log( "steam fwrite64 buffer overflow - writing %d with %d already",- size, fwrite_buf - fwrite_buf_orig );+ size, stream->fwrite_buf - stream->fwrite_buf_orig ); return; }- memcpy( fwrite_buf, buf, size );- fwrite_buf += size;+ memcpy( stream->fwrite_buf, buf, size );+ stream->fwrite_buf += size; } static void write_pack(hb_stream_t* stream, uint64_t time, int stuffing) {- uint8_t buf[64];- set_buf(buf, 64, 1); // clear buffer+ uint8_t buf[24]; - set_bits(0x000001ba, 32); // pack id 32- set_bits(1, 2); // 0x01 2- set_bits(time >> 30, 3); // system_clock_reference_base 3- set_bits(1, 1); // marker_bit 1- set_bits(time >> 15, 15); // system_clock_reference_base 15- set_bits(1, 1); // marker_bit 1- set_bits(time, 15); // system_clock_reference_base1 15- set_bits(1, 1); // marker_bit 1- set_bits(0, 9); // system_clock_reference_extension 9- set_bits(1, 1); // marker_bit 1- set_bits(384000, 22); // program_mux_rate 22- set_bits(1, 1); // marker_bit 1- set_bits(1, 1); // marker_bit 1- set_bits(31, 5); // reserved 5- set_bits(stuffing, 3); // pack_stuffing_length 3- while ( --stuffing >= 0 )- {- set_bits(0xff, 8 );- }- fwrite64(buf, buf_size());+ buf[0] = 0x00; // pack id+ buf[1] = 0x00;+ buf[2] = 0x01;+ buf[3] = 0xba;++ buf[4] = 0x44 | // SCR+ ( ( ( time >> 30 ) & 7 ) << 3 ) |+ ( ( time >> 28 ) & 3 );+ buf[5] = time >> 20;+ buf[6] = 0x04 |+ ( ( ( time >> 15 ) & 0x1f ) << 3 ) |+ ( ( time >> 13 ) & 3 );+ buf[7] = time >> 5;+ buf[8] = 0x04 | ( time << 3 );++ buf[9] = 0x01; // SCR extension++ buf[10] = 384000 >> (22 - 8); // program mux rate+ buf[11] = (uint8_t)( 384000 >> (22 - 16) );+ buf[12] = (uint8_t)( 384000 << 2 ) | 0x03;++ buf[13] = 0xf8 | stuffing;++ int i;+ for (i = 0; i < stuffing; ++i )+ buf[14+i] = 0xff;++ fwrite64(stream, buf, 14 + stuffing ); } -static void pad_buffer(int pad)+static void pad_buffer(hb_stream_t* stream, int pad) { pad -= 6; @@ -1474,39 +1563,27 @@ buf[4] = pad >> 8; buf[5] = pad; - fwrite64(buf, 6);+ fwrite64(stream, buf, 6); buf[0] = 0xff; while ( --pad >= 0 ) {- fwrite64(buf, 1);+ fwrite64(stream, buf, 1); } } -static void make_pes_header(int len, uint8_t streamid)+static void make_pes_header(hb_stream_t* stream, int len, uint8_t streamid) { uint8_t buf[9];- set_buf(buf, 9, 1); // clear the buffer - set_bits(0x000001, 24); // packet_start_code_prefix 24- set_bits(streamid, 8); // directory_stream_id 8- set_bits(len + 3, 16); // PES_packet_length 16- set_bits(0x2, 2); // '10' 2- set_bits(0, 2); // PES_scrambling_control 2- set_bits(1, 1); // PES_priority 1- set_bits(0, 1); // data_alignment_indicator 1- set_bits(0, 1); // copyright 1- set_bits(0, 1); // original_or_copy 1- set_bits(0, 2); // PTS_DTS_flags 2- set_bits(0, 1); // ESCR_flag 1- set_bits(0, 1); // ES_rate_flag 1- set_bits(0, 1); // DSM_trick_mode_flag 1- set_bits(0, 1); // additional_copy_info_flag 1- set_bits(0, 1); // PES_CRC_flag 1- set_bits(0, 1); // PES_extension_flag 1- set_bits(0, 8); // PES_header_data_length 8+ memset(buf, 0, sizeof(buf) );+ buf[2] = 1;+ buf[3] = streamid;+ buf[4] = ( len + 3 ) >> 8;+ buf[5] = len + 3;+ buf[6] = 0x88; - fwrite64(buf, 9);+ fwrite64(stream, buf, 9); } static void generate_output_data(hb_stream_t *stream, int curstream)@@ -1568,7 +1645,7 @@ // Write out the PES header int hdrsize = 9 + tdat[8];- fwrite64(tdat, hdrsize);+ fwrite64(stream, tdat, hdrsize); // add a four byte DVD ac3 stream header uint8_t ac3_substream_id[4];@@ -1577,17 +1654,17 @@ ac3_substream_id[1] = 0x01; // number of sync words ac3_substream_id[2] = 0x00; // first offset (16 bits) ac3_substream_id[3] = 0x02;- fwrite64(ac3_substream_id, 4);+ fwrite64(stream, ac3_substream_id, 4); // add the rest of the data- fwrite64(tdat + hdrsize, stream->ts_pos[curstream] - hdrsize);+ fwrite64(stream, tdat + hdrsize, stream->ts_pos[curstream] - hdrsize); } else { // not audio - don't need to modify the stream so write what we've got tdat[4] = plen >> 8; tdat[5] = plen;- fwrite64( tdat, stream->ts_pos[curstream] );+ fwrite64( stream, tdat, stream->ts_pos[curstream] ); } } else@@ -1596,12 +1673,12 @@ // PES header. AC3 audio also needs its substream header. if ( stream->ts_audio_stream_type[curstream] != 0x81) {- make_pes_header(stream->ts_pos[curstream],+ make_pes_header(stream, stream->ts_pos[curstream], stream->ts_streamid[curstream]); } else {- make_pes_header(stream->ts_pos[curstream] + 4,+ make_pes_header(stream, stream->ts_pos[curstream] + 4, stream->ts_streamid[curstream]); // add a four byte DVD ac3 stream header@@ -1611,16 +1688,16 @@ ac3_substream_id[1] = 0x01; // number of sync words ac3_substream_id[2] = 0x00; // first offset (16 bits) ac3_substream_id[3] = 0x02;- fwrite64(ac3_substream_id, 4);+ fwrite64(stream, ac3_substream_id, 4); }- fwrite64( tdat, stream->ts_pos[curstream] );+ fwrite64( stream, tdat, stream->ts_pos[curstream] ); } // Write padding int left = HB_DVD_READ_BUFFER_SIZE - len; if ( left >= 8 ) {- pad_buffer(left);+ pad_buffer(stream, left); } stream->ts_pos[curstream] = 0;@@ -1717,7 +1794,12 @@ int curstream; uint8_t buf[188]; - set_fwrite_buf( obuf );+ /*+ * stash the output buffer pointer in our stream so we don't have to+ * pass it & its original value to everything we call.+ */+ stream->fwrite_buf = obuf;+ stream->fwrite_buf_orig = obuf; // spin until we get a packet of data from some stream or hit eof while ( 1 )Index: libhb/internal.h===================================================================--- libhb/internal.h (revision 1345)+++ libhb/internal.h (working copy)@@ -136,7 +136,7 @@ int hb_dvd_is_break( hb_dvd_t * d ); void hb_dvd_close( hb_dvd_t ** ); -hb_stream_t * hb_stream_open( char * path );+hb_stream_t * hb_stream_open( char * path, int opentype ); 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 *);Index: libhb/scan.c===================================================================--- libhb/scan.c (revision 1345)+++ libhb/scan.c (working copy)@@ -70,7 +70,7 @@ } } }- else if ( (data->stream = hb_stream_open (data->path)) != NULL )+ else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL ) { hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) ); }