summaryrefslogtreecommitdiffstats
path: root/libhb/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/stream.c')
-rwxr-xr-xlibhb/stream.c174
1 files changed, 87 insertions, 87 deletions
diff --git a/libhb/stream.c b/libhb/stream.c
index f3f75ce30..0af712c91 100755
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -13,7 +13,7 @@
#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;
-
+
#define kMaxNumberDecodeStreams 8
#define kMaxNumberVideoPIDS 16
#define kMaxNumberAudioPIDS 16
@@ -31,7 +31,7 @@ struct hb_stream_s
char * path;
FILE * file_handle;
hb_stream_type_t stream_type;
-
+
int ps_current_write_buffer_index;
int ps_current_read_buffer_index;
@@ -42,20 +42,20 @@ struct hb_stream_s
int write_pos;
unsigned char * data;
} ps_decode_buffer[kNumDecodeBuffers];
-
+
struct {
int lang_code;
int flags;
int rate;
int bitrate;
} a52_info[kMaxNumberAudioPIDS];
-
+
int ts_video_pids[kMaxNumberVideoPIDS];
int ts_audio_pids[kMaxNumberAudioPIDS];
-
+
int ts_number_video_pids;
int ts_number_audio_pids;
-
+
unsigned char* ts_packetbuf[kMaxNumberDecodeStreams];
int ts_packetpos[kMaxNumberDecodeStreams];
// int ts_bufpackets[kMaxNumberDecodeStreams];
@@ -64,21 +64,21 @@ struct hb_stream_s
int ts_streamcont[kMaxNumberDecodeStreams];
int ts_streamid[kMaxNumberDecodeStreams];
int ts_audio_stream_type[kMaxNumberAudioPIDS];
-
- struct
+
+ 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;
@@ -205,7 +205,7 @@ static void hb_stream_delete( hb_stream_t ** _d )
d->ps_decode_buffer[i].data = NULL;
}
}
-
+
for (i = 0; i < kMaxNumberDecodeStreams; i++)
{
if (d->ts_packetbuf[i])
@@ -304,11 +304,11 @@ hb_title_t * hb_stream_title_scan(hb_stream_t *stream)
char *dot_term = strrchr(aTitle->name, '.');
if (dot_term)
*dot_term = '\0';
-
+
// Height, width, rate and aspect ratio information is filled in when the previews are built
hb_stream_duration(stream, aTitle);
-
+
// One Chapter
hb_chapter_t * chapter;
chapter = calloc( sizeof( hb_chapter_t ), 1 );
@@ -318,7 +318,7 @@ hb_title_t * hb_stream_title_scan(hb_stream_t *stream)
chapter->minutes = aTitle->minutes;
chapter->seconds = aTitle->seconds;
hb_list_add( aTitle->list_chapter, chapter );
-
+
// Figure out how many audio streams we really have:
// - For transport streams, for each PID listed in the PMT (whether
// or not it was an audio stream type) read the bitstream until we
@@ -460,7 +460,7 @@ static uint64_t hb_ps_stream_getVideoPTS(hb_stream_t *stream)
* of the video. This says that we want to compute the rate over relatively
* long segments to get a representative average but long segments increase
* the likelihood that we'll cross a piece boundary.
- *
+ *
* What we do is take time stamp samples at several places in the file
* (currently 16) then compute the average rate (i.e., ticks of video per
* byte of the file) for all pairs of samples (N^2 rates computed for N
@@ -626,7 +626,7 @@ int hb_stream_read( hb_stream_t * src_stream, hb_buffer_t * b )
}
else
{
- // Not quite enough data in the buffer - transfer what is present, fill the buffer and then
+ // Not quite enough data in the buffer - transfer what is present, fill the buffer and then
// transfer what's still needed.
int transfer_size = HB_DVD_READ_BUFFER_SIZE;
int amt_avail_to_transfer = src_stream->ps_decode_buffer[read_buffer_index].len - src_stream->ps_decode_buffer[read_buffer_index].read_pos;
@@ -637,25 +637,25 @@ int hb_stream_read( hb_stream_t * src_stream, hb_buffer_t * b )
src_stream->ps_decode_buffer[read_buffer_index].read_pos = 0;
src_stream->ps_decode_buffer[read_buffer_index].write_pos = 0;
src_stream->ps_decode_buffer[read_buffer_index].len = 0;
-
+
// Fill the buffer
hb_ts_stream_decode(src_stream);
-
+
// Decoding will almost certainly have changed the current read buffer index
read_buffer_index = src_stream->ps_current_read_buffer_index;
-
+
if (src_stream->ps_decode_buffer[read_buffer_index].len == 0)
{
hb_log("hb_stream_read - buffer after decode has zero length data");
return 0;
}
-
+
// Read the bit we still need
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);
src_stream->ps_decode_buffer[read_buffer_index].read_pos += transfer_size;
-
+
return 1;
- }
+ }
}
else
return 0;
@@ -676,20 +676,20 @@ int hb_stream_seek( hb_stream_t * src_stream, float f )
new_pos = (off_t) ((double) (stream_size) * pos_ratio);
new_pos &=~ (HB_DVD_READ_BUFFER_SIZE - 1);
int r = fseeko(src_stream->file_handle, new_pos, SEEK_SET);
-
+
if (r == -1)
{
fseeko(src_stream->file_handle, cur_pos, SEEK_SET);
return 0;
}
-
+
if (src_stream->stream_type == hb_stream_type_transport)
{
// We need to drop the current decoder output and move
// forwards to the next transport stream packet.
hb_ts_stream_reset(src_stream);
}
-
+
// Now we must scan forwards for a valid start code (0x000001BA)
int done = 0;
hb_buffer_t *buf = hb_buffer_init(HB_DVD_READ_BUFFER_SIZE);
@@ -810,7 +810,7 @@ static void hb_ps_stream_find_audio_ids(hb_stream_t *stream, hb_title_t *title)
// start looking 20% into the file since there's occasionally no
// audio at the beginning (particularly for vobs).
hb_stream_seek(stream, 0.2f);
-
+
while (--blksleft >= 0 && hb_stream_read(stream, buf) == 1)
{
hb_buffer_t *es;
@@ -850,7 +850,7 @@ static void hb_ps_stream_find_audio_ids(hb_stream_t *stream, hb_title_t *title)
void hb_stream_update_audio(hb_stream_t *stream, hb_audio_t *audio)
{
iso639_lang_t *lang;
-
+
if (stream->stream_type == hb_stream_type_transport)
{
// Find the audio stream info for this PID. The stream index is
@@ -870,7 +870,7 @@ void hb_stream_update_audio(hb_stream_t *stream, hb_audio_t *audio)
stream->a52_info[i].rate = 48000 /*Hz*/;
stream->a52_info[i].bitrate = 384000 /*Bps*/;
}
-
+
lang = lang_for_code(stream->a52_info[i].lang_code);
if (!audio->rate)
audio->rate = stream->a52_info[i].rate;
@@ -885,7 +885,7 @@ void hb_stream_update_audio(hb_stream_t *stream, hb_audio_t *audio)
// XXX should try to get language code from the AC3 bitstream
lang = lang_for_code(0x0000);
}
-
+
if (!audio->input_channel_layout)
{
switch( audio->ac3flags & A52_CHANNEL_MASK )
@@ -934,7 +934,7 @@ void hb_stream_update_audio(hb_stream_t *stream, hb_audio_t *audio)
audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
}
}
-
+
snprintf( audio->lang, sizeof( audio->lang ), "%s (%s)", strlen(lang->native_name) ? lang->native_name : lang->eng_name,
audio->codec == HB_ACODEC_AC3 ? "AC3" : ( audio->codec == HB_ACODEC_MPGA ? "MPEG" : ( audio->codec == HB_ACODEC_DCA ? "DTS" : "LPCM" ) ) );
snprintf( audio->lang_simple, sizeof( audio->lang_simple ), "%s", strlen(lang->native_name) ? lang->native_name : lang->eng_name );
@@ -971,8 +971,8 @@ static void hb_stream_put_back(hb_stream_t *stream, int i)
else if (stream->stream_type == hb_stream_type_transport)
{
int read_buffer_index = stream->ps_current_read_buffer_index;
-
- // Transport streams are a little more tricky - so long as the
+
+ // Transport streams are a little more tricky - so long as the
// amount to back up is still within the current decode buffer
// we can just adjust the read pos.
if (stream->ps_decode_buffer[read_buffer_index].read_pos - i > 0)
@@ -991,7 +991,7 @@ static void hb_stream_put_back(hb_stream_t *stream, int i)
*
**********************************************************************/
#define PS_DECODE_BUFFER_SIZE ( 1024 * 1024 * 4)
-
+
static void hb_ts_stream_init(hb_stream_t *stream)
{
// Output Program Stream
@@ -1004,25 +1004,25 @@ static void hb_ts_stream_init(hb_stream_t *stream)
stream->ps_decode_buffer[i].len = 0;
stream->ps_decode_buffer[i].write_pos = 0;
}
-
+
for (i=0; i < kMaxNumberDecodeStreams; i++)
{
stream->ts_streamcont[i] = -1;
}
-
+
stream->ps_current_write_buffer_index = 0;
stream->ps_current_read_buffer_index = 1;
-
+
// Find the audio and video pids in the stream
hb_ts_stream_find_pids(stream);
-
+
for (i=0; i < stream->ts_number_video_pids; i++)
{
// In progress audio/video data during the transport stream -> program stream processing
stream->ts_packetbuf[i] = (unsigned char *) malloc(1024 * 1024);
stream->ts_streamid[i] = 0xE0; // Stream is Video
}
-
+
for (i = stream->ts_number_video_pids; i < stream->ts_number_video_pids + stream->ts_number_audio_pids; i++)
{
stream->ts_packetbuf[i] = (unsigned char *) malloc(1024 * 1024);
@@ -1134,7 +1134,7 @@ static inline unsigned int get_bits(int bits)
int pos = bitpos >> 3;
bitval = (bitbuf[pos] << 24) | (bitbuf[pos + 1] << 16) | (bitbuf[pos + 2] << 8) | bitbuf[pos + 3];
-
+
if (bits > 0)
{
val |= (bitval >> (32 - bits)) & bitmask[bits];
@@ -1198,8 +1198,8 @@ int decode_program_map(hb_stream_t* stream)
for (i = 0; i < program_info_length; i++)
{
descriptor_buf[i] = get_bits(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)
@@ -1209,14 +1209,14 @@ int decode_program_map(hb_stream_t* stream)
unsigned int elementary_PID = get_bits(13);
get_bits(4);
unsigned int ES_info_length = get_bits(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);
}
-
+
if (stream_type == 0x02)
{
if (stream->ts_number_video_pids <= kMaxNumberVideoPIDS)
@@ -1236,7 +1236,7 @@ int decode_program_map(hb_stream_t* stream)
stream->ts_number_audio_pids++;
stream->ts_audio_pids[i] = elementary_PID;
stream->ts_audio_stream_type[i] = stream_type;
-
+
if (ES_info_length > 0)
{
decode_element_descriptors(stream, i, ES_info_buf, ES_info_length);
@@ -1244,13 +1244,13 @@ int decode_program_map(hb_stream_t* stream)
}
cur_pos += 5 /* stream header */ + ES_info_length;
-
+
free(ES_info_buf);
-
+
if (cur_pos >= section_length - 4 /* stop before the CRC */)
done_reading_stream_types = 1;
}
-
+
free(descriptor_buf);
return 1;
}
@@ -1295,7 +1295,7 @@ int build_program_map(unsigned char *buf, hb_stream_t *stream)
{
pointer_len = buf[4 + adapt_len] + 1;
stream->pmt_info.tablepos = 0;
- }
+ }
// Get Continuity Counter
int continuity_counter = buf[3] & 0x0f;
if (!start && (stream->pmt_info.current_continuity_counter + 1 != continuity_counter))
@@ -1311,7 +1311,7 @@ int build_program_map(unsigned char *buf, hb_stream_t *stream)
if (stream->pmt_info.reading && (amount_to_copy > 0))
{
stream->pmt_info.tablebuf = realloc(stream->pmt_info.tablebuf, stream->pmt_info.tablepos + amount_to_copy);
-
+
memcpy(stream->pmt_info.tablebuf + stream->pmt_info.tablepos, buf + 4 + adapt_len + pointer_len, amount_to_copy);
stream->pmt_info.tablepos += amount_to_copy;
}
@@ -1323,7 +1323,7 @@ int decode_PAT(unsigned char *buf, hb_stream_t *stream)
{
unsigned char tablebuf[1024];
unsigned int tablepos = 0;
-
+
int reading = 0;
@@ -1365,7 +1365,7 @@ int decode_PAT(unsigned char *buf, hb_stream_t *stream)
{
memcpy(tablebuf + tablepos, buf + 4 + adapt_len + 1, pointer_len - 1);
-
+
unsigned int pos = 0;
//while (pos < tablepos)
{
@@ -1394,7 +1394,7 @@ int decode_PAT(unsigned char *buf, hb_stream_t *stream)
{
unsigned int pkt_program_num = get_bits(16);
stream->pat_info[stream->ts_number_pat_entries].program_number = pkt_program_num;
-
+
get_bits(3); // Reserved
if (pkt_program_num == 0)
{
@@ -1436,16 +1436,16 @@ static int flushbuf(hb_stream_t *stream)
stream->ps_current_write_buffer_index++;
if (stream->ps_current_write_buffer_index > kNumDecodeBuffers-1)
stream->ps_current_write_buffer_index = 0;
-
+
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) )
{
hb_log("flushbuf - new buffer (index %d) has non zero length and write position !", stream->ps_current_write_buffer_index);
return 0;
}
-
+
stream->ps_current_read_buffer_index = old_write_index;
stream->ps_decode_buffer[stream->ps_current_read_buffer_index].read_pos = 0;
-
+
return 1;
}
@@ -1454,10 +1454,10 @@ static int fwrite64(void* buf, int elsize, int elnum, hb_stream_t* stream)
int size = elsize;
if (elnum > 1)
size *= elnum;
-
+
int written = 0;
int current_write_index = stream->ps_current_write_buffer_index;
-
+
if (size <= stream->ps_decode_buffer[current_write_index].size - stream->ps_decode_buffer[current_write_index].write_pos)
{
memcpy(stream->ps_decode_buffer[current_write_index].data + stream->ps_decode_buffer[current_write_index].write_pos, buf, size);
@@ -1476,7 +1476,7 @@ static int fwrite64(void* buf, int elsize, int elnum, hb_stream_t* stream)
{
// FLushing the buffer will have change the current write buffer
current_write_index = stream->ps_current_write_buffer_index;
-
+
memcpy(stream->ps_decode_buffer[current_write_index].data, (unsigned char*)buf + written, size - written);
stream->ps_decode_buffer[current_write_index].write_pos += size - written;
stream->ps_decode_buffer[current_write_index].len = stream->ps_decode_buffer[current_write_index].write_pos;
@@ -1577,7 +1577,7 @@ int make_pes_header(unsigned char* buf, int streamid, int len, int64_t PTS, int6
set_bits(0, 1); // PES_CRC_flag 1
set_bits(0, 1); // PES_extension_flag 1
set_bits(hdrlen, 8); // PES_header_data_length 8
-
+
if (PTS_DTS_flags == 2)
{
set_bits(2, 4); // '0010' 4
@@ -1613,7 +1613,7 @@ int generate_output_data(hb_stream_t *stream, int write_ac3, int curstream, int
{
unsigned char ac3_substream_id[4];
int ac3len = 0;
-
+
if (write_ac3)
{
// Make a four byte DVD ac3 stream header
@@ -1624,10 +1624,10 @@ int generate_output_data(hb_stream_t *stream, int write_ac3, int curstream, int
ac3_substream_id[3] = 0x02;
ac3len = 4;
}
-
+
int written = 0; // Bytes we've written to output file
int pos = 0; // Position in PES packet buffer
-
+
for (;;)
{
if ((stream->ps_decode_buffer[stream->ps_current_write_buffer_index].len % HB_DVD_READ_BUFFER_SIZE) != 0)
@@ -1673,7 +1673,7 @@ int generate_output_data(hb_stream_t *stream, int write_ac3, int curstream, int
hb_log("write_output_stream - Failed to write output file!");
return 1;
}
-
+
// Write stuffing
int i=0;
for (i = 0; i < stuffing; i++) // Write any stuffing bytes
@@ -1736,7 +1736,7 @@ int generate_output_data(hb_stream_t *stream, int write_ac3, int curstream, int
static void hb_ts_handle_mpeg_audio(hb_stream_t *stream, int curstream, unsigned char* buf, int adapt_len )
{
// Although we don't have AC3/A52 audio here we can still use the same structure to record this useful information.
-
+
stream->a52_info[curstream - stream->ts_number_video_pids].flags = A52_STEREO;
stream->a52_info[curstream - stream->ts_number_video_pids].rate = 48000 /*Hz*/;
stream->a52_info[curstream - stream->ts_number_video_pids].bitrate = 384000 /*Bps*/;
@@ -1822,7 +1822,7 @@ static void hb_ts_stream_find_pids(hb_stream_t *stream)
// Read the Transport Stream Packets (188 bytes each) looking at first for PID 0 (the PAT PID), then decode that
// to find the program map PID and then decode that to get the list of audio and video PIDs
-
+
int bytesReadInPacket = 0;
for (;;)
{
@@ -1835,7 +1835,7 @@ static void hb_ts_stream_find_pids(hb_stream_t *stream)
bytesReadInPacket += bytesRead;
hb_log("hb_ts_stream_find_pids - end of file");
- break;
+ break;
}
else
{
@@ -1854,13 +1854,13 @@ static void hb_ts_stream_find_pids(hb_stream_t *stream)
// Get pid
int pid = (((buf[1] & 0x1F) << 8) | buf[2]) & 0x1FFF;
-
+
if ((pid == 0x0000) && (stream->ts_number_pat_entries == 0))
{
decode_PAT(buf, stream);
continue;
}
-
+
int pat_index = 0;
for (pat_index = 0; pat_index < stream->ts_number_pat_entries; pat_index++)
{
@@ -1868,8 +1868,8 @@ static void hb_ts_stream_find_pids(hb_stream_t *stream)
// multiple programs in the same transport stream, and yet there's actually only one
// program really in the stream. This seems to be true for transport streams that
// originate in the HDHomeRun but have been output by EyeTV's export utility. What I think
- // is happening is that the HDHomeRun is sending the entire transport stream as broadcast,
- // but the EyeTV is only recording a single (selected) program number and not rewriting the
+ // is happening is that the HDHomeRun is sending the entire transport stream as broadcast,
+ // but the EyeTV is only recording a single (selected) program number and not rewriting the
// PAT info on export to match what's actually on the stream.
// Until we have a way of handling multiple programs per transport stream elegantly we'll match
// on the first pat entry for which we find a matching program map PID. The ideal solution would
@@ -1885,7 +1885,7 @@ static void hb_ts_stream_find_pids(hb_stream_t *stream)
if ((stream->ts_number_video_pids > 0) && (stream->ts_number_audio_pids > 0))
break;
}
-
+
hb_log("hb_ts_stream_find_pids - found the following PIDS");
hb_log(" Video PIDS : ");
int i=0;
@@ -1903,7 +1903,7 @@ static void hb_ts_stream_find_pids(hb_stream_t *stream)
int index_of_video_pid(int pid, hb_stream_t *stream)
{
int found_pid = -1, i = 0;
-
+
for (i = 0; (i < stream->ts_number_video_pids) && (found_pid < 0); i++)
{
if (pid == stream->ts_video_pids[i])
@@ -1927,13 +1927,13 @@ int index_of_audio_pid(int pid, hb_stream_t *stream)
int index_of_pid(int pid, hb_stream_t *stream)
{
int found_pid = -1;
-
+
if ((found_pid = index_of_video_pid(pid, stream)) >= 0)
return found_pid;
-
+
if ((found_pid = index_of_audio_pid(pid, stream)) >= 0)
return found_pid;
-
+
return found_pid;
}
@@ -1947,23 +1947,23 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
unsigned char buf[188];
int curstream;
int doing_iframe;
-
+
int i = 0;
for (i=0; i < stream->ts_number_video_pids + stream->ts_number_audio_pids; i++)
{
stream->ts_skipbad[i] = 0;
}
-
+
doing_iframe = 0;
-
+
if ((stream->ts_number_video_pids == 0) || (stream->ts_number_audio_pids == 0))
{
hb_log("hb_ts_stream_decode - no Video or Audio PID selected, cannot decode transport stream");
return;
}
-
+
int curr_write_buffer_index = stream->ps_current_write_buffer_index;
-
+
// Write output data until a buffer switch occurs.
while (curr_write_buffer_index == stream->ps_current_write_buffer_index)
{
@@ -1979,7 +1979,7 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
// Check sync byte
if ((buf[0] != 0x47) && (buf[0] != 0x72) && (buf[0] != 0x29))
{
- // lost sync - back up to where we started then try to
+ // lost sync - back up to where we started then try to
// re-establish sync.
off_t pos = ftello(stream->file_handle) - 188;
off_t pos2 = align_to_next_packet(stream->file_handle);
@@ -2019,11 +2019,11 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
}
else
curstream = index_of_selected_pid;
-
+
// Get start code
int start;
start = (buf[1] & 0x40) != 0;
-
+
if (!start && stream->ts_skipbad[curstream])
continue;
@@ -2053,7 +2053,7 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
}
stream->ts_streamcont[curstream] = continuity;
}
-
+
// Get adaption header size
if (adaption == 0)
{
@@ -2101,7 +2101,7 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
// Couldn't find an AC3 sync start in this packet.. don't make a PES packet!
if (!sync_found)
{
- adapt_len = 184;
+ adapt_len = 184;
start = 0;
}
}
@@ -2160,7 +2160,7 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
stream->ts_foundfirst[curstream] |= 1;
}
}
-
+
// If we were skipping a bad packet, start fresh on this new PES packet..
if (stream->ts_skipbad[curstream] == 1)
{
@@ -2190,7 +2190,7 @@ static void hb_ts_stream_decode(hb_stream_t *stream)
write_ac3 = hb_ts_handle_ac3_audio(stream, curstream, buf, adapt_len);
}
}
-
+
if (generate_output_data(stream, write_ac3, curstream, pid) != 0)
return ;
}