📄 live555.cpp
字号:
tk = (live_track_t*)malloc( sizeof( live_track_t ) ); if( !tk ) { delete iter; return VLC_ENOMEM; } tk->p_demux = p_demux; tk->sub = sub; tk->p_es = NULL; tk->b_quicktime = false; tk->b_asf = false; tk->b_muxed = false; tk->p_out_muxed = NULL; tk->waiting = 0; tk->b_rtcp_sync = false; tk->i_pts = 0; tk->i_npt = 0; tk->i_buffer = 65536; tk->p_buffer = (uint8_t *)malloc( 65536 ); if( !tk->p_buffer ) { delete iter; return VLC_ENOMEM; } /* Value taken from mplayer */ if( !strcmp( sub->mediumName(), "audio" ) ) { es_format_Init( &tk->fmt, AUDIO_ES, VLC_FOURCC('u','n','d','f') ); tk->fmt.audio.i_channels = sub->numChannels(); tk->fmt.audio.i_rate = sub->rtpTimestampFrequency(); if( !strcmp( sub->codecName(), "MPA" ) || !strcmp( sub->codecName(), "MPA-ROBUST" ) || !strcmp( sub->codecName(), "X-MP3-DRAFT-00" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' ); tk->fmt.audio.i_rate = 0; } else if( !strcmp( sub->codecName(), "AC3" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'a', '5', '2', ' ' ); tk->fmt.audio.i_rate = 0; } else if( !strcmp( sub->codecName(), "L16" ) ) { tk->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' ); tk->fmt.audio.i_bitspersample = 16; } else if( !strcmp( sub->codecName(), "L8" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' ); tk->fmt.audio.i_bitspersample = 8; } else if( !strcmp( sub->codecName(), "PCMU" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'u', 'l', 'a', 'w' ); } else if( !strcmp( sub->codecName(), "PCMA" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'a', 'l', 'a', 'w' ); } else if( !strncmp( sub->codecName(), "G726", 4 ) ) { tk->fmt.i_codec = VLC_FOURCC( 'g', '7', '2', '6' ); tk->fmt.audio.i_rate = 8000; tk->fmt.audio.i_channels = 1; if( !strcmp( sub->codecName()+5, "40" ) ) tk->fmt.i_bitrate = 40000; else if( !strcmp( sub->codecName()+5, "32" ) ) tk->fmt.i_bitrate = 32000; else if( !strcmp( sub->codecName()+5, "24" ) ) tk->fmt.i_bitrate = 24000; else if( !strcmp( sub->codecName()+5, "16" ) ) tk->fmt.i_bitrate = 16000; } else if( !strcmp( sub->codecName(), "AMR" ) ) { tk->fmt.i_codec = VLC_FOURCC( 's', 'a', 'm', 'r' ); } else if( !strcmp( sub->codecName(), "AMR-WB" ) ) { tk->fmt.i_codec = VLC_FOURCC( 's', 'a', 'w', 'b' ); } else if( !strcmp( sub->codecName(), "MP4A-LATM" ) ) { unsigned int i_extra; uint8_t *p_extra; tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' ); if( ( p_extra = parseStreamMuxConfigStr( sub->fmtp_config(), i_extra ) ) ) { tk->fmt.i_extra = i_extra; tk->fmt.p_extra = malloc( i_extra ); memcpy( tk->fmt.p_extra, p_extra, i_extra ); delete[] p_extra; } /* Because the "faad" decoder does not handle the LATM data length field at the start of each returned LATM frame, tell the RTP source to omit it. */ ((MPEG4LATMAudioRTPSource*)sub->rtpSource())->omitLATMDataLengthField(); } else if( !strcmp( sub->codecName(), "MPEG4-GENERIC" ) ) { unsigned int i_extra; uint8_t *p_extra; tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'a' ); if( ( p_extra = parseGeneralConfigStr( sub->fmtp_config(), i_extra ) ) ) { tk->fmt.i_extra = i_extra; tk->fmt.p_extra = malloc( i_extra ); memcpy( tk->fmt.p_extra, p_extra, i_extra ); delete[] p_extra; } } else if( !strcmp( sub->codecName(), "X-ASF-PF" ) ) { tk->b_asf = true; if( p_sys->p_out_asf == NULL ) p_sys->p_out_asf = stream_DemuxNew( p_demux, "asf", p_demux->out ); } else if( !strcmp( sub->codecName(), "X-QT" ) || !strcmp( sub->codecName(), "X-QUICKTIME" ) ) { tk->b_quicktime = true; } else if( !strcmp( sub->codecName(), "SPEEX" ) ) { tk->fmt.i_codec = VLC_FOURCC( 's', 'p', 'x', 'r' ); if ( sub->rtpTimestampFrequency() ) tk->fmt.audio.i_rate = sub->rtpTimestampFrequency(); else { msg_Warn( p_demux,"Using 8kHz as default sample rate." ); tk->fmt.audio.i_rate = 8000; } } } else if( !strcmp( sub->mediumName(), "video" ) ) { es_format_Init( &tk->fmt, VIDEO_ES, VLC_FOURCC('u','n','d','f') ); if( !strcmp( sub->codecName(), "MPV" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'v' ); } else if( !strcmp( sub->codecName(), "H263" ) || !strcmp( sub->codecName(), "H263-1998" ) || !strcmp( sub->codecName(), "H263-2000" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'H', '2', '6', '3' ); } else if( !strcmp( sub->codecName(), "H261" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'H', '2', '6', '1' ); } else if( !strcmp( sub->codecName(), "H264" ) ) { unsigned int i_extra = 0; uint8_t *p_extra = NULL; tk->fmt.i_codec = VLC_FOURCC( 'h', '2', '6', '4' ); tk->fmt.b_packetized = false; if((p_extra=parseH264ConfigStr( sub->fmtp_spropparametersets(), i_extra ) ) ) { tk->fmt.i_extra = i_extra; tk->fmt.p_extra = malloc( i_extra ); memcpy( tk->fmt.p_extra, p_extra, i_extra ); delete[] p_extra; } } else if( !strcmp( sub->codecName(), "JPEG" ) ) { tk->fmt.i_codec = VLC_FOURCC( 'M', 'J', 'P', 'G' ); } else if( !strcmp( sub->codecName(), "MP4V-ES" ) ) { unsigned int i_extra; uint8_t *p_extra; tk->fmt.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' ); if( ( p_extra = parseGeneralConfigStr( sub->fmtp_config(), i_extra ) ) ) { tk->fmt.i_extra = i_extra; tk->fmt.p_extra = malloc( i_extra ); memcpy( tk->fmt.p_extra, p_extra, i_extra ); delete[] p_extra; } } else if( !strcmp( sub->codecName(), "X-QT" ) || !strcmp( sub->codecName(), "X-QUICKTIME" ) || !strcmp( sub->codecName(), "X-QDM" ) || !strcmp( sub->codecName(), "X-SV3V-ES" ) || !strcmp( sub->codecName(), "X-SORENSONVIDEO" ) ) { tk->b_quicktime = true; } else if( !strcmp( sub->codecName(), "MP2T" ) ) { tk->b_muxed = true; tk->p_out_muxed = stream_DemuxNew( p_demux, "ts", p_demux->out ); } else if( !strcmp( sub->codecName(), "MP2P" ) || !strcmp( sub->codecName(), "MP1S" ) ) { tk->b_muxed = true; tk->p_out_muxed = stream_DemuxNew( p_demux, "ps", p_demux->out ); } else if( !strcmp( sub->codecName(), "X-ASF-PF" ) ) { tk->b_asf = true; if( p_sys->p_out_asf == NULL ) p_sys->p_out_asf = stream_DemuxNew( p_demux, "asf", p_demux->out );; } } if( !tk->b_quicktime && !tk->b_muxed && !tk->b_asf ) { tk->p_es = es_out_Add( p_demux->out, &tk->fmt ); } if( sub->rtcpInstance() != NULL ) { sub->rtcpInstance()->setByeHandler( StreamClose, tk ); } if( tk->p_es || tk->b_quicktime || tk->b_muxed || tk->b_asf ) { /* Append */ p_sys->track = (live_track_t**)realloc( p_sys->track, sizeof( live_track_t ) * ( p_sys->i_track + 1 ) ); p_sys->track[p_sys->i_track++] = tk; } else { /* BUG ??? */ msg_Err( p_demux, "unusable RTSP track. this should not happen" ); es_format_Clean( &tk->fmt ); free( tk ); } } } delete iter; if( p_sys->i_track <= 0 ) i_return = VLC_EGENERIC; /* Retrieve the starttime if possible */ p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 ); if( p_sys->i_npt_start < 0 ) p_sys->i_npt_start = -1; /* Retrieve the duration if possible */ p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 ); if( p_sys->i_npt_length < 0 ) p_sys->i_npt_length = -1; msg_Dbg( p_demux, "setup start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length ); return i_return;}/***************************************************************************** * Play: starts the actual playback of the stream *****************************************************************************/static int Play( demux_t *p_demux ){ demux_sys_t *p_sys = p_demux->p_sys; int i; if( p_sys->rtsp ) { /* The PLAY */ if( !p_sys->rtsp->playMediaSession( *p_sys->ms, p_sys->i_npt_start, -1, 1 ) ) { msg_Err( p_demux, "RTSP PLAY failed %s", p_sys->env->getResultMsg() ); return VLC_EGENERIC; } /* Retrieve the timeout value and set up a timeout prevention thread */ p_sys->i_timeout = p_sys->rtsp->sessionTimeoutParameter(); if( p_sys->i_timeout <= 0 ) p_sys->i_timeout = 60; /* default value from RFC2326 */ /* start timeout-thread only if GET_PARAMETER is supported by the server */ if( !p_sys->p_timeout && p_sys->b_get_param ) { msg_Dbg( p_demux, "We have a timeout of %d seconds", p_sys->i_timeout ); p_sys->p_timeout = (timeout_thread_t *)vlc_object_create( p_demux, sizeof(timeout_thread_t) ); p_sys->p_timeout->p_sys = p_demux->p_sys; /* lol, object recursion :D */ if( vlc_thread_create( p_sys->p_timeout, "liveMedia-timeout", TimeoutPrevention, VLC_THREAD_PRIORITY_LOW, true ) ) { msg_Err( p_demux, "cannot spawn liveMedia timeout thread" ); vlc_object_release( p_sys->p_timeout ); } msg_Dbg( p_demux, "spawned timeout thread" ); vlc_object_attach( p_sys->p_timeout, p_demux ); } } p_sys->i_pcr = 0; /* Retrieve the starttime if possible */ p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 ); if( p_sys->i_npt_start < 0 ) p_sys->i_npt_start = -1; p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 ); if( p_sys->i_npt_length < 0 ) p_sys->i_npt_length = -1; msg_Dbg( p_demux, "play start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length ); return VLC_SUCCESS;}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){ demux_sys_t *p_sys = p_demux->p_sys; TaskToken task; bool b_send_pcr = true; int64_t i_pcr = 0; int i; /* Check if we need to send the server a Keep-A-Live signal */ if( p_sys->b_timeout_call && p_sys->rtsp && p_sys->ms ) { char *psz_bye = NULL; p_sys->rtsp->getMediaSessionParameter( *p_sys->ms, NULL, psz_bye ); p_sys->b_timeout_call = false; } for( i = 0; i < p_sys->i_track; i++ ) { live_track_t *tk = p_sys->track[i]; if( tk->b_asf || tk->b_muxed ) b_send_pcr = false;#if 0 if( i_pcr == 0 ) { i_pcr = tk->i_pts; } else if( tk->i_pts != 0 && i_pcr > tk->i_pts ) { i_pcr = tk->i_pts ; }#endif } if( p_sys->i_pcr > 0 ) { if( b_send_pcr ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr ); } /* First warn we want to read data */ p_sys->event = 0; for( i = 0; i < p_sys->i_track; i++ ) { live_track_t *tk = p_sys->track[i]; if( tk->waiting == 0 ) { tk->waiting = 1; tk->sub->readSource()->getNextFrame( tk->p_buffer, tk->i_buffer,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -