?? ts.c
字號:
bool b_key_frame;} ts_stream_t;struct sout_mux_sys_t{ int i_pcr_pid; sout_input_t *p_pcr_input; vlc_mutex_t csa_lock; int i_audio_bound; int i_video_bound; bool b_es_id_pid; bool b_sdt; int i_pid_video; int i_pid_audio; int i_pid_spu; int i_pid_free; /* first usable pid */ int i_tsid; int i_netid; int i_num_pmt; int i_pmtslots; int i_pat_version_number; ts_stream_t pat; int i_pmt_version_number; ts_stream_t pmt[MAX_PMT]; pmt_map_t pmtmap[MAX_PMT_PID]; int i_pmt_program_number[MAX_PMT]; sdt_desc_t sdt_descriptors[MAX_PMT]; bool b_data_alignment; int i_mpeg4_streams; int i_null_continuity_counter; /* Needed ? */ ts_stream_t sdt; dvbpsi_pmt_t *dvbpmt; /* for TS building */ int64_t i_bitrate_min; int64_t i_bitrate_max; int64_t i_shaping_delay; int64_t i_pcr_delay; int64_t i_dts_delay; bool b_use_key_frames; mtime_t i_pcr; /* last PCR emited */ csa_t *csa; int i_csa_pkt_size; bool b_crypt_audio; bool b_crypt_video;};/* Reserve a pid and return it */static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat ){ int i_pid; if ( i_cat == VIDEO_ES && p_sys->i_pid_video ) { i_pid = p_sys->i_pid_video; p_sys->i_pid_video = 0; } else if ( i_cat == AUDIO_ES && p_sys->i_pid_audio ) { i_pid = p_sys->i_pid_audio; p_sys->i_pid_audio = 0; } else if ( i_cat == SPU_ES && p_sys->i_pid_spu ) { i_pid = p_sys->i_pid_spu; p_sys->i_pid_spu = 0; } else { i_pid = ++p_sys->i_pid_free; } return i_pid;}static int pmtcompare( const void *pa, const void *pb ){ if ( ((pmt_map_t *)pa)->i_pid < ((pmt_map_t *)pb)->i_pid ) return -1; else if ( ((pmt_map_t *)pa)->i_pid > ((pmt_map_t *)pb)->i_pid ) return 1; else return 0;}static int intcompare( const void *pa, const void *pb ){ if ( *(int *)pa < *(int *)pb ) return -1; else if ( *(int *)pa > *(int *)pb ) return 1; else return 0;}/***************************************************************************** * Local prototypes *****************************************************************************/static int Control ( sout_mux_t *, int, va_list );static int AddStream( sout_mux_t *, sout_input_t * );static int DelStream( sout_mux_t *, sout_input_t * );static int Mux ( sout_mux_t * );static block_t *FixPES( sout_mux_t *p_mux, block_fifo_t *p_fifo );static block_t *Add_ADTS( block_t *, es_format_t * );static void TSSchedule ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts, mtime_t i_pcr_length, mtime_t i_pcr_dts );static void TSDate ( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts, mtime_t i_pcr_length, mtime_t i_pcr_dts );static void GetPAT( sout_mux_t *p_mux, sout_buffer_chain_t *c );static void GetPMT( sout_mux_t *p_mux, sout_buffer_chain_t *c );static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream, bool b_pcr );static void TSSetPCR( block_t *p_ts, mtime_t i_dts );static void PEStoTS ( sout_instance_t *, sout_buffer_chain_t *, block_t *, ts_stream_t * );/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){ sout_mux_t *p_mux =(sout_mux_t*)p_this; sout_mux_sys_t *p_sys = NULL; vlc_value_t val; int i; config_ChainParse( p_mux, SOUT_CFG_PREFIX, ppsz_sout_options, p_mux->p_cfg ); p_sys = malloc( sizeof( sout_mux_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; p_sys->i_pmtslots = p_sys->b_sdt = 0; p_sys->i_num_pmt = 1; p_sys->dvbpmt = NULL; memset( &p_sys->pmtmap, 0, sizeof(p_sys->pmtmap) ); vlc_mutex_init( &p_sys->csa_lock ); p_mux->pf_control = Control; p_mux->pf_addstream = AddStream; p_mux->pf_delstream = DelStream; p_mux->pf_mux = Mux; p_mux->p_sys = p_sys; srand( (uint32_t)mdate() ); for ( i = 0; i < MAX_PMT; i++ ) p_sys->sdt_descriptors[i].psz_service_name = p_sys->sdt_descriptors[i].psz_provider = NULL; memset( p_sys->sdt_descriptors, 0, sizeof(sdt_desc_t) ); p_sys->i_audio_bound = 0; p_sys->i_video_bound = 0; var_Get( p_mux, SOUT_CFG_PREFIX "es-id-pid", &val ); p_sys->b_es_id_pid = val.b_bool; var_Get( p_mux, SOUT_CFG_PREFIX "muxpmt", &val ); /* fetch string of pmts. Here's a sample: --sout-ts-muxpmt="0x451,0x200,0x28a,0x240,,0x450,0x201,0x28b,0x241,,0x452,0x202,0x28c,0x242" This would mean 0x451, 0x200, 0x28a, 0x240 would fall under one pmt (program), 0x450,0x201,0x28b,0x241 would fall under another */ if( val.psz_string != NULL && *val.psz_string ) { char *psz_next; char *psz = val.psz_string; uint16_t i_pid; psz_next = psz; while( psz != NULL ) { i_pid = strtoul( psz, &psz_next, 0 ); if ( strlen(psz_next) > 0 ) psz = &psz_next[1]; if ( i_pid == 0 ) { p_sys->i_num_pmt++; if ( p_sys->i_num_pmt > MAX_PMT ) { msg_Err( p_mux, "Number of PMTs greater than compiled maximum (%d)", MAX_PMT ); p_sys->i_num_pmt = MAX_PMT; } } else { p_sys->pmtmap[p_sys->i_pmtslots].i_pid = i_pid; p_sys->pmtmap[p_sys->i_pmtslots].i_prog = p_sys->i_num_pmt - 1; p_sys->i_pmtslots++; if ( p_sys->i_pmtslots > MAX_PMT_PID ) { msg_Err( p_mux, "Number of pids in PMT greater than compiled maximum (%d)", MAX_PMT_PID ); p_sys->i_pmtslots = MAX_PMT_PID; } } /* Now sort according to pids for fast search later on */ qsort( (void *)p_sys->pmtmap, p_sys->i_pmtslots, sizeof(pmt_map_t), &pmtcompare ); if ( !*psz_next ) psz = NULL; } } free( val.psz_string ); p_sys->i_pat_version_number = rand() % 32; p_sys->pat.i_pid = 0; p_sys->pat.i_continuity_counter = 0; p_sys->pat.b_discontinuity = false; var_Get( p_mux, SOUT_CFG_PREFIX "tsid", &val ); if ( val.i_int ) p_sys->i_tsid = val.i_int; else p_sys->i_tsid = rand() % 65536; p_sys->i_netid = rand() % 65536;#ifdef HAVE_DVBPSI_SDT var_Get( p_mux, SOUT_CFG_PREFIX "netid", &val ); if ( val.i_int ) p_sys->i_netid = val.i_int;#endif p_sys->i_pmt_version_number = rand() % 32; for( i = 0; i < p_sys->i_num_pmt; i++ ) { p_sys->pmt[i].i_continuity_counter = 0; p_sys->pmt[i].b_discontinuity = false; } p_sys->sdt.i_pid = 0x11; p_sys->sdt.i_continuity_counter = 0; p_sys->sdt.b_discontinuity = false;#ifdef HAVE_DVBPSI_SDT var_Get( p_mux, SOUT_CFG_PREFIX "sdtdesc", &val ); p_sys->b_sdt = val.psz_string && *val.psz_string ? true : false; /* Syntax is provider_sdt1,service_name_sdt1,provider_sdt2,service_name_sdt2... */ if( p_sys->b_sdt ) { char *psz = val.psz_string; char *psz_sdttoken = psz; i = 0; while ( psz_sdttoken != NULL ) { char *psz_end = strchr( psz_sdttoken, ',' ); if( psz_end != NULL ) { *psz_end++ = '\0'; } if ( !(i % 2) ) { p_sys->sdt_descriptors[i/2].psz_provider = strdup(psz_sdttoken); } else { p_sys->sdt_descriptors[i/2].psz_service_name = strdup(psz_sdttoken); } i++; psz_sdttoken = psz_end; } } free( val.psz_string );#else p_sys->b_sdt = false;#endif var_Get( p_mux, SOUT_CFG_PREFIX "alignment", &val ); p_sys->b_data_alignment = val.b_bool; var_Get( p_mux, SOUT_CFG_PREFIX "program-pmt", &val ); if( val.psz_string && *val.psz_string ) { char *psz_next; char *psz = val.psz_string; uint16_t i_pid; psz_next = psz; i = 0; while ( psz != NULL ) { i_pid = strtoul( psz, &psz_next, 0 ); if( strlen(psz_next) > 0 ) psz = &psz_next[1]; else psz = NULL; if( i_pid == 0 ) { if( i > MAX_PMT ) msg_Err( p_mux, "Number of PMTs > maximum (%d)", MAX_PMT ); } else { p_sys->i_pmt_program_number[i] = i_pid; i++; } } } else { /* Option not specified, use 1, 2, 3... */ for( i = 0; i < p_sys->i_num_pmt; i++ ) p_sys->i_pmt_program_number[i] = i + 1; } free( val.psz_string ); var_Get( p_mux, SOUT_CFG_PREFIX "pid-pmt", &val ); if( val.i_int ) { for( i = 0; i < p_sys->i_num_pmt; i++ ) p_sys->pmt[i].i_pid = val.i_int + i; /* Does this make any sense? */ } else { for( i = 0; i < p_sys->i_num_pmt; i++ ) p_sys->pmt[i].i_pid = 0x42 + i; } p_sys->i_pid_free = p_sys->pmt[p_sys->i_num_pmt - 1].i_pid + 1; var_Get( p_mux, SOUT_CFG_PREFIX "pid-video", &val ); p_sys->i_pid_video = val.i_int; if ( p_sys->i_pid_video > p_sys->i_pid_free ) { p_sys->i_pid_free = p_sys->i_pid_video + 1; } var_Get( p_mux, SOUT_CFG_PREFIX "pid-audio", &val ); p_sys->i_pid_audio = val.i_int; if ( p_sys->i_pid_audio > p_sys->i_pid_free ) { p_sys->i_pid_free = p_sys->i_pid_audio + 1; } var_Get( p_mux, SOUT_CFG_PREFIX "pid-spu", &val ); p_sys->i_pid_spu = val.i_int; if ( p_sys->i_pid_spu > p_sys->i_pid_free ) { p_sys->i_pid_free = p_sys->i_pid_spu + 1; } p_sys->i_pcr_pid = 0x1fff; p_sys->p_pcr_input = NULL; p_sys->i_mpeg4_streams = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -