[FFmpeg-devel] [PATCH] rtpenc: packetizer for VP9 RTP payload format (draft v2)

Thomas Volkert silvo at gmx.net
Mon May 30 16:41:21 CEST 2016


From: Thomas Volkert <thomas at netzeal.de>

---
 libavformat/Makefile     |  1 +
 libavformat/rtpenc.c     | 14 +++++++++++++
 libavformat/rtpenc.h     |  1 +
 libavformat/rtpenc_vp9.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/sdp.c        |  4 ++++
 5 files changed, 74 insertions(+)
 create mode 100644 libavformat/rtpenc_vp9.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 6684ead..481f3b1 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -413,6 +413,7 @@ OBJS-$(CONFIG_RTP_MUXER)                 += rtp.o         \
                                             rtpenc.o      \
                                             rtpenc_vc2hq.o              \
                                             rtpenc_vp8.o  \
+                                            rtpenc_vp9.o                \
                                             rtpenc_xiph.o \
                                             avc.o hevc.o
 OBJS-$(CONFIG_RTSP_DEMUXER)              += rtsp.o rtspdec.o httpauth.o \
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index f477650..db1ec81 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -75,6 +75,7 @@ static int is_supported(enum AVCodecID id)
     case AV_CODEC_ID_VORBIS:
     case AV_CODEC_ID_THEORA:
     case AV_CODEC_ID_VP8:
+    case AV_CODEC_ID_VP9:
     case AV_CODEC_ID_ADPCM_G722:
     case AV_CODEC_ID_ADPCM_G726:
     case AV_CODEC_ID_ILBC:
@@ -211,6 +212,16 @@ static int rtp_write_header(AVFormatContext *s1)
             s->nal_length_size = (st->codecpar->extradata[21] & 0x03) + 1;
         }
         break;
+    case AV_CODEC_ID_VP9:
+        if (s1->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+            av_log(s, AV_LOG_ERROR,
+                   "Packetizing VP9 is experimental and its specification is "
+                   "still in draft state. "
+                   "Please set -strict experimental in order to enable it.\n");
+            ret = AVERROR_EXPERIMENTAL;
+            goto fail;
+        }
+        break;
     case AV_CODEC_ID_VORBIS:
     case AV_CODEC_ID_THEORA:
         s->max_frames_per_packet = 15;
@@ -594,6 +605,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
     case AV_CODEC_ID_VP8:
         ff_rtp_send_vp8(s1, pkt->data, size);
         break;
+    case AV_CODEC_ID_VP9:
+        ff_rtp_send_vp9(s1, pkt->data, size);
+        break;
     case AV_CODEC_ID_ILBC:
         rtp_send_ilbc(s1, pkt->data, size);
         break;
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index dc30a6d..70f18ed 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -93,6 +93,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size);
 void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size);
 void ff_rtp_send_vc2hq(AVFormatContext *s1, const uint8_t *buf, int size, int interlaced);
 void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t *buff, int size);
+void ff_rtp_send_vp9(AVFormatContext *s1, const uint8_t *buff, int size);
 void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buff, int size);
 
 const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *av_restrict start,
diff --git a/libavformat/rtpenc_vp9.c b/libavformat/rtpenc_vp9.c
new file mode 100644
index 0000000..172ab21
--- /dev/null
+++ b/libavformat/rtpenc_vp9.c
@@ -0,0 +1,54 @@
+/*
+ * RTP packetizer for VP9 payload format (draft version 02) - experimental
+ * Copyright (c) 2016 Thomas Volkert <thomas at netzeal.de>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "rtpenc.h"
+
+#define RTP_VP9_DESC_REQUIRED_SIZE 1
+
+void ff_rtp_send_vp9(AVFormatContext *ctx, const uint8_t *buf, int size)
+{
+    RTPMuxContext *rtp_ctx = ctx->priv_data;
+    int len;
+
+    rtp_ctx->timestamp  = rtp_ctx->cur_timestamp;
+    rtp_ctx->buf_ptr    = rtp_ctx->buf;
+
+    /* mark the first fragment */
+    *rtp_ctx->buf_ptr++ = 0x08;
+
+    while (size > 0) {
+        len = FFMIN(size, rtp_ctx->max_payload_size - RTP_VP9_DESC_REQUIRED_SIZE);
+
+        if (len == size) {
+            /* mark the last fragment */
+            rtp_ctx->buf[0] |= 0x04;
+        }
+
+        memcpy(rtp_ctx->buf_ptr, buf, len);
+        ff_rtp_send_data(ctx, rtp_ctx->buf, len + RTP_VP9_DESC_REQUIRED_SIZE, size == len);
+
+        size            -= len;
+        buf             += len;
+
+        /* clear the end bit */
+        rtp_ctx->buf[0] &= ~0x08;
+    }
+}
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index 8279d59..ea369e9 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -657,6 +657,10 @@ static char *sdp_write_media_attributes(char *buff, int size, AVStream *st, int
             av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",
                                      payload_type);
             break;
+        case AV_CODEC_ID_VP9:
+            av_strlcatf(buff, size, "a=rtpmap:%d VP9/90000\r\n",
+                                     payload_type);
+            break;
         case AV_CODEC_ID_MJPEG:
             if (payload_type >= RTP_PT_PRIVATE)
                 av_strlcatf(buff, size, "a=rtpmap:%d JPEG/90000\r\n",
-- 
1.9.1



More information about the ffmpeg-devel mailing list