3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
9 #include "a52dec/a52.h"
13 #define min(a, b) a < b ? a : b
15 typedef enum { hb_stream_type_unknown
= 0, hb_stream_type_transport
, hb_stream_type_program
} hb_stream_type_t
;
17 #define kMaxNumberDecodeStreams 8
18 #define kMaxNumberVideoPIDS 16
19 #define kMaxNumberAudioPIDS 16
20 //#define kVideoStream 0
21 //#define kAudioStream 1
22 #define kNumDecodeBuffers 2
23 #define kMaxNumberPMTStreams 32
25 #define CLOCKRATE ((int64_t)27000000) // MPEG System clock rate
26 #define STREAMRATE ((int64_t)2401587) // Original HD stream rate 19.2 Mbps
27 #define DEMUX (((int)STREAMRATE * 8) / 50)// Demux value for HD content STREAMRATE / 50
33 hb_stream_type_t stream_type
;
35 int ps_current_write_buffer_index
;
36 int ps_current_read_buffer_index
;
44 } ps_decode_buffer
[kNumDecodeBuffers
];
51 } a52_info
[kMaxNumberAudioPIDS
];
53 int ts_video_pids
[kMaxNumberVideoPIDS
];
54 int ts_audio_pids
[kMaxNumberAudioPIDS
];
56 int ts_number_video_pids
;
57 int ts_number_audio_pids
;
59 unsigned char* ts_packetbuf
[kMaxNumberDecodeStreams
];
60 int ts_packetpos
[kMaxNumberDecodeStreams
];
61 // int ts_bufpackets[kMaxNumberDecodeStreams];
62 int ts_foundfirst
[kMaxNumberDecodeStreams
];
63 int ts_skipbad
[kMaxNumberDecodeStreams
];
64 int ts_streamcont
[kMaxNumberDecodeStreams
];
65 int ts_streamid
[kMaxNumberDecodeStreams
];
66 int ts_audio_stream_type
[kMaxNumberAudioPIDS
];
70 unsigned short program_number
;
71 unsigned short program_map_PID
;
72 } pat_info
[kMaxNumberPMTStreams
];
73 int ts_number_pat_entries
;
78 unsigned char *tablebuf
;
79 unsigned int tablepos
;
80 unsigned char current_continuity_counter
;
85 int program_info_length
;
86 unsigned char *progam_info_descriptor_data
;
89 unsigned char stream_type
;
90 unsigned short elementary_PID
;
91 unsigned short ES_info_length
;
92 unsigned char *es_info_descriptor_data
;
93 } pmt_stream_info
[kMaxNumberPMTStreams
];
97 /***********************************************************************
99 **********************************************************************/
100 static void hb_stream_duration(hb_stream_t
*stream
, hb_title_t
*inTitle
);
101 static void hb_ts_stream_init(hb_stream_t
*stream
);
102 static void hb_ts_stream_find_pids(hb_stream_t
*stream
);
103 static void hb_ts_stream_decode(hb_stream_t
*stream
);
104 static void hb_ts_stream_reset(hb_stream_t
*stream
);
105 static void hb_stream_put_back(hb_stream_t
*stream
, int i
);
106 static hb_audio_t
*hb_ts_stream_set_audio_id_and_codec(hb_stream_t
*stream
,
108 static void hb_ps_stream_find_audio_ids(hb_stream_t
*stream
, hb_title_t
*title
);
109 static off_t
align_to_next_packet(FILE* f
);
112 * streams have a bunch of state that's learned during the scan. We don't
113 * want to throw away the state when scan does a close then relearn
114 * everything when reader does an open. So we basically ignore
115 * a stream close, remember the most recent stream we've opened and only
116 * delete it when a stream of a different name is opened.
118 static hb_stream_t
*current_stream
;
121 static inline int check_ps_sync(const uint8_t *buf
)
123 // a legal MPEG program stream must start with a Pack header in the
125 return (buf
[0] == 0x00) && (buf
[1] == 0x00) &&
126 (buf
[2] == 0x01) && (buf
[3] == 0xba);
129 static inline int check_ts_sync(const uint8_t *buf
)
131 // must have initial sync byte, no scrambling & a legal adaptation ctrl
132 return (buf
[0] == 0x47) && ((buf
[3] >> 6) == 0) && ((buf
[3] >> 4) > 0);
135 static inline int have_ts_sync(const uint8_t *buf
)
137 return check_ts_sync(&buf
[0*188]) && check_ts_sync(&buf
[1*188]) &&
138 check_ts_sync(&buf
[2*188]) && check_ts_sync(&buf
[3*188]) &&
139 check_ts_sync(&buf
[4*188]) && check_ts_sync(&buf
[5*188]) &&
140 check_ts_sync(&buf
[6*188]) && check_ts_sync(&buf
[7*188]);
143 static int hb_stream_check_for_ts(const uint8_t *buf
)
145 // transport streams should have a sync byte every 188 bytes.
146 // search the first KB of buf looking for at least 8 consecutive
147 // correctly located sync patterns.
150 for ( offset
= 0; offset
< 1024; ++offset
)
152 if ( have_ts_sync( &buf
[offset
]) )
158 static int hb_stream_check_for_ps(const uint8_t *buf
)
160 // program streams should have a Pack header every 2048 bytes.
161 // check that we have 4 of these.
162 return check_ps_sync(&buf
[0*2048]) && check_ps_sync(&buf
[1*2048]) &&
163 check_ps_sync(&buf
[2*2048]) && check_ps_sync(&buf
[3*2048]);
166 static int hb_stream_get_type(hb_stream_t
*stream
)
170 if ( fread(buf
, 1, sizeof(buf
), stream
->file_handle
) == sizeof(buf
) )
172 if ( hb_stream_check_for_ts(buf
) != 0 )
174 hb_log("file is MPEG Transport Stream");
175 stream
->stream_type
= hb_stream_type_transport
;
176 hb_ts_stream_init(stream
);
179 if ( hb_stream_check_for_ps(buf
) != 0 )
181 hb_log("file is MPEG Program Stream");
182 stream
->stream_type
= hb_stream_type_program
;
189 static void hb_stream_delete( hb_stream_t
** _d
)
191 hb_stream_t
* d
= *_d
;
195 fclose( d
->file_handle
);
196 d
->file_handle
= NULL
;
200 for (i
= 0; i
< kNumDecodeBuffers
; i
++)
202 if (d
->ps_decode_buffer
[i
].data
)
204 free(d
->ps_decode_buffer
[i
].data
);
205 d
->ps_decode_buffer
[i
].data
= NULL
;
209 for (i
= 0; i
< kMaxNumberDecodeStreams
; i
++)
211 if (d
->ts_packetbuf
[i
])
213 free(d
->ts_packetbuf
[i
]);
214 d
->ts_packetbuf
[i
] = NULL
;
222 /***********************************************************************
224 ***********************************************************************
226 **********************************************************************/
227 hb_stream_t
* hb_stream_open( char * path
)
231 if (strcmp( path
, current_stream
->path
) == 0 )
233 hb_stream_seek( current_stream
, 0. );
234 return current_stream
;
236 hb_stream_delete( ¤t_stream
);
238 hb_stream_t
*d
= calloc( sizeof( hb_stream_t
), 1 );
240 /* open the file and see if it's a type we know about. return a stream
241 * reference structure if we can deal with it & NULL otherwise. */
242 if( ( d
->file_handle
= fopen( path
, "rb" ) ) )
244 d
->path
= strdup( path
);
245 if (d
->path
!= NULL
&& hb_stream_get_type( d
) != 0 )
250 fclose( d
->file_handle
);
254 hb_log( "hb_stream_open: open %s failed", path
);
259 /***********************************************************************
261 ***********************************************************************
262 * Closes and frees everything
263 **********************************************************************/
264 void hb_stream_close( hb_stream_t
** _d
)
268 /* when the file was first opened we made entries for all the audio elementary
269 * streams we found in it. Streams that were later found during the preview scan
270 * now have an audio codec, type, rate, etc., associated with them. At the end
271 * of the scan we delete all the audio entries that weren't found by the scan
272 * or don't have a format we support. This routine deletes audio entry 'indx'
273 * by copying all later entries down one slot. */
274 static void hb_stream_delete_audio_entry(hb_stream_t
*stream
, int indx
)
278 for (i
= indx
+1; i
< stream
->ts_number_audio_pids
; ++i
)
280 stream
->ts_audio_pids
[indx
] = stream
->ts_audio_pids
[i
];
281 stream
->ts_audio_stream_type
[indx
] = stream
->ts_audio_stream_type
[i
];
282 stream
->ts_streamid
[stream
->ts_number_video_pids
+ indx
] =
283 stream
->ts_streamid
[stream
->ts_number_video_pids
+ i
];
286 --stream
->ts_number_audio_pids
;
289 /***********************************************************************
290 * hb_ps_stream_title_scan
291 ***********************************************************************
293 **********************************************************************/
294 hb_title_t
* hb_stream_title_scan(hb_stream_t
*stream
)
297 hb_title_t
*aTitle
= hb_title_init( stream
->path
, 0 );
300 // Copy part of the stream path to the title name
301 char *sep
= strrchr(stream
->path
, '/');
303 strcpy(aTitle
->name
, sep
+1);
304 char *dot_term
= strrchr(aTitle
->name
, '.');
308 // Height, width, rate and aspect ratio information is filled in when the previews are built
310 hb_stream_duration(stream
, aTitle
);
313 hb_chapter_t
* chapter
;
314 chapter
= calloc( sizeof( hb_chapter_t
), 1 );
316 chapter
->duration
= aTitle
->duration
;
317 chapter
->hours
= aTitle
->hours
;
318 chapter
->minutes
= aTitle
->minutes
;
319 chapter
->seconds
= aTitle
->seconds
;
320 hb_list_add( aTitle
->list_chapter
, chapter
);
322 // Figure out how many audio streams we really have:
323 // - For transport streams, for each PID listed in the PMT (whether
324 // or not it was an audio stream type) read the bitstream until we
325 // find an packet from that PID containing a PES header and see if
326 // the elementary stream is an audio type.
327 // - For program streams read the first 4MB and take every unique
328 // audio stream we find.
329 if (stream
->stream_type
== hb_stream_type_transport
)
333 for (i
=0; i
< stream
->ts_number_audio_pids
; i
++)
335 hb_audio_t
*audio
= hb_ts_stream_set_audio_id_and_codec(stream
, i
);
337 hb_list_add( aTitle
->list_audio
, audio
);
341 hb_stream_delete_audio_entry(stream
, i
);
348 hb_ps_stream_find_audio_ids(stream
, aTitle
);
355 * scan the next MB of 'stream' to find the next start packet for
356 * the Packetized Elementary Stream associated with TS PID 'pid'.
358 static const uint8_t *hb_ts_stream_getPEStype(hb_stream_t
*stream
, uint32_t pid
)
360 static uint8_t buf
[188];
361 int npack
= 100000; // max packets to read
365 if (fread(buf
, 1, 188, stream
->file_handle
) != 188)
367 hb_log("hb_ts_stream_getPEStype: EOF while searching for PID 0x%x", pid
);
372 hb_log("hb_ts_stream_getPEStype: lost sync while searching for PID 0x%x", pid
);
373 align_to_next_packet(stream
->file_handle
);
378 * The PES header is only in TS packets with 'start' set so we check
379 * that first then check for the right PID.
381 if ((buf
[1] & 0x40) == 0 || (buf
[1] & 0x1f) != (pid
>> 8) ||
382 buf
[2] != (pid
& 0xff))
384 // not a start packet or not the pid we want
388 /* skip over the TS hdr to return a pointer to the PES hdr */
390 switch (buf
[3] & 0x30)
392 case 0x00: // illegal
393 case 0x20: // fill packet
396 case 0x30: // adaptation
399 hb_log("hb_ts_stream_getPEStype: invalid adaptation field length %d for PID 0x%x", buf
[4], pid
);
412 static uint64_t hb_ps_stream_getVideoPTS(hb_stream_t
*stream
)
414 hb_buffer_t
*buf
= hb_buffer_init(HB_DVD_READ_BUFFER_SIZE
);
415 hb_list_t
*list
= hb_list_init();
416 // how many blocks we read while searching for a video PES header
420 while (--blksleft
>= 0 && hb_stream_read(stream
, buf
) == 1)
424 // 'buf' contains an MPEG2 PACK - get a list of all it's elementary streams
425 hb_demux_ps(buf
, list
);
427 while ( ( es
= hb_list_item( list
, 0 ) ) )
429 hb_list_rem( list
, es
);
430 if ( es
->id
== 0xe0 )
432 // this PES contains video - if there's a PTS we're done
433 // hb_demux_ps left the PTS in buf_es->start.
434 if ( es
->start
!= ~0 )
441 hb_buffer_close( &es
);
444 hb_list_empty( &list
);
445 hb_buffer_close(&buf
);
449 /***********************************************************************
451 ***********************************************************************
453 * Finding stream duration is difficult. One issue is that the video file
454 * may have chunks from several different program fragments (main feature,
455 * commercials, station id, trailers, etc.) all with their own base pts
456 * value. We can't find the piece boundaries without reading the entire
457 * file but if we compute a rate based on time stamps from two different
458 * pieces the result will be meaningless. The second issue is that the
459 * data rate of compressed video normally varies by 5-10x over the length
460 * of the video. This says that we want to compute the rate over relatively
461 * long segments to get a representative average but long segments increase
462 * the likelihood that we'll cross a piece boundary.
464 * What we do is take time stamp samples at several places in the file
465 * (currently 16) then compute the average rate (i.e., ticks of video per
466 * byte of the file) for all pairs of samples (N^2 rates computed for N
467 * samples). Some of those rates will be absurd because the samples came
468 * from different segments. Some will be way low or high because the
469 * samples came from a low or high motion part of the segment. But given
470 * that we're comparing *all* pairs the majority of the computed rates
471 * should be near the overall average. So we median filter the computed
472 * rates to pick the most representative value.
474 **********************************************************************/
476 uint64_t pos
; /* file position of this PTS sample */
477 uint64_t pts
; /* PTS from video stream */
480 #define NDURSAMPLES 16
482 // get one (position, timestamp) sampple from a transport or program
484 static struct pts_pos
hb_sample_pts(hb_stream_t
*stream
, uint64_t fpos
)
486 struct pts_pos pp
= { 0, 0 };
488 if ( stream
->stream_type
== hb_stream_type_program
)
490 // round address down to nearest dvd sector start
491 fpos
&=~ ( HB_DVD_READ_BUFFER_SIZE
- 1 );
492 fseeko( stream
->file_handle
, fpos
, SEEK_SET
);
493 pp
.pts
= hb_ps_stream_getVideoPTS( stream
);
498 fseeko( stream
->file_handle
, fpos
, SEEK_SET
);
499 align_to_next_packet( stream
->file_handle
);
500 buf
= hb_ts_stream_getPEStype( stream
, stream
->ts_video_pids
[0] );
503 hb_log("hb_sample_pts: couldn't find video packet near %llu", fpos
);
506 if ( ( buf
[7] >> 7 ) != 1 )
508 hb_log("hb_sample_pts: no PTS in video packet near %llu", fpos
);
511 pp
.pts
= ( ( (uint64_t)buf
[9] >> 1 ) & 7 << 30 ) |
512 ( (uint64_t)buf
[10] << 22 ) |
513 ( ( (uint64_t)buf
[11] >> 1 ) << 15 ) |
514 ( (uint64_t)buf
[12] << 7 ) |
515 ( (uint64_t)buf
[13] >> 1 );
517 pp
.pos
= ftello(stream
->file_handle
);
518 hb_log("hb_sample_pts: pts %lld at %llu", pp
.pts
, pp
.pos
);
522 static int dur_compare( const void *a
, const void *b
)
524 const double *aval
= a
, *bval
= b
;
525 return ( *aval
< *bval
? -1 : ( *aval
== *bval
? 0 : 1 ) );
528 // given an array of (position, time) samples, compute a max-likelihood
529 // estimate of the average rate by computing the rate between all pairs
530 // of samples then taking the median of those rates.
531 static double compute_stream_rate( struct pts_pos
*pp
, int n
)
534 double rates
[NDURSAMPLES
* NDURSAMPLES
/ 2];
537 // the following nested loops compute the rates between all pairs.
539 for ( i
= 0; i
< n
-1; ++i
)
541 // Bias the median filter by not including pairs that are "far"
542 // frome one another. This is to handle cases where the file is
543 // made of roughly equal size pieces where a symmetric choice of
544 // pairs results in having the same number of intra-piece &
545 // inter-piece rate estimates. This would mean that the median
546 // could easily fall in the inter-piece part of the data which
547 // would give a bogus estimate. The 'ns' index creates an
548 // asymmetry that favors locality.
549 int ns
= i
+ ( n
>> 1 );
552 for ( j
= i
+1; j
< ns
; ++j
)
554 if ( pp
[j
].pts
!= pp
[i
].pts
&& pp
[j
].pos
> pp
[i
].pos
)
556 *rp
= ((double)( pp
[j
].pts
- pp
[i
].pts
)) /
557 ((double)( pp
[j
].pos
- pp
[i
].pos
));
562 // now compute and return the median of all the (n*n/2) rates we computed
564 int nrates
= rp
- rates
;
565 qsort( rates
, nrates
, sizeof (rates
[0] ), dur_compare
);
566 return rates
[nrates
>> 1];
569 static void hb_stream_duration(hb_stream_t
*stream
, hb_title_t
*inTitle
)
571 struct pts_pos ptspos
[NDURSAMPLES
];
572 struct pts_pos
*pp
= ptspos
;
575 fseeko(stream
->file_handle
, 0, SEEK_END
);
576 uint64_t fsize
= ftello(stream
->file_handle
);
577 uint64_t fincr
= fsize
/ NDURSAMPLES
;
578 uint64_t fpos
= fincr
/ 2;
579 for ( i
= NDURSAMPLES
; --i
>= 0; fpos
+= fincr
)
581 *pp
++ = hb_sample_pts(stream
, fpos
);
583 uint64_t dur
= compute_stream_rate( ptspos
, pp
- ptspos
) * (double)fsize
;
584 inTitle
->duration
= dur
;
586 inTitle
->hours
= dur
/ 3600;
587 inTitle
->minutes
= ( dur
% 3600 ) / 60;
588 inTitle
->seconds
= dur
% 60;
590 rewind(stream
->file_handle
);
593 /***********************************************************************
595 ***********************************************************************
597 **********************************************************************/
598 int hb_stream_read( hb_stream_t
* src_stream
, hb_buffer_t
* b
)
600 if (src_stream
->stream_type
== hb_stream_type_program
)
603 amt_read
= fread(b
->data
, HB_DVD_READ_BUFFER_SIZE
, 1, src_stream
->file_handle
);
609 else if (src_stream
->stream_type
== hb_stream_type_transport
)
611 int read_buffer_index
= src_stream
->ps_current_read_buffer_index
;
613 // Transport streams are a little more complex - we might be able to just
614 // read from the transport stream conversion buffer (if there's enough data)
615 // or we may need to transfer what's left and fill it again.
616 if (src_stream
->ps_decode_buffer
[read_buffer_index
].len
617 - src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
618 >= HB_DVD_READ_BUFFER_SIZE
)
621 src_stream
->ps_decode_buffer
[read_buffer_index
].data
+
622 src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
,
623 HB_DVD_READ_BUFFER_SIZE
);
624 src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
+= HB_DVD_READ_BUFFER_SIZE
;
629 // Not quite enough data in the buffer - transfer what is present, fill the buffer and then
630 // transfer what's still needed.
631 int transfer_size
= HB_DVD_READ_BUFFER_SIZE
;
632 int amt_avail_to_transfer
= src_stream
->ps_decode_buffer
[read_buffer_index
].len
- src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
;
633 memcpy(b
->data
, src_stream
->ps_decode_buffer
[read_buffer_index
].data
+ src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
, amt_avail_to_transfer
);
634 transfer_size
-= amt_avail_to_transfer
;
636 // Give up this buffer - decoding may well need it, and we're done
637 src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
= 0;
638 src_stream
->ps_decode_buffer
[read_buffer_index
].write_pos
= 0;
639 src_stream
->ps_decode_buffer
[read_buffer_index
].len
= 0;
642 hb_ts_stream_decode(src_stream
);
644 // Decoding will almost certainly have changed the current read buffer index
645 read_buffer_index
= src_stream
->ps_current_read_buffer_index
;
647 if (src_stream
->ps_decode_buffer
[read_buffer_index
].len
== 0)
649 hb_log("hb_stream_read - buffer after decode has zero length data");
653 // Read the bit we still need
654 memcpy(b
->data
+amt_avail_to_transfer
, src_stream
->ps_decode_buffer
[read_buffer_index
].data
+ src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
,transfer_size
);
655 src_stream
->ps_decode_buffer
[read_buffer_index
].read_pos
+= transfer_size
;
664 /***********************************************************************
666 ***********************************************************************
668 **********************************************************************/
669 int hb_stream_seek( hb_stream_t
* src_stream
, float f
)
671 off_t stream_size
, cur_pos
, new_pos
;
672 double pos_ratio
= f
;
673 cur_pos
= ftello(src_stream
->file_handle
);
674 fseeko(src_stream
->file_handle
,0 ,SEEK_END
);
675 stream_size
= ftello(src_stream
->file_handle
);
676 new_pos
= (off_t
) ((double) (stream_size
) * pos_ratio
);
677 new_pos
&=~ (HB_DVD_READ_BUFFER_SIZE
- 1);
678 int r
= fseeko(src_stream
->file_handle
, new_pos
, SEEK_SET
);
682 fseeko(src_stream
->file_handle
, cur_pos
, SEEK_SET
);
686 if (src_stream
->stream_type
== hb_stream_type_transport
)
688 // We need to drop the current decoder output and move
689 // forwards to the next transport stream packet.
690 hb_ts_stream_reset(src_stream
);
693 // Now we must scan forwards for a valid start code (0x000001BA)
695 hb_buffer_t
*buf
= hb_buffer_init(HB_DVD_READ_BUFFER_SIZE
);
698 if (hb_stream_read(src_stream
,buf
) == 1)
701 for (i
=0; (i
<= HB_DVD_READ_BUFFER_SIZE
-4) && (!done
); i
++)
703 if ((buf
->data
[i
] == 0x00) && (buf
->data
[i
+1] == 0x00) && (buf
->data
[i
+2] == 0x01) && (buf
->data
[i
+3] == 0xba))
706 // 'Put Back' the data we've just read (up to this point)
707 hb_stream_put_back(src_stream
, i
);
712 done
= 1; // End of data;
714 hb_buffer_close(&buf
);
718 static hb_audio_t
*hb_ts_stream_set_audio_id_and_codec(hb_stream_t
*stream
,
721 off_t cur_pos
= ftello(stream
->file_handle
);
722 hb_audio_t
*audio
= calloc( sizeof( hb_audio_t
), 1 );
725 fseeko(stream
->file_handle
, 0, SEEK_SET
);
726 align_to_next_packet(stream
->file_handle
);
727 buf
= hb_ts_stream_getPEStype(stream
, stream
->ts_audio_pids
[aud_pid_index
]);
729 /* check that we found a PES header */
730 if (buf
&& buf
[0] == 0x00 && buf
[1] == 0x00 && buf
[2] == 0x01)
734 audio
->id
= 0x80bd | (aud_pid_index
<< 8);
735 audio
->codec
= HB_ACODEC_AC3
;
736 hb_log("transport stream pid 0x%x (type 0x%x) is AC-3 audio id 0x%x",
737 stream
->ts_audio_pids
[aud_pid_index
],
738 stream
->ts_audio_stream_type
[aud_pid_index
],
740 stream
->ts_audio_stream_type
[aud_pid_index
] = 0x81;
741 stream
->ts_streamid
[stream
->ts_number_video_pids
+ aud_pid_index
] = buf
[3];
743 else if ((buf
[3] & 0xe0) == 0xc0)
745 audio
->id
= buf
[3] | aud_pid_index
;
746 audio
->codec
= HB_ACODEC_MPGA
;
747 hb_log("transport stream pid 0x%x (type 0x%x) is MPEG audio id 0x%x",
748 stream
->ts_audio_pids
[aud_pid_index
],
749 stream
->ts_audio_stream_type
[aud_pid_index
],
751 stream
->ts_audio_stream_type
[aud_pid_index
] = 0x03;
752 stream
->ts_streamid
[stream
->ts_number_video_pids
+ aud_pid_index
] = buf
[3];
755 fseeko(stream
->file_handle
, cur_pos
, SEEK_SET
);
758 hb_log("transport stream pid 0x%x (type 0x%x) isn't audio",
759 stream
->ts_audio_pids
[aud_pid_index
],
760 stream
->ts_audio_stream_type
[aud_pid_index
]);
765 static void add_audio_to_title(hb_title_t
*title
, int id
)
767 hb_audio_t
*audio
= calloc( sizeof( hb_audio_t
), 1 );
773 audio
->codec
= HB_ACODEC_MPGA
;
774 hb_log("add_audio_to_title: added MPEG audio stream 0x%x", id
);
777 // type 2 is a DVD subtitle stream - just ignore it */
781 audio
->codec
= HB_ACODEC_AC3
;
782 hb_log("add_audio_to_title: added AC3 audio stream 0x%x", id
);
785 audio
->codec
= HB_ACODEC_LPCM
;
786 hb_log("add_audio_to_title: added LPCM audio stream 0x%x", id
);
789 hb_log("add_audio_to_title: unknown audio stream type 0x%x", id
);
794 hb_list_add( title
->list_audio
, audio
);
797 static void hb_ps_stream_find_audio_ids(hb_stream_t
*stream
, hb_title_t
*title
)
799 off_t cur_pos
= ftello(stream
->file_handle
);
800 hb_buffer_t
*buf
= hb_buffer_init(HB_DVD_READ_BUFFER_SIZE
);
801 hb_list_t
*list
= hb_list_init();
802 // how many blocks we read while searching for audio streams
804 // there can be at most 16 unique streams in an MPEG PS (8 in a DVD)
805 // so we use a bitmap to keep track of the ones we've already seen.
806 // Bit 'i' of smap is set if we've already added the audio for
807 // audio substream id 'i' to the title's audio list.
810 // start looking 20% into the file since there's occasionally no
811 // audio at the beginning (particularly for vobs).
812 hb_stream_seek(stream
, 0.2f
);
814 while (--blksleft
>= 0 && hb_stream_read(stream
, buf
) == 1)
818 // 'buf' contains an MPEG2 PACK - get a list of all it's elementary streams
819 hb_demux_ps(buf
, list
);
821 while ( ( es
= hb_list_item( list
, 0 ) ) )
823 hb_list_rem( list
, es
);
824 if ( (es
->id
& 0xff) == 0xbd || (es
->id
& 0xe0) == 0xc0 )
826 // this PES contains some kind of audio - get the substream id
827 // and check if we've seen it already.
828 int ssid
= (es
->id
> 0xff ? es
->id
>> 8 : es
->id
) & 0xf;
829 if ( (smap
& (1 << ssid
)) == 0 )
831 // we haven't seen this stream before - add it to the
832 // title's list of audio streams.
834 add_audio_to_title(title
, es
->id
);
837 hb_buffer_close( &es
);
840 hb_list_empty( &list
);
841 hb_buffer_close(&buf
);
842 fseeko(stream
->file_handle
, cur_pos
, SEEK_SET
);
845 /***********************************************************************
846 * hb_stream_update_audio
847 ***********************************************************************
849 **********************************************************************/
850 void hb_stream_update_audio(hb_stream_t
*stream
, hb_audio_t
*audio
)
854 if (stream
->stream_type
== hb_stream_type_transport
)
856 // Find the audio stream info for this PID. The stream index is
857 // the subchannel id which is in the bottom four bits for MPEG audio
858 // and the bottom four bits of the upper byte for everything else.
859 int i
= ( audio
->id
>= 0xd0 ? audio
->id
>> 8 : audio
->id
) & 0xf;
860 if (i
>= stream
->ts_number_audio_pids
)
862 hb_log("hb_stream_update_audio: no PID for audio stream 0x%x",
866 if (audio
->id
< 0xd0)
868 /* XXX fake mpeg audio sample rate & bps */
869 stream
->a52_info
[i
].flags
= A52_STEREO
;
870 stream
->a52_info
[i
].rate
= 48000 /*Hz*/;
871 stream
->a52_info
[i
].bitrate
= 384000 /*Bps*/;
874 lang
= lang_for_code(stream
->a52_info
[i
].lang_code
);
876 audio
->rate
= stream
->a52_info
[i
].rate
;
878 audio
->bitrate
= stream
->a52_info
[i
].bitrate
;
879 if (!audio
->config
.a52
.ac3flags
)
880 audio
->config
.a52
.ac3flags
= audio
->ac3flags
= stream
->a52_info
[i
].flags
;
885 // XXX should try to get language code from the AC3 bitstream
886 lang
= lang_for_code(0x0000);
889 if (!audio
->input_channel_layout
)
891 switch( audio
->ac3flags
& A52_CHANNEL_MASK
)
897 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_MONO
;
902 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_STEREO
;
904 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
906 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_DOLBY
;
910 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F2R
;
914 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F1R
;
918 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F
;
921 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_2F1R
;
924 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_2F2R
;
928 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_STEREO
;
931 /* add in our own LFE flag if the source has LFE */
932 if (audio
->ac3flags
& A52_LFE
)
934 audio
->input_channel_layout
= audio
->input_channel_layout
| HB_INPUT_CH_LAYOUT_HAS_LFE
;
938 snprintf( audio
->lang
, sizeof( audio
->lang
), "%s (%s)", strlen(lang
->native_name
) ? lang
->native_name
: lang
->eng_name
,
939 audio
->codec
== HB_ACODEC_AC3
? "AC3" : ( audio
->codec
== HB_ACODEC_MPGA
? "MPEG" : ( audio
->codec
== HB_ACODEC_DCA
? "DTS" : "LPCM" ) ) );
940 snprintf( audio
->lang_simple
, sizeof( audio
->lang_simple
), "%s", strlen(lang
->native_name
) ? lang
->native_name
: lang
->eng_name
);
941 snprintf( audio
->iso639_2
, sizeof( audio
->iso639_2
), "%s", lang
->iso639_2
);
943 if ( (audio
->ac3flags
& A52_CHANNEL_MASK
) == A52_DOLBY
) {
944 sprintf( audio
->lang
+ strlen( audio
->lang
),
945 " (Dolby Surround)" );
947 sprintf( audio
->lang
+ strlen( audio
->lang
),
949 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio
->input_channel_layout
) +
950 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio
->input_channel_layout
),
951 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio
->input_channel_layout
));
954 hb_log( "hb_stream_update_audio: id=%x, lang=%s, 3cc=%s, rate = %d, bitrate = %d, flags = 0x%x (%d)", audio
->id
, audio
->lang
, audio
->iso639_2
, audio
->rate
, audio
->bitrate
, audio
->ac3flags
, audio
->ac3flags
);
958 /***********************************************************************
960 ***********************************************************************
962 **********************************************************************/
963 static void hb_stream_put_back(hb_stream_t
*stream
, int i
)
965 if (stream
->stream_type
== hb_stream_type_program
)
967 // Program streams are pretty easy - we just reposition the source file
969 fseeko(stream
->file_handle
, -(HB_DVD_READ_BUFFER_SIZE
-i
), SEEK_CUR
);
971 else if (stream
->stream_type
== hb_stream_type_transport
)
973 int read_buffer_index
= stream
->ps_current_read_buffer_index
;
975 // Transport streams are a little more tricky - so long as the
976 // amount to back up is still within the current decode buffer
977 // we can just adjust the read pos.
978 if (stream
->ps_decode_buffer
[read_buffer_index
].read_pos
- i
> 0)
980 stream
->ps_decode_buffer
[read_buffer_index
].read_pos
-= i
;
983 hb_error("hb_stream_put_back - trying to step beyond the start of the buffer, read_pos = %d amt to put back = %d\n", stream
->ps_decode_buffer
[read_buffer_index
].read_pos
, i
);
988 /***********************************************************************
990 ***********************************************************************
992 **********************************************************************/
993 #define PS_DECODE_BUFFER_SIZE ( 1024 * 1024 * 4)
995 static void hb_ts_stream_init(hb_stream_t
*stream
)
997 // Output Program Stream
999 for (i
=0; i
< kNumDecodeBuffers
; i
++)
1001 stream
->ps_decode_buffer
[i
].data
= (unsigned char *) malloc(PS_DECODE_BUFFER_SIZE
);
1002 stream
->ps_decode_buffer
[i
].read_pos
= 0;
1003 stream
->ps_decode_buffer
[i
].size
= PS_DECODE_BUFFER_SIZE
;
1004 stream
->ps_decode_buffer
[i
].len
= 0;
1005 stream
->ps_decode_buffer
[i
].write_pos
= 0;
1008 for (i
=0; i
< kMaxNumberDecodeStreams
; i
++)
1010 stream
->ts_streamcont
[i
] = -1;
1013 stream
->ps_current_write_buffer_index
= 0;
1014 stream
->ps_current_read_buffer_index
= 1;
1016 // Find the audio and video pids in the stream
1017 hb_ts_stream_find_pids(stream
);
1019 for (i
=0; i
< stream
->ts_number_video_pids
; i
++)
1021 // In progress audio/video data during the transport stream -> program stream processing
1022 stream
->ts_packetbuf
[i
] = (unsigned char *) malloc(1024 * 1024);
1023 stream
->ts_streamid
[i
] = 0xE0; // Stream is Video
1026 for (i
= stream
->ts_number_video_pids
; i
< stream
->ts_number_video_pids
+ stream
->ts_number_audio_pids
; i
++)
1028 stream
->ts_packetbuf
[i
] = (unsigned char *) malloc(1024 * 1024);
1032 // ------------------------------------------------------------------------------------
1034 static off_t
align_to_next_packet(FILE* f
)
1036 unsigned char buf
[188*20];
1038 off_t start
= ftello(f
);
1041 if (fread(buf
, 188*20, 1, f
) == 1)
1044 while (!found
&& (pos
< 188))
1048 for (i
= 0; i
< 188*20; i
+= 188)
1050 unsigned char c
= buf
[pos
+i
];
1052 if ((c
!= 0x47) && (c
!= 0x72) && (c
!= 0x29))
1054 // this offset failed, try next
1064 pos
= 0; // failed to find anything!!!!!?
1066 fseeko(f
, start
+pos
, SEEK_SET
);
1071 // ------------------------------------------------------------------------------------
1074 unsigned int bitval
= 0;
1075 unsigned char* bitbuf
= NULL
;
1076 unsigned int bitmask
[] = {
1077 0x0,0x1,0x3,0x7,0xf,0x1f,0x3f,0x7f,0xff,
1078 0x1ff,0x3ff,0x7ff,0xfff,0x1fff,0x3fff,0x7fff,0xffff,
1079 0x1ffff,0x3ffff,0x7ffff,0xfffff,0x1fffff,0x3fffff,0x7fffff,0xffffff,
1080 0x1ffffff,0x3ffffff,0x7ffffff,0xfffffff,0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
1082 static inline void set_buf(unsigned char* buf
, int bufsize
, int clear
)
1086 bitval
= (bitbuf
[0] << 24) | (bitbuf
[1] << 16) | (bitbuf
[2] << 8) | bitbuf
[3];
1088 memset(bitbuf
, 0, bufsize
);
1091 static inline int buf_size()
1096 static inline void set_bits(unsigned int val
, int bits
)
1098 val
&= bitmask
[bits
];
1102 int bitsleft
= (8 - (bitpos
& 7));
1103 if (bits
>= bitsleft
)
1105 bitbuf
[bitpos
>> 3] |= val
>> (bits
- bitsleft
);
1108 val
&= bitmask
[bits
];
1112 bitbuf
[bitpos
>> 3] |= val
<< (bitsleft
- bits
);
1119 static inline unsigned int get_bits(int bits
)
1122 int left
= 32 - (bitpos
& 31);
1126 val
= (bitval
>> (left
- bits
)) & bitmask
[bits
];
1131 val
= (bitval
& bitmask
[left
]) << (bits
- left
);
1135 int pos
= bitpos
>> 3;
1136 bitval
= (bitbuf
[pos
] << 24) | (bitbuf
[pos
+ 1] << 16) | (bitbuf
[pos
+ 2] << 8) | bitbuf
[pos
+ 3];
1140 val
|= (bitval
>> (32 - bits
)) & bitmask
[bits
];
1148 // extract what useful information we can from the elementary stream
1149 // descriptor list at 'dp' and add it to the stream at 'esindx'.
1150 // Descriptors with info we don't currently use are ignored.
1151 // The descriptor list & descriptor item formats are defined in
1152 // ISO 13818-1 (2000E) section 2.6 (pg. 62).
1153 static void decode_element_descriptors(hb_stream_t
* stream
, int esindx
,
1154 const uint8_t *dp
, uint8_t dlen
)
1156 const uint8_t *ep
= dp
+ dlen
;
1162 case 10: // ISO_639_language descriptor
1163 stream
->a52_info
[esindx
].lang_code
= lang_to_code(lang_for_code2((const char *)&dp
[2]));
1173 int decode_program_map(hb_stream_t
* stream
)
1175 set_buf(stream
->pmt_info
.tablebuf
, stream
->pmt_info
.tablepos
, 0);
1177 get_bits(8); // table_id
1179 unsigned int section_length
= get_bits(12);
1180 stream
->pmt_info
.section_length
= section_length
;
1182 unsigned int program_number
= get_bits(16);
1183 stream
->pmt_info
.program_number
= program_number
;
1185 get_bits(5); // version_number
1187 get_bits(8); // section_number
1188 get_bits(8); // last_section_number
1190 unsigned int PCR_PID
= get_bits(13);
1191 stream
->pmt_info
.PCR_PID
= PCR_PID
;
1193 unsigned int program_info_length
= get_bits(12);
1194 stream
->pmt_info
.program_info_length
= program_info_length
;
1197 unsigned char *descriptor_buf
= (unsigned char *) malloc(program_info_length
);
1198 for (i
= 0; i
< program_info_length
; i
++)
1200 descriptor_buf
[i
] = get_bits(8);
1203 int cur_pos
= 9 /* data after the section length field*/ + program_info_length
;
1204 int done_reading_stream_types
= 0;
1205 while (!done_reading_stream_types
)
1207 unsigned char stream_type
= get_bits(8);
1209 unsigned int elementary_PID
= get_bits(13);
1211 unsigned int ES_info_length
= get_bits(12);
1214 unsigned char *ES_info_buf
= (unsigned char *) malloc(ES_info_length
);
1215 for (i
=0; i
< ES_info_length
; i
++)
1217 ES_info_buf
[i
] = get_bits(8);
1220 if (stream_type
== 0x02)
1222 if (stream
->ts_number_video_pids
<= kMaxNumberVideoPIDS
)
1223 stream
->ts_number_video_pids
++;
1224 stream
->ts_video_pids
[stream
->ts_number_video_pids
-1] = elementary_PID
;
1228 // Defined audio stream types are 0x81 for AC-3/A52 audio and 0x03
1229 // for mpeg audio. But content producers seem to use other
1230 // values (0x04 and 0x06 have both been observed) so at this point
1231 // we say everything that isn't a video pid is audio then at the end
1232 // of hb_stream_title_scan we'll figure out which are really audio
1233 // by looking at the PES headers.
1234 i
= stream
->ts_number_audio_pids
;
1235 if (i
< kMaxNumberAudioPIDS
)
1236 stream
->ts_number_audio_pids
++;
1237 stream
->ts_audio_pids
[i
] = elementary_PID
;
1238 stream
->ts_audio_stream_type
[i
] = stream_type
;
1240 if (ES_info_length
> 0)
1242 decode_element_descriptors(stream
, i
, ES_info_buf
, ES_info_length
);
1246 cur_pos
+= 5 /* stream header */ + ES_info_length
;
1250 if (cur_pos
>= section_length
- 4 /* stop before the CRC */)
1251 done_reading_stream_types
= 1;
1254 free(descriptor_buf
);
1258 // ------------------------------------------------------------------------------------
1260 int build_program_map(unsigned char *buf
, hb_stream_t
*stream
)
1262 // Get adaption header info
1264 int adaption
= (buf
[3] & 0x30) >> 4;
1267 else if (adaption
== 0x2)
1269 else if (adaption
== 0x3)
1270 adapt_len
= buf
[4] + 1;
1271 if (adapt_len
> 184)
1274 // Get payload start indicator
1276 start
= (buf
[1] & 0x40) != 0;
1278 // Get pointer length - only valid in packets with a start flag
1279 int pointer_len
= 0;
1280 if (start
&& stream
->pmt_info
.reading
)
1282 // We just finished a bunch of packets - parse the program map details
1284 if (stream
->pmt_info
.tablebuf
[0] == 0x02)
1285 decode_ok
= decode_program_map(stream
);
1286 free(stream
->pmt_info
.tablebuf
);
1287 stream
->pmt_info
.tablebuf
= NULL
;
1288 stream
->pmt_info
.tablepos
= 0;
1289 stream
->pmt_info
.reading
= 0;
1296 pointer_len
= buf
[4 + adapt_len
] + 1;
1297 stream
->pmt_info
.tablepos
= 0;
1299 // Get Continuity Counter
1300 int continuity_counter
= buf
[3] & 0x0f;
1301 if (!start
&& (stream
->pmt_info
.current_continuity_counter
+ 1 != continuity_counter
))
1303 hb_log("build_program_map - Continuity Counter %d out of sequence - expected %d", continuity_counter
, stream
->pmt_info
.current_continuity_counter
+1);
1306 stream
->pmt_info
.current_continuity_counter
= continuity_counter
;
1307 stream
->pmt_info
.reading
|= start
;
1309 // Add the payload for this packet to the current buffer
1310 int amount_to_copy
= 184 - adapt_len
- pointer_len
;
1311 if (stream
->pmt_info
.reading
&& (amount_to_copy
> 0))
1313 stream
->pmt_info
.tablebuf
= realloc(stream
->pmt_info
.tablebuf
, stream
->pmt_info
.tablepos
+ amount_to_copy
);
1315 memcpy(stream
->pmt_info
.tablebuf
+ stream
->pmt_info
.tablepos
, buf
+ 4 + adapt_len
+ pointer_len
, amount_to_copy
);
1316 stream
->pmt_info
.tablepos
+= amount_to_copy
;
1322 int decode_PAT(unsigned char *buf
, hb_stream_t
*stream
)
1324 unsigned char tablebuf
[1024];
1325 unsigned int tablepos
= 0;
1330 // Get adaption header info
1332 int adaption
= (buf
[3] & 0x30) >> 4;
1335 else if (adaption
== 0x2)
1337 else if (adaption
== 0x3)
1338 adapt_len
= buf
[4] + 1;
1339 if (adapt_len
> 184)
1342 // Get pointer length
1343 int pointer_len
= buf
[4 + adapt_len
] + 1;
1345 // Get payload start indicator
1347 start
= (buf
[1] & 0x40) != 0;
1352 // Add the payload for this packet to the current buffer
1353 if (reading
&& (184 - adapt_len
) > 0)
1355 if (tablepos
+ 184 - adapt_len
- pointer_len
> 1024)
1357 hb_log("decode_PAT - Bad program section length (> 1024)");
1360 memcpy(tablebuf
+ tablepos
, buf
+ 4 + adapt_len
+ pointer_len
, 184 - adapt_len
- pointer_len
);
1361 tablepos
+= 184 - adapt_len
- pointer_len
;
1364 if (start
&& reading
)
1366 memcpy(tablebuf
+ tablepos
, buf
+ 4 + adapt_len
+ 1, pointer_len
- 1);
1369 unsigned int pos
= 0;
1370 //while (pos < tablepos)
1372 set_buf(tablebuf
+ pos
, tablepos
- pos
, 0);
1374 unsigned char section_id
= get_bits(8);
1376 unsigned int section_len
= get_bits(12);
1377 get_bits(16); // transport_id
1379 get_bits(5); // version_num
1380 get_bits(1); // current_next
1381 get_bits(8); // section_num
1382 get_bits(8); // last_section
1388 // Program Association Section
1389 section_len
-= 5; // Already read transport stream ID, version num, section num, and last section num
1390 section_len
-= 4; // Ignore the CRC
1392 stream
->ts_number_pat_entries
= 0;
1393 while ((curr_pos
< section_len
) && (stream
->ts_number_pat_entries
< kMaxNumberPMTStreams
))
1395 unsigned int pkt_program_num
= get_bits(16);
1396 stream
->pat_info
[stream
->ts_number_pat_entries
].program_number
= pkt_program_num
;
1398 get_bits(3); // Reserved
1399 if (pkt_program_num
== 0)
1401 get_bits(13); // pkt_network_id
1405 unsigned int pkt_program_map_PID
= get_bits(13);
1406 stream
->pat_info
[stream
->ts_number_pat_entries
].program_map_PID
= pkt_program_map_PID
;
1409 stream
->ts_number_pat_entries
++;
1423 pos
+= 3 + section_len
;
1431 static int flushbuf(hb_stream_t
*stream
)
1433 int old_write_index
= stream
->ps_current_write_buffer_index
;
1435 // Flip the buffers and start moving on to the next
1436 stream
->ps_current_write_buffer_index
++;
1437 if (stream
->ps_current_write_buffer_index
> kNumDecodeBuffers
-1)
1438 stream
->ps_current_write_buffer_index
= 0;
1440 if ( (stream
->ps_decode_buffer
[stream
->ps_current_write_buffer_index
].len
!= 0) || (stream
->ps_decode_buffer
[stream
->ps_current_write_buffer_index
].write_pos
!= 0) )
1442 hb_log("flushbuf - new buffer (index %d) has non zero length and write position !", stream
->ps_current_write_buffer_index
);
1446 stream
->ps_current_read_buffer_index
= old_write_index
;
1447 stream
->ps_decode_buffer
[stream
->ps_current_read_buffer_index
].read_pos
= 0;
1452 static int fwrite64(void* buf
, int elsize
, int elnum
, hb_stream_t
* stream
)
1459 int current_write_index
= stream
->ps_current_write_buffer_index
;
1461 if (size
<= stream
->ps_decode_buffer
[current_write_index
].size
- stream
->ps_decode_buffer
[current_write_index
].write_pos
)
1463 memcpy(stream
->ps_decode_buffer
[current_write_index
].data
+ stream
->ps_decode_buffer
[current_write_index
].write_pos
, buf
, size
);
1464 stream
->ps_decode_buffer
[current_write_index
].write_pos
+= size
;
1465 stream
->ps_decode_buffer
[current_write_index
].len
= stream
->ps_decode_buffer
[current_write_index
].write_pos
;
1470 memcpy(stream
->ps_decode_buffer
[current_write_index
].data
+ stream
->ps_decode_buffer
[current_write_index
].write_pos
, buf
, stream
->ps_decode_buffer
[current_write_index
].size
- stream
->ps_decode_buffer
[current_write_index
].write_pos
);
1471 written
+= stream
->ps_decode_buffer
[current_write_index
].size
- stream
->ps_decode_buffer
[current_write_index
].write_pos
;
1472 stream
->ps_decode_buffer
[current_write_index
].write_pos
+= stream
->ps_decode_buffer
[current_write_index
].size
- stream
->ps_decode_buffer
[current_write_index
].write_pos
;
1473 stream
->ps_decode_buffer
[current_write_index
].len
= stream
->ps_decode_buffer
[current_write_index
].write_pos
;
1475 if (flushbuf(stream
))
1477 // FLushing the buffer will have change the current write buffer
1478 current_write_index
= stream
->ps_current_write_buffer_index
;
1480 memcpy(stream
->ps_decode_buffer
[current_write_index
].data
, (unsigned char*)buf
+ written
, size
- written
);
1481 stream
->ps_decode_buffer
[current_write_index
].write_pos
+= size
- written
;
1482 stream
->ps_decode_buffer
[current_write_index
].len
= stream
->ps_decode_buffer
[current_write_index
].write_pos
;
1483 written
+= size
- written
;
1488 if (elnum
== 1 && written
== size
)
1491 return written
/ elsize
;
1494 static int write_pack(hb_stream_t
* stream
, int64_t time
)
1496 unsigned char buf
[64];
1497 set_buf(buf
, 64, 1); // clear buffer
1499 int64_t ext_time
= time
% 300;
1502 set_bits(0x000001ba, 32); // pack id 32
1503 set_bits(1, 2); // 0x01 2
1504 set_bits((unsigned int)(time
>> 30), 3); // system_clock_reference_base 3
1505 set_bits(1, 1); // marker_bit 1
1506 set_bits((unsigned int)(time
>> 15), 15); // system_clock_reference_base 15
1507 set_bits(1, 1); // marker_bit 1
1508 set_bits((unsigned int)time
, 15); // system_clock_reference_base1 15
1509 set_bits(1, 1); // marker_bit 1
1510 set_bits((unsigned int)ext_time
, 9); // system_clock_reference_extension 9
1511 set_bits(1, 1); // marker_bit 1
1512 set_bits(DEMUX
, 22); // program_mux_rate 22
1513 set_bits(1, 1); // marker_bit 1
1514 set_bits(1, 1); // marker_bit 1
1515 set_bits(31, 5); // reserved 5
1516 set_bits(0, 3); // pack_stuffing_length 3
1518 return fwrite64(buf
, buf_size(), 1, stream
) == 1;
1521 static int pad_buffer(hb_stream_t
*stream
, int pad
)
1526 buf
[0] = '\x0'; buf
[1] = '\x0'; buf
[2] = '\x1'; buf
[3] = '\xbe';
1527 buf
[4] = pad
>> 8; buf
[5] = pad
& 0xff;
1529 if (fwrite64(buf
, 6, 1, stream
) != 1)
1532 unsigned char padbyte
= 0xff;
1534 for (i
= 0; i
< pad
; i
++)
1536 if (fwrite64(&padbyte
, 1, 1, stream
) != 1)
1543 int make_pes_header(unsigned char* buf
, int streamid
, int len
, int64_t PTS
, int64_t DTS
)
1546 int PTS_DTS_flags
= 0;
1561 set_buf(buf
, 9 + hdrlen
, 1); // clear the buffer
1563 set_bits(0x000001, 24); // packet_start_code_prefix 24
1564 set_bits((unsigned int)streamid
, 8); // directory_stream_id 8
1565 set_bits(len
, 16); // PES_packet_length 16
1566 set_bits(0x2, 2); // '10' 2
1567 set_bits(0, 2); // PES_scrambling_control 2
1568 set_bits(1, 1); // PES_priority 1
1569 set_bits(0, 1); // data_alignment_indicator 1
1570 set_bits(0, 1); // copyright 1
1571 set_bits(0, 1); // original_or_copy 1
1572 set_bits(PTS_DTS_flags
, 2); // PTS_DTS_flags 2
1573 set_bits(0, 1); // ESCR_flag 1
1574 set_bits(0, 1); // ES_rate_flag 1
1575 set_bits(0, 1); // DSM_trick_mode_flag 1
1576 set_bits(0, 1); // additional_copy_info_flag 1
1577 set_bits(0, 1); // PES_CRC_flag 1
1578 set_bits(0, 1); // PES_extension_flag 1
1579 set_bits(hdrlen
, 8); // PES_header_data_length 8
1581 if (PTS_DTS_flags
== 2)
1583 set_bits(2, 4); // '0010' 4
1584 set_bits((unsigned int)(PTS
>> 30), 3); // PTS [32..30] 3
1585 set_bits(1, 1); // marker bit 1
1586 set_bits((unsigned int)(PTS
>> 15), 15); // PTS [29..15] 15
1587 set_bits(1, 1); // marker bit 1
1588 set_bits((unsigned int)PTS
, 15); // PTS [14..0] 15
1589 set_bits(1, 1); // marker bit 1
1591 else if (PTS_DTS_flags
== 3)
1593 set_bits(3, 4); // '0011' 4
1594 set_bits((unsigned int)(PTS
>> 30), 3); // PTS [32..30] 3
1595 set_bits(1, 1); // marker bit 1
1596 set_bits((unsigned int)(PTS
>> 15), 15); // PTS [29..15] 15
1597 set_bits(1, 1); // marker bit 1
1598 set_bits((unsigned int)PTS
, 15); // PTS [14..0] 15
1599 set_bits(1, 1); // marker bit 1
1600 set_bits(1, 4); // '0001' 4
1601 set_bits((unsigned int)(DTS
>> 30), 3); // DTS [32..30] 3
1602 set_bits(1, 1); // marker bit 1
1603 set_bits((unsigned int)(DTS
>> 15), 15); // DTS [29..15] 15
1604 set_bits(1, 1); // marker bit 1
1605 set_bits((unsigned int)DTS
, 15); // DTS [14..0] 15
1606 set_bits(1, 1); // marker bit 1
1612 int generate_output_data(hb_stream_t
*stream
, int write_ac3
, int curstream
, int pid
)
1614 unsigned char ac3_substream_id
[4];
1619 // Make a four byte DVD ac3 stream header
1620 int ssid
= (curstream
- stream
->ts_number_video_pids
) & 0xf;
1621 ac3_substream_id
[0] = 0x80 | ssid
; // substream id
1622 ac3_substream_id
[1] = 0x01; // number of sync words
1623 ac3_substream_id
[2] = 0x00; // first offset (16 bits)
1624 ac3_substream_id
[3] = 0x02;
1628 int written
= 0; // Bytes we've written to output file
1629 int pos
= 0; // Position in PES packet buffer
1633 if ((stream
->ps_decode_buffer
[stream
->ps_current_write_buffer_index
].len
% HB_DVD_READ_BUFFER_SIZE
) != 0)
1635 hb_log("write_output_stream - Packet's not falling on read buffer size boundries!");
1639 // Get total length of this pack
1640 int len
= min(14 + ac3len
+ stream
->ts_packetpos
[curstream
] - pos
, HB_DVD_READ_BUFFER_SIZE
);
1642 // Figure out stuffing (if we have less than 16 bytes left)
1644 if (len
< HB_DVD_READ_BUFFER_SIZE
&& HB_DVD_READ_BUFFER_SIZE
- len
< 16)
1646 stuffing
= HB_DVD_READ_BUFFER_SIZE
- len
;
1650 // Write out pack header
1651 off_t file_offset
= ftello(stream
->file_handle
);
1652 int64_t packet_time
= (file_offset
* CLOCKRATE
/ STREAMRATE
) + 0 /*file_time*/;
1653 if (!write_pack(stream
, packet_time
))
1655 hb_log("write_output_stream - Couldn't write pack header!");
1659 stream
->ts_packetbuf
[curstream
][pos
+ 3] =
1660 stream
->ts_streamid
[curstream
];
1663 // Subtract pack size (14) and pes id and len (6) from lenth
1664 stream
->ts_packetbuf
[curstream
][pos
+ 4] = (len
- 6 - 14) >> 8; stream
->ts_packetbuf
[curstream
][pos
+ 5] = (len
- 6 - 14) & 0xFF;
1666 // Add any stuffing bytes to header extra len
1667 int hdrsize
= 9 + stream
->ts_packetbuf
[curstream
][pos
+ 8];
1668 stream
->ts_packetbuf
[curstream
][pos
+ 8] += stuffing
; // Add stuffing to header bytes
1670 // Write out id, streamid, len
1671 if (fwrite64(stream
->ts_packetbuf
[curstream
] + pos
, hdrsize
, 1, stream
) != 1) // Write pes id, streamid, and len
1673 hb_log("write_output_stream - Failed to write output file!");
1679 for (i
= 0; i
< stuffing
; i
++) // Write any stuffing bytes
1681 unsigned char stuff
= 0xff;
1682 if (fwrite64(&stuff
, 1, 1, stream
) != 1)
1684 hb_log("write_output_stream - Failed to write output file!");
1689 // Write ac3 streamid
1692 if (fwrite64(ac3_substream_id
, ac3len
, 1, stream
) != 1)
1694 hb_log("write_output_stream - Failed to write output file!");
1699 // Write rest of data len minus headersize (9) stuffing, and pack size (14)
1700 if (fwrite64(stream
->ts_packetbuf
[curstream
] + pos
+ hdrsize
, len
- hdrsize
- 14 - stuffing
- ac3len
, 1, stream
) != 1) // Write data bytes
1702 hb_log("write_output_stream - Failed to write output file!");
1707 // Add len minus stuff we added like the pack (14) and the stuffing.
1708 pos
+= len
- 14 - stuffing
- ac3len
;
1709 if (pos
== stream
->ts_packetpos
[curstream
])
1712 // Add pes header for next packet
1714 make_pes_header(stream
->ts_packetbuf
[curstream
] + pos
, stream
->ts_streamid
[curstream
], 0, -1, -1);
1717 stream
->ts_packetpos
[curstream
] = 0;
1718 stream
->ts_streamcont
[curstream
] = -1;
1721 if ((written
% HB_DVD_READ_BUFFER_SIZE
) != 0)
1723 int left
= HB_DVD_READ_BUFFER_SIZE
- (written
% HB_DVD_READ_BUFFER_SIZE
);
1725 // Pad out to HB_DVD_READ_BUFFER_SIZE bytes
1726 if (!pad_buffer(stream
, left
))
1728 hb_log("write_output_stream - Couldn't write pad buffer!");
1736 static void hb_ts_handle_mpeg_audio(hb_stream_t
*stream
, int curstream
, unsigned char* buf
, int adapt_len
)
1738 // Although we don't have AC3/A52 audio here we can still use the same structure to record this useful information.
1740 stream
->a52_info
[curstream
- stream
->ts_number_video_pids
].flags
= A52_STEREO
;
1741 stream
->a52_info
[curstream
- stream
->ts_number_video_pids
].rate
= 48000 /*Hz*/;
1742 stream
->a52_info
[curstream
- stream
->ts_number_video_pids
].bitrate
= 384000 /*Bps*/;
1745 static int hb_ts_handle_ac3_audio(hb_stream_t
*stream
, int curstream
, unsigned char* buf
, int adapt_len
)
1749 // Make sure we start with 0x0b77
1750 if (stream
->ts_packetbuf
[curstream
][9 + stream
->ts_packetbuf
[curstream
][8]] != 0x0b || stream
->ts_packetbuf
[curstream
][9 + stream
->ts_packetbuf
[curstream
][8] + 1] != 0x77)
1752 spos
= 9 + stream
->ts_packetbuf
[curstream
][8];
1753 dpos
= 9 + stream
->ts_packetbuf
[curstream
][8];
1754 while (spos
<= stream
->ts_packetpos
[curstream
] - 2 && !(stream
->ts_packetbuf
[curstream
][spos
] == 0x0b && stream
->ts_packetbuf
[curstream
][spos
+ 1] == 0x77))
1757 if (!(stream
->ts_packetbuf
[curstream
][spos
] == 0x0b && stream
->ts_packetbuf
[curstream
][spos
+ 1] == 0x77))
1759 hb_log("hb_ts_stream_decode - Couldn't sync AC3 packet!");
1760 stream
->ts_skipbad
[curstream
] = 1;
1764 while (spos
< stream
->ts_packetpos
[curstream
])
1766 stream
->ts_packetbuf
[curstream
][dpos
] = stream
->ts_packetbuf
[curstream
][spos
];
1770 stream
->ts_packetpos
[curstream
] = dpos
;
1773 // Check the next packet to make sure IT starts with a 0x0b77
1775 plen
= 9 + buf
[4 + adapt_len
+ 8];
1776 int pstart
= 4 + adapt_len
+ plen
;
1777 if (buf
[pstart
] != 0x0b || buf
[pstart
+ 1] != 0x77)
1780 while (spos
< 188 - 2 && !(buf
[spos
] == 0x0b && buf
[spos
+ 1] == 0x77))
1782 stream
->ts_packetbuf
[curstream
][stream
->ts_packetpos
[curstream
]] = buf
[spos
];
1783 stream
->ts_packetpos
[curstream
]++;
1787 if (!(buf
[spos
] == 0x0b && buf
[spos
+ 1] == 0x77))
1789 hb_log("hb_ts_stream_decode - Couldn't sync AC3 packet!");
1790 stream
->ts_skipbad
[curstream
] = 1;
1794 adapt_len
= spos
- 4 - plen
;
1798 while (spos
>= pstart
- plen
)
1800 buf
[dpos
] = buf
[spos
];
1806 int flags
, rate
, bitrate
;
1807 if( a52_syncinfo( &buf
[pstart
], &flags
, &rate
, &bitrate
) )
1809 stream
->a52_info
[curstream
- stream
->ts_number_video_pids
].flags
= flags
;
1810 stream
->a52_info
[curstream
- stream
->ts_number_video_pids
].rate
= rate
;
1811 stream
->a52_info
[curstream
- stream
->ts_number_video_pids
].bitrate
= bitrate
;
1816 static void hb_ts_stream_find_pids(hb_stream_t
*stream
)
1818 unsigned char buf
[188];
1820 // align to first packet
1821 align_to_next_packet(stream
->file_handle
);
1823 // Read the Transport Stream Packets (188 bytes each) looking at first for PID 0 (the PAT PID), then decode that
1824 // to find the program map PID and then decode that to get the list of audio and video PIDs
1826 int bytesReadInPacket
= 0;
1829 // Try to read packet..
1831 if ((bytesRead
= fread(buf
+bytesReadInPacket
, 1, 188-bytesReadInPacket
, stream
->file_handle
)) != 188-bytesReadInPacket
)
1835 bytesReadInPacket
+= bytesRead
;
1837 hb_log("hb_ts_stream_find_pids - end of file");
1842 bytesReadInPacket
= 0;
1846 if ((buf
[0] != 0x47) && (buf
[0] != 0x72) && (buf
[0] != 0x29))
1848 hb_log("hb_ts_stream_find_pids - Bad transport packet (no sync byte 0x47)!");
1850 for (i
=0; i
< stream
->ts_number_video_pids
+ stream
->ts_number_audio_pids
; i
++)
1851 stream
->ts_skipbad
[i
] = 1;
1856 int pid
= (((buf
[1] & 0x1F) << 8) | buf
[2]) & 0x1FFF;
1858 if ((pid
== 0x0000) && (stream
->ts_number_pat_entries
== 0))
1860 decode_PAT(buf
, stream
);
1865 for (pat_index
= 0; pat_index
< stream
->ts_number_pat_entries
; pat_index
++)
1867 // There are some streams where the PAT table has multiple entries as if their are
1868 // multiple programs in the same transport stream, and yet there's actually only one
1869 // program really in the stream. This seems to be true for transport streams that
1870 // originate in the HDHomeRun but have been output by EyeTV's export utility. What I think
1871 // is happening is that the HDHomeRun is sending the entire transport stream as broadcast,
1872 // but the EyeTV is only recording a single (selected) program number and not rewriting the
1873 // PAT info on export to match what's actually on the stream.
1874 // Until we have a way of handling multiple programs per transport stream elegantly we'll match
1875 // on the first pat entry for which we find a matching program map PID. The ideal solution would
1876 // be to build a title choice popup from the PAT program number details and then select from
1877 // their - but right now the API's not capable of that.
1878 if (pid
== stream
->pat_info
[pat_index
].program_map_PID
)
1880 if (build_program_map(buf
, stream
) > 0)
1884 // Keep going until we have a complete set of PIDs
1885 if ((stream
->ts_number_video_pids
> 0) && (stream
->ts_number_audio_pids
> 0))
1889 hb_log("hb_ts_stream_find_pids - found the following PIDS");
1890 hb_log(" Video PIDS : ");
1892 for (i
=0; i
< stream
->ts_number_video_pids
; i
++)
1894 hb_log(" 0x%x (%d)", stream
->ts_video_pids
[i
], stream
->ts_video_pids
[i
]);
1896 hb_log(" Audio PIDS : ");
1897 for (i
= 0; i
< stream
->ts_number_audio_pids
; i
++)
1899 hb_log(" 0x%x (%d)", stream
->ts_audio_pids
[i
], stream
->ts_audio_pids
[i
]);
1903 int index_of_video_pid(int pid
, hb_stream_t
*stream
)
1905 int found_pid
= -1, i
= 0;
1907 for (i
= 0; (i
< stream
->ts_number_video_pids
) && (found_pid
< 0); i
++)
1909 if (pid
== stream
->ts_video_pids
[i
])
1915 int index_of_audio_pid(int pid
, hb_stream_t
*stream
)
1917 int i
= 0, found_pid
= -1;
1919 for (i
= 0; (i
< stream
->ts_number_audio_pids
) && (found_pid
< 0); i
++)
1921 if (pid
== stream
->ts_audio_pids
[i
])
1927 int index_of_pid(int pid
, hb_stream_t
*stream
)
1931 if ((found_pid
= index_of_video_pid(pid
, stream
)) >= 0)
1934 if ((found_pid
= index_of_audio_pid(pid
, stream
)) >= 0)
1940 /***********************************************************************
1941 * hb_ts_stream_decode
1942 ***********************************************************************
1944 **********************************************************************/
1945 static void hb_ts_stream_decode(hb_stream_t
*stream
)
1947 unsigned char buf
[188];
1952 for (i
=0; i
< stream
->ts_number_video_pids
+ stream
->ts_number_audio_pids
; i
++)
1954 stream
->ts_skipbad
[i
] = 0;
1959 if ((stream
->ts_number_video_pids
== 0) || (stream
->ts_number_audio_pids
== 0))
1961 hb_log("hb_ts_stream_decode - no Video or Audio PID selected, cannot decode transport stream");
1965 int curr_write_buffer_index
= stream
->ps_current_write_buffer_index
;
1967 // Write output data until a buffer switch occurs.
1968 while (curr_write_buffer_index
== stream
->ps_current_write_buffer_index
)
1970 if ((fread(buf
, 188, 1, stream
->file_handle
)) != 1)
1972 // end of file - we didn't finish filling our ps write buffer
1973 // so just discard the remainder (the partial buffer is useless)
1974 hb_log("hb_ts_stream_decode - eof");
1975 stream
->ps_decode_buffer
[stream
->ps_current_write_buffer_index
].len
= 0;
1980 if ((buf
[0] != 0x47) && (buf
[0] != 0x72) && (buf
[0] != 0x29))
1982 // lost sync - back up to where we started then try to
1983 // re-establish sync.
1984 off_t pos
= ftello(stream
->file_handle
) - 188;
1985 off_t pos2
= align_to_next_packet(stream
->file_handle
);
1988 hb_log( "hb_ts_stream_decode: eof while re-establishing sync @ %lld",
1990 stream
->ps_decode_buffer
[stream
->ps_current_write_buffer_index
].len
= 0;
1993 hb_log("hb_ts_stream_decode: sync lost @%lld, regained after %lld bytes",
1995 for (i
=0; i
< stream
->ts_number_video_pids
+ stream
->ts_number_audio_pids
; i
++)
1997 stream
->ts_skipbad
[i
] = 1;
2003 int pid
= (((buf
[1] & 0x1F) << 8) | buf
[2]) & 0x1FFF;
2005 // Get the pos and buf - we organize our streams as 'n' video streams then 'm' audio streams
2006 int index_of_selected_pid
;
2007 if ((index_of_selected_pid
= index_of_video_pid(pid
,stream
)) < 0)
2009 // Not a video PID perhaps audio ?
2010 if ((index_of_selected_pid
= index_of_audio_pid(pid
,stream
)) < 0)
2012 // not a pid we want
2017 curstream
= stream
->ts_number_video_pids
+ index_of_selected_pid
;
2021 curstream
= index_of_selected_pid
;
2025 start
= (buf
[1] & 0x40) != 0;
2027 if (!start
&& stream
->ts_skipbad
[curstream
])
2031 int errorbit
= (buf
[1] & 0x80) != 0;
2034 hb_log("hb_ts_stream_decode - Error bit set in packet");
2035 stream
->ts_skipbad
[curstream
] = 1;
2039 // Get adaption header info
2040 int adaption
= (buf
[3] & 0x30) >> 4;
2044 // Continuity only increments for adaption values of 0x3 or 0x01
2045 int continuity
= (buf
[3] & 0xF);
2046 if ((stream
->ts_streamcont
[curstream
] != -1) && ((adaption
& 0x01) != 0))
2048 if (continuity
!= ((stream
->ts_streamcont
[curstream
] + 1) & 0xF))
2050 hb_log("hb_ts_stream_decode - Bad continuity code in packet");
2051 stream
->ts_skipbad
[curstream
] = 1;
2054 stream
->ts_streamcont
[curstream
] = continuity
;
2057 // Get adaption header size
2060 hb_log("hb_ts_stream_decode - Bad adaption code (code was 0)!");
2061 for (i
=0; i
< stream
->ts_number_video_pids
+ stream
->ts_number_audio_pids
; i
++)
2063 stream
->ts_skipbad
[i
] = 1;
2067 else if (adaption
== 0x2)
2069 else if (adaption
== 0x3)
2071 adapt_len
= buf
[4] + 1;
2072 if (adapt_len
> 184)
2074 hb_log("hb_ts_stream_decode - Invalid adapt len %d", adapt_len
);
2075 for (i
=0; i
< stream
->ts_number_video_pids
+ stream
->ts_number_audio_pids
; i
++)
2077 stream
->ts_skipbad
[i
] = 1;
2082 // HBO is slick, it doesn't bother to sync AC3 packets with PES elementary stream packets.. so
2083 // we have to swizzle them together! (ARGHH!)
2084 if (start
&& curstream
>= stream
->ts_number_video_pids
&&
2085 stream
->ts_audio_stream_type
[curstream
- stream
->ts_number_video_pids
]
2088 // Is there an AC3 packet start 0b77 code in this packet??
2090 unsigned char *p
= buf
+ 4 + adapt_len
;
2091 while (p
<= buf
+ 186)
2093 if (p
[0] == 0x0b && p
[1] == 0x77)
2101 // Couldn't find an AC3 sync start in this packet.. don't make a PES packet!
2109 // Found a random access point (now we can start a frame/audio packet..)
2112 // Check to see if this is an i_frame (group of picture start)
2113 if (pid
== stream
->ts_video_pids
[0])
2115 // Look for the Group of Pictures packet.. indicates this is an I-Frame packet..
2117 unsigned int strid
= 0;
2119 for (i
= 4 + adapt_len
; i
< 188; i
++)
2121 strid
= (strid
<< 8) | buf
[i
];
2122 if (strid
== 0x000001B8) // group_start_code
2124 // found a Group of Pictures header, subsequent picture must be an I-frame
2127 else if (strid
== 0x000001B3) // sequence_header code
2131 else if (strid
== 0x00000100) // picture_start_code
2133 // picture_header, let's see if it's an I-frame
2136 // check if picture_coding_type == 1
2137 if ((buf
[i
+2] & (0x7 << 3)) == (1 << 3))
2139 // found an I-frame picture
2147 if (!stream
->ts_foundfirst
[curstream
])
2149 stream
->ts_foundfirst
[curstream
] = 1;
2150 // first_video_PCR = PCR;
2156 else if (index_of_audio_pid(pid
, stream
) >= 0)
2158 if (stream
->ts_foundfirst
[0]) // Set audio found first ONLY after first video frame found. There's an assumption here that stream '0' is a video stream
2160 stream
->ts_foundfirst
[curstream
] |= 1;
2164 // If we were skipping a bad packet, start fresh on this new PES packet..
2165 if (stream
->ts_skipbad
[curstream
] == 1)
2167 stream
->ts_skipbad
[curstream
] = 0;
2168 stream
->ts_packetpos
[curstream
] = 0;
2171 // Get the continuity code of this packet
2172 stream
->ts_streamcont
[curstream
] = continuity
;
2175 // Write a 2048 byte program stream packet..
2176 if (start
&& stream
->ts_packetpos
[curstream
] > 0 && stream
->ts_foundfirst
[curstream
] && !stream
->ts_skipbad
[curstream
])
2178 // Save the substream id block so we can added it to subsequent blocks
2180 if (curstream
>= stream
->ts_number_video_pids
)
2182 // Curstream is a zero based index of streams and includes both video and audio streams, so we must subtract the numver of video streams
2183 // from the indes value used here since ts_audio_stream_type is indexed only by audio streams.
2184 if (stream
->ts_audio_stream_type
[curstream
- stream
->ts_number_video_pids
] == 0x03)
2186 hb_ts_handle_mpeg_audio(stream
, curstream
, buf
, adapt_len
);
2190 write_ac3
= hb_ts_handle_ac3_audio(stream
, curstream
, buf
, adapt_len
);
2194 if (generate_output_data(stream
, write_ac3
, curstream
, pid
) != 0)
2198 // Add the payload for this packet to the current buffer
2199 if (!stream
->ts_skipbad
[curstream
] && stream
->ts_foundfirst
[curstream
] &&
2200 (184 - adapt_len
) > 0)
2202 // XXX this shouldn't happen but we'll be paranoid
2203 if (stream
->ts_packetpos
[curstream
] + 184 - adapt_len
> 1024*1024)
2205 hb_log("hb_ts_stream_decode: ts_packetbuf overflow, pos = %d ,"
2206 "len = %d", stream
->ts_packetpos
[curstream
],
2210 memcpy(stream
->ts_packetbuf
[curstream
] + stream
->ts_packetpos
[curstream
], buf
+ 4 + adapt_len
, 184 - adapt_len
);
2211 stream
->ts_packetpos
[curstream
] += 184 - adapt_len
;
2216 /***********************************************************************
2217 * hb_ts_stream_reset
2218 ***********************************************************************
2220 **********************************************************************/
2221 static void hb_ts_stream_reset(hb_stream_t
*stream
)
2224 for (i
=0; i
< kNumDecodeBuffers
; i
++)
2226 stream
->ps_decode_buffer
[i
].read_pos
= 0;
2227 stream
->ps_decode_buffer
[i
].write_pos
= 0;
2228 stream
->ps_decode_buffer
[i
].len
= 0;
2231 for (i
=0; i
< kMaxNumberDecodeStreams
; i
++)
2233 stream
->ts_streamcont
[i
] = -1;
2236 stream
->ps_current_write_buffer_index
= 0;
2237 stream
->ps_current_read_buffer_index
= 1;
2239 align_to_next_packet(stream
->file_handle
);