[FFmpeg-devel,v2,3/3] lavc/libvpxenc: add dynamic resolution encode support for libvpx

Submitted by Linjie Fu on July 31, 2019, 5:05 a.m.

Details

Message ID 1564549558-25773-1-git-send-email-linjie.fu@intel.com
State New
Headers show

Commit Message

Linjie Fu July 31, 2019, 5:05 a.m.
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 <linjie.fu@intel.com>
---
[v2]: use AV_CODEC_CAP_PARAM_CHANGE flag.

 libavcodec/libvpxenc.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Comments

James Zern July 31, 2019, 11:15 p.m.
Hi,

On Tue, Jul 30, 2019 at 10:06 PM Linjie Fu <linjie.fu@intel.com> wrote:
> [...]
> diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
> index feb52ea..800ba18 100644
> --- a/libavcodec/libvpxenc.c
> +++ b/libavcodec/libvpxenc.c
> @@ -1067,6 +1067,15 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt,
>      int res, coded_size;
>      vpx_enc_frame_flags_t flags = 0;
>
> +    if (frame && (avctx->width != frame->width ||
> +                  avctx->height != frame->height)) {
> +        avctx->width  = frame->width;
> +        avctx->height = frame->height;
> +
> +        avctx->codec->close(avctx);

You shouldn't need to destroy the encoder for a resolution change,
unless I'm missing something. Take a look at resize_test.cc [1].

[1] https://chromium.googlesource.com/webm/libvpx/+/refs/heads/master/test/resize_test.cc#305
Linjie Fu Aug. 1, 2019, 2:46 p.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of James Zern

> Sent: Thursday, August 1, 2019 07:15

> To: FFmpeg development discussions and patches <ffmpeg-

> devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH, v2 3/3] lavc/libvpxenc: add dynamic

> resolution encode support for libvpx

> 

> Hi,

> 

> On Tue, Jul 30, 2019 at 10:06 PM Linjie Fu <linjie.fu@intel.com> wrote:

> > [...]

> > diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c

> > index feb52ea..800ba18 100644

> > --- a/libavcodec/libvpxenc.c

> > +++ b/libavcodec/libvpxenc.c

> > @@ -1067,6 +1067,15 @@ static int vpx_encode(AVCodecContext *avctx,

> AVPacket *pkt,

> >      int res, coded_size;

> >      vpx_enc_frame_flags_t flags = 0;

> >

> > +    if (frame && (avctx->width != frame->width ||

> > +                  avctx->height != frame->height)) {

> > +        avctx->width  = frame->width;

> > +        avctx->height = frame->height;

> > +

> > +        avctx->codec->close(avctx);

> 

> You shouldn't need to destroy the encoder for a resolution change,

> unless I'm missing something. Take a look at resize_test.cc [1].

> 

> [1]

> https://chromium.googlesource.com/webm/libvpx/+/refs/heads/master/te

> st/resize_test.cc#305


Yes, IMHO vp8 supports resolution change in key frame, and for vp9,  resolution change
is supported per frame, thus current modification may lead to unnecessary Key frames.

Will find a better solution. Thanks.

- linjie

Patch hide | download patch | download mbox

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index feb52ea..800ba18 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1067,6 +1067,15 @@  static int vpx_encode(AVCodecContext *avctx, AVPacket *pkt,
     int res, coded_size;
     vpx_enc_frame_flags_t flags = 0;
 
+    if (frame && (avctx->width != frame->width ||
+                  avctx->height != frame->height)) {
+        avctx->width  = frame->width;
+        avctx->height = frame->height;
+
+        avctx->codec->close(avctx);
+        avctx->codec->init(avctx);
+    }
+
     if (frame) {
         rawimg                      = &ctx->rawimg;
         rawimg->planes[VPX_PLANE_Y] = frame->data[0];
@@ -1295,7 +1304,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,
@@ -1325,7 +1334,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,