aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2011-01-01 22:27:16 +0000
committerMartin Storsjö <martin@martin.st>2011-01-01 22:27:16 +0000
commit3a1cdcc798fd7cb60ef69d1d010f5d56218c4b3a (patch)
treea07de61f687827dc5a3bd9b70cae18e6eefb77f0
parentdfaa9f3cb328f245cc1f9c56145a21c6d6e58f42 (diff)
downloadffmpeg-3a1cdcc798fd7cb60ef69d1d010f5d56218c4b3a.tar.gz
rtpdec: Emit timestamps for packets before the first RTCP packet, too
Emitted timestamps in each stream start from 0, for the first received RTP packet. Once an RTCP packet is received, that one is used for sync, emitting timestamps that fit seamlessly into the earlier ones. Originally committed as revision 26187 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/rtpdec.c17
-rw-r--r--libavformat/rtpdec.h1
-rw-r--r--libavformat/rtsp.c14
-rw-r--r--libavformat/rtspdec.c2
4 files changed, 29 insertions, 5 deletions
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 77b59a3ff3..700924962e 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -123,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;
@@ -440,8 +444,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,
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 778ca92984..c5a521760d 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -172,6 +172,7 @@ struct RTPDemuxContext {
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
+ int64_t rtcp_ts_offset;
/* rtcp sender statistics */
unsigned int packet_count; // TODO: move into statistics (outgoing)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 8c9d79cd8f..ca84e5df2b 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1617,11 +1617,21 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
* in order to map their timestamp origin to the same ntp time
* as this one. */
int i;
+ AVStream *st = NULL;
+ if (rtsp_st->stream_index >= 0)
+ st = s->streams[rtsp_st->stream_index];
for (i = 0; i < rt->nb_rtsp_streams; i++) {
RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
- if (rtpctx2 &&
- rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE)
+ AVStream *st2 = NULL;
+ if (rt->rtsp_streams[i]->stream_index >= 0)
+ st2 = s->streams[rt->rtsp_streams[i]->stream_index];
+ if (rtpctx2 && st && st2 &&
+ rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
+ rtpctx2->rtcp_ts_offset = av_rescale_q(
+ rtpctx->rtcp_ts_offset, st->time_base,
+ st2->time_base);
+ }
}
}
if (ret == -RTCP_BYE) {
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 213f7095fb..ad13b170aa 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -67,6 +67,8 @@ static int rtsp_read_play(AVFormatContext *s)
if (reply->range_start != AV_NOPTS_VALUE) {
rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
+ rtpctx->base_timestamp = 0;
+ rtpctx->rtcp_ts_offset = 0;
if (st)
rtpctx->range_start_offset =
av_rescale_q(reply->range_start, AV_TIME_BASE_Q,