X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Frtpdec.c;h=0e4665b7ea7e4f072901a2c71a01c2e8396ef7f2;hb=29a290439ba28fde00b2a27d5afef863c63abb37;hp=c9cf855a593df4cfd7111df5b84e0cf857ff3b0c;hpb=1e515c4280acb70c615e8fe562fa6b463f1d8bed;p=ffmpeg diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index c9cf855a593..0e4665b7ea7 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -2,20 +2,20 @@ * RTP input format * Copyright (c) 2002 Fabrice Bellard * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -44,8 +44,14 @@ 'url_open_dyn_packet_buf') */ +static RTPDynamicProtocolHandler ff_realmedia_mp3_dynamic_handler = { + .enc_name = "X-MP3-draft-00", + .codec_type = AVMEDIA_TYPE_AUDIO, + .codec_id = CODEC_ID_MP3ADU, +}; + /* statistics functions */ -RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL; +static RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL; void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler) { @@ -69,6 +75,7 @@ void av_register_rtp_dynamic_payload_handlers(void) ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler); ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler); ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler); + ff_register_dynamic_payload_handler(&ff_realmedia_mp3_dynamic_handler); ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler); ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler); @@ -116,9 +123,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l payload_len = (AV_RB16(buf + 2) + 1) * 4; s->last_rtcp_ntp_time = AV_RB64(buf + 8); - if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) - s->first_rtcp_ntp_time = s->last_rtcp_ntp_time; s->last_rtcp_timestamp = AV_RB32(buf + 16); + if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) { + s->first_rtcp_ntp_time = s->last_rtcp_ntp_time; + if (!s->base_timestamp) + s->base_timestamp = s->last_rtcp_timestamp; + s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp; + } buf += payload_len; len -= payload_len; @@ -226,7 +237,7 @@ static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32 int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) { - ByteIOContext *pb; + AVIOContext *pb; uint8_t *buf; int len; int rtcp_bytes; @@ -257,12 +268,12 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) return -1; // Receiver Report - put_byte(pb, (RTP_VERSION << 6) + 1); /* 1 report block */ - put_byte(pb, RTCP_RR); - put_be16(pb, 7); /* length in words - 1 */ + avio_w8(pb, (RTP_VERSION << 6) + 1); /* 1 report block */ + avio_w8(pb, RTCP_RR); + avio_wb16(pb, 7); /* length in words - 1 */ // our own SSRC: we use the server's SSRC + 1 to avoid conflicts - put_be32(pb, s->ssrc + 1); - put_be32(pb, s->ssrc); // server SSRC + avio_wb32(pb, s->ssrc + 1); + avio_wb32(pb, s->ssrc); // server SSRC // some placeholders we should really fill... // RFC 1889/p64 extended_max= stats->cycles + stats->max_seq; @@ -279,43 +290,43 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) fraction= (fraction<<24) | lost; - put_be32(pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */ - put_be32(pb, extended_max); /* max sequence received */ - put_be32(pb, stats->jitter>>4); /* jitter */ + avio_wb32(pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */ + avio_wb32(pb, extended_max); /* max sequence received */ + avio_wb32(pb, stats->jitter>>4); /* jitter */ if(s->last_rtcp_ntp_time==AV_NOPTS_VALUE) { - put_be32(pb, 0); /* last SR timestamp */ - put_be32(pb, 0); /* delay since last SR */ + avio_wb32(pb, 0); /* last SR timestamp */ + avio_wb32(pb, 0); /* delay since last SR */ } else { uint32_t middle_32_bits= s->last_rtcp_ntp_time>>16; // this is valid, right? do we need to handle 64 bit values special? uint32_t delay_since_last= ntp_time - s->last_rtcp_ntp_time; - put_be32(pb, middle_32_bits); /* last SR timestamp */ - put_be32(pb, delay_since_last); /* delay since last SR */ + avio_wb32(pb, middle_32_bits); /* last SR timestamp */ + avio_wb32(pb, delay_since_last); /* delay since last SR */ } // CNAME - put_byte(pb, (RTP_VERSION << 6) + 1); /* 1 report block */ - put_byte(pb, RTCP_SDES); + avio_w8(pb, (RTP_VERSION << 6) + 1); /* 1 report block */ + avio_w8(pb, RTCP_SDES); len = strlen(s->hostname); - put_be16(pb, (6 + len + 3) / 4); /* length in words - 1 */ - put_be32(pb, s->ssrc); - put_byte(pb, 0x01); - put_byte(pb, len); - put_buffer(pb, s->hostname, len); + avio_wb16(pb, (6 + len + 3) / 4); /* length in words - 1 */ + avio_wb32(pb, s->ssrc); + avio_w8(pb, 0x01); + avio_w8(pb, len); + avio_write(pb, s->hostname, len); // padding for (len = (6 + len) % 4; len % 4; len++) { - put_byte(pb, 0); + avio_w8(pb, 0); } - put_flush_packet(pb); + avio_flush(pb); len = url_close_dyn_buf(pb, &buf); if ((len > 0) && buf) { int result; - dprintf(s->ic, "sending %d bytes of RR\n", len); + av_dlog(s->ic, "sending %d bytes of RR\n", len); result= url_write(s->rtp_ctx, buf, len); - dprintf(s->ic, "result from url_write: %d\n", result); + av_dlog(s->ic, "result from url_write: %d\n", result); av_free(buf); } return 0; @@ -323,7 +334,7 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count) void rtp_send_punch_packets(URLContext* rtp_handle) { - ByteIOContext *pb; + AVIOContext *pb; uint8_t *buf; int len; @@ -331,13 +342,13 @@ void rtp_send_punch_packets(URLContext* rtp_handle) if (url_open_dyn_buf(&pb) < 0) return; - put_byte(pb, (RTP_VERSION << 6)); - put_byte(pb, 0); /* Payload type */ - put_be16(pb, 0); /* Seq */ - put_be32(pb, 0); /* Timestamp */ - put_be32(pb, 0); /* SSRC */ + avio_w8(pb, (RTP_VERSION << 6)); + avio_w8(pb, 0); /* Payload type */ + avio_wb16(pb, 0); /* Seq */ + avio_wb32(pb, 0); /* Timestamp */ + avio_wb32(pb, 0); /* SSRC */ - put_flush_packet(pb); + avio_flush(pb); len = url_close_dyn_buf(pb, &buf); if ((len > 0) && buf) url_write(rtp_handle, buf, len); @@ -347,12 +358,12 @@ void rtp_send_punch_packets(URLContext* rtp_handle) if (url_open_dyn_buf(&pb) < 0) return; - put_byte(pb, (RTP_VERSION << 6)); - put_byte(pb, RTCP_RR); /* receiver report */ - put_be16(pb, 1); /* length in words - 1 */ - put_be32(pb, 0); /* our own SSRC */ + avio_w8(pb, (RTP_VERSION << 6)); + avio_w8(pb, RTCP_RR); /* receiver report */ + avio_wb16(pb, 1); /* length in words - 1 */ + avio_wb32(pb, 0); /* our own SSRC */ - put_flush_packet(pb); + avio_flush(pb); len = url_close_dyn_buf(pb, &buf); if ((len > 0) && buf) url_write(rtp_handle, buf, len); @@ -386,7 +397,6 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r return NULL; } } else { - av_set_pts_info(st, 32, 1, 90000); switch(st->codec->codec_id) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: @@ -398,16 +408,12 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r st->need_parsing = AVSTREAM_PARSE_FULL; break; case CODEC_ID_ADPCM_G722: - av_set_pts_info(st, 32, 1, st->codec->sample_rate); /* According to RFC 3551, the stream clock rate is 8000 * even if the sample rate is 16000. */ if (st->codec->sample_rate == 8000) st->codec->sample_rate = 16000; break; default: - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - av_set_pts_info(st, 32, 1, st->codec->sample_rate); - } break; } } @@ -430,6 +436,8 @@ rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, */ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) { + if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE) + return; /* Timestamp already set by depacketizer */ if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && timestamp != RTP_NOTS_VALUE) { int64_t addend; int delta_timestamp; @@ -438,8 +446,15 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam delta_timestamp = timestamp - s->last_rtcp_timestamp; /* convert to the PTS timebase */ addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time, s->st->time_base.den, (uint64_t)s->st->time_base.num << 32); - pkt->pts = s->range_start_offset + addend + delta_timestamp; + pkt->pts = s->range_start_offset + s->rtcp_ts_offset + addend + + delta_timestamp; + return; } + if (timestamp == RTP_NOTS_VALUE) + return; + if (!s->base_timestamp) + s->base_timestamp = timestamp; + pkt->pts = s->range_start_offset + timestamp - s->base_timestamp; } static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt, @@ -475,6 +490,12 @@ static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt, return -1; } + if (buf[0] & 0x20) { + int padding = buf[len - 1]; + if (len >= 12 + padding) + len -= padding; + } + s->seq = seq; len -= 12; buf += 12;