From 668fb1cb6a4ebdbf367881ca0f1b4dfd1fdafce8 Mon Sep 17 00:00:00 2001 From: Thomas Volkert Date: Mon, 30 May 2016 16:31:52 +0200 Subject: rtpenc: packetizer for VP9 RTP payload format (draft v2) --- libavformat/Makefile | 1 + libavformat/rtpenc.c | 14 +++++++++++++ libavformat/rtpenc.h | 1 + libavformat/rtpenc_vp9.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ libavformat/sdp.c | 4 ++++ libavformat/version.h | 4 ++-- 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 libavformat/rtpenc_vp9.c (limited to 'libavformat') diff --git a/libavformat/Makefile b/libavformat/Makefile index 6684ead4be..481f3b183e 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 f477650a87..db1ec81219 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 dc30a6da48..70f18edeea 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 0000000000..172ab21f1e --- /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 + * + * 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 8279d595c4..ea369e9226 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", diff --git a/libavformat/version.h b/libavformat/version.h index 5679cce3de..30fe43b6d5 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,8 +32,8 @@ // When bumping major check Ticket5467, 5421, 5451(compatibility with Chromium) for regressing // Also please add any ticket numbers that you belive might regress here #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 37 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 38 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- cgit v1.2.3