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