summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2010-04-20 07:34:28 +0000
committerMartin Storsjö <martin@martin.st>2010-04-20 07:34:28 +0000
commit2cab6b48ad9595abe24615c3262f22b76c9b921d (patch)
treecee1cf9ffde9beb4989a76f5b3615c59c57aed55 /libavformat
parent2293a2e67fb54aae165bb042d3154a7809a81860 (diff)
Revert svn rev 21857, readd first_rtcp_ntp_time in RTPDemuxContext
In order to sync RTP streams that get their initial RTCP timestamp at different times, propagate the NTP timestamp of the first RTCP packet to all other streams. This makes the timestamps of returned packets start at (near) zero instead of at any random offset. Originally committed as revision 22917 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/rtpdec.c5
-rw-r--r--libavformat/rtpdec.h1
-rw-r--r--libavformat/rtsp.c21
3 files changed, 25 insertions, 2 deletions
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index d2041878cf..bd3566e9f8 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -80,6 +80,8 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
if (buf[1] != 200)
return -1;
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);
return 0;
}
@@ -326,6 +328,7 @@ RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *r
return NULL;
s->payload_type = payload_type;
s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
+ s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
s->ic = s1;
s->st = st;
s->rtp_payload_data = rtp_payload_data;
@@ -433,7 +436,7 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
/* compute pts from timestamp with received ntp_time */
delta_timestamp = timestamp - s->last_rtcp_timestamp;
/* convert to the PTS timebase */
- addend = av_rescale(s->last_rtcp_ntp_time, s->st->time_base.den, (uint64_t)s->st->time_base.num << 32);
+ 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 = addend + delta_timestamp;
}
}
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 1754d2bce1..599e13d2a2 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -174,6 +174,7 @@ struct RTPDemuxContext {
/* rtcp sender statistics receive */
int64_t last_rtcp_ntp_time; // TODO: move into statistics
+ int64_t first_rtcp_ntp_time; // TODO: move into statistics
uint32_t last_rtcp_timestamp; // TODO: move into statistics
/* rtcp sender statistics */
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index b0fa2eae25..0931201f81 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1796,8 +1796,27 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
return AVERROR_EOF;
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
- } else
+ } else {
ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
+ if (ret < 0) {
+ /* Either bad packet, or a RTCP packet. Check if the
+ * first_rtcp_ntp_time field was initialized. */
+ RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
+ if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
+ /* first_rtcp_ntp_time has been initialized for this stream,
+ * copy the same value to all other uninitialized streams,
+ * in order to map their timestamp origin to the same ntp time
+ * as this one. */
+ int i;
+ for (i = 0; i < rt->nb_rtsp_streams; i++) {
+ RTPDemuxContext *rtpctx2 = rtsp_st->transport_priv;
+ if (rtpctx2 &&
+ rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE)
+ rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
+ }
+ }
+ }
+ }
if (ret < 0)
goto redo;
if (ret == 1)