📄 ts.c
字号:
/* Search pmt to be unselected */ for( i = 0; i < p_sys->i_pmt; i++ ) { ts_pid_t *pmt = p_sys->pmt[i]; int i_prg; for( i_prg = 0; i_prg < pmt->psi->i_prg; i_prg++ ) { if( pmt->psi->prg[i_prg]->i_number == p_sys->i_dvb_program ) { i_pmt_pid = p_sys->pmt[i]->i_pid; break; } } if( i_pmt_pid > 0 ) break; } if( i_pmt_pid > 0 ) { stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, i_pmt_pid, VLC_FALSE ); /* All ES */ for( i = 2; i < 8192; i++ ) { ts_pid_t *pid = &p_sys->pid[i]; int i_prg; if( !pid->b_valid || pid->psi ) continue; for( i_prg = 0; i_prg < pid->p_owner->i_prg; i_prg++ ) { if( pid->p_owner->prg[i_prg]->i_pid_pmt == i_pmt_pid && pid->es->id ) { /* We only remove es that aren't defined by extra pmt */ stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, i, VLC_FALSE ); break; } } } } /* select new program */ p_sys->i_dvb_program = i_int; i_pmt_pid = -1; for( i = 0; i < p_sys->i_pmt; i++ ) { ts_pid_t *pmt = p_sys->pmt[i]; int i_prg; for( i_prg = 0; i_prg < pmt->psi->i_prg; i_prg++ ) { if( pmt->psi->prg[i_prg]->i_number == i_int ) { i_pmt_pid = p_sys->pmt[i]->i_pid; p_prg = p_sys->pmt[i]->psi->prg[i_prg]; break; } } if( i_pmt_pid > 0 ) break; } if( i_pmt_pid > 0 ) { stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, i_pmt_pid, VLC_TRUE ); stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, p_prg->i_pid_pcr, VLC_TRUE ); for( i = 2; i < 8192; i++ ) { ts_pid_t *pid = &p_sys->pid[i]; int i_prg; if( !pid->b_valid || pid->psi ) continue; for( i_prg = 0; i_prg < pid->p_owner->i_prg; i_prg++ ) { if( pid->p_owner->prg[i_prg]->i_pid_pmt == i_pmt_pid && pid->es->id ) { if ( pid->es->fmt.i_cat == VIDEO_ES && !i_vpid ) i_vpid = i; if ( pid->es->fmt.i_cat == AUDIO_ES && !i_apid1 ) i_apid1 = i; else if ( pid->es->fmt.i_cat == AUDIO_ES && !i_apid2 ) i_apid2 = i; else if ( pid->es->fmt.i_cat == AUDIO_ES && !i_apid3 ) i_apid3 = i; stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, i, VLC_TRUE ); break; } } } } } else { p_sys->i_dvb_program = -1; p_sys->p_programs_list = p_list; } return VLC_SUCCESS; } case DEMUX_GET_FPS: case DEMUX_SET_TIME: default: return VLC_EGENERIC; }}static void PIDInit( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner ){ vlc_bool_t b_old_valid = pid->b_valid; pid->b_valid = VLC_TRUE; pid->i_cc = 0xff; pid->p_owner = p_owner; pid->i_owner_number = 0; pid->extra_es = NULL; pid->i_extra_es = 0; if( b_psi ) { pid->es = NULL; if( !b_old_valid ) { pid->psi = malloc( sizeof( ts_psi_t ) ); pid->psi->handle= NULL; pid->psi->i_prg = 0; pid->psi->prg = NULL; } pid->psi->i_pat_version = -1; pid->psi->i_sdt_version = -1; if( p_owner ) { ts_prg_psi_t *prg = malloc( sizeof( ts_prg_psi_t ) ); /* PMT */ prg->i_version = -1; prg->i_number = -1; prg->i_pid_pcr = -1; prg->i_pid_pmt = -1; prg->iod = NULL; prg->handle = NULL; TAB_APPEND( pid->psi->i_prg, pid->psi->prg, prg ); } } else { pid->psi = NULL; pid->es = malloc( sizeof( ts_es_t ) ); es_format_Init( &pid->es->fmt, UNKNOWN_ES, 0 ); pid->es->id = NULL; pid->es->p_pes = NULL; pid->es->i_pes_size= 0; pid->es->i_pes_gathered= 0; pid->es->pp_last = &pid->es->p_pes; pid->es->p_mpeg4desc = NULL; pid->es->b_gather = VLC_FALSE; }}static void PIDClean( es_out_t *out, ts_pid_t *pid ){ if( pid->psi ) { int i; if( pid->psi->handle ) dvbpsi_DetachPMT( pid->psi->handle ); for( i = 0; i < pid->psi->i_prg; i++ ) { if( pid->psi->prg[i]->iod ) IODFree( pid->psi->prg[i]->iod ); if( pid->psi->prg[i]->handle ) dvbpsi_DetachPMT( pid->psi->prg[i]->handle ); free( pid->psi->prg[i] ); } if( pid->psi->prg ) free( pid->psi->prg ); free( pid->psi ); } else { int i; if( pid->es->id ) es_out_Del( out, pid->es->id ); if( pid->es->p_pes ) block_ChainRelease( pid->es->p_pes ); es_format_Clean( &pid->es->fmt ); free( pid->es ); for( i = 0; i < pid->i_extra_es; i++ ) { if( pid->extra_es[i]->id ) es_out_Del( out, pid->extra_es[i]->id ); if( pid->extra_es[i]->p_pes ) block_ChainRelease( pid->extra_es[i]->p_pes ); es_format_Clean( &pid->extra_es[i]->fmt ); free( pid->extra_es[i] ); } if( pid->i_extra_es ) free( pid->extra_es ); } pid->b_valid = VLC_FALSE;}/**************************************************************************** * gathering stuff ****************************************************************************/static void ParsePES( demux_t *p_demux, ts_pid_t *pid ){ block_t *p_pes = pid->es->p_pes; uint8_t header[30]; int i_pes_size = 0; int i_skip = 0; mtime_t i_dts = -1; mtime_t i_pts = -1; mtime_t i_length = 0; int i_max; /* remove the pes from pid */ pid->es->p_pes = NULL; pid->es->i_pes_size= 0; pid->es->i_pes_gathered= 0; pid->es->pp_last = &pid->es->p_pes; /* FIXME find real max size */ i_max = block_ChainExtract( p_pes, header, 30 ); if( header[0] != 0 || header[1] != 0 || header[2] != 1 ) { if( !p_demux->p_sys->b_silent ) msg_Warn( p_demux, "invalid header [0x%x:%x:%x:%x] (pid: %d)", header[0], header[1],header[2],header[3], pid->i_pid ); block_ChainRelease( p_pes ); return; } /* TODO check size */ switch( header[3] ) { case 0xBC: /* Program stream map */ case 0xBE: /* Padding */ case 0xBF: /* Private stream 2 */ case 0xB0: /* ECM */ case 0xB1: /* EMM */ case 0xFF: /* Program stream directory */ case 0xF2: /* DSMCC stream */ case 0xF8: /* ITU-T H.222.1 type E stream */ i_skip = 6; break; default: if( ( header[6]&0xC0 ) == 0x80 ) { /* mpeg2 PES */ i_skip = header[8] + 9; if( header[7]&0x80 ) /* has pts */ { i_pts = ((mtime_t)(header[ 9]&0x0e ) << 29)| (mtime_t)(header[10] << 22)| ((mtime_t)(header[11]&0xfe) << 14)| (mtime_t)(header[12] << 7)| (mtime_t)(header[13] >> 1); if( header[7]&0x40 ) /* has dts */ { i_dts = ((mtime_t)(header[14]&0x0e ) << 29)| (mtime_t)(header[15] << 22)| ((mtime_t)(header[16]&0xfe) << 14)| (mtime_t)(header[17] << 7)| (mtime_t)(header[18] >> 1); } } } else { i_skip = 6; while( i_skip < 23 && header[i_skip] == 0xff ) { i_skip++; } if( i_skip == 23 ) { msg_Err( p_demux, "too much MPEG-1 stuffing" ); block_ChainRelease( p_pes ); return; } if( ( header[i_skip] & 0xC0 ) == 0x40 ) { i_skip += 2; } if( header[i_skip]&0x20 ) { i_pts = ((mtime_t)(header[i_skip]&0x0e ) << 29)| (mtime_t)(header[i_skip+1] << 22)| ((mtime_t)(header[i_skip+2]&0xfe) << 14)| (mtime_t)(header[i_skip+3] << 7)| (mtime_t)(header[i_skip+4] >> 1); if( header[i_skip]&0x10 ) /* has dts */ { i_dts = ((mtime_t)(header[i_skip+5]&0x0e ) << 29)| (mtime_t)(header[i_skip+6] << 22)| ((mtime_t)(header[i_skip+7]&0xfe) << 14)| (mtime_t)(header[i_skip+8] << 7)| (mtime_t)(header[i_skip+9] >> 1); i_skip += 10; } else { i_skip += 5; } } else { i_skip += 1; } } break; } if( pid->es->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', 'b' ) || pid->es->fmt.i_codec == VLC_FOURCC( 'd', 't', 's', 'b' ) ) { i_skip += 4; } else if( pid->es->fmt.i_codec == VLC_FOURCC( 'l', 'p', 'c', 'b' ) || pid->es->fmt.i_codec == VLC_FOURCC( 's', 'p', 'u', 'b' ) || pid->es->fmt.i_codec == VLC_FOURCC( 's', 'd', 'd', 'b' ) ) { i_skip += 1; } else if( pid->es->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) && pid->es->p_mpeg4desc ) { decoder_config_descriptor_t *dcd = &pid->es->p_mpeg4desc->dec_descr; if( dcd->i_decoder_specific_info_len > 2 && dcd->p_decoder_specific_info[0] == 0x10 && ( dcd->p_decoder_specific_info[1]&0x10 ) ) { /* display length */ if( p_pes->i_buffer + 2 <= i_skip ) { i_length = GetWBE( &p_pes->p_buffer[i_skip] ); } i_skip += 2; } if( p_pes->i_buffer + 2 <= i_skip ) { i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] ); } /* */ i_skip += 2; } /* skip header */ while( p_pes && i_skip > 0 ) { if( p_pes->i_buffer <= i_skip ) { block_t *p_next = p_pes->p_next; i_skip -= p_pes->i_buffer; block_Release( p_pes ); p_pes = p_next; } else { p_pes->i_buffer -= i_skip; p_pes->p_buffer += i_skip; break; } } /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */ if( i_pts >= 0 && i_dts < 0 ) i_dts = i_pts; if( p_pes ) { block_t *p_block; int i; if( i_dts >= 0 ) { p_pes->i_dts = i_dts * 100 / 9; } if( i_pts >= 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -