📄 ts.c
字号:
p_ts->i_flags |= BLOCK_FLAG_CLOCK; p_ts->p_buffer[4] = 7 + i_stuffing; p_ts->p_buffer[5] = 0x10; /* flags */ p_ts->p_buffer[6] = ( 0 )&0xff; p_ts->p_buffer[7] = ( 0 )&0xff; p_ts->p_buffer[8] = ( 0 )&0xff; p_ts->p_buffer[9] = ( 0 )&0xff; p_ts->p_buffer[10]= ( ( 0 )&0x80 ) | 0x7e; p_ts->p_buffer[11]= 0; for( i = 12; i < 12 + i_stuffing; i++ ) { p_ts->p_buffer[i] = 0xff; } } else { int i_stuffing = i_payload_max - i_payload; p_ts->p_buffer[4] = i_stuffing - 1; if( i_stuffing > 1 ) { p_ts->p_buffer[5] = 0x00; for( i = 6; i < 6 + i_stuffing - 2; i++ ) { p_ts->p_buffer[i] = 0xff; } } } } /* copy payload */ memcpy( &p_ts->p_buffer[188 - i_payload], &p_pes->p_buffer[p_stream->i_pes_used], i_payload ); p_stream->i_pes_used += i_payload; p_stream->i_pes_dts = p_pes->i_dts + p_pes->i_length * p_stream->i_pes_used / p_pes->i_buffer; p_stream->i_pes_length -= p_pes->i_length * i_payload / p_pes->i_buffer; if( p_stream->i_pes_used >= (int)p_pes->i_buffer ) { p_pes = BufferChainGet( &p_stream->chain_pes ); block_Release( p_pes ); p_pes = p_stream->chain_pes.p_first; if( p_pes ) { p_stream->i_pes_dts = p_pes->i_dts; p_stream->i_pes_length = 0; while( p_pes ) { p_stream->i_pes_length += p_pes->i_length; p_pes = p_pes->p_next; } } else { p_stream->i_pes_dts = 0; p_stream->i_pes_length = 0; } p_stream->i_pes_used = 0; } return p_ts;}static void TSSetPCR( block_t *p_ts, mtime_t i_dts ){ mtime_t i_pcr = 9 * i_dts / 100; p_ts->p_buffer[6] = ( i_pcr >> 25 )&0xff; p_ts->p_buffer[7] = ( i_pcr >> 17 )&0xff; p_ts->p_buffer[8] = ( i_pcr >> 9 )&0xff; p_ts->p_buffer[9] = ( i_pcr >> 1 )&0xff; p_ts->p_buffer[10]|= ( i_pcr << 7 )&0x80;}#if 0static void TSSetConstraints( sout_mux_t *p_mux, sout_buffer_chain_t *c, mtime_t i_length, int i_bitrate_min, int i_bitrate_max ){ sout_mux_sys_t *p_sys = p_mux->p_sys; sout_buffer_chain_t s = *c; int i_packets = 0; int i_packets_min = 0; int i_packets_max = 0; if( i_length <= 0 ) { return; } i_packets = c->i_depth; i_packets_min = ( (int64_t)i_bitrate_min * i_length / 8 / 1000000 + 187 ) / 188; i_packets_max = ( (int64_t)i_bitrate_max * i_length / 8 / 1000000 + 187 ) / 188; if( i_packets < i_packets_min && i_packets_min > 0 ) { block_t *p_pk; int i_div = ( i_packets_min - i_packets ) / i_packets; int i_mod = ( i_packets_min - i_packets ) % i_packets; int i_rest = 0; /* We need to pad with null packets (pid=0x1fff) * We try to melt null packets with true packets */ msg_Dbg( p_mux, "packets=%d but min=%d -> adding %d packets of padding", i_packets, i_packets_min, i_packets_min - i_packets ); BufferChainInit( c ); while( ( p_pk = BufferChainGet( &s ) ) ) { int i, i_null; BufferChainAppend( c, p_pk ); i_null = i_div + ( i_rest + i_mod ) / i_packets; for( i = 0; i < i_null; i++ ) { block_t *p_null; p_null = sout_BufferNew( p_mux->p_sout, 188 ); p_null->p_buffer[0] = 0x47; p_null->p_buffer[1] = 0x1f; p_null->p_buffer[2] = 0xff; p_null->p_buffer[3] = 0x10 | p_sys->i_null_continuity_counter; memset( &p_null->p_buffer[4], 0, 184 ); p_sys->i_null_continuity_counter = ( p_sys->i_null_continuity_counter + 1 ) % 16; BufferChainAppend( c, p_null ); } i_rest = ( i_rest + i_mod ) % i_packets; } } else if( i_packets > i_packets_max && i_packets_max > 0 ) { block_t *p_pk; int i; /* Arg, we need to drop packets, I don't do something clever (like * dropping complete pid, b frames, ... ), I just get the right amount * of packets and discard the others */ msg_Warn( p_mux, "packets=%d but max=%d -> removing %d packets -> stream broken", i_packets, i_packets_max, i_packets - i_packets_max ); BufferChainInit( c ); for( i = 0; i < i_packets_max; i++ ) { BufferChainAppend( c, BufferChainGet( &s ) ); } while( ( p_pk = BufferChainGet( &s ) ) ) { sout_BufferDelete( p_mux->p_sout, p_pk ); } }}#endifstatic void PEStoTS( sout_instance_t *p_sout, sout_buffer_chain_t *c, block_t *p_pes, ts_stream_t *p_stream ){ uint8_t *p_data; int i_size; int b_new_pes; /* get PES total size */ i_size = p_pes->i_buffer; p_data = p_pes->p_buffer; b_new_pes = VLC_TRUE; for( ;; ) { int b_adaptation_field; int i_copy; block_t *p_ts; p_ts = block_New( p_sout, 188 ); /* write header * 8b 0x47 sync byte * 1b transport_error_indicator * 1b payload_unit_start * 1b transport_priority * 13b pid * 2b transport_scrambling_control * 2b if adaptation_field 0x03 else 0x01 * 4b continuity_counter */ i_copy = __MIN( i_size, 184 ); b_adaptation_field = i_size < 184 ? VLC_TRUE : VLC_FALSE; p_ts->p_buffer[0] = 0x47; p_ts->p_buffer[1] = ( b_new_pes ? 0x40 : 0x00 )| ( ( p_stream->i_pid >> 8 )&0x1f ); p_ts->p_buffer[2] = p_stream->i_pid & 0xff; p_ts->p_buffer[3] = ( b_adaptation_field ? 0x30 : 0x10 )| p_stream->i_continuity_counter; b_new_pes = VLC_FALSE; p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16; if( b_adaptation_field ) { int i_stuffing = 184 - i_copy; int i; p_ts->p_buffer[4] = i_stuffing - 1; if( i_stuffing > 1 ) { p_ts->p_buffer[5] = 0x00; for( i = 6; i < 6 + i_stuffing - 2; i++ ) { p_ts->p_buffer[i] = 0xff; } } } /* copy payload */ memcpy( &p_ts->p_buffer[188 - i_copy], p_data, i_copy ); p_data += i_copy; i_size -= i_copy; BufferChainAppend( c, p_ts ); if( i_size <= 0 ) { block_t *p_next = p_pes->p_next; p_pes->p_next = NULL; block_Release( p_pes ); if( p_next == NULL ) { break; } b_new_pes = VLC_TRUE; p_pes = p_next; i_size = p_pes->i_buffer; p_data = p_pes->p_buffer; } } return;}static block_t *WritePSISection( sout_instance_t *p_sout, dvbpsi_psi_section_t* p_section ){ block_t *p_psi, *p_first = NULL; while( p_section ) { int i_size; i_size = (uint32_t)( p_section->p_payload_end - p_section->p_data )+ ( p_section->b_syntax_indicator ? 4 : 0 ); p_psi = block_New( p_sout, i_size + 1 ); p_psi->i_pts = 0; p_psi->i_dts = 0; p_psi->i_length = 0; p_psi->i_buffer = i_size + 1; p_psi->p_buffer[0] = 0; // pointer memcpy( p_psi->p_buffer + 1, p_section->p_data, i_size ); block_ChainAppend( &p_first, p_psi ); p_section = p_section->p_next; } return( p_first );}static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c ){ sout_mux_sys_t *p_sys = p_mux->p_sys; block_t *p_pat; dvbpsi_pat_t pat; dvbpsi_psi_section_t *p_section; dvbpsi_InitPAT( &pat, p_sys->i_tsid, p_sys->i_pat_version_number, 1 ); // b_current_next /* add all program (only one) */ dvbpsi_PATAddProgram( &pat, p_sys->i_pmt_program_number, // i_number p_sys->pmt.i_pid ); // i_pid p_section = dvbpsi_GenPATSections( &pat, 0 ); // max program per section p_pat = WritePSISection( p_mux->p_sout, p_section ); PEStoTS( p_mux->p_sout, c, p_pat, &p_sys->pat ); dvbpsi_DeletePSISections( p_section ); dvbpsi_EmptyPAT( &pat );}static uint32_t GetDescriptorLength24b( int i_length ){ uint32_t i_l1, i_l2, i_l3; i_l1 = i_length&0x7f; i_l2 = ( i_length >> 7 )&0x7f; i_l3 = ( i_length >> 14 )&0x7f; return( 0x808000 | ( i_l3 << 16 ) | ( i_l2 << 8 ) | i_l1 );}static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c ){ sout_mux_sys_t *p_sys = p_mux->p_sys; block_t *p_pmt; dvbpsi_pmt_t pmt; dvbpsi_pmt_es_t *p_es; dvbpsi_psi_section_t *p_section; int i_stream; dvbpsi_InitPMT( &pmt, p_sys->i_pmt_program_number, // program number p_sys->i_pmt_version_number, 1, // b_current_next p_sys->i_pcr_pid ); if( p_sys->i_mpeg4_streams > 0 ) { uint8_t iod[4096]; bits_buffer_t bits; bits_buffer_t bits_fix_IOD; /* Make valgrind happy : it works at byte level not bit one so * bit_write confuse it (but DON'T CHANGE the way that bit_write is * working (needed when fixing some bits) */ memset( iod, 0, 4096 ); bits_initwrite( &bits, 4096, iod ); // IOD_label_scope bits_write( &bits, 8, 0x11 ); // IOD_label bits_write( &bits, 8, 0x01 ); // InitialObjectDescriptor bits_align( &bits ); bits_write( &bits, 8, 0x02 ); // tag bits_fix_IOD = bits; // save states to fix length later bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); // variable length (fixed later) bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID bits_write( &bits, 1, 0x00 ); // URL Flag bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag bits_write( &bits, 4, 0x0f ); // reserved bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability ) bits_write( &bits, 8, 0xff ); // sceneProfile bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified) bits_write( &bits, 8, 0xfe ); // visualProfile( // ) bits_write( &bits, 8, 0xff ); // graphicProfile (no ) for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ ) { ts_stream_t *p_stream; p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys; if( p_stream->i_stream_id == 0xfa || p_stream->i_stream_id == 0xfb || p_stream->i_stream_id == 0xfe ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -