📄 ts.c
字号:
*pi64 = p_sys->i_time; return VLC_SUCCESS; case DEMUX_GET_LENGTH: pi64 = (int64_t*)va_arg( args, int64_t * ); if( p_sys->i_mux_rate > 0 ) { *pi64 = INT64_C(1000000) * ( stream_Size( p_demux->s ) / 50 ) / p_sys->i_mux_rate; return VLC_SUCCESS; } *pi64 = 0; return VLC_EGENERIC;#else case DEMUX_GET_TIME: pi64 = (int64_t*)va_arg( args, int64_t * ); if( DVBEventInformation( p_demux, pi64, NULL ) ) *pi64 = 0; return VLC_SUCCESS; case DEMUX_GET_LENGTH: pi64 = (int64_t*)va_arg( args, int64_t * ); if( DVBEventInformation( p_demux, NULL, pi64 ) ) *pi64 = 0; return VLC_SUCCESS;#endif case DEMUX_SET_GROUP: { uint16_t i_vpid = 0, i_apid1 = 0, i_apid2 = 0, i_apid3 = 0; ts_prg_psi_t *p_prg = NULL; vlc_list_t *p_list; i_int = (int)va_arg( args, int ); p_list = (vlc_list_t *)va_arg( args, vlc_list_t * ); msg_Dbg( p_demux, "DEMUX_SET_GROUP %d %p", i_int, p_list ); if( p_sys->b_dvb_control && i_int > 0 && i_int != p_sys->i_dvb_program ) { int i_pmt_pid = -1; int i; /* 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, 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, 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, true ); stream_Control( p_demux->s, STREAM_CONTROL_ACCESS, ACCESS_SET_PRIVATE_ID_STATE, p_prg->i_pid_pcr, 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, 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 int UserPmt( demux_t *p_demux, const char *psz_fmt ){ demux_sys_t *p_sys = p_demux->p_sys; char *psz_dup = strdup( psz_fmt ); char *psz = psz_dup; int i_pid; int i_number; if( !psz_dup ) return VLC_ENOMEM; /* Parse PID */ i_pid = strtol( psz, &psz, 0 ); if( i_pid < 2 || i_pid >= 8192 ) goto error; /* Parse optional program number */ i_number = 0; if( *psz == ':' ) i_number = strtol( &psz[1], &psz, 0 ); /* */ ts_pid_t *pmt = &p_sys->pid[i_pid]; ts_prg_psi_t *prg; msg_Dbg( p_demux, "user pmt specified (pid=%d,number=%d)", i_pid, i_number ); PIDInit( pmt, true, NULL ); /* Dummy PMT */ prg = malloc( sizeof( ts_prg_psi_t ) ); if( !prg ) goto error; memset( prg, 0, sizeof( ts_prg_psi_t ) ); prg->i_pid_pcr = -1; prg->i_pid_pmt = -1; prg->i_version = -1; prg->i_number = i_number != 0 ? i_number : TS_USER_PMT_NUMBER; prg->handle = dvbpsi_AttachPMT( i_number != TS_USER_PMT_NUMBER ? i_number : 1, (dvbpsi_pmt_callback)PMTCallBack, p_demux ); TAB_APPEND( pmt->psi->i_prg, pmt->psi->prg, prg ); psz = strchr( psz, '=' ); if( psz ) psz++; while( psz && *psz ) { char *psz_next = strchr( psz, ',' ); int i_pid; if( psz_next ) *psz_next++ = '\0'; i_pid = strtol( psz, &psz, 0 ); if( *psz != ':' || i_pid < 2 || i_pid >= 8192 ) goto next; char *psz_opt = &psz[1]; if( !strcmp( psz_opt, "pcr" ) ) { prg->i_pid_pcr = i_pid; } else if( !p_sys->pid[i_pid].b_valid ) { ts_pid_t *pid = &p_sys->pid[i_pid]; char *psz_arg = strchr( psz_opt, '=' ); if( psz_arg ) *psz_arg++ = '\0'; PIDInit( pid, false, pmt->psi); if( prg->i_pid_pcr <= 0 ) prg->i_pid_pcr = i_pid; if( psz_arg && strlen( psz_arg ) == 4 ) { const vlc_fourcc_t i_codec = VLC_FOURCC( psz_arg[0], psz_arg[1], psz_arg[2], psz_arg[3] ); int i_cat = UNKNOWN_ES; es_format_t *fmt = &pid->es->fmt; if( !strcmp( psz_opt, "video" ) ) i_cat = VIDEO_ES; else if( !strcmp( psz_opt, "audio" ) ) i_cat = AUDIO_ES; else if( !strcmp( psz_opt, "spu" ) ) i_cat = SPU_ES; es_format_Init( fmt, i_cat, i_codec ); fmt->b_packetized = false; } else { const int i_stream_type = strtol( psz_opt, NULL, 0 ); PIDFillFormat( pid, i_stream_type ); } pid->es->fmt.i_group = i_number; if( p_sys->b_es_id_pid ) pid->es->fmt.i_id = i_pid; if( pid->es->fmt.i_cat != UNKNOWN_ES ) { msg_Dbg( p_demux, " * es pid=%d fcc=%4.4s", i_pid, (char*)&pid->es->fmt.i_codec ); pid->es->id = es_out_Add( p_demux->out, &pid->es->fmt ); } } next: psz = psz_next; } p_sys->b_user_pmt = true; TAB_APPEND( p_sys->i_pmt, p_sys->pmt, pmt ); free( psz_dup ); return VLC_SUCCESS;error: free( psz_dup ); return VLC_EGENERIC;}static void PIDInit( ts_pid_t *pid, bool b_psi, ts_psi_t *p_owner ){ bool b_old_valid = pid->b_valid; pid->b_valid = true; pid->i_cc = 0xff; pid->p_owner = p_owner; pid->i_owner_number = 0; TAB_INIT( pid->i_extra_es, pid->extra_es ); if( b_psi ) { pid->es = NULL; if( !b_old_valid ) { free( pid->psi ); pid->psi = malloc( sizeof( ts_psi_t ) ); if( pid->psi ) { 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 ) ); if( prg ) { /* 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 ) ); if( pid->es ) { 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 = 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] ); } 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 = 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -