static int qsv_map_to(AVHWFramesContext *dst_ctx, AVFrame *dst, const AVFrame *src, int flags) { AVQSVFramesContext *hwctx = dst_ctx->hwctx; int i, err; for (i = 0; i < hwctx->nb_surfaces; i++) { #if CONFIG_VAAPI if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId == (VASurfaceID)(uintptr_t)src->data[3]) break; #endif #if CONFIG_DXVA2 if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId == (IDirect3DSurface9*)(uintptr_t)src->data[3]) break; #endif } if (i >= hwctx->nb_surfaces) { av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which " "is not in the mapped frames context.\n"); return AVERROR(EINVAL); } err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, NULL, NULL); if (err) return err; dst->width = src->width; dst->height = src->height; dst->data[3] = (uint8_t*)&hwctx->surfaces[i]; return 0; }
static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags) { IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3]; DXVA2Mapping *map; D3DSURFACE_DESC surfaceDesc; D3DLOCKED_RECT LockedRect; HRESULT hr; int i, err, nb_planes; int lock_flags = 0; nb_planes = av_pix_fmt_count_planes(dst->format); hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc); if (FAILED(hr)) { av_log(ctx, AV_LOG_ERROR, "Error getting a surface description\n"); return AVERROR_UNKNOWN; } if (!(flags & AV_HWFRAME_MAP_WRITE)) lock_flags |= D3DLOCK_READONLY; if (flags & AV_HWFRAME_MAP_OVERWRITE) lock_flags |= D3DLOCK_DISCARD; hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, lock_flags); if (FAILED(hr)) { av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n"); return AVERROR_UNKNOWN; } map = av_mallocz(sizeof(*map)); if (!map) goto fail; err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, dxva2_unmap_frame, map); if (err < 0) { av_freep(&map); goto fail; } for (i = 0; i < nb_planes; i++) dst->linesize[i] = LockedRect.Pitch; av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height, (uint8_t*)LockedRect.pBits, dst->linesize); if (dst->format == AV_PIX_FMT_PAL8) dst->data[1] = (uint8_t*)map->palette_dummy; return 0; fail: IDirect3DSurface9_UnlockRect(surface); return err; }
static int qsv_map_from(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src, int flags) { QSVFramesContext *s = ctx->internal->priv; mfxFrameSurface1 *surf = (mfxFrameSurface1*)src->data[3]; AVHWFramesContext *child_frames_ctx; const AVPixFmtDescriptor *desc; uint8_t *child_data; AVFrame *dummy; int ret = 0; if (!s->child_frames_ref) return AVERROR(ENOSYS); child_frames_ctx = (AVHWFramesContext*)s->child_frames_ref->data; switch (child_frames_ctx->device_ctx->type) { #if CONFIG_VAAPI case AV_HWDEVICE_TYPE_VAAPI: child_data = (uint8_t*)(intptr_t)*(VASurfaceID*)surf->Data.MemId; break; #endif #if CONFIG_DXVA2 case AV_HWDEVICE_TYPE_DXVA2: child_data = surf->Data.MemId; break; #endif default: return AVERROR(ENOSYS); } if (dst->format == child_frames_ctx->format) { ret = ff_hwframe_map_create(s->child_frames_ref, dst, src, NULL, NULL); if (ret < 0) return ret; dst->width = src->width; dst->height = src->height; dst->data[3] = child_data; return 0; } desc = av_pix_fmt_desc_get(dst->format); if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { // This only supports mapping to software. return AVERROR(ENOSYS); } dummy = av_frame_alloc(); if (!dummy) return AVERROR(ENOMEM); dummy->buf[0] = av_buffer_ref(src->buf[0]); dummy->hw_frames_ctx = av_buffer_ref(s->child_frames_ref); if (!dummy->buf[0] || !dummy->hw_frames_ctx) goto fail; dummy->format = child_frames_ctx->format; dummy->width = src->width; dummy->height = src->height; dummy->data[3] = child_data; ret = av_hwframe_map(dst, dummy, flags); fail: av_frame_free(&dummy); return ret; }