Bug 97086 - [SNB]invalid VASurfaceID when filtering a surface for color space transform
Summary: [SNB]invalid VASurfaceID when filtering a surface for color space transform
Status: NEW
Alias: None
Product: libva
Classification: Unclassified
Component: intel (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: ykzhao
QA Contact: Sean V Kelley
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-07-26 06:36 UTC by xiaoyur347
Modified: 2017-03-06 13:52 UTC (History)
2 users (show)

See Also:
i915 platform:
i915 features:


Attachments

Description xiaoyur347 2016-07-26 06:36:53 UTC
Overview:
Since libva-intel-driver >=1.6.2, the encode fails after we call vaCreateSurfaces() and  do filtering another surface into this surface.

Steps to Reproduce: 
1. render to a vasurface
2. create a surface for encoding
va_status = vaCreateSurfaces(
            va_dpy,
            VA_RT_FORMAT_YUV420, 1280, 720,
            &dst_surface, 1,
            NULL, 0
        );
3. like https://github.com/gbeauchesne/ffvademo/blob/master/src/ffvafilter.c
ffva_filter_process()
use the surface in step 1 to do color transform to the dst_surface.
4. Use the dst_surface to encode.

Actual Results:
For filter:
"
error: vaEndPicture(): invalid VASurfaceID
"
For encode:
"
error: vaEndPicture(): invalid VASurfaceID
ffvaencoder: i965_encoder.c:69: intel_encoder_check_yuv_surface: Assertion `obj_surface && obj_surface->bo' failed.
"
And the application crashed.

Expected Results:
Expect the application works well.

Build Date & Hardware:
Ubuntu 16.04.1 LTS (amd64)
libva 1.7.0 (sudo apt install libva-dev:1.7.0-1)
CPU: i3-2310E / i5-2410m

Additional Builds and Platforms:
(1)works well for Haswell.
Ubuntu 16.04.1 LTS (x86)
libva 1.7.0
CPU: Celeron G1820(Haswell)

Additional Information: 
This bug introduces by 
(1)
https://cgit.freedesktop.org/vaapi/intel-driver/commit/?h=v1.6-branch&id=7deaf55d3f927e32e0b2280601dae106c7b9e3d8
(2)
https://cgit.freedesktop.org/vaapi/intel-driver/commit/?h=v1.6-branch&id=bd018d617158734d8bbeff87873f781d0a1f25e5
If I add the following code to libra-driver 1.6.1, I can also reproduce the bug.
+    if (!dst_obj_surface->bo)
+        return VA_STATUS_ERROR_INVALID_SURFACE;

After I gdb it, I find the following reason.
(1)vaCreateSurfaces() may not initialize surface->bo.
Since i965_surface_native_memory() returns if 
    if (!expected_fourcc) {
        return VA_STATUS_SUCCESS;
    }
(2)If we use this surface(surface->bo = NULL), gen75_proc_picture(haswell) will call
    if (!obj_dst_surf->bo) {
        unsigned int is_tiled = 1;
        unsigned int fourcc = VA_FOURCC_NV12;
        int sampling = SUBSAMPLE_YUV420;
        i965_check_alloc_surface_bo(ctx, obj_dst_surf, is_tiled, fourcc, sampling);
    }
to make sure the bo != NULL
(3)For SNB, it will call i965_proc_picture() directly which has no i965_check_alloc_surface_bo() at all.
Comment 1 xiaoyur347 2016-07-26 07:41:18 UTC
Fix the Additional Information I mentioned.
"
(3)For SNB, it will call i965_proc_picture() directly which has no i965_check_alloc_surface_bo() at all.
"

I comment 
+    //if (!dst_obj_surface->bo)
+    //    return VA_STATUS_ERROR_INVALID_SURFACE; 
and run once more.
(1)
i965_proc_picture_fast() failed with VA_STATUS_ERROR_UNIMPLEMENTED,
    if (pp_index < 0)
        return VA_STATUS_ERROR_UNIMPLEMENTED;

(2)the i965_proc_picture() went on and surface->bo initialize here.

    int csc_needed = 0;
    if (obj_surface->fourcc && obj_surface->fourcc !=  VA_FOURCC_NV12){
        csc_needed = 1;
        out_surface_id = VA_INVALID_ID;
        status = i965_CreateSurfaces(ctx,
                                     obj_surface->orig_width,
                                     obj_surface->orig_height,
                                     VA_RT_FORMAT_YUV420, 
                                     1,
                                     &out_surface_id);
        assert(status == VA_STATUS_SUCCESS);
        tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
        struct object_surface *csc_surface = SURFACE(out_surface_id);
        assert(csc_surface);
        i965_check_alloc_surface_bo(ctx, csc_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
        dst_surface.base = (struct object_base *)csc_surface;
    } else {
        i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
        dst_surface.base = (struct object_base *)obj_surface;
    }
Comment 2 xiaoyur347 2016-07-26 08:11:02 UTC
Summarize the above on SNB,

For libra-driver 1.6.1, my code will run this way:
(1) i965_proc_picture() calls i965_proc_picture_fast(), and 
i965_proc_picture_fast() failed with VA_STATUS_ERROR_UNIMPLEMENTED,
    if (pp_index < 0)
        return VA_STATUS_ERROR_UNIMPLEMENTED;
(2) i965_proc_picture() went went on and surface->bo initialize here.

    int csc_needed = 0;
    if (obj_surface->fourcc && obj_surface->fourcc !=  VA_FOURCC_NV12){
        csc_needed = 1;
        out_surface_id = VA_INVALID_ID;
        status = i965_CreateSurfaces(ctx,
                                     obj_surface->orig_width,
                                     obj_surface->orig_height,
                                     VA_RT_FORMAT_YUV420, 
                                     1,
                                     &out_surface_id);
        assert(status == VA_STATUS_SUCCESS);
        tmp_surfaces[num_tmp_surfaces++] = out_surface_id;
        struct object_surface *csc_surface = SURFACE(out_surface_id);
        assert(csc_surface);
        i965_check_alloc_surface_bo(ctx, csc_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
        dst_surface.base = (struct object_base *)csc_surface;
    } else {
        i965_check_alloc_surface_bo(ctx, obj_surface, !!tiling, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
        dst_surface.base = (struct object_base *)obj_surface;
    }
(3) went on to call i965_post_processing_internal().


For libra-intel-driver >=1.6.2, I modify my code with
"
    VASurfaceAttrib va_attrib;
    va_attrib.type = VASurfaceAttribPixelFormat;
    va_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
    va_attrib.value.type = VAGenericValueTypeInteger;
    va_attrib.value.value.i = VA_FOURCC_NV12;
    va_status = vaCreateSurfaces(
            va_dpy,
            VA_RT_FORMAT_YUV420, 1280, 720,
            &dst_surface, 1,
            &va_attrib, 1
        );
"
And i965_proc_picture() calls i965_proc_picture_fast() which calls i965_post_processing_internal() directly.
Comment 3 haihao 2016-07-27 01:00:22 UTC
Could you provide a test case? I want to try it on other platforms.
Comment 4 xiaoyur347 2016-10-03 14:47:11 UTC
Sorry for long delay.
I make a demo with the base of ffvademo to describe my problem.

Seeing https://github.com/xiaoyur347/ffvademo/commit/ec31a905e3a5124b3806459f200d20552ff4a137

My demo do:
(1) render the video like the ffvademo does.
(2) using glCopyTexImage2D to capture the display to a glTexture.
which shares with the libva by eglCreateImageKHR().
(3) filter the captured libva surface from rgba to yuv.
And it fails when the dest surface created with ensure_filter_surface() #if 0 condition.


+static int ensure_filter_surface(FFVARendererEGL *rnd)
+{
+    s_vaFilter = ffva_filter_new(rnd->base.display);
+    VAStatus va_status;
+    // Create surface
+#if 0 //fail
+    va_status = vaCreateSurfaces(
+        rnd->va_display,
+        VA_RT_FORMAT_YUV420,
+        rnd->native_renderer->width, rnd->native_renderer->height,
+        &s_vaFilterSurface, 1,
+        NULL, 0
+    );
+#else //success
+    VASurfaceAttrib va_attrib;
+    va_attrib.type = VASurfaceAttribPixelFormat;
+    va_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
+    va_attrib.value.type = VAGenericValueTypeInteger;
+    va_attrib.value.value.i = VA_FOURCC_NV12;
+    va_status = vaCreateSurfaces(
+        rnd->va_display,
+        VA_RT_FORMAT_YUV420,
+        rnd->native_renderer->width, rnd->native_renderer->height,
+        &s_vaFilterSurface, 1,
+        &va_attrib, 1
+    );
+#endif
+}
Comment 5 xiaoyur347 2016-10-03 14:52:48 UTC
I run the ffvademo the following way.
export LD_LIBRARY_PATH=/opt/ffvademo/ext/ffmpeg/.libs/
./src/.libs/ffvademo -r egl -m mesa_image ./test.ts

With #if 0 condition,
libva info: VA-API version 0.39.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
[mpegts @ 0x10313c0] Could not find codec parameters for stream 1 (Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x10313c0] Could not find codec parameters for stream 2 (Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from './test.ts':
  Duration: 00:04:25.15, start: 600.014000, bitrate: 2975 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, smpte170m), 720x480 [SAR 40:33 DAR 20:11], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels
    Stream #0:2[0x1101]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels
glGenTextures 2
error: vaEndPicture(): invalid VASurfaceID
ret=-22
error: vaEndPicture(): invalid VASurfaceID
ret=-22
error: vaEndPicture(): invalid VASurfaceID
ret=-22
error: vaEndPicture(): invalid VASurfaceID
ret=-22
...

With the other condition,
libva info: VA-API version 0.39.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
[mpegts @ 0x9bd3c0] Could not find codec parameters for stream 1 (Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x9bd3c0] Could not find codec parameters for stream 2 (Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from './test.ts':
  Duration: 00:04:25.15, start: 600.014000, bitrate: 2975 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, smpte170m), 720x480 [SAR 40:33 DAR 20:11], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels
    Stream #0:2[0x1101]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels
glGenTextures 2
Comment 6 ykzhao 2016-12-15 04:59:28 UTC
Hi, 
    Does the issue still exists?
    Will you please try the latest driver code and see whether the issue still exists?

Thanks
Comment 7 bob 2017-01-05 18:13:52 UTC
I believe this bug is still present in libva 1.7.3, but I'm unable to replicate with the code provided (ffvademo bails out with the only output being "failed to create renderer"). Nonetheless, I'm guessing this is the same bug given:

0:00:01.422790532 29211 0x7f7bb4004140 DEBUG                  vaapi gstvaapiutils.c:53:vaapi_check_status: vaEndPicture(): invalid VASurfaceID
0:00:01.422812057 29211 0x7f7bb4004140 ERROR          vaapipostproc gstvaapipostproc.c:805:gst_vaapipostproc_process_vpp:<vaapipostproc0> failed to apply VPP filters (error 2)

I've tried the same GStreamer code on two Sandy Bridge machines and gotten the same result. I've not been able to replicate this on my Ivy Bridge desktop, but it has a discrete GPU whose VA driver is loaded by default; It still works if I set LIBVA_DRIVER_NAME to i965, but I've been unable to determine whether the video sink is still using whatever post-processing elements are default for Radeon VA or if that environment variable also has the effect of loading/using vaapipostproc.

FWIW, Googling "invalid vasurfaceid" not only yields this bug report but also a couple of recent posts on the Kodi forums from people reporting a similar issue on Ivy Bridge CPUs:

http://forum.kodi.tv/showthread.php?tid=255766
http://forum.kodi.tv/showthread.php?tid=274833

Hope this helps
Comment 8 xiaoyur347 2017-02-03 09:12:40 UTC
(In reply to ykzhao from comment #6)
> Hi, 
>     Does the issue still exists?
>     Will you please try the latest driver code and see whether the issue
> still exists?
> 
> Thanks

After downloading the new release libva 1.7.3 and libva-intel-driver 1.7.3, I run the program again. The problem is still there for Sandy Bridge. 
But I tested the old 1.7.0 libva-intel-driver, the code below
    VASurfaceAttrib va_attrib;
    va_attrib.type = VASurfaceAttribPixelFormat;
    va_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
    va_attrib.value.type = VAGenericValueTypeInteger;
    va_attrib.value.value.i = VA_FOURCC_NV12;
    va_status = vaCreateSurfaces(
            va_dpy,
            VA_RT_FORMAT_YUV420, 1280, 720,
            &dst_surface, 1,
            &va_attrib, 1
        );
can avoid kernel panic after encoding many times since my old code caused.
So I'm just curious why VA_FOURCC_NV12 is not the pixel format by default.
Sorry for another long delay since my old SNB laptop is not along my side.

Log here:
#export LD_LIBRARY_PATH=/usr/local/lib/:/opt/ffvademo/ext/ffmpeg/.libs/
./src/.libs/ffvademo -r egl -m mesa_image ./test.ts
libva info: VA-API version 0.39.4
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
[mpegts @ 0x1511420] Could not find codec parameters for stream 1 (Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[mpegts @ 0x1511420] Could not find codec parameters for stream 2 (Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels): unspecified frame size
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from './test.ts':
  Duration: 00:04:25.15, start: 600.014000, bitrate: 2975 kb/s
  Program 1 
    Stream #0:0[0x1011]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, smpte170m), 720x480 [SAR 40:33 DAR 20:11], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1100]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels
    Stream #0:2[0x1101]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels
glGenTextures 2
error: vaEndPicture(): invalid VASurfaceID
ret=-22
error: vaEndPicture(): invalid VASurfaceID
ret=-22
error: vaEndPicture(): invalid VASurfaceID
ret=-22


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.