After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 797222 - vaapijpegdec: [regression] allocated surfaces have incorrect chroma
vaapijpegdec: [regression] allocated surfaces have incorrect chroma
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer-vaapi
git master
Other Linux
: Normal blocker
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2018-09-28 05:56 UTC by U. Artie Eoff
Modified: 2018-10-10 18:26 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
actual result (49.38 KB, image/jpeg)
2018-09-28 06:17 UTC, U. Artie Eoff
  Details
expected result (56.65 KB, image/jpeg)
2018-09-28 06:18 UTC, U. Artie Eoff
  Details
patch for this issue. (3.76 KB, patch)
2018-09-30 02:02 UTC, Fei
none Details | Review
patch for this issue. (3.76 KB, patch)
2018-10-08 06:27 UTC, Fei
none Details | Review
patch for this issue. (3.85 KB, patch)
2018-10-10 05:51 UTC, Fei
committed Details | Review

Description U. Artie Eoff 2018-09-28 05:56:07 UTC
All JPEG Encode/Decode produces invalid results since:

commit 619abbdeb4c674ded188f7bab3ffa5c682702d12 
Author: Wangfei <fei.w.wang@intel.com>
Date:   Thu Sep 20 09:57:33 2018 +0800

    libs: dec: h265: add 422 chroma format support.
    
    Add main-422-10 profile which support 422 chroma format stream.
    Currently, this feature is only supported by media-driver in Icelake.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=797143
Comment 1 U. Artie Eoff 2018-09-28 06:06:25 UTC
Only decode is broken.
Comment 2 U. Artie Eoff 2018-09-28 06:17:46 UTC
Created attachment 373800 [details]
actual result
Comment 3 U. Artie Eoff 2018-09-28 06:18:25 UTC
Created attachment 373801 [details]
expected result
Comment 4 U. Artie Eoff 2018-09-28 06:19:12 UTC
gst-launch-1.0 -vf videotestsrc num-buffers=1 ! video/x-raw,width=1280,height=720 ! vaapijpegenc ! jpegparse ! filesink location=test1280x720.jpeg

gst-launch-1.0 -vf filesrc location=test1280x720.jpeg ! jpegparse ! vaapijpegdec ! vaapisink
Comment 5 U. Artie Eoff 2018-09-28 06:24:12 UTC
i965 driver
Comment 6 Fei 2018-09-28 07:04:21 UTC
Thanks for reporting. I will take a look at this issue.
Comment 7 Nicolas Dufresne (ndufresne) 2018-09-28 14:25:11 UTC
What I can see from the images is that so we get a 4:2:0 buffer, but we think it's 4:2:2. As a result, luma is fine, because it's the same, but the chroma is off. I assume we allocated to 4:2:2 buffer since we didn't crash on a buffer overrun.
Comment 8 Fei 2018-09-29 05:57:46 UTC
(In reply to Nicolas Dufresne (ndufresne) from comment #7)
> What I can see from the images is that so we get a 4:2:0 buffer, but we
> think it's 4:2:2. As a result, luma is fine, because it's the same, but the
> chroma is off. I assume we allocated to 4:2:2 buffer since we didn't crash
> on a buffer overrun.

Emm, I guess not. If in this case, all decode will have same problem. But now only vaapijpegdec fails but all other decode codecs looks good. This issue only happens on intel-vaapi-driver, but works fine with media-driver.

In our previous solution, when create vasurface with gst_vaapi_surface_new(gst-libs/gst/vaapi/gstvaapisurface.c +333), VASurfaceAttrib will be set as NULL, and now VASurfaceAttrib is filled with VASurfaceAttribPixelFormat of NV12.
With this change, vaapijpegdec fails.
Comment 9 Víctor Manuel Jáquez Leal 2018-09-29 07:44:25 UTC
If I understand correctly, the fix should be in intel-vaapi-driver,rather than workaround it in gstreamer-vaapi.
Comment 10 Fei 2018-09-29 07:57:04 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #9)
> If I understand correctly, the fix should be in intel-vaapi-driver,rather
> than workaround it in gstreamer-vaapi.

Talked with xiang,haihao, HW may not support NV12 surface format. One solution is that we can set surface format as NULL when create vasurface once detect it is jpeg decode. Not sure if this solution make sense. Also, add haihao in CC list.
Comment 11 Fei 2018-09-29 07:58:26 UTC
(In reply to Fei from comment #10)
> (In reply to Víctor Manuel Jáquez Leal from comment #9)
> > If I understand correctly, the fix should be in intel-vaapi-driver,rather
> > than workaround it in gstreamer-vaapi.
> 
> Talked with xiang,haihao, HW may not support NV12 surface format. One
> solution is that we can set surface format as NULL when create vasurface
> once detect it is jpeg decode. Not sure if this solution make sense. Also,
> add haihao in CC list.

TYPO:
> Talked with xiang,haihao, HW may not support NV12 format surface for jpeg decode.
Comment 12 Fei 2018-09-30 02:02:57 UTC
Created attachment 373812 [details] [review]
patch for this issue.
Comment 13 Víctor Manuel Jáquez Leal 2018-10-01 08:55:25 UTC
Review of attachment 373812 [details] [review]:

::: gst-libs/gst/vaapi/gstvaapicontext.c
@@ +134,3 @@
   guint i;
 
+  gst_vaapi_context_get_surface_formats (context);

memleak: this function returns a new reference to context->formats, but you are ignoring it, thus a memory leak is produced.

Please use the internal ensure_formats()

::: gst-libs/gst/vaapi/gstvaapisurface.c
@@ +323,3 @@
+ * @width: the requested surface width
+ * @height: the requested surface height
+ * @formats: the limited format list

add a new line here

@@ +325,3 @@
+ * @formats: the limited format list
+ * Creates a new #GstVaapiSurface with the specified chroma format and
+ * dimensions.

please explain here why this function is different from the rest.

@@ +337,3 @@
+  guint i;
+
+  surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);

this surface is only used in gst_vaapi_surface_create(), if your code-path  enables ensure_format branch, another memory leak is produced.

::: gst-libs/gst/vaapi/gstvaapisurface.h
@@ +174,3 @@
 GstVaapiSurface *
+gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display,
+    GstVaapiChromaType chroma_type, guint width, guint height, GArray * formts);

I'm not very fond to add new internal API. Are we sure that we couldn't add this new behavior within in the functions we already have?
Comment 14 Fei 2018-10-08 06:26:00 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #13)
> Review of attachment 373812 [details] [review] [review]:
> 
> ::: gst-libs/gst/vaapi/gstvaapicontext.c
> @@ +134,3 @@
>    guint i;
>  
> +  gst_vaapi_context_get_surface_formats (context);
> 
> memleak: this function returns a new reference to context->formats, but you
> are ignoring it, thus a memory leak is produced.
> 
> Please use the internal ensure_formats()
will fix this.
> 
> ::: gst-libs/gst/vaapi/gstvaapisurface.c
> @@ +323,3 @@
> + * @width: the requested surface width
> + * @height: the requested surface height
> + * @formats: the limited format list
> 
> add a new line here
will fix this.
> 
> @@ +325,3 @@
> + * @formats: the limited format list
> + * Creates a new #GstVaapiSurface with the specified chroma format and
> + * dimensions.
> 
> please explain here why this function is different from the rest.
will fix this.
> 
> @@ +337,3 @@
> +  guint i;
> +
> +  surface = gst_vaapi_object_new (gst_vaapi_surface_class (), display);
> 
> this surface is only used in gst_vaapi_surface_create(), if your code-path 
> enables ensure_format branch, another memory leak is produced.
will fix this.
> 
> ::: gst-libs/gst/vaapi/gstvaapisurface.h
> @@ +174,3 @@
>  GstVaapiSurface *
> +gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display,
> +    GstVaapiChromaType chroma_type, guint width, guint height, GArray *
> formts);
> 
> I'm not very fond to add new internal API. Are we sure that we couldn't add
> this new behavior within in the functions we already have?
I didn't find any create surface api which can pass through GstVaapiContext or GArray formats which can be used to get appropriate format that will used to create surafce.
Comment 15 Fei 2018-10-08 06:27:05 UTC
Created attachment 373867 [details] [review]
patch for this issue.
Comment 16 Víctor Manuel Jáquez Leal 2018-10-09 10:01:53 UTC
Review of attachment 373867 [details] [review]:

::: gst-libs/gst/vaapi/gstvaapisurface.c
@@ +325,3 @@
+ * @formats: the limited format list
+ *
+ * Creates a new #GstVaapiSurface by using the appropriate format in #formats

If I understand correctly I would rephrase this line as:

"Creates a new #GstVaapiSurface with a @chroma_type valid for any format in @formats; if there aren't any, the returned surface is created forcing the passed @chroma_type."

@@ +340,3 @@
+    GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
+    if (format == gst_vaapi_video_format_from_chroma (chroma_type))
+      ensure_format = TRUE;

I guess you will need a 'break' instruction here to avoid keep evaluating the format list.

Also you can do this

if (format == gst_vaapi_video_format_from_chroma (chroma_type))
  return gst_vaapi_surface_new (display, chroma_type, width, height);
}

/* Fallback: if there's no format valid for the chroma type let's just used the passed chroma */
...
Comment 17 Fei 2018-10-10 05:51:05 UTC
(In reply to Víctor Manuel Jáquez Leal from comment #16)
> Review of attachment 373867 [details] [review] [review]:
> 
> ::: gst-libs/gst/vaapi/gstvaapisurface.c
> @@ +325,3 @@
> + * @formats: the limited format list
> + *
> + * Creates a new #GstVaapiSurface by using the appropriate format in
> #formats
> 
> If I understand correctly I would rephrase this line as:
> 
> "Creates a new #GstVaapiSurface with a @chroma_type valid for any format in
> @formats; if there aren't any, the returned surface is created forcing the
> passed @chroma_type."
> 
> @@ +340,3 @@
> +    GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
> +    if (format == gst_vaapi_video_format_from_chroma (chroma_type))
> +      ensure_format = TRUE;
> 
> I guess you will need a 'break' instruction here to avoid keep evaluating
> the format list.
> 
> Also you can do this
> 
> if (format == gst_vaapi_video_format_from_chroma (chroma_type))
>   return gst_vaapi_surface_new (display, chroma_type, width, height);
> }
> 
> /* Fallback: if there's no format valid for the chroma type let's just used
> the passed chroma */
> ...

Will apply this.Thanks.
Comment 18 Fei 2018-10-10 05:51:33 UTC
Created attachment 373879 [details] [review]
patch for this issue.
Comment 19 Víctor Manuel Jáquez Leal 2018-10-10 18:19:26 UTC
attachment 373879 [details] [review] pushed as commit 82872f42 - libs: context: query surface format before context to create surface.