History

Merge commit '86d9181cf41edc3382bf2481f95a2fb321058689'

* commit '86d9181cf41edc3382bf2481f95a2fb321058689': rtpdec: Support sending RTCP feedback packets Conflicts: libavformat/version.h

Michael Niedermayer committed 13 years ago

Commit 34c1c082 parents 8c3ae9e 86d91815 files · +113 −1Browse files

Unified · Split

5 files
  1. libavformat/rtpdec.c +96 −0
  2. libavformat/rtpdec.h +5 −0
  3. libavformat/rtsp.c +8 −0
  4. libavformat/rtsp.h +3 −0
  5. libavformat/version.h +1 −1
libavformat/rtpdec.c+96−0
@@ -30,6 +30,8 @@ · 29 unmodified lines
3030 #include "rtpdec.h"
3131 #include "rtpdec_formats.h"
3232
33+#define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
34+
3335 static RTPDynamicProtocolHandler realmedia_mp3_dynamic_handler = {
3436 .enc_name = "X-MP3-draft-00",
3537 .codec_type = AVMEDIA_TYPE_AUDIO,
@@ -366,6 +368,100 @@ void ff_rtp_send_punch_packets(URLContext *rtp_handle) · 330 unmodified lines
366368 av_free(buf);
367369 }
368370
371+static int find_missing_packets(RTPDemuxContext *s, uint16_t *first_missing,
372+ uint16_t *missing_mask)
373+{
374+ int i;
375+ uint16_t next_seq = s->seq + 1;
376+ RTPPacket *pkt = s->queue;
377+
378+ if (!pkt || pkt->seq == next_seq)
379+ return 0;
380+
381+ *missing_mask = 0;
382+ for (i = 1; i <= 16; i++) {
383+ uint16_t missing_seq = next_seq + i;
384+ while (pkt) {
385+ int16_t diff = pkt->seq - missing_seq;
386+ if (diff >= 0)
387+ break;
388+ pkt = pkt->next;
389+ }
390+ if (!pkt)
391+ break;
392+ if (pkt->seq == missing_seq)
393+ continue;
394+ *missing_mask |= 1 << (i - 1);
395+ }
396+
397+ *first_missing = next_seq;
398+ return 1;
399+}
400+
401+int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
402+ AVIOContext *avio)
403+{
404+ int len, need_keyframe, missing_packets;
405+ AVIOContext *pb;
406+ uint8_t *buf;
407+ int64_t now;
408+ uint16_t first_missing, missing_mask;
409+
410+ if (!fd && !avio)
411+ return -1;
412+
413+ need_keyframe = s->handler && s->handler->need_keyframe &&
414+ s->handler->need_keyframe(s->dynamic_protocol_context);
415+ missing_packets = find_missing_packets(s, &first_missing, &missing_mask);
416+
417+ if (!need_keyframe && !missing_packets)
418+ return 0;
419+
420+ /* Send new feedback if enough time has elapsed since the last
421+ * feedback packet. */
422+
423+ now = av_gettime();
424+ if (s->last_feedback_time &&
425+ (now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)
426+ return 0;
427+ s->last_feedback_time = now;
428+
429+ if (!fd)
430+ pb = avio;
431+ else if (avio_open_dyn_buf(&pb) < 0)
432+ return -1;
433+
434+ if (need_keyframe) {
435+ avio_w8(pb, (RTP_VERSION << 6) | 1); /* PLI */
436+ avio_w8(pb, RTCP_PSFB);
437+ avio_wb16(pb, 2); /* length in words - 1 */
438+ // our own SSRC: we use the server's SSRC + 1 to avoid conflicts
439+ avio_wb32(pb, s->ssrc + 1);
440+ avio_wb32(pb, s->ssrc); // server SSRC
441+ }
442+
443+ if (missing_packets) {
444+ avio_w8(pb, (RTP_VERSION << 6) | 1); /* NACK */
445+ avio_w8(pb, RTCP_RTPFB);
446+ avio_wb16(pb, 3); /* length in words - 1 */
447+ avio_wb32(pb, s->ssrc + 1);
448+ avio_wb32(pb, s->ssrc); // server SSRC
449+
450+ avio_wb16(pb, first_missing);
451+ avio_wb16(pb, missing_mask);
452+ }
453+
454+ avio_flush(pb);
455+ if (!fd)
456+ return 0;
457+ len = avio_close_dyn_buf(pb, &buf);
458+ if (len > 0 && buf) {
459+ ffurl_write(fd, buf, len);
460+ av_free(buf);
461+ }
462+ return 0;
463+}
464+
369465 /**
370466 * open a new RTP parse context for stream 'st'. 'st' can be NULL for
371467 * MPEG2-TS streams to indicate that they should be demuxed inside the
libavformat/rtpdec.h+5−0
@@ -73,6 +73,8 @@ void ff_rtp_send_punch_packets(URLContext* rtp_handle); · 72 unmodified lines
7373 */
7474 int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
7575 AVIOContext *avio, int count);
76+int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
77+ AVIOContext *avio);
7678
7779 // these statistics are used for rtcp receiver reports...
7880 typedef struct RTPStatistics {
@@ -130,6 +132,7 @@ struct RTPDynamicProtocolHandler { · 51 unmodified lines
130132 void (*free)(PayloadContext *protocol_data);
131133 /** Parse handler for this dynamic packet */
132134 DynamicPayloadPacketHandlerProc parse_packet;
135+ int (*need_keyframe)(PayloadContext *context);
133136
134137 struct RTPDynamicProtocolHandler *next;
135138 };
@@ -180,6 +183,8 @@ struct RTPDemuxContext { · 44 unmodified lines
180183 unsigned int packet_count;
181184 unsigned int octet_count;
182185 unsigned int last_octet_count;
186+ int64_t last_feedback_time;
187+
183188 /* buffer for partially parsed packets */
184189 uint8_t buf[RTP_MAX_PACKET_LENGTH];
185190
libavformat/rtsp.c+8−0
@@ -380,6 +380,8 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, · 379 unmodified lines
380380 get_word(buf1, sizeof(buf1), &p); /* protocol */
381381 if (!strcmp(buf1, "udp"))
382382 rt->transport = RTSP_TRANSPORT_RAW;
383+ else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
384+ rtsp_st->feedback = 1;
383385
384386 /* XXX: handle list of formats */
385387 get_word(buf1, sizeof(buf1), &p); /* format list */
@@ -1932,6 +1934,12 @@ redo: · 1546 unmodified lines
19321934 ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
19331935 } else if (rt->transport == RTSP_TRANSPORT_RTP) {
19341936 ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1937+ if (rtsp_st->feedback) {
1938+ AVIOContext *pb = NULL;
1939+ if (rt->lower_transport == RTSP_LOWER_TRANSPORT_CUSTOM)
1940+ pb = s->pb;
1941+ ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
1942+ }
19351943 if (ret < 0) {
19361944 /* Either bad packet, or a RTCP packet. Check if the
19371945 * first_rtcp_ntp_time field was initialized. */
libavformat/rtsp.h+3−0
@@ -437,6 +437,9 @@ typedef struct RTSPStream { · 436 unmodified lines
437437 /** private data associated with the dynamic protocol */
438438 PayloadContext *dynamic_protocol_context;
439439 //@}
440+
441+ /** Enable sending RTCP feedback messages according to RFC 4585 */
442+ int feedback;
440443 } RTSPStream;
441444
442445 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
libavformat/version.h+1−1
@@ -31,7 +31,7 @@ · 30 unmodified lines
3131
3232 #define LIBAVFORMAT_VERSION_MAJOR 54
3333 #define LIBAVFORMAT_VERSION_MINOR 59
34−#define LIBAVFORMAT_VERSION_MICRO 106
34+#define LIBAVFORMAT_VERSION_MICRO 107
3535
3636 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
3737 LIBAVFORMAT_VERSION_MINOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t