You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
lavf: add and use AVRTCPSenderReport struct
This will be used in a future commit to expose the SR as side-data.
This commit is contained in:
@ -333,6 +333,20 @@ typedef struct AVProducerReferenceTime {
|
|||||||
int flags;
|
int flags;
|
||||||
} AVProducerReferenceTime;
|
} AVProducerReferenceTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RTCP SR (Sender Report) information
|
||||||
|
*
|
||||||
|
* The received sender report information for an RTSP
|
||||||
|
* stream, exposed as AV_PKT_DATA_RTCP_SR side data.
|
||||||
|
*/
|
||||||
|
typedef struct AVRTCPSenderReport {
|
||||||
|
uint32_t ssrc; ///< Synchronization source identifier
|
||||||
|
uint64_t ntp_timestamp; ///< NTP time when the report was sent
|
||||||
|
uint32_t rtp_timestamp; ///< RTP time when the report was sent
|
||||||
|
uint32_t sender_nb_packets; ///< Total number of packets sent
|
||||||
|
uint32_t sender_nb_bytes; ///< Total number of bytes sent (excluding headers or padding)
|
||||||
|
} AVRTCPSenderReport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode extradata length to a buffer. Used by xiph codecs.
|
* Encode extradata length to a buffer. Used by xiph codecs.
|
||||||
*
|
*
|
||||||
|
@ -192,14 +192,20 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf,
|
|||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->last_sr.ssrc = AV_RB32(buf + 4);
|
||||||
|
s->last_sr.ntp_timestamp = AV_RB64(buf + 8);
|
||||||
|
s->last_sr.rtp_timestamp = AV_RB32(buf + 16);
|
||||||
|
s->last_sr.sender_nb_packets = AV_RB32(buf + 20);
|
||||||
|
s->last_sr.sender_nb_bytes = AV_RB32(buf + 24);
|
||||||
|
|
||||||
|
s->pending_sr = 1;
|
||||||
s->last_rtcp_reception_time = av_gettime_relative();
|
s->last_rtcp_reception_time = av_gettime_relative();
|
||||||
s->last_rtcp_ntp_time = AV_RB64(buf + 8);
|
|
||||||
s->last_rtcp_timestamp = AV_RB32(buf + 16);
|
|
||||||
if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
|
if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
|
||||||
s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
|
s->first_rtcp_ntp_time = s->last_sr.ntp_timestamp;
|
||||||
if (!s->base_timestamp)
|
if (!s->base_timestamp)
|
||||||
s->base_timestamp = s->last_rtcp_timestamp;
|
s->base_timestamp = s->last_sr.rtp_timestamp;
|
||||||
s->rtcp_ts_offset = (int32_t)(s->last_rtcp_timestamp - s->base_timestamp);
|
s->rtcp_ts_offset = (int32_t)(s->last_sr.rtp_timestamp - s->base_timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -367,11 +373,11 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
|
|||||||
avio_wb32(pb, extended_max); /* max sequence received */
|
avio_wb32(pb, extended_max); /* max sequence received */
|
||||||
avio_wb32(pb, stats->jitter >> 4); /* jitter */
|
avio_wb32(pb, stats->jitter >> 4); /* jitter */
|
||||||
|
|
||||||
if (s->last_rtcp_ntp_time == AV_NOPTS_VALUE) {
|
if (s->last_sr.ntp_timestamp == AV_NOPTS_VALUE) {
|
||||||
avio_wb32(pb, 0); /* last SR timestamp */
|
avio_wb32(pb, 0); /* last SR timestamp */
|
||||||
avio_wb32(pb, 0); /* delay since last SR */
|
avio_wb32(pb, 0); /* delay since last SR */
|
||||||
} else {
|
} 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 middle_32_bits = s->last_sr.ntp_timestamp >> 16; // this is valid, right? do we need to handle 64 bit values special?
|
||||||
uint32_t delay_since_last = av_rescale(av_gettime_relative() - s->last_rtcp_reception_time,
|
uint32_t delay_since_last = av_rescale(av_gettime_relative() - s->last_rtcp_reception_time,
|
||||||
65536, AV_TIME_BASE);
|
65536, AV_TIME_BASE);
|
||||||
|
|
||||||
@ -538,7 +544,7 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
|
|||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return NULL;
|
||||||
s->payload_type = payload_type;
|
s->payload_type = payload_type;
|
||||||
s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
|
s->last_sr.ntp_timestamp = AV_NOPTS_VALUE;
|
||||||
s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
|
s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
|
||||||
s->ic = s1;
|
s->ic = s1;
|
||||||
s->st = st;
|
s->st = st;
|
||||||
@ -596,9 +602,9 @@ static int rtp_set_prft(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp) {
|
|||||||
if (!prft)
|
if (!prft)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
rtcp_time = ff_parse_ntp_time(s->last_rtcp_ntp_time) - NTP_OFFSET_US;
|
rtcp_time = ff_parse_ntp_time(s->last_sr.ntp_timestamp) - NTP_OFFSET_US;
|
||||||
/* Cast to int32_t to handle timestamp wraparound correctly */
|
/* Cast to int32_t to handle timestamp wraparound correctly */
|
||||||
delta_timestamp = (int32_t)(timestamp - s->last_rtcp_timestamp);
|
delta_timestamp = (int32_t)(timestamp - s->last_sr.rtp_timestamp);
|
||||||
delta_time = av_rescale_q(delta_timestamp, s->st->time_base, AV_TIME_BASE_Q);
|
delta_time = av_rescale_q(delta_timestamp, s->st->time_base, AV_TIME_BASE_Q);
|
||||||
|
|
||||||
prft->wallclock = rtcp_time + delta_time;
|
prft->wallclock = rtcp_time + delta_time;
|
||||||
@ -617,21 +623,21 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
|
|||||||
if (timestamp == RTP_NOTS_VALUE)
|
if (timestamp == RTP_NOTS_VALUE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
|
if (s->last_sr.ntp_timestamp != AV_NOPTS_VALUE) {
|
||||||
if (rtp_set_prft(s, pkt, timestamp) < 0) {
|
if (rtp_set_prft(s, pkt, timestamp) < 0) {
|
||||||
av_log(s->ic, AV_LOG_WARNING, "rtpdec: failed to set prft");
|
av_log(s->ic, AV_LOG_WARNING, "rtpdec: failed to set prft");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && s->ic->nb_streams > 1) {
|
if (s->last_sr.ntp_timestamp != AV_NOPTS_VALUE && s->ic->nb_streams > 1) {
|
||||||
int64_t addend;
|
int64_t addend;
|
||||||
int32_t delta_timestamp;
|
int32_t delta_timestamp;
|
||||||
|
|
||||||
/* compute pts from timestamp with received ntp_time */
|
/* compute pts from timestamp with received ntp_time */
|
||||||
/* Cast to int32_t to handle timestamp wraparound correctly */
|
/* Cast to int32_t to handle timestamp wraparound correctly */
|
||||||
delta_timestamp = (int32_t)(timestamp - s->last_rtcp_timestamp);
|
delta_timestamp = (int32_t)(timestamp - s->last_sr.rtp_timestamp);
|
||||||
/* convert to the PTS timebase */
|
/* convert to the PTS timebase */
|
||||||
addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time,
|
addend = av_rescale(s->last_sr.ntp_timestamp - s->first_rtcp_ntp_time,
|
||||||
s->st->time_base.den,
|
s->st->time_base.den,
|
||||||
(uint64_t) s->st->time_base.num << 32);
|
(uint64_t) s->st->time_base.num << 32);
|
||||||
pkt->pts = s->range_start_offset + s->rtcp_ts_offset + addend +
|
pkt->pts = s->range_start_offset + s->rtcp_ts_offset + addend +
|
||||||
|
@ -173,11 +173,11 @@ struct RTPDemuxContext {
|
|||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/* rtcp sender statistics receive */
|
/* rtcp sender statistics receive */
|
||||||
uint64_t last_rtcp_ntp_time;
|
|
||||||
int64_t last_rtcp_reception_time;
|
int64_t last_rtcp_reception_time;
|
||||||
uint64_t first_rtcp_ntp_time;
|
uint64_t first_rtcp_ntp_time;
|
||||||
uint32_t last_rtcp_timestamp;
|
|
||||||
int64_t rtcp_ts_offset;
|
int64_t rtcp_ts_offset;
|
||||||
|
AVRTCPSenderReport last_sr; ///< Last RTCP SR data
|
||||||
|
int pending_sr; ///< Indicates if there is a SR pending to be attached as sidedata
|
||||||
|
|
||||||
/* rtcp sender statistics */
|
/* rtcp sender statistics */
|
||||||
unsigned int packet_count;
|
unsigned int packet_count;
|
||||||
|
@ -553,7 +553,7 @@ static int rtsp_read_play(AVFormatContext *s)
|
|||||||
if (!rtpctx)
|
if (!rtpctx)
|
||||||
continue;
|
continue;
|
||||||
ff_rtp_reset_packet_queue(rtpctx);
|
ff_rtp_reset_packet_queue(rtpctx);
|
||||||
rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
|
rtpctx->last_sr.ntp_timestamp = AV_NOPTS_VALUE;
|
||||||
rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
|
rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
|
||||||
rtpctx->base_timestamp = 0;
|
rtpctx->base_timestamp = 0;
|
||||||
rtpctx->timestamp = 0;
|
rtpctx->timestamp = 0;
|
||||||
|
Reference in New Issue
Block a user