X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Fty.c;h=9c27d97e0a848c2d1c0acd42ab2a70e33f05d3cb;hb=a7c0e2a065b845e9bdd7f00bb7bd8e86a93b5dbe;hp=98d48ca831faf6188a136a6cb9e1f94c614c102f;hpb=3561b9b28f58eb7a4183e158a8fd973800d31ceb;p=vlc diff --git a/modules/demux/ty.c b/modules/demux/ty.c index 98d48ca831..9c27d97e0a 100644 --- a/modules/demux/ty.c +++ b/modules/demux/ty.c @@ -42,9 +42,9 @@ #include #include #include -#include "vlc_codec.h" -#include "vlc_meta.h" -#include "vlc_input.h" +#include +#include +#include #include "../codec/cc.h" #include @@ -55,20 +55,20 @@ static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); -vlc_module_begin(); - set_shortname( N_("TY") ); - set_description(N_("TY Stream audio/video demux")); - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_DEMUX ); - set_capability("demux", 6); +vlc_module_begin () + set_shortname( N_("TY") ) + set_description(N_("TY Stream audio/video demux")) + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_DEMUX ) + set_capability("demux", 6) /* FIXME: there seems to be a segfault when using PVR access * and TY demux has a bigger priority than PS * Something must be wrong. */ - set_callbacks( Open, Close ); - add_shortcut("ty"); - add_shortcut("tivo"); -vlc_module_end(); + set_callbacks( Open, Close ) + add_shortcut("ty") + add_shortcut("tivo") +vlc_module_end () /***************************************************************************** * Local prototypes @@ -116,7 +116,7 @@ static const uint8_t ty_AC3AudioPacket[] = { 0x00, 0x00, 0x01, 0xbd }; typedef struct { long l_rec_size; - uint8_t ex1, ex2; + uint8_t ex[2]; uint8_t rec_type; uint8_t subrec_type; bool b_ext; @@ -241,8 +241,8 @@ struct demux_sys_t //mtime_t l_last_ty_pts_sync; /* audio PTS at time of last TY PTS */ uint64_t l_first_ty_pts; /* first TY PTS in this master chunk */ uint64_t l_final_ty_pts; /* final TY PTS in this master chunk */ - int i_seq_table_size; /* number of entries in SEQ table */ - int i_bits_per_seq_entry; /* # of bits in SEQ table bitmask */ + unsigned i_seq_table_size; /* number of entries in SEQ table */ + unsigned i_bits_per_seq_entry; /* # of bits in SEQ table bitmask */ mtime_t firstAudioPTS; mtime_t lastAudioPTS; @@ -264,7 +264,7 @@ static int find_es_header( const uint8_t *header, static int ty_stream_seek_pct(demux_t *p_demux, double seek_pct); static int ty_stream_seek_time(demux_t *, uint64_t); -static ty_rec_hdr_t *parse_chunk_headers( demux_t *p_demux, const uint8_t *p_buf, +static ty_rec_hdr_t *parse_chunk_headers( const uint8_t *p_buf, int i_num_recs, int *pi_payload_size); static int probe_stream(demux_t *p_demux); static void analyze_chunk(demux_t *p_demux, const uint8_t *p_chunk); @@ -331,6 +331,8 @@ static int Open(vlc_object_t *p_this) p_sys->b_first_chunk = true; p_sys->b_have_master = (U32_AT(p_peek) == TIVO_PES_FILEID); p_sys->firstAudioPTS = -1; + p_sys->lastAudioPTS = VLC_TS_INVALID; + p_sys->lastVideoPTS = VLC_TS_INVALID; p_sys->i_stream_size = stream_Size(p_demux->s); p_sys->tivo_type = TIVO_TYPE_UNKNOWN; p_sys->audio_type = TIVO_AUDIO_UNKNOWN; @@ -352,15 +354,15 @@ static int Open(vlc_object_t *p_this) /* register the proper audio codec */ if (p_sys->audio_type == TIVO_AUDIO_MPEG) { - es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'm', 'p', 'g', 'a' ) ); + es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_MPGA ); } else { - es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'a', '5', '2', ' ' ) ); + es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_A52 ); } fmt.i_group = TY_ES_GROUP; p_sys->p_audio = es_out_Add( p_demux->out, &fmt ); /* register the video stream */ - es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC( 'm', 'p', 'g', 'v' ) ); + es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_MPGV ); fmt.i_group = TY_ES_GROUP; p_sys->p_video = es_out_Add( p_demux->out, &fmt ); @@ -441,7 +443,7 @@ static int Demux( demux_t *p_demux ) /* set these as 'unknown' for now */ p_block_in->i_pts = - p_block_in->i_dts = 0; + p_block_in->i_dts = VLC_TS_INVALID; } /*else { @@ -505,7 +507,7 @@ static int Control(demux_t *p_demux, int i_query, va_list args) if( ( i64 = p_sys->i_stream_size ) > 0 ) { pf = (double*) va_arg( args, double* ); - *pf = (double)stream_Tell( p_demux->s ) / (double) i64; + *pf = ((double)1.0) * stream_Tell( p_demux->s ) / (double) i64; return VLC_SUCCESS; } return VLC_EGENERIC; @@ -607,7 +609,7 @@ static int check_sync_pes( demux_t *p_demux, block_t *p_block, if( offset < 0 ) { /* no header found, fake some 00's (this works, believe me) */ - memset( p_sys->pes_buffer, 4, 0 ); + memset( p_sys->pes_buffer, 0, 4 ); p_sys->i_pes_buf_cnt = 4; if( rec_len > 4 ) msg_Err( p_demux, "PES header not found in record of %d bytes!", @@ -628,8 +630,8 @@ static int check_sync_pes( demux_t *p_demux, block_t *p_block, return -1; /* partial PES, no audio data */ } /* full PES header present, extract PTS */ - p_sys->lastAudioPTS = get_pts( &p_block->p_buffer[ offset + - p_sys->i_Pts_Offset ] ); + p_sys->lastAudioPTS = VLC_TS_0 + get_pts( &p_block->p_buffer[ offset + + p_sys->i_Pts_Offset ] ); if (p_sys->firstAudioPTS < 0) p_sys->firstAudioPTS = p_sys->lastAudioPTS; p_block->i_pts = p_sys->lastAudioPTS; @@ -691,7 +693,7 @@ static int DemuxRecVideo( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl { //msg_Dbg(p_demux, "Video PES hdr in pkt type 0x%02x at offset %d", //subrec_type, esOffset1); - p_sys->lastVideoPTS = get_pts( + p_sys->lastVideoPTS = VLC_TS_0 + get_pts( &p_block_in->p_buffer[ esOffset1 + VIDEO_PTS_OFFSET ] ); /*msg_Dbg(p_demux, "Video rec %d PTS %"PRId64, p_sys->i_cur_rec, p_sys->lastVideoPTS );*/ @@ -748,13 +750,13 @@ static int DemuxRecVideo( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl //p_sys->l_last_ty_pts += 33366667; } /* set PTS for this block before we send */ - if (p_sys->lastVideoPTS > 0) + if (p_sys->lastVideoPTS > VLC_TS_INVALID) { p_block_in->i_pts = p_sys->lastVideoPTS; /* PTS gets used ONCE. * Any subsequent frames we get BEFORE next PES * header will have their PTS computed in the codec */ - p_sys->lastVideoPTS = 0; + p_sys->lastVideoPTS = VLC_TS_INVALID; } } @@ -780,33 +782,26 @@ static int DemuxRecVideo( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl continue; es_format_Init( &fmt, SPU_ES, fcc[i] ); - fmt.psz_description = strdup( _(ppsz_description[i]) ); + fmt.psz_description = strdup( vlc_gettext(ppsz_description[i]) ); fmt.i_group = TY_ES_GROUP; p_sys->p_cc[i] = es_out_Add( p_demux->out, &fmt ); es_format_Clean( &fmt ); } /* Send the CC data */ - if( p_block_in->i_pts > 0 && p_sys->cc.i_data > 0 ) + if( p_block_in->i_pts > VLC_TS_INVALID && p_sys->cc.i_data > 0 ) { - int i_cc_count; - - block_t *p_cc = block_New( p_demux, p_sys->cc.i_data ); - p_cc->i_flags |= BLOCK_FLAG_TYPE_I; - p_cc->i_pts = p_block_in->i_pts; - memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data ); - - for( i = 0, i_cc_count = 0; i < 4; i++ ) - i_cc_count += p_sys->p_cc[i] ? 1 : 0; - for( i = 0; i < 4; i++ ) { - if( !p_sys->p_cc[i] ) - continue; - if( i_cc_count > 1 ) - es_out_Send( p_demux->out, p_sys->p_cc[i], block_Duplicate( p_cc ) ); - else + if( p_sys->p_cc[i] ) + { + block_t *p_cc = block_New( p_demux, p_sys->cc.i_data ); + p_cc->i_flags |= BLOCK_FLAG_TYPE_I; + p_cc->i_pts = p_block_in->i_pts; + memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data ); + es_out_Send( p_demux->out, p_sys->p_cc[i], p_cc ); + } } cc_Flush( &p_sys->cc ); } @@ -828,10 +823,10 @@ static int DemuxRecAudio( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl return -1; #if 0 int i; - printf( "Audio Packet Header " ); + fprintf( stderr, "Audio Packet Header " ); for( i = 0 ; i < 24 ; i++ ) - printf( "%2.2x ", p_block_in->p_buffer[i] ); - printf( "\n" ); + fprintf( stderr, "%2.2x ", p_block_in->p_buffer[i] ); + fprintf( stderr, "\n" ); #endif if( subrec_type == 2 ) @@ -878,7 +873,7 @@ static int DemuxRecAudio( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl } else { - p_sys->lastAudioPTS = get_pts( + p_sys->lastAudioPTS = VLC_TS_0 + get_pts( &p_sys->pes_buffer[ esOffset1 + p_sys->i_Pts_Offset ] ); p_block_in->i_pts = p_sys->lastAudioPTS; } @@ -917,7 +912,7 @@ static int DemuxRecAudio( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl /* ================================================ */ if ( ( esOffset1 == 0 ) && ( l_rec_size == 16 ) ) { - p_sys->lastAudioPTS = get_pts( &p_block_in->p_buffer[ + p_sys->lastAudioPTS = VLC_TS_0 + get_pts( &p_block_in->p_buffer[ SA_PTS_OFFSET ] ); if (p_sys->firstAudioPTS < 0) p_sys->firstAudioPTS = p_sys->lastAudioPTS; @@ -960,7 +955,7 @@ static int DemuxRecAudio( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl /*msg_Dbg(p_demux, "Adding SA Audio Packet Size %ld", l_rec_size ); */ - if (p_sys->lastAudioPTS > 0) + if (p_sys->lastAudioPTS > VLC_TS_INVALID ) p_block_in->i_pts = p_sys->lastAudioPTS; } else if( subrec_type == 0x09 ) @@ -1011,7 +1006,7 @@ static int DemuxRecAudio( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_bl } /* set PCR before we send (if PTS found) */ - if( p_block_in->i_pts > 0 ) + if( p_block_in->i_pts > VLC_TS_INVALID ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_in->i_pts ); /* Send data */ @@ -1023,7 +1018,6 @@ static int DemuxRecCc( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_block { demux_sys_t *p_sys = p_demux->p_sys; int i_field; - int i_channel; if( p_block_in ) block_Release(p_block_in); @@ -1037,19 +1031,12 @@ static int DemuxRecCc( demux_t *p_demux, ty_rec_hdr_t *rec_hdr, block_t *p_block /* XDS data (extract programs infos) transmitted on field 2 only */ if( i_field == 1 ) - DemuxDecodeXds( p_demux, rec_hdr->ex1, rec_hdr->ex2 ); + DemuxDecodeXds( p_demux, rec_hdr->ex[0], rec_hdr->ex[1] ); if( p_sys->cc.i_data + 3 > CC_MAX_DATA_SIZE ) return 0; - p_sys->cc.p_data[p_sys->cc.i_data+0] = i_field; - p_sys->cc.p_data[p_sys->cc.i_data+1] = rec_hdr->ex1; - p_sys->cc.p_data[p_sys->cc.i_data+2] = rec_hdr->ex2; - p_sys->cc.i_data += 3; - - i_channel = cc_Channel( i_field, &p_sys->cc.p_data[p_sys->cc.i_data-3 + 1] ); - if( i_channel >= 0 && i_channel < 4 ) - p_sys->cc.pb_present[i_channel] = true; + cc_AppendData( &p_sys->cc, i_field, rec_hdr->ex ); return 0; } @@ -1058,8 +1045,9 @@ static int ty_stream_seek_pct(demux_t *p_demux, double seek_pct) { demux_sys_t *p_sys = p_demux->p_sys; int64_t seek_pos = p_sys->i_stream_size * seek_pct; - int i, i_cur_part; long l_skip_amt; + int i; + unsigned i_cur_part; /* if we're not seekable, there's nothing to do */ if (!p_sys->b_seekable) @@ -1103,8 +1091,7 @@ static int ty_stream_seek_pct(demux_t *p_demux, double seek_pct) (p_sys->i_num_recs * 16) + l_skip_amt + 4); /* to hell with syncing any audio or video, just start reading records... :) */ - /*p_sys->lastAudioPTS = p_sys->lastVideoPTS = 0;*/ - es_out_Control( p_demux->out, ES_OUT_RESET_PCR ); + /*p_sys->lastAudioPTS = p_sys->lastVideoPTS = VLC_TS_INVALID;*/ return VLC_SUCCESS; } @@ -1480,10 +1467,11 @@ static void DemuxDecodeXds( demux_t *p_demux, uint8_t d1, uint8_t d2 ) static int ty_stream_seek_time(demux_t *p_demux, uint64_t l_seek_time) { demux_sys_t *p_sys = p_demux->p_sys; - int i, i_seq_entry = 0; + int i_seq_entry = 0; int i_skip_cnt; + unsigned i; long l_cur_pos = stream_Tell(p_demux->s); - int i_cur_part = l_cur_pos / TIVO_PART_LENGTH; + unsigned i_cur_part = l_cur_pos / TIVO_PART_LENGTH; long l_seek_secs = l_seek_time / 1000000000; uint64_t l_fwd_stamp = 1; @@ -1606,8 +1594,8 @@ static int ty_stream_seek_time(demux_t *p_demux, uint64_t l_seek_time) so we need to skip past any stream data prior to the seq_rec in this chunk */ i_skip_cnt = 0; - for (i=0; ii_seq_rec; i++) - i_skip_cnt += p_sys->rec_hdrs[i].l_rec_size; + for (int j=0; ji_seq_rec; j++) + i_skip_cnt += p_sys->rec_hdrs[j].l_rec_size; stream_Read(p_demux->s, NULL, i_skip_cnt); p_sys->i_cur_rec = p_sys->i_seq_rec; //p_sys->l_last_ty_pts = p_sys->rec_hdrs[p_sys->i_seq_rec].l_ty_pts; @@ -1624,7 +1612,7 @@ static void parse_master(demux_t *p_demux) { demux_sys_t *p_sys = p_demux->p_sys; uint8_t mst_buf[32]; - int i, i_map_size; + uint32_t i, i_map_size; int64_t i_save_pos = stream_Tell(p_demux->s); int64_t i_pts_secs; @@ -1645,14 +1633,20 @@ static void parse_master(demux_t *p_demux) p_sys->i_seq_table_size = i / (8 + i_map_size); /* parse all the entries */ - p_sys->seq_table = malloc(p_sys->i_seq_table_size * sizeof(ty_seq_table_t)); - for (i=0; ii_seq_table_size; i++) { - stream_Read(p_demux->s, mst_buf, 8 + i_map_size); + p_sys->seq_table = calloc(p_sys->i_seq_table_size, sizeof(ty_seq_table_t)); + if (p_sys->seq_table == NULL) + { + p_sys->i_seq_table_size = 0; + return; + } + for (unsigned i=0; ii_seq_table_size; i++) { + stream_Read(p_demux->s, mst_buf, 8); p_sys->seq_table[i].l_timestamp = U64_AT(&mst_buf[0]); if (i_map_size > 8) { msg_Err(p_demux, "Unsupported SEQ bitmap size in master chunk"); - memset(p_sys->seq_table[i].chunk_bitmask, i_map_size, 0); + stream_Read(p_demux->s, NULL, i_map_size); } else { + stream_Read(p_demux->s, mst_buf + 8, i_map_size); memcpy(p_sys->seq_table[i].chunk_bitmask, &mst_buf[8], i_map_size); } } @@ -1664,11 +1658,13 @@ static void parse_master(demux_t *p_demux) p_sys->b_have_master = true; i_pts_secs = p_sys->l_first_ty_pts / 1000000000; - msg_Dbg( p_demux, "first TY pts in master is %02d:%02d:%02d", - (int)(i_pts_secs / 3600), (int)((i_pts_secs / 60) % 60), (int)(i_pts_secs % 60) ); + msg_Dbg( p_demux, + "first TY pts in master is %02"PRId64":%02"PRId64":%02"PRId64, + i_pts_secs / 3600, (i_pts_secs / 60) % 60, i_pts_secs % 60 ); i_pts_secs = p_sys->l_final_ty_pts / 1000000000; - msg_Dbg( p_demux, "final TY pts in master is %02d:%02d:%02d", - (int)(i_pts_secs / 3600), (int)((i_pts_secs / 60) % 60), (int)(i_pts_secs % 60) ); + msg_Dbg( p_demux, + "final TY pts in master is %02"PRId64":%02"PRId64":%02"PRId64, + i_pts_secs / 3600, (i_pts_secs / 60) % 60, i_pts_secs % 60 ); /* seek past this chunk */ stream_Seek(p_demux->s, i_save_pos + CHUNK_SIZE); @@ -1731,7 +1727,7 @@ static void analyze_chunk(demux_t *p_demux, const uint8_t *p_chunk) int i_num_recs, i; ty_rec_hdr_t *p_hdrs; int i_num_6e0, i_num_be0, i_num_9c0, i_num_3c0; - uint32_t i_payload_size; + int i_payload_size; /* skip if it's a Part header */ if( U32_AT( &p_chunk[ 0 ] ) == TIVO_PES_FILEID ) @@ -1747,7 +1743,7 @@ static void analyze_chunk(demux_t *p_demux, const uint8_t *p_chunk) p_chunk += 4; /* skip past rec count & SEQ bytes */ //msg_Dbg(p_demux, "probe: chunk has %d recs", i_num_recs); - p_hdrs = parse_chunk_headers(p_demux, p_chunk, i_num_recs, &i_payload_size); + p_hdrs = parse_chunk_headers(p_chunk, i_num_recs, &i_payload_size); /* scan headers. * 1. check video packets. Presence of 0x6e0 means S1. * No 6e0 but have be0 means S2. @@ -1906,7 +1902,7 @@ static int get_chunk_header(demux_t *p_demux) return 0; } /* parse them */ - p_sys->rec_hdrs = parse_chunk_headers(p_demux, p_hdr_buf, i_num_recs, + p_sys->rec_hdrs = parse_chunk_headers(p_hdr_buf, i_num_recs, &i_payload_size); free(p_hdr_buf); @@ -1919,7 +1915,7 @@ static int get_chunk_header(demux_t *p_demux) } -static ty_rec_hdr_t *parse_chunk_headers( demux_t *p_demux, const uint8_t *p_buf, +static ty_rec_hdr_t *parse_chunk_headers( const uint8_t *p_buf, int i_num_recs, int *pi_payload_size) { int i; @@ -1940,13 +1936,11 @@ static ty_rec_hdr_t *parse_chunk_headers( demux_t *p_demux, const uint8_t *p_buf /* marker bit 2 set, so read extended data */ b1 = ( ( ( record_header[ 0 ] & 0x0f ) << 4 ) | ( ( record_header[ 1 ] & 0xf0 ) >> 4 ) ); - b1 &= 0x7f; b2 = ( ( ( record_header[ 1 ] & 0x0f ) << 4 ) | ( ( record_header[ 2 ] & 0xf0 ) >> 4 ) ); - b2 &= 0x7f; - p_rec_hdr->ex1 = b1; - p_rec_hdr->ex2 = b2; + p_rec_hdr->ex[0] = b1; + p_rec_hdr->ex[1] = b2; p_rec_hdr->l_rec_size = 0; p_rec_hdr->l_ty_pts = 0; p_rec_hdr->b_ext = true;