On Thu, 2020-06-25 at 00:32 +0200, Lynne wrote: > Jun 19, 2020, 07:47 by haihao.xi...@intel.com: > > > User should provide the modifier when importing a DMABuf if this DMABuf > > has modifier. > > > > Signed-off-by: Haihao Xiang <haihao.xi...@intel.com> > > --- > > libavutil/hwcontext_vaapi.c | 137 +++++++++++++++++++++++++++++++++--- > > 1 file changed, 126 insertions(+), 11 deletions(-) > > > > diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c > > index a378bcd12a..514bb07a20 100644 > > --- a/libavutil/hwcontext_vaapi.c > > +++ b/libavutil/hwcontext_vaapi.c > > @@ -999,8 +999,9 @@ static void vaapi_unmap_from_drm(AVHWFramesContext > > *dst_fc, > > vaDestroySurfaces(dst_dev->display, &surface_id, 1); > > } > > > > -static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, > > - const AVFrame *src, int flags) > > +static VASurfaceID vaapi_get_surface_from_drm_prime(AVHWFramesContext > > *dst_fc, > > + AVFrame *dst, > > + const AVFrame *src) > > { > > AVHWFramesContext *src_fc = > > (AVHWFramesContext*)src->hw_frames_ctx->data; > > @@ -1010,7 +1011,7 @@ static int vaapi_map_from_drm(AVHWFramesContext > > *dst_fc, AVFrame *dst, > > VASurfaceID surface_id; > > VAStatus vas; > > uint32_t va_fourcc; > > - int err, i, j, k; > > + int i, j, k; > > > > unsigned long buffer_handle; > > VASurfaceAttribExternalBuffers buffer_desc; > > @@ -1030,13 +1031,6 @@ static int vaapi_map_from_drm(AVHWFramesContext > > *dst_fc, AVFrame *dst, > > }; > > > > desc = (AVDRMFrameDescriptor*)src->data[0]; > > - > > - if (desc->nb_objects != 1) { > > - av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " > > - "made from a single DRM object.\n"); > > - return AVERROR(EINVAL); > > - } > > - > > va_fourcc = 0; > > for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { > > if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) > > @@ -1092,9 +1086,130 @@ static int vaapi_map_from_drm(AVHWFramesContext > > *dst_fc, AVFrame *dst, > > src->width, src->height, > > &surface_id, 1, > > attrs, FF_ARRAY_ELEMS(attrs)); > > + > > + if (vas != VA_STATUS_SUCCESS) { > > + av_log(dst_fc, AV_LOG_DEBUG, "Failed to create surface from > > DRM_PRIME " > > + "object: %d (%s).\n", vas, vaErrorStr(vas)); > > + return VA_INVALID_ID; > > + } > > + > > + return surface_id; > > +} > > + > > +static VASurfaceID vaapi_get_surface_from_drm_prime2(AVHWFramesContext > > *dst_fc, > > + AVFrame *dst, > > + const AVFrame *src) > > +{ > > + AVHWFramesContext *src_fc = > > + (AVHWFramesContext*)src->hw_frames_ctx->data; > > + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; > > + const AVDRMFrameDescriptor *desc; > > + const VAAPIFormatDescriptor *format_desc; > > + VASurfaceID surface_id; > > + VAStatus vas; > > + uint32_t va_fourcc; > > + int i, j; > > + > > + VADRMPRIMESurfaceDescriptor surface_desc; > > + VASurfaceAttrib attrs[2] = { > > + { > > + .type = VASurfaceAttribMemoryType, > > + .flags = VA_SURFACE_ATTRIB_SETTABLE, > > + .value.type = VAGenericValueTypeInteger, > > + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, > > + }, > > + { > > + .type = VASurfaceAttribExternalBufferDescriptor, > > + .flags = VA_SURFACE_ATTRIB_SETTABLE, > > + .value.type = VAGenericValueTypePointer, > > + .value.value.p = &surface_desc, > > + } > > + }; > > + > > + desc = (AVDRMFrameDescriptor*)src->data[0]; > > + va_fourcc = 0; > > + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { > > + if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) > > + continue; > > + for (j = 0; j < desc->nb_layers; j++) { > > + if (desc->layers[j].format != > > + vaapi_drm_format_map[i].layer_formats[j]) > > + break; > > + } > > + if (j != desc->nb_layers) > > + continue; > > + va_fourcc = vaapi_drm_format_map[i].va_fourcc; > > + break; > > + } > > + if (!va_fourcc) { > > + av_log(dst_fc, AV_LOG_ERROR, "DRM format not supported " > > + "by VAAPI.\n"); > > + return AVERROR(EINVAL); > > + } > > + > > + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM object %d to VAAPI as " > > + "%08x.\n", desc->objects[0].fd, va_fourcc); > > + > > + format_desc = vaapi_format_from_fourcc(va_fourcc); > > + av_assert0(format_desc && !format_desc->chroma_planes_swapped); > > + > > + surface_desc.fourcc = va_fourcc; > > + surface_desc.width = src_fc->width; > > + surface_desc.height = src_fc->height; > > + surface_desc.num_objects = 1; > > + surface_desc.objects[0].fd = desc->objects[0].fd; > > + surface_desc.objects[0].size = desc->objects[0].size; > > + surface_desc.objects[0].drm_format_modifier = desc- > > >objects[0].format_modifier; > > + surface_desc.num_layers = desc->nb_layers; > > + > > + for (i = 0; i < desc->nb_layers; i++) { > > + surface_desc.layers[i].drm_format = desc->layers[i].format; > > + surface_desc.layers[i].num_planes = desc->layers[i].nb_planes; > > + > > + for (j = 0; j < desc->layers[i].nb_planes; j++) { > > + surface_desc.layers[i].object_index[j] = desc- > > >layers[i].planes[j].object_index; > > + surface_desc.layers[i].offset[j] = desc- > > >layers[i].planes[j].offset; > > + surface_desc.layers[i].pitch[j] = desc- > > >layers[i].planes[j].pitch; > > + } > > + } > > + > > + vas = vaCreateSurfaces(dst_dev->display, format_desc->rt_format, > > + src->width, src->height, > > + &surface_id, 1, > > + attrs, FF_ARRAY_ELEMS(attrs)); > > + > > if (vas != VA_STATUS_SUCCESS) { > > - av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from DRM " > > + av_log(dst_fc, AV_LOG_DEBUG, "Failed to create surface from > > DRM_PRIME_2" > > "object: %d (%s).\n", vas, vaErrorStr(vas)); > > + return VA_INVALID_ID; > > + } > > + > > + return surface_id; > > +} > > + > > +static int vaapi_map_from_drm(AVHWFramesContext *dst_fc, AVFrame *dst, > > + const AVFrame *src, int flags) > > +{ > > + const AVDRMFrameDescriptor *desc; > > + VASurfaceID surface_id; > > + int err; > > + > > + desc = (AVDRMFrameDescriptor*)src->data[0]; > > + > > + if (desc->nb_objects != 1) { > > + av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " > > + "made from a single DRM object.\n"); > > + return AVERROR(EINVAL); > > + } > > + > > + surface_id = vaapi_get_surface_from_drm_prime2(dst_fc, dst, src); > > + > > + if (surface_id == VA_INVALID_SURFACE) > > + surface_id = vaapi_get_surface_from_drm_prime(dst_fc, dst, src); > > + > > + if (surface_id == VA_INVALID_SURFACE) { > > + av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from " > > + "DRM_PRIME2 or DRM_PRIME.\n"); > > return AVERROR(EIO); > > } > > av_log(dst_fc, AV_LOG_DEBUG, "Create surface %#x.\n", surface_id); > > > > I tested this because I need it to import compressed display framebuffers > where the second > object FD contains the compression parameters, but after patching it, mapping > fails with: > > [AVHWFramesContext @ 0x5644973a4f00] Failed to read image from surface 0x1: > > -1 (unknown libva error). > > [dmabuf-capture @ 0x7ffc14d6d9a0] Error encoding: Invalid argument! > > I've attached a diff of what I used. > > Does DRM_PRIME_2 on intel still not support compressed framebuffers? Users > have been wanting > to use kmsgrab but if the compositor picks a compressed modifier, they're out > of luck. >
Thanks for testing. Maybe your issue is not caused by compressed framebuffers. The current media driver is hard-coded to use the first object only. We will fix the media driver and this patch to support multiple objects. > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".