ImageRawPtr VaapiImageRaw::create(const DisplayPtr& display, const ImagePtr& image, VideoDataMemoryType memoryType) { ImageRawPtr raw; RealeaseCallback release; uintptr_t handle; VAStatus status; VAImagePtr& vaImage = image->m_image; if (memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_POINTER || memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_COPY) { void* data; status = vaMapBuffer(display->getID(), vaImage->buf, &data); release = vaUnmapBuffer; handle = (uintptr_t)data; } else { VABufferInfo bufferInfo; if (memoryType == VIDEO_DATA_MEMORY_TYPE_DRM_NAME) bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; else if (memoryType == VIDEO_DATA_MEMORY_TYPE_DMA_BUF) bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; else ASSERT(0); status = vaAcquireBufferHandle(display->getID(), vaImage->buf, &bufferInfo); release = vaReleaseBufferHandle; handle = (uintptr_t)bufferInfo.handle; } if (!checkVaapiStatus(status, "VaapiImageRaw::create()")) return raw; raw.reset(new VaapiImageRaw(display, image, memoryType, handle, release)); return raw; }
bool EglVaapiImage::acquireBufferHandle(VideoDataMemoryType memoryType) { uint32_t i; if (m_acquired) { ASSERT(memoryType = m_frameInfo.memoryType); return true; } // FIXME, more type can be supported if (memoryType == VIDEO_DATA_MEMORY_TYPE_DRM_NAME) m_bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; else if (memoryType == VIDEO_DATA_MEMORY_TYPE_DMA_BUF) m_bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; else ASSERT(0); VAStatus vaStatus = vaAcquireBufferHandle(m_display, m_image.buf, &m_bufferInfo); m_frameInfo.memoryType = memoryType; m_frameInfo.width = m_width; m_frameInfo.height = m_height; for (i=0; i<m_image.num_planes; i++) { m_frameInfo.pitch[i] = m_image.pitches[i]; m_frameInfo.offset[i] = m_image.offsets[i]; } m_frameInfo.fourcc = m_image.format.fourcc; m_frameInfo.size = m_image.data_size; // not interest for bufferhandle m_frameInfo.handle = m_bufferInfo.handle; m_acquired = true; return checkVaapiStatus(vaStatus, "vaAcquireBufferHandle"); }
VaapiImageRaw *VaapiImage::map(VideoDataMemoryType memoryType) { uint32_t i; void *data; VAStatus status; if (m_isMapped) { return &m_rawImage; } m_rawImage.format = m_image->format.fourcc; m_rawImage.width = m_image->width; m_rawImage.height = m_image->height; m_rawImage.numPlanes = m_image->num_planes; m_rawImage.size = m_image->data_size; for (i = 0; i < m_image->num_planes; i++) { m_rawImage.strides[i] = m_image->pitches[i]; } if (memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_POINTER || memoryType == VIDEO_DATA_MEMORY_TYPE_RAW_COPY) { status = vaMapBuffer(m_display->getID(), m_image->buf, &data); if (!checkVaapiStatus(status, "vaMapBuffer()")) return NULL; for (i = 0; i < m_image->num_planes; i++) { m_rawImage.handles[i] = (intptr_t) data + m_image->offsets[i]; } } else { VABufferInfo bufferInfo; if (memoryType == VIDEO_DATA_MEMORY_TYPE_DRM_NAME) bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM; else if (memoryType == VIDEO_DATA_MEMORY_TYPE_DMA_BUF) bufferInfo.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; else ASSERT(0); status = vaAcquireBufferHandle(m_display->getID(), m_image->buf, &bufferInfo); if (!checkVaapiStatus(status, "vaAcquireBufferHandle()")) return NULL; for (i = 0; i < m_image->num_planes; i++) { m_rawImage.handles[i] = (intptr_t) bufferInfo.handle; } } m_rawImage.memoryType = memoryType; m_isMapped = true; return &m_rawImage; }
static int map_image(struct gl_hwdec *hw, struct mp_image *hw_image, GLuint *out_textures) { struct priv *p = hw->priv; GL *gl = hw->gl; VAStatus status; VAImage *va_image = &p->current_image; unref_image(hw); mp_image_setrefp(&p->current_ref, hw_image); va_lock(p->ctx); status = vaDeriveImage(p->display, va_surface_id(hw_image), va_image); if (!CHECK_VA_STATUS(p, "vaDeriveImage()")) goto err; int mpfmt = va_fourcc_to_imgfmt(va_image->format.fourcc); if (mpfmt != IMGFMT_NV12 && mpfmt != IMGFMT_420P) { MP_FATAL(p, "unsupported VA image format %s\n", VA_STR_FOURCC(va_image->format.fourcc)); goto err; } if (!hw->converted_imgfmt) { MP_VERBOSE(p, "format: %s %s\n", VA_STR_FOURCC(va_image->format.fourcc), mp_imgfmt_to_name(mpfmt)); hw->converted_imgfmt = mpfmt; } if (hw->converted_imgfmt != mpfmt) { MP_FATAL(p, "mid-stream hwdec format change (%s -> %s) not supported\n", mp_imgfmt_to_name(hw->converted_imgfmt), mp_imgfmt_to_name(mpfmt)); goto err; } VABufferInfo buffer_info = {.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME}; status = vaAcquireBufferHandle(p->display, va_image->buf, &buffer_info); if (!CHECK_VA_STATUS(p, "vaAcquireBufferHandle()")) goto err; p->buffer_acquired = true; struct mp_image layout = {0}; mp_image_set_params(&layout, &hw_image->params); mp_image_setfmt(&layout, mpfmt); // (it would be nice if we could use EGL_IMAGE_INTERNAL_FORMAT_EXT) int drm_fmts[4] = {MP_FOURCC('R', '8', ' ', ' '), // DRM_FORMAT_R8 MP_FOURCC('G', 'R', '8', '8'), // DRM_FORMAT_GR88 MP_FOURCC('R', 'G', '2', '4'), // DRM_FORMAT_RGB888 MP_FOURCC('R', 'A', '2', '4')}; // DRM_FORMAT_RGBA8888 for (int n = 0; n < layout.num_planes; n++) { int attribs[20] = {EGL_NONE}; int num_attribs = 0; ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, drm_fmts[layout.fmt.bytes[n] - 1]); ADD_ATTRIB(EGL_WIDTH, mp_image_plane_w(&layout, n)); ADD_ATTRIB(EGL_HEIGHT, mp_image_plane_h(&layout, n)); ADD_ATTRIB(EGL_DMA_BUF_PLANE0_FD_EXT, buffer_info.handle); ADD_ATTRIB(EGL_DMA_BUF_PLANE0_OFFSET_EXT, va_image->offsets[n]); ADD_ATTRIB(EGL_DMA_BUF_PLANE0_PITCH_EXT, va_image->pitches[n]); p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (!p->images[n]) goto err; gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]); p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]); out_textures[n] = p->gl_textures[n]; } gl->BindTexture(GL_TEXTURE_2D, 0); if (va_image->format.fourcc == VA_FOURCC_YV12) MPSWAP(GLuint, out_textures[1], out_textures[2]); va_unlock(p->ctx); return 0; err: va_unlock(p->ctx); MP_FATAL(p, "mapping VAAPI EGL image failed\n"); unref_image(hw); return -1; }