[FFmpeg-devel,RFC,2/2] fftools/ffmpeg: add dynamic resolution encode support for libvpx-vp9

Submitted by Linjie Fu on July 28, 2019, 9:54 a.m.

Details

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

Commit Message

Linjie Fu July 28, 2019, 9:54 a.m.
According to spec, vp9 should support dynamic resolution changes.

Add dynamic resolution encoding support in libvpx-vp9, and flush
encoders when resolution change happens.

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>
---
 fftools/ffmpeg.c       | 9 +++++++++
 libavcodec/libvpxenc.c | 9 +++++++++
 2 files changed, 18 insertions(+)

Comments

Nicolas George July 28, 2019, 9:57 a.m.
Linjie Fu (12019-07-28):
> +        enc->internal->draining = 0;

"internal" means you should not be doing that.

Regards,
Linjie Fu July 28, 2019, 10:08 a.m.
> -----Original Message-----
> From: Nicolas George [mailto:george@nsup.org]
> Sent: Sunday, July 28, 2019 17:58
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Cc: Fu, Linjie <linjie.fu@intel.com>
> Subject: Re: [FFmpeg-devel] [PATCH, RFC 2/2] fftools/ffmpeg: add dynamic
> resolution encode support for libvpx-vp9
> 
> Linjie Fu (12019-07-28):
> > +        enc->internal->draining = 0;
> 
> "internal" means you should not be doing that.
> 
Sure,  will address this, thanks.
Gyan July 28, 2019, 11:01 a.m.
On 28-07-2019 03:24 PM, Linjie Fu wrote:
> According to spec, vp9 should support dynamic resolution changes.
>
> Add dynamic resolution encoding support in libvpx-vp9, and flush
> encoders when resolution change happens.
>
> 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>
> ---
>   fftools/ffmpeg.c       | 9 +++++++++
>   libavcodec/libvpxenc.c | 9 +++++++++
>   2 files changed, 18 insertions(+)
>
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 5d52430..e091117 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -64,6 +64,7 @@
>   #include "libavutil/thread.h"
>   #include "libavutil/threadmessage.h"
>   #include "libavcodec/mathops.h"
> +#include "libavcodec/internal.h"
>   #include "libavformat/os_support.h"
>   
>   # include "libavfilter/avfilter.h"
> @@ -130,6 +131,7 @@ static void do_video_stats(OutputStream *ost, int frame_size);
>   static BenchmarkTimeStamps get_benchmark_time_stamps(void);
>   static int64_t getmaxrss(void);
>   static int ifilter_has_all_input_formats(FilterGraph *fg);
> +static void flush_encoders(void);
>   
>   static int run_as_daemon  = 0;
>   static int nb_frames_dup = 0;
> @@ -1067,6 +1069,13 @@ static void do_video_out(OutputFile *of,
>       InputStream *ist = NULL;
>       AVFilterContext *filter = ost->filter->filter;
>   
> +    /* flush encoders in dynamic resolution encode */
> +    if (next_picture && (enc->width != next_picture->width ||
> +                         enc->height != next_picture->height)) {
> +        flush_encoders();
> +        enc->internal->draining = 0;
> +    }
> +
>       if (ost->source_index >= 0)
>           ist = input_streams[ost->source_index];
>   
> diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
> index feb52ea..54ac365 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];

The avcodec and fftools changes should be in separate patches.

Gyan

Patch hide | download patch | download mbox

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 5d52430..e091117 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -64,6 +64,7 @@ 
 #include "libavutil/thread.h"
 #include "libavutil/threadmessage.h"
 #include "libavcodec/mathops.h"
+#include "libavcodec/internal.h"
 #include "libavformat/os_support.h"
 
 # include "libavfilter/avfilter.h"
@@ -130,6 +131,7 @@  static void do_video_stats(OutputStream *ost, int frame_size);
 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
 static int64_t getmaxrss(void);
 static int ifilter_has_all_input_formats(FilterGraph *fg);
+static void flush_encoders(void);
 
 static int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -1067,6 +1069,13 @@  static void do_video_out(OutputFile *of,
     InputStream *ist = NULL;
     AVFilterContext *filter = ost->filter->filter;
 
+    /* flush encoders in dynamic resolution encode */
+    if (next_picture && (enc->width != next_picture->width ||
+                         enc->height != next_picture->height)) {
+        flush_encoders();
+        enc->internal->draining = 0;
+    }
+
     if (ost->source_index >= 0)
         ist = input_streams[ost->source_index];
 
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index feb52ea..54ac365 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];