diff mbox series

[FFmpeg-devel] dnn: add NV12 pixel format support

Message ID 20201218080829.11997-1-ting.fu@intel.com
State Accepted
Commit 5dbabb020ed842889590045156c2b996f7aff4bd
Headers show
Series [FFmpeg-devel] dnn: add NV12 pixel format support | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate warning Make fate failed

Commit Message

Fu, Ting Dec. 18, 2020, 8:08 a.m. UTC
Signed-off-by: Ting Fu <ting.fu@intel.com>
---
 libavfilter/dnn/dnn_io_proc.c   |  2 ++
 libavfilter/vf_dnn_processing.c | 30 +++++++++++++++++++++---------
 2 files changed, 23 insertions(+), 9 deletions(-)

Comments

Guo, Yejun Dec. 22, 2020, 2:53 a.m. UTC | #1
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Ting Fu
> Sent: 2020年12月18日 16:08
> To: ffmpeg-devel@ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH] dnn: add NV12 pixel format support
> 
> Signed-off-by: Ting Fu <ting.fu@intel.com>
> ---
>  libavfilter/dnn/dnn_io_proc.c   |  2 ++
>  libavfilter/vf_dnn_processing.c | 30 +++++++++++++++++++++---------
>  2 files changed, 23 insertions(+), 9 deletions(-)
> 
> diff --git a/libavfilter/dnn/dnn_io_proc.c b/libavfilter/dnn/dnn_io_proc.c index
> c9b49be3bd..2744cb6502 100644
> --- a/libavfilter/dnn/dnn_io_proc.c
> +++ b/libavfilter/dnn/dnn_io_proc.c
> @@ -64,6 +64,7 @@ DNNReturnType proc_from_dnn_to_frame(AVFrame
> *frame, DNNData *output, void *log_
>      case AV_PIX_FMT_YUV410P:
>      case AV_PIX_FMT_YUV411P:
>      case AV_PIX_FMT_GRAY8:
> +    case AV_PIX_FMT_NV12:
>          sws_ctx = sws_getContext(frame->width,
>                                   frame->height,
>                                   AV_PIX_FMT_GRAYF32, @@ -135,6
> +136,7 @@ DNNReturnType proc_from_frame_to_dnn(AVFrame *frame,
> DNNData *input, void *log_c
>      case AV_PIX_FMT_YUV410P:
>      case AV_PIX_FMT_YUV411P:
>      case AV_PIX_FMT_GRAY8:
> +    case AV_PIX_FMT_NV12:
>          sws_ctx = sws_getContext(frame->width,
>                                   frame->height,
>                                   AV_PIX_FMT_GRAY8, diff --git
> a/libavfilter/vf_dnn_processing.c b/libavfilter/vf_dnn_processing.c index
> 334243bd2b..76fd2e88db 100644
> --- a/libavfilter/vf_dnn_processing.c
> +++ b/libavfilter/vf_dnn_processing.c
> @@ -113,6 +113,7 @@ static int query_formats(AVFilterContext *context)
>          AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAYF32,
>          AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
>          AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P,
> AV_PIX_FMT_YUV411P,
> +        AV_PIX_FMT_NV12,
>          AV_PIX_FMT_NONE
>      };
>      AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); @@ -161,6
> +162,7 @@ static int check_modelinput_inlink(const DNNData *model_input,
> const AVFilterLin
>      case AV_PIX_FMT_YUV444P:
>      case AV_PIX_FMT_YUV410P:
>      case AV_PIX_FMT_YUV411P:
> +    case AV_PIX_FMT_NV12:
>          if (model_input->channels != 1) {
>              LOG_FORMAT_CHANNEL_MISMATCH();
>              return AVERROR(EIO);
> @@ -212,15 +214,22 @@ static int prepare_uv_scale(AVFilterLink *outlink)
> 
>      if (isPlanarYUV(fmt)) {
>          if (inlink->w != outlink->w || inlink->h != outlink->h) {
> -            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
> -            int sws_src_h = AV_CEIL_RSHIFT(inlink->h,
> desc->log2_chroma_h);
> -            int sws_src_w = AV_CEIL_RSHIFT(inlink->w,
> desc->log2_chroma_w);
> -            int sws_dst_h = AV_CEIL_RSHIFT(outlink->h,
> desc->log2_chroma_h);
> -            int sws_dst_w = AV_CEIL_RSHIFT(outlink->w,
> desc->log2_chroma_w);
> -            ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h,
> AV_PIX_FMT_GRAY8,
> -                                               sws_dst_w, sws_dst_h,
> AV_PIX_FMT_GRAY8,
> -                                               SWS_BICUBIC, NULL,
> NULL, NULL);
> -            ctx->sws_uv_height = sws_src_h;
> +            if (fmt == AV_PIX_FMT_NV12) {
> +                ctx->sws_uv_scale = sws_getContext(inlink->w >> 1,
> inlink->h >> 1, AV_PIX_FMT_YA8,
> +                                                   outlink->w >> 1,
> outlink->h >> 1, AV_PIX_FMT_YA8,
> +                                                   SWS_BICUBIC,
> NULL, NULL, NULL);
> +                ctx->sws_uv_height = inlink->h >> 1;
> +            } else {
> +                const AVPixFmtDescriptor *desc =
> av_pix_fmt_desc_get(fmt);
> +                int sws_src_h = AV_CEIL_RSHIFT(inlink->h,
> desc->log2_chroma_h);
> +                int sws_src_w = AV_CEIL_RSHIFT(inlink->w,
> desc->log2_chroma_w);
> +                int sws_dst_h = AV_CEIL_RSHIFT(outlink->h,
> desc->log2_chroma_h);
> +                int sws_dst_w = AV_CEIL_RSHIFT(outlink->w,
> desc->log2_chroma_w);
> +                ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h,
> AV_PIX_FMT_GRAY8,
> +                                                   sws_dst_w,
> sws_dst_h, AV_PIX_FMT_GRAY8,
> +                                                   SWS_BICUBIC,
> NULL, NULL, NULL);
> +                ctx->sws_uv_height = sws_src_h;
> +            }
>          }
>      }
> 
> @@ -262,6 +271,9 @@ static int copy_uv_planes(DnnProcessingContext *ctx,
> AVFrame *out, const AVFrame
>                                  in->data[i], in->linesize[i],
>                                  bytewidth, uv_height);
>          }
> +    } else if (in->format == AV_PIX_FMT_NV12) {
> +        sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1),
> in->linesize + 1,
> +                  0, ctx->sws_uv_height, out->data + 1, out->linesize +
> + 1);
>      } else {
>          sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1),
> in->linesize + 1,
>                    0, ctx->sws_uv_height, out->data + 1, out->linesize + 1);
> --
LGTM, will push soon, thanks.
diff mbox series

Patch

diff --git a/libavfilter/dnn/dnn_io_proc.c b/libavfilter/dnn/dnn_io_proc.c
index c9b49be3bd..2744cb6502 100644
--- a/libavfilter/dnn/dnn_io_proc.c
+++ b/libavfilter/dnn/dnn_io_proc.c
@@ -64,6 +64,7 @@  DNNReturnType proc_from_dnn_to_frame(AVFrame *frame, DNNData *output, void *log_
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
     case AV_PIX_FMT_GRAY8:
+    case AV_PIX_FMT_NV12:
         sws_ctx = sws_getContext(frame->width,
                                  frame->height,
                                  AV_PIX_FMT_GRAYF32,
@@ -135,6 +136,7 @@  DNNReturnType proc_from_frame_to_dnn(AVFrame *frame, DNNData *input, void *log_c
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
     case AV_PIX_FMT_GRAY8:
+    case AV_PIX_FMT_NV12:
         sws_ctx = sws_getContext(frame->width,
                                  frame->height,
                                  AV_PIX_FMT_GRAY8,
diff --git a/libavfilter/vf_dnn_processing.c b/libavfilter/vf_dnn_processing.c
index 334243bd2b..76fd2e88db 100644
--- a/libavfilter/vf_dnn_processing.c
+++ b/libavfilter/vf_dnn_processing.c
@@ -113,6 +113,7 @@  static int query_formats(AVFilterContext *context)
         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAYF32,
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P,
         AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_NV12,
         AV_PIX_FMT_NONE
     };
     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
@@ -161,6 +162,7 @@  static int check_modelinput_inlink(const DNNData *model_input, const AVFilterLin
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
+    case AV_PIX_FMT_NV12:
         if (model_input->channels != 1) {
             LOG_FORMAT_CHANNEL_MISMATCH();
             return AVERROR(EIO);
@@ -212,15 +214,22 @@  static int prepare_uv_scale(AVFilterLink *outlink)
 
     if (isPlanarYUV(fmt)) {
         if (inlink->w != outlink->w || inlink->h != outlink->h) {
-            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
-            int sws_src_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
-            int sws_src_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
-            int sws_dst_h = AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h);
-            int sws_dst_w = AV_CEIL_RSHIFT(outlink->w, desc->log2_chroma_w);
-            ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8,
-                                               sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8,
-                                               SWS_BICUBIC, NULL, NULL, NULL);
-            ctx->sws_uv_height = sws_src_h;
+            if (fmt == AV_PIX_FMT_NV12) {
+                ctx->sws_uv_scale = sws_getContext(inlink->w >> 1, inlink->h >> 1, AV_PIX_FMT_YA8,
+                                                   outlink->w >> 1, outlink->h >> 1, AV_PIX_FMT_YA8,
+                                                   SWS_BICUBIC, NULL, NULL, NULL);
+                ctx->sws_uv_height = inlink->h >> 1;
+            } else {
+                const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
+                int sws_src_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
+                int sws_src_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
+                int sws_dst_h = AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h);
+                int sws_dst_w = AV_CEIL_RSHIFT(outlink->w, desc->log2_chroma_w);
+                ctx->sws_uv_scale = sws_getContext(sws_src_w, sws_src_h, AV_PIX_FMT_GRAY8,
+                                                   sws_dst_w, sws_dst_h, AV_PIX_FMT_GRAY8,
+                                                   SWS_BICUBIC, NULL, NULL, NULL);
+                ctx->sws_uv_height = sws_src_h;
+            }
         }
     }
 
@@ -262,6 +271,9 @@  static int copy_uv_planes(DnnProcessingContext *ctx, AVFrame *out, const AVFrame
                                 in->data[i], in->linesize[i],
                                 bytewidth, uv_height);
         }
+    } else if (in->format == AV_PIX_FMT_NV12) {
+        sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1,
+                  0, ctx->sws_uv_height, out->data + 1, out->linesize + 1);
     } else {
         sws_scale(ctx->sws_uv_scale, (const uint8_t **)(in->data + 1), in->linesize + 1,
                   0, ctx->sws_uv_height, out->data + 1, out->linesize + 1);