?? ts.c
字號:
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 (%"PRId64"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 (%"PRId64"ms) resetting to 70ms", p_sys->i_pcr_delay / 1000 ); p_sys->i_pcr_delay = 70000; } 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=%"PRId64" pcr=%"PRId64" dts_delay=%"PRId64, 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_Create( p_mux, SOUT_CFG_PREFIX "csa-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND ); var_Get( p_mux, SOUT_CFG_PREFIX "csa-ck", &val ); if( val.psz_string && *val.psz_string ) { int i_res; vlc_value_t csa2; p_sys->csa = csa_New(); var_Create( p_mux, SOUT_CFG_PREFIX "csa2-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND ); var_Get( p_mux, SOUT_CFG_PREFIX "csa2-ck", &csa2 ); i_res = csa_SetCW( (vlc_object_t*)p_mux, p_sys->csa, val.psz_string, true ); if( i_res == VLC_SUCCESS && csa2.psz_string && *csa2.psz_string ) { if( csa_SetCW( (vlc_object_t*)p_mux, p_sys->csa, csa2.psz_string, false ) != VLC_SUCCESS ) { csa_SetCW( (vlc_object_t*)p_mux, p_sys->csa, val.psz_string, false ); } } else if( i_res == VLC_SUCCESS ) { csa_SetCW( (vlc_object_t*)p_mux, p_sys->csa, val.psz_string, false ); } else { csa_Delete( p_sys->csa ); p_sys->csa = NULL; } if( p_sys->csa ) { vlc_value_t use_val, pkt_val; var_Create( p_mux, SOUT_CFG_PREFIX "csa-use", VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND ); var_Get( p_mux, SOUT_CFG_PREFIX "csa-use", &use_val ); var_AddCallback( p_mux, SOUT_CFG_PREFIX "csa-use", ActiveKeyCallback, NULL ); var_AddCallback( p_mux, SOUT_CFG_PREFIX "csa-ck", ChangeKeyCallback, (void *)1 ); var_AddCallback( p_mux, SOUT_CFG_PREFIX "csa2-ck", ChangeKeyCallback, NULL ); if ( var_Set( p_mux, SOUT_CFG_PREFIX "csa-use", use_val ) != VLC_SUCCESS ) { var_SetString( p_mux, SOUT_CFG_PREFIX "csa-use", "odd" ); } free( use_val.psz_string ); var_Get( p_mux, SOUT_CFG_PREFIX "csa-pkt", &pkt_val ); if( pkt_val.i_int < 12 || pkt_val.i_int > 188 ) { msg_Err( p_mux, "wrong packet size %d specified.", pkt_val.i_int ); msg_Warn( p_mux, "using default packet size of 188 bytes" ); p_sys->i_csa_pkt_size = 188; } else p_sys->i_csa_pkt_size = pkt_val.i_int; msg_Dbg( p_mux, "encrypting %d bytes of packet", p_sys->i_csa_pkt_size ); } free( csa2.psz_string ); } free( val.psz_string ); var_Get( p_mux, SOUT_CFG_PREFIX "crypt-audio", &val ); p_sys->b_crypt_audio = val.b_bool; var_Get( p_mux, SOUT_CFG_PREFIX "crypt-video", &val ); p_sys->b_crypt_video = 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; int i; vlc_mutex_lock( &p_sys->csa_lock ); if( p_sys->csa ) { var_DelCallback( p_mux, SOUT_CFG_PREFIX "csa-ck", ChangeKeyCallback, NULL ); var_DelCallback( p_mux, SOUT_CFG_PREFIX "csa2-ck", ChangeKeyCallback, NULL ); var_DelCallback( p_mux, SOUT_CFG_PREFIX "csa-use", ActiveKeyCallback, NULL ); csa_Delete( p_sys->csa ); p_sys->csa = NULL; } vlc_mutex_unlock( &p_sys->csa_lock ); for( i = 0; i < MAX_PMT; i++ ) { free( p_sys->sdt_descriptors[i].psz_service_name ); free( p_sys->sdt_descriptors[i].psz_provider ); } vlc_mutex_destroy( &p_sys->csa_lock ); free( p_sys->dvbpmt ); free( p_sys );}/***************************************************************************** * ChangeKeyCallback: called when changing the odd encryption key on the fly. *****************************************************************************/static int ChangeKeyCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); sout_mux_t *p_mux = (sout_mux_t*)p_this; sout_mux_sys_t *p_sys = p_mux->p_sys; int ret; vlc_mutex_lock( &p_sys->csa_lock ); ret = csa_SetCW( p_this, p_sys->csa, newval.psz_string, !!(intptr_t)p_data ); vlc_mutex_unlock( &p_sys->csa_lock ); return ret;}/***************************************************************************** * ActiveKeyCallback: called when changing the active (in use) encryption key on the fly. *****************************************************************************/static int ActiveKeyCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_data); sout_mux_t *p_mux = (sout_mux_t*)p_this; sout_mux_sys_t *p_sys = p_mux->p_sys; int i_res = VLC_EBADVAR; vlc_mutex_lock( &p_sys->csa_lock ); if( !strcmp(newval.psz_string, "odd" ) || !strcmp(newval.psz_string, "first" ) || !strcmp(newval.psz_string, "1" ) ) { i_res = csa_UseKey( (vlc_object_t*)p_mux, p_sys->csa, 1 ); } else if( !strcmp(newval.psz_string, "even" ) || !strcmp(newval.psz_string, "second" ) || !strcmp(newval.psz_string, "2" ) ) { i_res = csa_UseKey( (vlc_object_t*)p_mux, p_sys->csa, 0 ); } vlc_mutex_unlock( &p_sys->csa_lock ); return i_res;}/***************************************************************************** * Control: *****************************************************************************/static int Control( sout_mux_t *p_mux, int i_query, va_list args ){ VLC_UNUSED(p_mux); bool *pb_bool; char **ppsz; switch( i_query ) { case MUX_CAN_ADD_STREAM_WHILE_MUXING: pb_bool = (bool*)va_arg( args, bool * ); *pb_bool = true; return VLC_SUCCESS; case MUX_GET_ADD_STREAM_WAIT: pb_bool = (bool*)va_arg( args, bool * ); *pb_bool = 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; int i; p_input->p_sys = p_stream = malloc( sizeof( ts_stream_t ) ); if( !p_input->p_sys ) return VLC_ENOMEM; /* 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->b_discontinuity = false; 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 = 0xe0; 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' ): case VLC_FOURCC( 'm', 'p', '3', ' ' ): 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' ): /* XXX: make that configurable in some way when LOAS * is implemented for AAC in TS */ //p_stream->i_stream_type = 0x11; /* LOAS/LATM */ p_stream->i_stream_type = 0x0f; /* ADTS */ 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; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -