This repository has been archived by the owner on Feb 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path0014-lavc-libvpxenc-add-dynamic-resolution-encode-support.patch
91 lines (83 loc) · 3.89 KB
/
0014-lavc-libvpxenc-add-dynamic-resolution-encode-support.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
From 741cba89953634ca801e8d187186493b495d4f53 Mon Sep 17 00:00:00 2001
From: Linjie Fu <[email protected]>
Date: Wed, 31 Jul 2019 12:18:21 +0800
Subject: [PATCH 14/28] lavc/libvpxenc: add dynamic resolution encode support
for libvpx
According to spec, libvpx should support dynamic resolution changes.
Add dynamic resolution encoding support in libvpx.
Format change should also be supported, but I didn't test it so just
leave it open.
cmdline:
ffmpeg -noautoscale -y -i ./reinit-large_420_8-to-small_420_8.h264
-pix_fmt yuv420p -c:v libvpx-vp9 lena.ivf
Signed-off-by: Linjie Fu <[email protected]>
---
libavcodec/libvpxenc.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 60a8588..fb1b2c8 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1489,6 +1489,34 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt,
vpx_svc_layer_id_t layer_id;
int layer_id_valid = 0;
+ if (frame && (avctx->width != frame->width ||
+ avctx->height != frame->height)) {
+ // set enc_config without reinit
+ struct vpx_codec_enc_cfg new_cfg = { 0 };
+ memcpy(&new_cfg, ctx->encoder.config.enc, sizeof(struct vpx_codec_enc_cfg));
+
+ if (frame->width <= avctx->width &&
+ frame->height <= avctx->height &&
+ !ctx->lag_in_frames && new_cfg.g_pass == VPX_RC_ONE_PASS) {
+
+ new_cfg.g_w = frame->width;
+ new_cfg.g_h = frame->height;
+ avctx->width = frame->width;
+ avctx->height = frame->height;
+ vpx_codec_enc_config_set(&ctx->encoder, &new_cfg);
+ } else {
+ if (new_cfg.g_lag_in_frames > 1 || new_cfg.g_pass != VPX_RC_ONE_PASS)
+ av_log(avctx, AV_LOG_WARNING, "Only single pass mode "
+ "with no look ahead is supported for variable "
+ "resolution encoding without initialization.\n");
+ // since frame enlarge leads to force key frame, reinit directly
+ avctx->width = frame->width;
+ avctx->height = frame->height;
+ avctx->codec->close(avctx);
+ avctx->codec->init(avctx);
+ }
+ }
+
if (frame) {
const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
rawimg = &ctx->rawimg;
@@ -1498,6 +1526,8 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt,
rawimg->stride[VPX_PLANE_Y] = frame->linesize[0];
rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
+ rawimg->d_w = frame->width;
+ rawimg->d_h = frame->height;
if (ctx->is_alpha) {
rawimg_alpha = &ctx->rawimg_alpha;
res = realloc_alpha_uv(avctx, frame->width, frame->height);
@@ -1759,7 +1789,7 @@ AVCodec ff_libvpx_vp8_encoder = {
.init = vp8_init,
.encode2 = vpx_encode,
.close = vpx_free,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_PARAM_CHANGE,
.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },
.priv_class = &class_vp8,
.defaults = defaults,
@@ -1789,7 +1819,7 @@ AVCodec ff_libvpx_vp9_encoder = {
.init = vp9_init,
.encode2 = vpx_encode,
.close = vpx_free,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_PARAM_CHANGE,
.profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles),
.priv_class = &class_vp9,
.defaults = defaults,
--
2.7.4