[Libva] encode surfaces created from prime fd (backed by OpenGL 2D texture)
Zhao Yakui
yakui.zhao at intel.com
Thu May 26 08:03:46 UTC 2016
On 05/26/2016 02:09 PM, Kristine Ferrell wrote:
> On Thu, May 26, 2016 at 12:20 AM, Zhao Yakui<yakui.zhao at intel.com> wrote:
>>
>> On 05/26/2016 10:44 AM, Kristine Ferrell wrote:
>>>
>>> Shengquan,
>>>
>>> Thanks for the sample code. I have some follow-up questions:
>>>
>>> 1. Can I use VA_RT_FORMAT_RGB32 as the pixel format for
>>> vaCreateSurfaces? It'll be simpler since normally the 2D texture is in
>>> ARGB format.
>>
>>
>> [Yakui]: Yes. You can use the VA_RT_FORMAT_RBG32 as the pixel format.
>>
>>> 2. Do I have to align the picture width and height, i.e., can I just use
>>> 1920x1080 for a full HD picture?
>>
>>
>> [Yakui]: You only need to use 1920x1080 for full HD picture. If the buffer is created by the vaapi driver, the driver can help to do the alignment of width and height. And you don't need to care it.
>>
>> BTW: How do you use the buffer? Is the buffer created in other component and then used for the vaapi driver or created by the vaapi driver?
>>
>
> The buffer is from prime fd which is created on a RGB format opengl 2D
> texture. I want to use the prime fd and opengl 2D texture as is (no
> conversion from RGB to NV12, no width / height alignment) since I
> expect way better performance as the hardware encoder and GPU both
> have direct access to the memory holding the texture data. Reading the
> 2D texture into main memory and then uploading the data into vaSurface
> takes too much time and the performance won't be acceptable for my
> application.
[Yakui]: That is OK. In such scenario you don't need to align the
width/height. You only need to obtain the prime_fd exported from OGL 2D
texture and then use it to create vaSurface for the later usage.
>
>>
>>>
>>> Best
>>> Christine
>>>
>>> On Wed, May 25, 2016 at 3:46 AM, Yuan, Shengquan
>>> <shengquan.yuan at intel.com<mailto:shengquan.yuan at intel.com>> wrote:
>>>
>>> For vaCreateContext, I think render_targets/num_render_targets are
>>> optional (it depends on driver implementation), and the surface of
>>> vaBeginPicture can a brand-new surface
>>>
>>> VAStatus vaCreateContext (
>>>
>>> VADisplay dpy,
>>>
>>> VAConfigID config_id,
>>>
>>> int picture_width,
>>>
>>> int picture_height,
>>>
>>> int flag,
>>>
>>> VASurfaceID *render_targets,
>>>
>>> int num_render_targets,
>>>
>>> VAContextID *context /* out */
>>>
>>> );
>>>
>>> DMA buffer can be imported through
>>> VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, e.g.
>>>
>>> VASurfaceAttribExternalBuffers buf;
>>>
>>> VASurfaceAttribType type,
>>>
>>> VASurfaceAttrib attrib_list[2]
>>>
>>> unsigned long prime_fd; /* an input variable, it is the imported
>>> prime fd from other process */
>>>
>>> int stride = frame_width_aligned, height_aligned =
>>> frame_height_aligned;
>>>
>>> if (stride == 0)
>>>
>>> stride = frame_width_mbaligned;
>>>
>>> if (height_aligned == 0)
>>>
>>> height_aligned = frame_height_mbaligned;
>>>
>>> buf.pixel_format = VA_FOURCC_NV12;
>>>
>>> buf.width = frame_width_mbaligned;
>>>
>>> buf.height = frame_height_mbaligned;
>>>
>>> buf.data_size = stride * height_aligned * 1.5;
>>>
>>> buf.num_buffers = 1; /* import only 1 buffer */
>>>
>>> buf.num_planes = 3;
>>>
>>> buf.pitches[0] = stride;
>>>
>>> buf.pitches[1] = stride;
>>>
>>> buf.pitches[2] = stride;
>>>
>>> buf.pitches[3] = 0;
>>>
>>> buf.offsets[0] = 0;
>>>
>>> buf.offsets[1] = stride * height_aligned;
>>>
>>> buf.offsets[2] = buf.offsets[1];
>>>
>>> buf.offsets[3] = 0;
>>>
>>> buf.buffers =&prime_fd;
>>>
>>> buf.flags = 0;
>>>
>>> buf.private_data = NULL;
>>>
>>> attrib_list[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
>>>
>>> attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
>>>
>>> attrib_list[0].value.type = VAGenericValueTypeInteger;
>>>
>>> attrib_list[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
>>>
>>> attrib_list[1].type =
>>> (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
>>>
>>> attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
>>>
>>> attrib_list[1].value.type = VAGenericValueTypePointer;
>>>
>>> attrib_list[1].value.value.p = (void *)buf;
>>>
>>> vaCreateSurfaces(
>>>
>>> va_dpy,
>>>
>>> VA_RT_FORMAT_YUV420,
>>>
>>> frame_width_mbaligned, frame_height_mbaligned,
>>>
>>> &surface_id, 1,
>>>
>>> &attrib_list, 2);
>>>
>>> *From:*Libva [mailto:libva-bounces at lists.freedesktop.org
>>> <mailto:libva-bounces at lists.freedesktop.org>] *On Behalf Of *Anon
>>> *Sent:* Wednesday, May 25, 2016 2:23 PM
>>> *To:* libva at lists.freedesktop.org<mailto:libva at lists.freedesktop.org>
>>> *Subject:* [Libva] encode surfaces created from prime fd (backed by
>>> OpenGL 2D texture)
>>>
>>> Hi All,
>>>
>>> I want to implement the following use case on Intel Haswell CPU with
>>> HD graphics:
>>>
>>> offscreen OpenGL rendering to OpenGL 2D texture -> use
>>> EGL_MESA_image_dma_buf_export to export the texture as prime fd ->
>>> vaCreateSurfaces from the prime fd -> use vaapi to hw acclerate h264
>>> encoding
>>>
>>> Is this supported by the latest va-api and libva-intel-driver
>>> release (i.e., 1.7.0)? If so, is there any example I can start with?
>>>
>>> I did read the sample application h264encode.c and thought it might
>>> be a good starting point. However, the first major issue I
>>> encountered is when creating context through vaCreateContext, a
>>> number of pre-allocated va surfaces are required and thus statically
>>> associated with the new va context. However, with prime fd, the fd
>>> will change so a new va surface is created with every new prime fd.
>>> I don't see any API can be used to dynamically add/remove va
>>> surfaces after the context is created. Can you please give me some
>>> suggestions?
>>>
>>> Best,
>>>
>>> Kristine
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> Libva mailing list
>>> Libva at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/libva
>>
>>
More information about the Libva
mailing list