📄 standard.c
字号:
} /* We fix access/mux to valid couple */ if( !psz_access && !psz_mux ) { if( psz_mux_byext ) { msg_Warn( p_stream, "no access _and_ no muxer, extension gives file/%s", psz_mux_byext ); psz_access = strdup("file"); psz_mux = strdup(psz_mux_byext); } else { msg_Err( p_stream, "no access _and_ no muxer (fatal error)" ); free( psz_url ); free( p_sys ); return VLC_EGENERIC; } } if( psz_access && !psz_mux ) { /* access given, no mux */ if( !strncmp( psz_access, "mmsh", 4 ) ) { psz_mux = strdup("asfh"); } else if (!strcmp (psz_access, "udp")) { psz_mux = strdup("ts"); } else if( psz_mux_byext ) { psz_mux = strdup(psz_mux_byext); } else { msg_Err( p_stream, "no mux specified or found by extension" ); free( p_sys ); return VLC_EGENERIC; } } else if( psz_mux && !psz_access ) { /* mux given, no access */ if( !strncmp( psz_mux, "asfh", 4 ) ) { psz_access = strdup("mmsh"); } else { /* default file */ psz_access = strdup("file"); } } /* fix or warn of incompatible couple */ if( !strncmp( psz_access, "mmsh", 4 ) && strncmp( psz_mux, "asfh", 4 ) ) { char *p = strchr( psz_mux,'{' ); msg_Warn( p_stream, "fixing to mmsh/asfh" ); if( p ) { if( asprintf( &p, "asfh%s", p ) == -1 ) p = NULL; free( psz_mux ); psz_mux = p; } else { free( psz_mux ); psz_mux = strdup("asfh"); } } else if( !strncmp( psz_access, "udp", 3 ) ) { if( !strncmp( psz_mux, "ffmpeg", 6 ) ) { /* why would you use ffmpeg's ts muxer ? YOU DON'T LOVE VLC ??? */ char *psz_ffmpeg_mux = var_CreateGetString( p_this, "ffmpeg-mux" ); if( !psz_ffmpeg_mux || strncmp( psz_ffmpeg_mux, "mpegts", 6 ) ) msg_Err( p_stream, "UDP is only valid with TS" ); free( psz_ffmpeg_mux ); } else if( strncmp( psz_mux, "ts", 2 ) ) { msg_Err( p_stream, "UDP is only valid with TS" ); } } else if( strncmp( psz_access, "file", 4 ) && ( !strncmp( psz_mux, "mov", 3 ) || !strncmp( psz_mux, "mp4", 3 ) ) ) { msg_Err( p_stream, "mov and mp4 work only with file output" ); } msg_Dbg( p_this, "using `%s/%s://%s'", psz_access, psz_mux, psz_url ); /* *** find and open appropriate access module *** */ p_access = sout_AccessOutNew( p_sout, psz_access, psz_url ); if( p_access == NULL ) { msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'", psz_access, psz_mux, psz_url ); free( psz_access ); free( psz_mux ); free( psz_url ); free( p_sys ); return VLC_EGENERIC; } msg_Dbg( p_stream, "access opened" ); /* *** find and open appropriate mux module *** */ p_mux = sout_MuxNew( p_sout, psz_mux, p_access ); if( p_mux == NULL ) { msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'", psz_access, psz_mux, psz_url ); sout_AccessOutDelete( p_access ); free( psz_access ); free( psz_mux ); free( psz_url ); free( p_sys ); return VLC_EGENERIC; } msg_Dbg( p_stream, "mux opened" ); /* *** Create the SAP Session structure *** */ if( var_GetBool( p_stream, SOUT_CFG_PREFIX"sap" ) ) { /* Create the SDP */ static const struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, .ai_protocol = 0, .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV }; char *shost = var_GetNonEmptyString (p_access, "src-addr"); char *dhost = var_GetNonEmptyString (p_access, "dst-addr"); int sport = var_GetInteger (p_access, "src-port"); int dport = var_GetInteger (p_access, "dst-port"); struct sockaddr_storage src, dst; socklen_t srclen = 0, dstlen = 0; struct addrinfo *res; if ( vlc_getaddrinfo ( VLC_OBJECT(p_stream), dhost, dport, &hints, &res) == 0) { memcpy (&dst, res->ai_addr, dstlen = res->ai_addrlen); vlc_freeaddrinfo (res); } if (vlc_getaddrinfo ( VLC_OBJECT(p_stream), shost, sport, &hints, &res) == 0) { memcpy (&src, res->ai_addr, srclen = res->ai_addrlen); vlc_freeaddrinfo (res); } char *head = vlc_sdp_Start (VLC_OBJECT (p_stream), SOUT_CFG_PREFIX, (struct sockaddr *)&src, srclen, (struct sockaddr *)&dst, dstlen); free (shost); char *psz_sdp = NULL; if (head != NULL) { if (asprintf (&psz_sdp, "%s" "m=video %d udp mpeg\r\n", head, dport) == -1) psz_sdp = NULL; free (head); } /* Register the SDP with the SAP thread */ if (psz_sdp != NULL) { announce_method_t *p_method = sout_SAPMethod (); msg_Dbg (p_stream, "Generated SDP:\n%s", psz_sdp); p_sys->p_session = sout_AnnounceRegisterSDP (p_sout, psz_sdp, dhost, p_method); sout_MethodRelease (p_method); free( psz_sdp ); } free (dhost); } p_stream->pf_add = Add; p_stream->pf_del = Del; p_stream->pf_send = Send; p_sys->p_mux = p_mux; free( psz_access ); free( psz_mux ); free( psz_url ); return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t * p_this ){ sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys = p_stream->p_sys; sout_access_out_t *p_access = p_sys->p_mux->p_access; if( p_sys->p_session != NULL ) sout_AnnounceUnRegister( p_stream->p_sout, p_sys->p_session ); sout_MuxDelete( p_sys->p_mux ); sout_AccessOutDelete( p_access ); free( p_sys );}struct sout_stream_id_t{ sout_input_t *p_input;};static sout_stream_id_t * Add( sout_stream_t *p_stream, es_format_t *p_fmt ){ sout_stream_sys_t *p_sys = p_stream->p_sys; sout_stream_id_t *id; id = malloc( sizeof( sout_stream_id_t ) ); if( !id ) return NULL; if( ( id->p_input = sout_MuxAddStream( p_sys->p_mux, p_fmt ) ) == NULL ) { free( id ); return NULL; } return id;}static int Del( sout_stream_t *p_stream, sout_stream_id_t *id ){ sout_stream_sys_t *p_sys = p_stream->p_sys; sout_MuxDeleteStream( p_sys->p_mux, id->p_input ); free( id ); return VLC_SUCCESS;}static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, block_t *p_buffer ){ sout_stream_sys_t *p_sys = p_stream->p_sys; sout_MuxSendBuffer( p_sys->p_mux, id->p_input, p_buffer ); return VLC_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -