Commit 3a1cdcc7 authored by Martin Storsjö's avatar Martin Storsjö

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
parent dfaa9f3c
...@@ -123,9 +123,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l ...@@ -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; payload_len = (AV_RB16(buf + 2) + 1) * 4;
s->last_rtcp_ntp_time = AV_RB64(buf + 8); 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); 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; buf += payload_len;
len -= payload_len; len -= payload_len;
...@@ -440,8 +444,15 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam ...@@ -440,8 +444,15 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
delta_timestamp = timestamp - s->last_rtcp_timestamp; delta_timestamp = timestamp - s->last_rtcp_timestamp;
/* convert to the PTS timebase */ /* 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); 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, static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
......
...@@ -172,6 +172,7 @@ struct RTPDemuxContext { ...@@ -172,6 +172,7 @@ struct RTPDemuxContext {
int64_t last_rtcp_ntp_time; // TODO: move into statistics int64_t last_rtcp_ntp_time; // TODO: move into statistics
int64_t first_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 uint32_t last_rtcp_timestamp; // TODO: move into statistics
int64_t rtcp_ts_offset;
/* rtcp sender statistics */ /* rtcp sender statistics */
unsigned int packet_count; // TODO: move into statistics (outgoing) unsigned int packet_count; // TODO: move into statistics (outgoing)
......
...@@ -1617,11 +1617,21 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -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 * in order to map their timestamp origin to the same ntp time
* as this one. */ * as this one. */
int i; 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++) { for (i = 0; i < rt->nb_rtsp_streams; i++) {
RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv; RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
if (rtpctx2 && AVStream *st2 = NULL;
rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) 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->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) { if (ret == -RTCP_BYE) {
......
...@@ -67,6 +67,8 @@ static int rtsp_read_play(AVFormatContext *s) ...@@ -67,6 +67,8 @@ static int rtsp_read_play(AVFormatContext *s)
if (reply->range_start != AV_NOPTS_VALUE) { if (reply->range_start != AV_NOPTS_VALUE) {
rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE; rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
rtpctx->first_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) if (st)
rtpctx->range_start_offset = rtpctx->range_start_offset =
av_rescale_q(reply->range_start, AV_TIME_BASE_Q, av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment