[FFmpeg-devel] lavu/hwcontext_vaapi: cope with race map for YUV420P

Submitted by Linjie Fu on Aug. 1, 2019, 4:45 a.m.

Details

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

Commit Message

Linjie Fu Aug. 1, 2019, 4:45 a.m.
There is a race condition for AV_PIX_FMT_YUV420P when mapping from pix_fmt
to fourcc, both VA_FOURCC_I420 and VA_FOURCC_YV12 could be find by pix_fmt.

Currently, vaapi_get_image_format will go through the query results of
pix_fmt and returned the first matched result according to the declared
order in driver.This may leads to a wrong image_format.

Modify to find image_format via fourcc.

Fix vaapi CSC to I420:
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo
-pix_fmt nv12 -s:v 1280x720 -i NV12.yuv -vf
'format=nv12,hwupload,scale_vaapi=format=yuv420p,hwdownload,format=yuv420p'
-f rawvideo -vsync passthrough -vframes 10 -y aa.yuv

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
 libavutil/hwcontext_vaapi.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

Comments

Linjie Fu Aug. 14, 2019, 1:59 a.m.
> -----Original Message-----
> From: Fu, Linjie
> Sent: Thursday, August 1, 2019 12:45
> To: ffmpeg-devel@ffmpeg.org
> Cc: Fu, Linjie <linjie.fu@intel.com>
> Subject: [PATCH] lavu/hwcontext_vaapi: cope with race map for YUV420P
> 
> There is a race condition for AV_PIX_FMT_YUV420P when mapping from
> pix_fmt
> to fourcc, both VA_FOURCC_I420 and VA_FOURCC_YV12 could be find by
> pix_fmt.
> 
> Currently, vaapi_get_image_format will go through the query results of
> pix_fmt and returned the first matched result according to the declared
> order in driver.This may leads to a wrong image_format.
> 
> Modify to find image_format via fourcc.
> 
> Fix vaapi CSC to I420:
> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo
> -pix_fmt nv12 -s:v 1280x720 -i NV12.yuv -vf
> 'format=nv12,hwupload,scale_vaapi=format=yuv420p,hwdownload,format=
> yuv420p'
> -f rawvideo -vsync passthrough -vframes 10 -y aa.yuv
> 
> Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> ---
>  libavutil/hwcontext_vaapi.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
> index cf11764..64f14de 100644
> --- a/libavutil/hwcontext_vaapi.c
> +++ b/libavutil/hwcontext_vaapi.c
> @@ -63,6 +63,7 @@ typedef struct VAAPIDevicePriv {
>  typedef struct VAAPISurfaceFormat {
>      enum AVPixelFormat pix_fmt;
>      VAImageFormat image_format;
> +    unsigned int fourcc;
>  } VAAPISurfaceFormat;
> 
>  typedef struct VAAPIDeviceContext {
> @@ -171,15 +172,21 @@ static int
> vaapi_get_image_format(AVHWDeviceContext *hwdev,
>                                    VAImageFormat **image_format)
>  {
>      VAAPIDeviceContext *ctx = hwdev->internal->priv;
> +    VAAPIFormatDescriptor *desc;
>      int i;
> 
> +    desc = vaapi_format_from_pix_fmt(pix_fmt);
> +    if (!desc || !image_format)
> +        goto fail;
> +
>      for (i = 0; i < ctx->nb_formats; i++) {
> -        if (ctx->formats[i].pix_fmt == pix_fmt) {
> -            if (image_format)
> -                *image_format = &ctx->formats[i].image_format;
> +        if (ctx->formats[i].fourcc == desc->fourcc) {
> +            *image_format = &ctx->formats[i].image_format;
>              return 0;
>          }
>      }
> +
> +fail:
>      return AVERROR(EINVAL);
>  }
> 
> @@ -368,6 +375,7 @@ static int vaapi_device_init(AVHWDeviceContext
> *hwdev)
>              av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
>                     fourcc, av_get_pix_fmt_name(pix_fmt));
>              ctx->formats[ctx->nb_formats].pix_fmt      = pix_fmt;
> +            ctx->formats[ctx->nb_formats].fourcc       = fourcc;
>              ctx->formats[ctx->nb_formats].image_format = image_list[i];
>              ++ctx->nb_formats;
>          }
> --
> 2.7.4
A gentle ping.
Zhong Li Aug. 14, 2019, 7:10 a.m.
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Fu, Linjie

> Sent: Wednesday, August 14, 2019 9:59 AM

> To: ffmpeg-devel@ffmpeg.org

> Subject: Re: [FFmpeg-devel] [PATCH] lavu/hwcontext_vaapi: cope with race

> map for YUV420P

> 

> > -----Original Message-----

> > From: Fu, Linjie

> > Sent: Thursday, August 1, 2019 12:45

> > To: ffmpeg-devel@ffmpeg.org

> > Cc: Fu, Linjie <linjie.fu@intel.com>

> > Subject: [PATCH] lavu/hwcontext_vaapi: cope with race map for YUV420P

> >

> > There is a race condition for AV_PIX_FMT_YUV420P when mapping from

> > pix_fmt to fourcc, both VA_FOURCC_I420 and VA_FOURCC_YV12 could be

> > find by pix_fmt.


find -> found

> > Currently, vaapi_get_image_format will go through the query results of

> > pix_fmt and returned the first matched result according to the

> > declared order in driver.This may leads to a wrong image_format.

> >

> > Modify to find image_format via fourcc.

> >

> > Fix vaapi CSC to I420:

> > ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo

> > -pix_fmt nv12 -s:v 1280x720 -i NV12.yuv -vf

> >

> 'format=nv12,hwupload,scale_vaapi=format=yuv420p,hwdownload,format=

> > yuv420p'

> > -f rawvideo -vsync passthrough -vframes 10 -y aa.yuv

> >

> > Signed-off-by: Linjie Fu <linjie.fu@intel.com>

> > ---

> >  libavutil/hwcontext_vaapi.c | 14 +++++++++++---

> >  1 file changed, 11 insertions(+), 3 deletions(-)

> >

> > diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c

> > index cf11764..64f14de 100644

> > --- a/libavutil/hwcontext_vaapi.c

> > +++ b/libavutil/hwcontext_vaapi.c

> > @@ -63,6 +63,7 @@ typedef struct VAAPIDevicePriv {  typedef struct

> > VAAPISurfaceFormat {

> >      enum AVPixelFormat pix_fmt;

> >      VAImageFormat image_format;

> > +    unsigned int fourcc;

> >  } VAAPISurfaceFormat;

> >

> >  typedef struct VAAPIDeviceContext {

> > @@ -171,15 +172,21 @@ static int

> > vaapi_get_image_format(AVHWDeviceContext *hwdev,

> >                                    VAImageFormat

> **image_format)  {

> >      VAAPIDeviceContext *ctx = hwdev->internal->priv;

> > +    VAAPIFormatDescriptor *desc;

> >      int i;

> >

> > +    desc = vaapi_format_from_pix_fmt(pix_fmt);

> > +    if (!desc || !image_format)

> > +        goto fail;

> > +

> >      for (i = 0; i < ctx->nb_formats; i++) {

> > -        if (ctx->formats[i].pix_fmt == pix_fmt) {

> > -            if (image_format)

> > -                *image_format = &ctx->formats[i].image_format;

> > +        if (ctx->formats[i].fourcc == desc->fourcc) {

> > +            *image_format = &ctx->formats[i].image_format;

> >              return 0;

> >          }

> >      }

> > +

> > +fail:

> >      return AVERROR(EINVAL);

> >  }

> >

> > @@ -368,6 +375,7 @@ static int vaapi_device_init(AVHWDeviceContext

> > *hwdev)

> >              av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",

> >                     fourcc, av_get_pix_fmt_name(pix_fmt));

> >              ctx->formats[ctx->nb_formats].pix_fmt      = pix_fmt;

> > +            ctx->formats[ctx->nb_formats].fourcc       = fourcc;

> >              ctx->formats[ctx->nb_formats].image_format =

> image_list[i];

> >              ++ctx->nb_formats;

> >          }

> > --

> > 2.7.4

> A gentle ping.


Patch LGTM

Patch hide | download patch | download mbox

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index cf11764..64f14de 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -63,6 +63,7 @@  typedef struct VAAPIDevicePriv {
 typedef struct VAAPISurfaceFormat {
     enum AVPixelFormat pix_fmt;
     VAImageFormat image_format;
+    unsigned int fourcc;
 } VAAPISurfaceFormat;
 
 typedef struct VAAPIDeviceContext {
@@ -171,15 +172,21 @@  static int vaapi_get_image_format(AVHWDeviceContext *hwdev,
                                   VAImageFormat **image_format)
 {
     VAAPIDeviceContext *ctx = hwdev->internal->priv;
+    VAAPIFormatDescriptor *desc;
     int i;
 
+    desc = vaapi_format_from_pix_fmt(pix_fmt);
+    if (!desc || !image_format)
+        goto fail;
+
     for (i = 0; i < ctx->nb_formats; i++) {
-        if (ctx->formats[i].pix_fmt == pix_fmt) {
-            if (image_format)
-                *image_format = &ctx->formats[i].image_format;
+        if (ctx->formats[i].fourcc == desc->fourcc) {
+            *image_format = &ctx->formats[i].image_format;
             return 0;
         }
     }
+
+fail:
     return AVERROR(EINVAL);
 }
 
@@ -368,6 +375,7 @@  static int vaapi_device_init(AVHWDeviceContext *hwdev)
             av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
                    fourcc, av_get_pix_fmt_name(pix_fmt));
             ctx->formats[ctx->nb_formats].pix_fmt      = pix_fmt;
+            ctx->formats[ctx->nb_formats].fourcc       = fourcc;
             ctx->formats[ctx->nb_formats].image_format = image_list[i];
             ++ctx->nb_formats;
         }