1From c39ca2bf72f7b83d5810c142beba97abcfbc7147 Mon Sep 17 00:00:00 2001 2From: hassene <hassene.tmar@intel.com> 3Date: Fri, 15 Feb 2019 17:43:54 -0800 4Subject: [PATCH] Add ability for ffmpeg to run svt vp9 5 6Signed-off-by: hassene <hassene.tmar@intel.com> 7Signed-off-by: Jing Sun <jing.a.sun@intel.com> 8Signed-off-by: Austin Hu <austin.hu@intel.com> 9Signed-off-by: Guo Jiansheng <jiansheng.guo@intel.com> 10--- 11 configure | 4 + 12 libavcodec/Makefile | 1 + 13 libavcodec/allcodecs.c | 1 + 14 libavcodec/avcodec.h | 2 + 15 libavcodec/libsvt_vp9.c | 481 ++++++++++++++++++++++++++++++++++++++ 16 libavformat/dashenc.c | 49 +++- 17 libavformat/ivfenc.c | 34 ++- 18 libavformat/matroskaenc.c | 108 ++++++++- 19 libavformat/movenc.c | 42 +++- 20 9 files changed, 712 insertions(+), 10 deletions(-) 21 create mode 100644 libavcodec/libsvt_vp9.c 22 23diff --git a/configure b/configure 24index 34c2adb4a4..ea125e68ae 100755 25--- a/configure 26+++ b/configure 27@@ -278,6 +278,7 @@ External library support: 28 --enable-libvorbis enable Vorbis en/decoding via libvorbis, 29 native implementation exists [no] 30 --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] 31+ --enable-libsvtvp9 enable VP9 encoding via svt [no] 32 --enable-libwavpack enable wavpack encoding via libwavpack [no] 33 --enable-libwebp enable WebP encoding via libwebp [no] 34 --enable-libx264 enable H.264 encoding via x264 [no] 35@@ -1800,6 +1801,7 @@ EXTERNAL_LIBRARY_LIST=" 36 libv4l2 37 libvorbis 38 libvpx 39+ libsvtvp9 40 libwavpack 41 libwebp 42 libxml2 43@@ -3201,6 +3203,7 @@ libvpx_vp8_decoder_deps="libvpx" 44 libvpx_vp8_encoder_deps="libvpx" 45 libvpx_vp9_decoder_deps="libvpx" 46 libvpx_vp9_encoder_deps="libvpx" 47+libsvt_vp9_encoder_deps="libsvtvp9" 48 libwavpack_encoder_deps="libwavpack" 49 libwavpack_encoder_select="audio_frame_queue" 50 libwebp_encoder_deps="libwebp" 51@@ -6299,6 +6302,7 @@ enabled libvpx && { 52 fi 53 } 54 55+enabled libsvtvp9 && require_pkg_config libsvtvp9 SvtVp9Enc EbSvtVp9Enc.h eb_vp9_svt_init_handle 56 enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack 57 enabled libwebp && { 58 enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion 59diff --git a/libavcodec/Makefile b/libavcodec/Makefile 60index 3cd73fbcc6..cc756acfe7 100644 61--- a/libavcodec/Makefile 62+++ b/libavcodec/Makefile 63@@ -1001,6 +1001,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o 64 OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o 65 OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o 66 OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o 67+OBJS-$(CONFIG_LIBSVT_VP9_ENCODER) += libsvt_vp9.o 68 OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o 69 OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o 70 OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o 71diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c 72index d2f9a39ce5..205333db96 100644 73--- a/libavcodec/allcodecs.c 74+++ b/libavcodec/allcodecs.c 75@@ -716,6 +716,7 @@ extern AVCodec ff_libvpx_vp8_encoder; 76 extern AVCodec ff_libvpx_vp8_decoder; 77 extern AVCodec ff_libvpx_vp9_encoder; 78 extern AVCodec ff_libvpx_vp9_decoder; 79+extern AVCodec ff_libsvt_vp9_encoder; 80 extern AVCodec ff_libwavpack_encoder; 81 /* preferred over libwebp */ 82 extern AVCodec ff_libwebp_anim_encoder; 83diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h 84index d234271c5b..0d903571b3 100644 85--- a/libavcodec/avcodec.h 86+++ b/libavcodec/avcodec.h 87@@ -1527,6 +1527,8 @@ typedef struct AVPacket { 88 */ 89 #define AV_PKT_FLAG_DISPOSABLE 0x0010 90 91+#define AV_PKT_FLAG_SVT_VP9_EXT_ON 0x10000 // Indicating SVT VP9 frame header ext on 92+#define AV_PKT_FLAG_SVT_VP9_EXT_OFF 0x20000 // Indicating SVT VP9 frame header ext off 93 94 enum AVSideDataParamChangeFlags { 95 AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001, 96diff --git a/libavcodec/libsvt_vp9.c b/libavcodec/libsvt_vp9.c 97new file mode 100644 98index 0000000000..037467366e 99--- /dev/null 100+++ b/libavcodec/libsvt_vp9.c 101@@ -0,0 +1,481 @@ 102+/* 103+* Scalable Video Technology for VP9 encoder library plugin 104+* 105+* Copyright (c) 2018 Intel Corporation 106+* 107+* This file is part of FFmpeg. 108+* 109+* FFmpeg is free software; you can redistribute it and/or 110+* modify it under the terms of the GNU Lesser General Public 111+* License as published by the Free Software Foundation; either 112+* version 2.1 of the License, or (at your option) any later version. 113+* 114+* FFmpeg is distributed in the hope that it will be useful, 115+* but WITHOUT ANY WARRANTY; without even the implied warranty of 116+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 117+* Lesser General Public License for more details. 118+* 119+* You should have received a copy of the GNU Lesser General Public 120+* License along with this program; if not, write to the Free Software 121+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 122+*/ 123+ 124+#include <stdint.h> 125+#include "EbSvtVp9ErrorCodes.h" 126+#include "EbSvtVp9Enc.h" 127+ 128+#include "libavutil/common.h" 129+#include "libavutil/frame.h" 130+#include "libavutil/opt.h" 131+ 132+#include "internal.h" 133+#include "avcodec.h" 134+ 135+typedef enum eos_status { 136+ EOS_NOT_REACHED = 0, 137+ EOS_REACHED, 138+ EOS_TOTRIGGER 139+}EOS_STATUS; 140+ 141+typedef struct SvtContext { 142+ AVClass *class; 143+ 144+ EbSvtVp9EncConfiguration enc_params; 145+ EbComponentType *svt_handle; 146+ 147+ EbBufferHeaderType *in_buf; 148+ int raw_size; 149+ 150+ AVBufferPool* pool; 151+ 152+ EOS_STATUS eos_flag; 153+ 154+ // User options. 155+ int enc_mode; 156+ int rc_mode; 157+ int tune; 158+ int qp; 159+ 160+ int forced_idr; 161+ 162+ int level; 163+ 164+ int base_layer_switch_mode; 165+} SvtContext; 166+ 167+static int error_mapping(EbErrorType svt_ret) 168+{ 169+ int err; 170+ 171+ switch (svt_ret) { 172+ case EB_ErrorInsufficientResources: 173+ err = AVERROR(ENOMEM); 174+ break; 175+ 176+ case EB_ErrorUndefined: 177+ case EB_ErrorInvalidComponent: 178+ case EB_ErrorBadParameter: 179+ err = AVERROR(EINVAL); 180+ break; 181+ 182+ case EB_ErrorDestroyThreadFailed: 183+ case EB_ErrorSemaphoreUnresponsive: 184+ case EB_ErrorDestroySemaphoreFailed: 185+ case EB_ErrorCreateMutexFailed: 186+ case EB_ErrorMutexUnresponsive: 187+ case EB_ErrorDestroyMutexFailed: 188+ err = AVERROR_EXTERNAL; 189+ break; 190+ 191+ case EB_NoErrorEmptyQueue: 192+ err = AVERROR(EAGAIN); 193+ 194+ case EB_ErrorNone: 195+ err = 0; 196+ break; 197+ 198+ default: 199+ err = AVERROR_UNKNOWN; 200+ } 201+ 202+ return err; 203+} 204+ 205+static void free_buffer(SvtContext *svt_enc) 206+{ 207+ if (svt_enc->in_buf) { 208+ EbSvtEncInput *in_data = (EbSvtEncInput *)svt_enc->in_buf->p_buffer; 209+ av_freep(&in_data); 210+ av_freep(&svt_enc->in_buf); 211+ } 212+ av_buffer_pool_uninit(&svt_enc->pool); 213+} 214+ 215+static int alloc_buffer(EbSvtVp9EncConfiguration *config, SvtContext *svt_enc) 216+{ 217+ const size_t luma_size_8bit = 218+ config->source_width * config->source_height; 219+ const size_t luma_size_10bit = 220+ (config->encoder_bit_depth > 8) ? luma_size_8bit : 0; 221+ 222+ EbSvtEncInput *in_data; 223+ 224+ svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2; 225+ 226+ // allocate buffer for in and out 227+ svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf)); 228+ if (!svt_enc->in_buf) 229+ goto failed; 230+ 231+ 232+ svt_enc->in_buf->p_buffer = (unsigned char *)av_mallocz(sizeof(*in_data)); 233+ if (!svt_enc->in_buf->p_buffer) 234+ goto failed; 235+ 236+ svt_enc->in_buf->size = sizeof(*svt_enc->in_buf); 237+ svt_enc->in_buf->p_app_private = NULL; 238+ 239+ svt_enc->pool = av_buffer_pool_init(svt_enc->raw_size, NULL); 240+ if (!svt_enc->pool) 241+ goto failed; 242+ 243+ return 0; 244+ 245+failed: 246+ free_buffer(svt_enc); 247+ return AVERROR(ENOMEM); 248+} 249+ 250+static int config_enc_params(EbSvtVp9EncConfiguration *param, 251+ AVCodecContext *avctx) 252+{ 253+ SvtContext *svt_enc = avctx->priv_data; 254+ int ret; 255+ int ten_bits = 0; 256+ 257+ param->source_width = avctx->width; 258+ param->source_height = avctx->height; 259+ 260+ if (avctx->pix_fmt == AV_PIX_FMT_YUV420P10LE) { 261+ av_log(avctx, AV_LOG_DEBUG , "Encoder 10 bits depth input\n"); 262+ // Disable Compressed 10-bit format default 263+ ten_bits = 1; 264+ } 265+ 266+ // Update param from options 267+ param->enc_mode = svt_enc->enc_mode; 268+ param->level = svt_enc->level; 269+ param->rate_control_mode = svt_enc->rc_mode; 270+ param->tune = svt_enc->tune; 271+ param->base_layer_switch_mode = svt_enc->base_layer_switch_mode; 272+ param->qp = svt_enc->qp; 273+ 274+ param->target_bit_rate = avctx->bit_rate; 275+ if (avctx->gop_size > 0) 276+ param->intra_period = avctx->gop_size - 1; 277+ 278+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { 279+ param->frame_rate_numerator = avctx->framerate.num; 280+ param->frame_rate_denominator = avctx->framerate.den * avctx->ticks_per_frame; 281+ } else { 282+ param->frame_rate_numerator = avctx->time_base.den; 283+ param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame; 284+ } 285+ 286+ if (param->rate_control_mode) { 287+ param->max_qp_allowed = avctx->qmax; 288+ param->min_qp_allowed = avctx->qmin; 289+ } 290+ 291+ if (ten_bits) { 292+ param->encoder_bit_depth = 10; 293+ } 294+ 295+ ret = alloc_buffer(param, svt_enc); 296+ 297+ return ret; 298+} 299+ 300+static void read_in_data(EbSvtVp9EncConfiguration *config, 301+ const AVFrame *frame, 302+ EbBufferHeaderType *headerPtr) 303+{ 304+ uint8_t is16bit = config->encoder_bit_depth > 8; 305+ uint64_t luma_size = 306+ (uint64_t)config->source_width * config->source_height<< is16bit; 307+ EbSvtEncInput *in_data = (EbSvtEncInput *)headerPtr->p_buffer; 308+ 309+ // support yuv420p and yuv420p010 310+ in_data->luma = frame->data[0]; 311+ in_data->cb = frame->data[1]; 312+ in_data->cr = frame->data[2]; 313+ 314+ // stride info 315+ in_data->y_stride = frame->linesize[0] >> is16bit; 316+ in_data->cb_stride = frame->linesize[1] >> is16bit; 317+ in_data->cr_stride = frame->linesize[2] >> is16bit; 318+ 319+ headerPtr->n_filled_len += luma_size * 3/2u; 320+} 321+ 322+static av_cold int eb_enc_init(AVCodecContext *avctx) 323+{ 324+ SvtContext *svt_enc = avctx->priv_data; 325+ EbErrorType svt_ret; 326+ 327+ svt_enc->eos_flag = EOS_NOT_REACHED; 328+ 329+ svt_ret = eb_vp9_svt_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params); 330+ if (svt_ret != EB_ErrorNone) { 331+ av_log(avctx, AV_LOG_ERROR, "Error init encoder handle\n"); 332+ goto failed; 333+ } 334+ 335+ svt_ret = config_enc_params(&svt_enc->enc_params, avctx); 336+ if (svt_ret != EB_ErrorNone) { 337+ av_log(avctx, AV_LOG_ERROR, "Error configure encoder parameters\n"); 338+ goto failed_init_handle; 339+ } 340+ 341+ svt_ret = eb_vp9_svt_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params); 342+ if (svt_ret != EB_ErrorNone) { 343+ av_log(avctx, AV_LOG_ERROR, "Error setting encoder parameters\n"); 344+ goto failed_init_handle; 345+ } 346+ 347+ svt_ret = eb_vp9_init_encoder(svt_enc->svt_handle); 348+ if (svt_ret != EB_ErrorNone) { 349+ av_log(avctx, AV_LOG_ERROR, "Error init encoder\n"); 350+ goto failed_init_handle; 351+ } 352+ 353+ // if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { 354+ // EbBufferHeaderType* headerPtr; 355+ // headerPtr->size = sizeof(headerPtr); 356+ // headerPtr->n_filled_len = 0; /* in/out */ 357+ // headerPtr->p_buffer = av_malloc(10 * 1024 * 1024); 358+ // headerPtr->n_alloc_len = (10 * 1024 * 1024); 359+ // 360+ // if (!headerPtr->p_buffer) { 361+ // av_log(avctx, AV_LOG_ERROR, 362+ // "Cannot allocate buffer size %d.\n", headerPtr->n_alloc_len); 363+ // svt_ret = EB_ErrorInsufficientResources; 364+ // goto failed_init_enc; 365+ // } 366+ // 367+ // svt_ret = eb_svt_enc_stream_header(svt_enc->svt_handle, &headerPtr); 368+ // if (svt_ret != EB_ErrorNone) { 369+ // av_log(avctx, AV_LOG_ERROR, "Error when build stream header.\n"); 370+ // av_freep(&headerPtr->p_buffer); 371+ // goto failed_init_enc; 372+ // } 373+ // 374+ // avctx->extradata_size = headerPtr->n_filled_len; 375+ // avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 376+ // if (!avctx->extradata) { 377+ // av_log(avctx, AV_LOG_ERROR, 378+ // "Cannot allocate VP9 header of size %d.\n", avctx->extradata_size); 379+ // av_freep(&headerPtr->p_buffer); 380+ // svt_ret = EB_ErrorInsufficientResources; 381+ // goto failed_init_enc; 382+ // } 383+ // memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size); 384+ // 385+ // av_freep(&headerPtr->p_buffer); 386+ // } 387+ return 0; 388+ 389+//failed_init_enc: 390+// eb_deinit_encoder(svt_enc->svt_handle); 391+failed_init_handle: 392+ eb_vp9_deinit_handle(svt_enc->svt_handle); 393+failed: 394+ free_buffer(svt_enc); 395+ return error_mapping(svt_ret); 396+} 397+ 398+static int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) 399+{ 400+ SvtContext *svt_enc = avctx->priv_data; 401+ EbBufferHeaderType *headerPtr = svt_enc->in_buf; 402+ 403+ if (!frame) { 404+ EbBufferHeaderType headerPtrLast; 405+ headerPtrLast.n_alloc_len = 0; 406+ headerPtrLast.n_filled_len = 0; 407+ headerPtrLast.n_tick_count = 0; 408+ headerPtrLast.p_app_private = NULL; 409+ headerPtrLast.p_buffer = NULL; 410+ headerPtrLast.flags = EB_BUFFERFLAG_EOS; 411+ 412+ eb_vp9_svt_enc_send_picture(svt_enc->svt_handle, &headerPtrLast); 413+ svt_enc->eos_flag = EOS_REACHED; 414+ av_log(avctx, AV_LOG_DEBUG, "Finish sending frames!!!\n"); 415+ return 0; 416+ } 417+ 418+ read_in_data(&svt_enc->enc_params, frame, headerPtr); 419+ 420+ headerPtr->flags = 0; 421+ headerPtr->p_app_private = NULL; 422+ headerPtr->pts = frame->pts; 423+ switch (frame->pict_type) { 424+ case AV_PICTURE_TYPE_I: 425+ headerPtr->pic_type = svt_enc->forced_idr > 0 ? EB_IDR_PICTURE : EB_I_PICTURE; 426+ break; 427+ case AV_PICTURE_TYPE_P: 428+ headerPtr->pic_type = EB_P_PICTURE; 429+ break; 430+ case AV_PICTURE_TYPE_B: 431+ headerPtr->pic_type = EB_B_PICTURE; 432+ break; 433+ default: 434+ headerPtr->pic_type = EB_INVALID_PICTURE; 435+ break; 436+ } 437+ eb_vp9_svt_enc_send_picture(svt_enc->svt_handle, headerPtr); 438+ 439+ return 0; 440+} 441+ 442+static int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt) 443+{ 444+ SvtContext *svt_enc = avctx->priv_data; 445+ EbBufferHeaderType *headerPtr; 446+ EbErrorType svt_ret; 447+ AVBufferRef *ref; 448+ 449+ if (EOS_TOTRIGGER == svt_enc->eos_flag) { 450+ pkt = NULL; 451+ return AVERROR_EOF; 452+ } 453+ 454+ svt_ret = eb_vp9_svt_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag); 455+ if (svt_ret == EB_NoErrorEmptyQueue) 456+ return AVERROR(EAGAIN); 457+ 458+ ref = av_buffer_pool_get(svt_enc->pool); 459+ if (!ref) { 460+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n"); 461+ eb_vp9_svt_release_out_buffer(&headerPtr); 462+ return AVERROR(ENOMEM); 463+ } 464+ pkt->buf = ref; 465+ pkt->data = ref->data; 466+ 467+ memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len); 468+ pkt->size = headerPtr->n_filled_len; 469+ pkt->pts = headerPtr->pts; 470+ pkt->dts = headerPtr->dts; 471+ if (headerPtr->pic_type == EB_IDR_PICTURE) 472+ pkt->flags |= AV_PKT_FLAG_KEY; 473+ if (headerPtr->pic_type == EB_NON_REF_PICTURE) 474+ pkt->flags |= AV_PKT_FLAG_DISPOSABLE; 475+ 476+ if (headerPtr->flags & EB_BUFFERFLAG_SHOW_EXT) 477+ pkt->flags |= AV_PKT_FLAG_SVT_VP9_EXT_ON; 478+ else 479+ pkt->flags |= AV_PKT_FLAG_SVT_VP9_EXT_OFF; 480+ 481+ if (EB_BUFFERFLAG_EOS & headerPtr->flags) 482+ svt_enc->eos_flag = EOS_TOTRIGGER; 483+ 484+ eb_vp9_svt_release_out_buffer(&headerPtr); 485+ return 0; 486+} 487+ 488+static av_cold int eb_enc_close(AVCodecContext *avctx) 489+{ 490+ SvtContext *svt_enc = avctx->priv_data; 491+ 492+ eb_vp9_deinit_encoder(svt_enc->svt_handle); 493+ eb_vp9_deinit_handle(svt_enc->svt_handle); 494+ 495+ free_buffer(svt_enc); 496+ 497+ return 0; 498+} 499+ 500+#define OFFSET(x) offsetof(SvtContext, x) 501+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 502+static const AVOption options[] = { 503+ { "preset", "Encoding preset [1, 1]", 504+ OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = 9 }, 0, 9, VE }, 505+ 506+ { "level", "Set level (level_idc)", OFFSET(level), 507+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xff, VE, "level" }, 508+ 509+#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ 510+ { .i64 = value }, 0, 0, VE, "level" 511+ { LEVEL("1", 10) }, 512+ { LEVEL("2", 20) }, 513+ { LEVEL("2.1", 21) }, 514+ { LEVEL("3", 30) }, 515+ { LEVEL("3.1", 31) }, 516+ { LEVEL("4", 40) }, 517+ { LEVEL("4.1", 41) }, 518+ { LEVEL("5", 50) }, 519+ { LEVEL("5.1", 51) }, 520+ { LEVEL("5.2", 52) }, 521+ { LEVEL("6", 60) }, 522+ { LEVEL("6.1", 61) }, 523+ { LEVEL("6.2", 62) }, 524+#undef LEVEL 525+ 526+ { "tune", "Tune mode", OFFSET(tune), 527+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE , "tune"}, 528+ { "vq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "tune" }, 529+ { "ssim", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "tune" }, 530+ { "vmaf", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "tune" }, 531+ 532+ { "rc", "Bit rate control mode", OFFSET(rc_mode), 533+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE , "rc"}, 534+ { "cqp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "rc" }, 535+ { "vbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "rc" }, 536+ { "cbr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "rc" }, 537+ 538+ { "qp", "QP value for intra frames", OFFSET(qp), 539+ AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 51, VE }, 540+ 541+ { "bl_mode", "Random Access Prediction Structure type setting", OFFSET(base_layer_switch_mode), 542+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, 543+ 544+ { "forced-idr", "If forcing keyframes, force them as IDR frames.", OFFSET(forced_idr), 545+ AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE }, 546+ 547+ {NULL}, 548+}; 549+ 550+static const AVClass class = { 551+ .class_name = "libsvt_vp9", 552+ .item_name = av_default_item_name, 553+ .option = options, 554+ .version = LIBAVUTIL_VERSION_INT, 555+}; 556+ 557+static const AVCodecDefault eb_enc_defaults[] = { 558+ { "b", "7M" }, 559+ { "flags", "-cgop" }, 560+ { "qmin", "10" }, 561+ { "qmax", "48" }, 562+ { NULL }, 563+}; 564+ 565+AVCodec ff_libsvt_vp9_encoder = { 566+ .name = "libsvt_vp9", 567+ .long_name = NULL_IF_CONFIG_SMALL("SVT-VP9(Scalable Video Technology for VP9) encoder"), 568+ .priv_data_size = sizeof(SvtContext), 569+ .type = AVMEDIA_TYPE_VIDEO, 570+ .id = AV_CODEC_ID_VP9, 571+ .init = eb_enc_init, 572+ .send_frame = eb_send_frame, 573+ .receive_packet = eb_receive_packet, 574+ .close = eb_enc_close, 575+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, 576+ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, 577+ AV_PIX_FMT_NONE }, 578+ .priv_class = &class, 579+ .defaults = eb_enc_defaults, 580+ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, 581+ .wrapper_name = "libsvt_vp9", 582+}; 583diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c 584index 24d43c34ea..ba47bd6413 100644 585--- a/libavformat/dashenc.c 586+++ b/libavformat/dashenc.c 587@@ -1823,6 +1823,48 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) 588 return ret; 589 } 590 591+static int dash_write_packet_vp9(AVFormatContext *s, AVPacket *pkt) 592+{ 593+ int ret; 594+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { 595+ uint8_t *saved_data = pkt->data; 596+ int saved_size = pkt->size; 597+ int64_t saved_pts = pkt->pts; 598+ 599+ // Main frame 600+ pkt->data = saved_data; 601+ pkt->size = saved_size - 4; 602+ pkt->pts = saved_pts; 603+ ret = dash_write_packet(s, pkt); 604+ 605+ // Latter 4 one-byte repeated frames 606+ pkt->data = saved_data + saved_size - 4; 607+ pkt->size = 1; 608+ pkt->pts = saved_pts - 2; 609+ ret = dash_write_packet(s, pkt); 610+ 611+ pkt->data = saved_data + saved_size - 3; 612+ pkt->size = 1; 613+ pkt->pts = saved_pts - 1; 614+ ret = dash_write_packet(s, pkt); 615+ 616+ pkt->data = saved_data + saved_size - 2; 617+ pkt->size = 1; 618+ pkt->pts = saved_pts; 619+ ret = dash_write_packet(s, pkt); 620+ 621+ pkt->data = saved_data + saved_size - 1; 622+ pkt->size = 1; 623+ pkt->pts = saved_pts + 1; 624+ ret = dash_write_packet(s, pkt); 625+ } 626+ else{ 627+ ret = dash_write_packet(s, pkt); 628+ } 629+ 630+ return ret; 631+} 632+ 633 static int dash_write_trailer(AVFormatContext *s) 634 { 635 DASHContext *c = s->priv_data; 636@@ -1870,6 +1912,11 @@ static int dash_check_bitstream(struct AVFormatContext *s, const AVPacket *avpkt 637 DASHContext *c = s->priv_data; 638 OutputStream *os = &c->streams[avpkt->stream_index]; 639 AVFormatContext *oc = os->ctx; 640+ 641+ if ((avpkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 642+ (avpkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 643+ return 0; 644+ 645 if (oc->oformat->check_bitstream) { 646 int ret; 647 AVPacket pkt = *avpkt; 648@@ -1942,7 +1989,7 @@ AVOutputFormat ff_dash_muxer = { 649 .flags = AVFMT_GLOBALHEADER | AVFMT_NOFILE | AVFMT_TS_NEGATIVE, 650 .init = dash_init, 651 .write_header = dash_write_header, 652- .write_packet = dash_write_packet, 653+ .write_packet = dash_write_packet_vp9, 654 .write_trailer = dash_write_trailer, 655 .deinit = dash_free, 656 .check_bitstream = dash_check_bitstream, 657diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c 658index adf72117e9..05f08131a6 100644 659--- a/libavformat/ivfenc.c 660+++ b/libavformat/ivfenc.c 661@@ -63,9 +63,33 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) 662 AVIOContext *pb = s->pb; 663 IVFEncContext *ctx = s->priv_data; 664 665- avio_wl32(pb, pkt->size); 666- avio_wl64(pb, pkt->pts); 667- avio_write(pb, pkt->data, pkt->size); 668+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { 669+ avio_wl32(pb, pkt->size - 4); 670+ avio_wl64(pb, pkt->pts); 671+ avio_write(pb, pkt->data, pkt->size - 4); 672+ 673+ avio_wl32(pb, 1); 674+ avio_wl64(pb, pkt->pts - 2); 675+ avio_write(pb, pkt->data + pkt->size - 4, 1); 676+ 677+ avio_wl32(pb, 1); 678+ avio_wl64(pb, pkt->pts - 1); 679+ avio_write(pb, pkt->data + pkt->size - 3, 1); 680+ 681+ avio_wl32(pb, 1); 682+ avio_wl64(pb, pkt->pts); 683+ avio_write(pb, pkt->data + pkt->size - 2, 1); 684+ 685+ avio_wl32(pb, 1); 686+ avio_wl64(pb, pkt->pts + 1); 687+ avio_write(pb, pkt->data + pkt->size - 1, 1); 688+ } 689+ else { 690+ avio_wl32(pb, pkt->size); 691+ avio_wl64(pb, pkt->pts); 692+ avio_write(pb, pkt->data, pkt->size); 693+ } 694+ 695 if (ctx->frame_cnt) 696 ctx->sum_delta_pts += pkt->pts - ctx->last_pts; 697 ctx->frame_cnt++; 698@@ -95,6 +119,10 @@ static int ivf_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) 699 int ret = 1; 700 AVStream *st = s->streams[pkt->stream_index]; 701 702+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 703+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 704+ return 0; 705+ 706 if (st->codecpar->codec_id == AV_CODEC_ID_VP9) 707 ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL); 708 else if (st->codecpar->codec_id == AV_CODEC_ID_AV1) 709diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c 710index cef504fa05..de8e3872c1 100644 711--- a/libavformat/matroskaenc.c 712+++ b/libavformat/matroskaenc.c 713@@ -161,6 +161,9 @@ typedef struct MatroskaMuxContext { 714 int64_t *stream_duration_offsets; 715 716 int allow_raw_vfw; 717+ 718+ int simple_block_timecode; 719+ int accumulated_cluster_timecode; 720 } MatroskaMuxContext; 721 722 /** 2 bytes * 7 for EBML IDs, 7 1-byte EBML lengths, 6 1-byte uint, 723@@ -2180,7 +2183,13 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, 724 put_ebml_num(pb, size + 4, 0); 725 // this assumes stream_index is less than 126 726 avio_w8(pb, 0x80 | track_number); 727- avio_wb16(pb, ts - mkv->cluster_pts); 728+ 729+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 730+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 731+ avio_wb16(pb, mkv->simple_block_timecode); 732+ else 733+ avio_wb16(pb, ts - mkv->cluster_pts); 734+ 735 avio_w8(pb, (blockid == MATROSKA_ID_SIMPLEBLOCK && keyframe) ? (1 << 7) : 0); 736 avio_write(pb, data + offset, size); 737 if (data != pkt->data) 738@@ -2386,6 +2395,8 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ 739 int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; 740 int64_t relative_packet_pos; 741 int dash_tracknum = mkv->is_dash ? mkv->dash_track_number : pkt->stream_index + 1; 742+ double fps = 0; 743+ int pts_interval = 0; 744 745 if (ts == AV_NOPTS_VALUE) { 746 av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); 747@@ -2401,12 +2412,23 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ 748 } 749 } 750 751+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) { 752+ fps = av_q2d(s->streams[pkt->stream_index]->avg_frame_rate); 753+ pts_interval = 1000 / fps; 754+ } 755+ 756 if (mkv->cluster_pos == -1) { 757 mkv->cluster_pos = avio_tell(s->pb); 758 ret = start_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER); 759 if (ret < 0) 760 return ret; 761- put_ebml_uint(mkv->cluster_bc, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); 762+ 763+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 764+ put_ebml_uint(mkv->cluster_bc, MATROSKA_ID_CLUSTERTIMECODE, 765+ mkv->accumulated_cluster_timecode + pts_interval); 766+ else 767+ put_ebml_uint(mkv->cluster_bc, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); 768+ 769 mkv->cluster_pts = FFMAX(0, ts); 770 } 771 pb = mkv->cluster_bc; 772@@ -2414,7 +2436,67 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ 773 relative_packet_pos = avio_tell(pb); 774 775 if (par->codec_type != AVMEDIA_TYPE_SUBTITLE) { 776- mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 777+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { 778+ uint8_t *saved_data = pkt->data; 779+ int saved_size = pkt->size; 780+ int64_t saved_pts = pkt->pts; 781+ // Main frame 782+ pkt->data = saved_data; 783+ pkt->size = saved_size - 4; 784+ pkt->pts = saved_pts; 785+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 786+ 787+ // Latter 4 one-byte repeated frames 788+ pkt->data = saved_data + saved_size - 4; 789+ pkt->size = 1; 790+ pkt->pts = saved_pts - 2; 791+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 792+ mkv->simple_block_timecode += pts_interval; 793+ 794+ pkt->data = saved_data + saved_size - 3; 795+ pkt->size = 1; 796+ pkt->pts = saved_pts - 1; 797+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 798+ mkv->simple_block_timecode += pts_interval; 799+ 800+ pkt->data = saved_data + saved_size - 2; 801+ pkt->size = 1; 802+ pkt->pts = saved_pts; 803+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 804+ mkv->simple_block_timecode += pts_interval; 805+ 806+ pkt->data = saved_data + saved_size - 1; 807+ pkt->size = 1; 808+ pkt->pts = saved_pts + 1; 809+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 810+ mkv->simple_block_timecode += pts_interval; 811+ } else { 812+ mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe); 813+ 814+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF) { 815+ GetBitContext gb; 816+ int invisible, profile; 817+ 818+ if ((ret = init_get_bits8(&gb, pkt->data, pkt->size)) < 0) 819+ return ret; 820+ 821+ get_bits(&gb, 2); // frame marker 822+ profile = get_bits1(&gb); 823+ profile |= get_bits1(&gb) << 1; 824+ if (profile == 3) profile += get_bits1(&gb); 825+ 826+ if (get_bits1(&gb)) { 827+ invisible = 0; 828+ } else { 829+ get_bits1(&gb); // keyframe 830+ invisible = !get_bits1(&gb); 831+ } 832+ 833+ if (!invisible) 834+ mkv->simple_block_timecode += pts_interval; 835+ } 836+ } 837+ 838 if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && (par->codec_type == AVMEDIA_TYPE_VIDEO && keyframe || add_cue)) { 839 ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, dash_tracknum, ts, mkv->cluster_pos, relative_packet_pos, -1); 840 if (ret < 0) return ret; 841@@ -2473,8 +2555,13 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) 842 843 if (mkv->tracks[pkt->stream_index].write_dts) 844 cluster_time = pkt->dts - mkv->cluster_pts; 845- else 846- cluster_time = pkt->pts - mkv->cluster_pts; 847+ else { 848+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 849+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 850+ cluster_time = mkv->accumulated_cluster_timecode - mkv->cluster_pts; 851+ else 852+ cluster_time = pkt->pts - mkv->cluster_pts; 853+ } 854 cluster_time += mkv->tracks[pkt->stream_index].ts_offset; 855 856 // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or 857@@ -2502,6 +2589,13 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) 858 } 859 860 if (mkv->cluster_pos != -1 && start_new_cluster) { 861+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 862+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) { 863+ // Reset Timecode for new cluster. 864+ mkv->accumulated_cluster_timecode += mkv->simple_block_timecode; 865+ mkv->simple_block_timecode = 0; 866+ } 867+ 868 mkv_start_new_cluster(s, pkt); 869 } 870 871@@ -2736,6 +2830,10 @@ static int mkv_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) 872 int ret = 1; 873 AVStream *st = s->streams[pkt->stream_index]; 874 875+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 876+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 877+ return 0; 878+ 879 if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { 880 if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) 881 ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL); 882diff --git a/libavformat/movenc.c b/libavformat/movenc.c 883index 4d4d0cd024..eeebf10147 100644 884--- a/libavformat/movenc.c 885+++ b/libavformat/movenc.c 886@@ -5624,7 +5624,43 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) 887 } 888 } 889 890- return ff_mov_write_packet(s, pkt); 891+ if (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) { 892+ uint8_t *saved_data = pkt->data; 893+ int saved_size = pkt->size; 894+ int64_t saved_pts = pkt->pts; 895+ 896+ // Main frame 897+ pkt->data = saved_data; 898+ pkt->size = saved_size - 4; 899+ pkt->pts = saved_pts; 900+ ret = ff_mov_write_packet(s, pkt); 901+ 902+ // Latter 4 one-byte repeated frames 903+ pkt->data = saved_data + saved_size - 4; 904+ pkt->size = 1; 905+ pkt->pts = saved_pts - 2; 906+ ret = ff_mov_write_packet(s, pkt); 907+ 908+ pkt->data = saved_data + saved_size - 3; 909+ pkt->size = 1; 910+ pkt->pts = saved_pts - 1; 911+ ret = ff_mov_write_packet(s, pkt); 912+ 913+ pkt->data = saved_data + saved_size - 2; 914+ pkt->size = 1; 915+ pkt->pts = saved_pts; 916+ ret = ff_mov_write_packet(s, pkt); 917+ 918+ pkt->data = saved_data + saved_size - 1; 919+ pkt->size = 1; 920+ pkt->pts = saved_pts + 1; 921+ ret = ff_mov_write_packet(s, pkt); 922+ } 923+ else{ 924+ ret = ff_mov_write_packet(s, pkt); 925+ } 926+ 927+ return ret; 928 } 929 930 static int mov_write_subtitle_end_packet(AVFormatContext *s, 931@@ -6763,6 +6799,10 @@ static int mov_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) 932 int ret = 1; 933 AVStream *st = s->streams[pkt->stream_index]; 934 935+ if ((pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_ON) || 936+ (pkt->flags & AV_PKT_FLAG_SVT_VP9_EXT_OFF)) 937+ return 0; 938+ 939 if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { 940 if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) 941 ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL); 942-- 9432.25.1 944