📄 ts.c
字号:
p_mux->pf_delstream = DelStream; p_mux->pf_mux = Mux; p_mux->p_sys = p_sys; srand( (uint32_t)mdate() ); p_sys->i_audio_bound = 0; p_sys->i_video_bound = 0; p_sys->i_pat_version_number = rand() % 32; p_sys->pat.i_pid = 0; p_sys->pat.i_continuity_counter = 0; 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_pmt_version_number = rand() % 32; p_sys->pmt.i_continuity_counter = 0; var_Get( p_mux, SOUT_CFG_PREFIX "program-pmt", &val ); if (val.i_int ) { p_sys->i_pmt_program_number = val.i_int; } else { p_sys->i_pmt_program_number = 1; } var_Get( p_mux, SOUT_CFG_PREFIX "pid-pmt", &val ); if (val.i_int ) { p_sys->pmt.i_pid = val.i_int; } else { p_sys->pmt.i_pid = 0x42; } p_sys->i_pid_free = p_sys->pmt.i_pid + 1; 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 "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; p_sys->i_null_continuity_counter = 0; /* Allow to create constrained stream */ var_Get( p_mux, SOUT_CFG_PREFIX "bmin", &val ); p_sys->i_bitrate_min = val.i_int; var_Get( p_mux, SOUT_CFG_PREFIX "bmax", &val ); p_sys->i_bitrate_max = val.i_int; if( p_sys->i_bitrate_min > 0 && p_sys->i_bitrate_max > 0 && p_sys->i_bitrate_min > p_sys->i_bitrate_max ) { msg_Err( p_mux, "incompatible minimum and maximum bitrate, " "disabling bitrate control" ); p_sys->i_bitrate_min = 0; p_sys->i_bitrate_max = 0; } if( p_sys->i_bitrate_min > 0 || p_sys->i_bitrate_max > 0 ) { msg_Err( p_mux, "bmin and bmax no more supported " "(if you need them report it)" ); } var_Get( p_mux, SOUT_CFG_PREFIX "shaping", &val ); p_sys->i_shaping_delay = (int64_t)val.i_int * 1000; if( p_sys->i_shaping_delay <= 0 ) { msg_Err( p_mux, "invalid shaping ("I64Fd"ms) resetting to 200ms", p_sys->i_shaping_delay / 1000 ); p_sys->i_shaping_delay = 200000; } var_Get( p_mux, SOUT_CFG_PREFIX "pcr", &val ); p_sys->i_pcr_delay = (int64_t)val.i_int * 1000; if( p_sys->i_pcr_delay <= 0 || p_sys->i_pcr_delay >= p_sys->i_shaping_delay ) { msg_Err( p_mux, "invalid pcr delay ("I64Fd"ms) resetting to 30ms", p_sys->i_pcr_delay / 1000 ); p_sys->i_pcr_delay = 30000; } var_Get( p_mux, SOUT_CFG_PREFIX "dts-delay", &val ); p_sys->i_dts_delay = (int64_t)val.i_int * 1000; msg_Dbg( p_mux, "shaping="I64Fd" pcr="I64Fd" dts_delay="I64Fd, p_sys->i_shaping_delay, p_sys->i_pcr_delay, p_sys->i_dts_delay ); var_Get( p_mux, SOUT_CFG_PREFIX "use-key-frames", &val ); p_sys->b_use_key_frames = val.b_bool; /* for TS generation */ p_sys->i_pcr = 0; p_sys->csa = NULL; var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val ); if( val.psz_string && *val.psz_string ) { char *psz = val.psz_string; /* skip 0x */ if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) ) { psz += 2; } if( strlen( psz ) != 16 ) { msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" ); } else { uint64_t i_ck = strtoull( psz, NULL, 16 ); uint8_t ck[8]; int i; for( i = 0; i < 8; i++ ) { ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff; } msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x", ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] ); p_sys->csa = csa_New(); csa_SetCW( p_sys->csa, ck, ck ); } } if( val.psz_string ) free( val.psz_string ); var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val ); p_sys->b_crypt_audio = val.b_bool; return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t * p_this ){ sout_mux_t *p_mux = (sout_mux_t*)p_this; sout_mux_sys_t *p_sys = p_mux->p_sys; msg_Dbg( p_mux, "Close" ); if( p_sys->csa ) { csa_Delete( p_sys->csa ); } free( p_sys );}/***************************************************************************** * Control: *****************************************************************************/static int Control( sout_mux_t *p_mux, int i_query, va_list args ){ vlc_bool_t *pb_bool; char **ppsz; switch( i_query ) { case MUX_CAN_ADD_STREAM_WHILE_MUXING: pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * ); *pb_bool = VLC_TRUE; return VLC_SUCCESS; case MUX_GET_ADD_STREAM_WAIT: pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t * ); *pb_bool = VLC_FALSE; return VLC_SUCCESS; case MUX_GET_MIME: ppsz = (char**)va_arg( args, char ** ); *ppsz = strdup( "video/mpeg" ); /* FIXME not sure */ return VLC_SUCCESS; default: return VLC_EGENERIC; }}/***************************************************************************** * AddStream: called for each stream addition *****************************************************************************/static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ){ sout_mux_sys_t *p_sys = p_mux->p_sys; ts_stream_t *p_stream; p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) ); /* Init this new stream */ if ( p_sys->b_es_id_pid ) p_stream->i_pid = p_input->p_fmt->i_id & 0x1fff; else p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat ); p_stream->i_codec = p_input->p_fmt->i_codec; p_stream->i_continuity_counter = 0; p_stream->i_decoder_specific_info = 0; p_stream->p_decoder_specific_info = NULL; msg_Dbg( p_mux, "adding input codec=%4.4s pid=%d", (char*)&p_input->p_fmt->i_codec, p_stream->i_pid ); /* All others fields depand on codec */ switch( p_input->p_fmt->i_cat ) { case VIDEO_ES: switch( p_input->p_fmt->i_codec ) { case VLC_FOURCC( 'm', 'p','g', 'v' ): /* TODO: do we need to check MPEG-I/II ? */ p_stream->i_stream_type = 0x02; p_stream->i_stream_id = 0xe0; break; case VLC_FOURCC( 'm', 'p','4', 'v' ): p_stream->i_stream_type = 0x10; p_stream->i_stream_id = 0xfa; p_sys->i_mpeg4_streams++; p_stream->i_es_id = p_stream->i_pid; break; case VLC_FOURCC( 'h', '2','6', '4' ): p_stream->i_stream_type = 0x1b; p_stream->i_stream_id = 0xe0; break; /* XXX dirty dirty but somebody want that: * using crapy MS-codec XXX */ /* I didn't want to do that :P */ case VLC_FOURCC( 'H', '2', '6', '3' ): case VLC_FOURCC( 'I', '2', '6', '3' ): case VLC_FOURCC( 'W', 'M', 'V', '3' ): case VLC_FOURCC( 'W', 'M', 'V', '2' ): case VLC_FOURCC( 'W', 'M', 'V', '1' ): case VLC_FOURCC( 'D', 'I', 'V', '3' ): case VLC_FOURCC( 'D', 'I', 'V', '2' ): case VLC_FOURCC( 'D', 'I', 'V', '1' ): case VLC_FOURCC( 'M', 'J', 'P', 'G' ): p_stream->i_stream_type = 0xa0; // private p_stream->i_stream_id = 0xa0; // beurk p_stream->i_bih_codec = p_input->p_fmt->i_codec; p_stream->i_bih_width = p_input->p_fmt->video.i_width; p_stream->i_bih_height = p_input->p_fmt->video.i_height; break; default: free( p_stream ); return VLC_EGENERIC; } p_sys->i_video_bound++; break; case AUDIO_ES: switch( p_input->p_fmt->i_codec ) { case VLC_FOURCC( 'm', 'p','g', 'a' ): p_stream->i_stream_type = p_input->p_fmt->audio.i_rate >= 32000 ? 0x03 : 0x04; p_stream->i_stream_id = 0xc0; break; case VLC_FOURCC( 'a', '5','2', ' ' ): p_stream->i_stream_type = 0x81; p_stream->i_stream_id = 0xbd; break; case VLC_FOURCC( 'l', 'p','c', 'm' ): p_stream->i_stream_type = 0x83; p_stream->i_stream_id = 0xbd; break; case VLC_FOURCC( 'd', 't','s', ' ' ): p_stream->i_stream_type = 0x06; p_stream->i_stream_id = 0xbd; break; case VLC_FOURCC( 'm', 'p','4', 'a' ): p_stream->i_stream_type = 0x11; p_stream->i_stream_id = 0xfa; p_sys->i_mpeg4_streams++; p_stream->i_es_id = p_stream->i_pid; break; default: free( p_stream ); return VLC_EGENERIC; } p_sys->i_audio_bound++; break; case SPU_ES: switch( p_input->p_fmt->i_codec ) { case VLC_FOURCC( 's', 'p','u', ' ' ): p_stream->i_stream_type = 0x82; p_stream->i_stream_id = 0xbd; break; case VLC_FOURCC( 's', 'u','b', 't' ): p_stream->i_stream_type = 0x12; p_stream->i_stream_id = 0xfa; p_sys->i_mpeg4_streams++; p_stream->i_es_id = p_stream->i_pid; break; case VLC_FOURCC('d','v','b','s'): p_stream->i_stream_type = 0x06; p_stream->i_es_id = p_input->p_fmt->subs.dvb.i_id; p_stream->i_stream_id = 0xbd; break; case VLC_FOURCC('t','e','l','x'): p_stream->i_stream_type = 0x06; p_stream->i_stream_id = 0xbd; /* FIXME */ break; default: free( p_stream ); return VLC_EGENERIC; } break; default: free( p_stream ); return VLC_EGENERIC; } p_stream->lang[0] = p_stream->lang[1] = p_stream->lang[2] = '\0'; if( p_input->p_fmt->psz_language ) { char *psz = p_input->p_fmt->psz_language; const iso639_lang_t *pl = NULL; if( strlen( psz ) == 2 ) { pl = GetLang_1( psz ); } else if( strlen( psz ) == 3 ) { pl = GetLang_2B( psz ); if( !strcmp( pl->psz_iso639_1, "??" ) ) { pl = GetLang_2T( psz ); } } if( pl && strcmp( pl->psz_iso639_1, "??" ) ) { p_stream->lang[0] = pl->psz_iso639_2T[0]; p_stream->lang[1] = pl->psz_iso639_2T[1]; p_stream->lang[2] = pl->psz_iso639_2T[2]; msg_Dbg( p_mux, " - lang=%c%c%c", p_stream->lang[0], p_stream->lang[1], p_stream->lang[2] ); } } /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */ p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -