static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags) { AVHWFramesContext *ctx = (AVHWFramesContext*)src->hw_frames_ctx->data; AVFrame *frame_tmp; int ret = 0; frame_tmp = av_frame_alloc(); if (!frame_tmp) return AVERROR(ENOMEM); /* if the format is set, use that * otherwise pick the first supported one */ if (dst->format >= 0) { frame_tmp->format = dst->format; } else { enum AVPixelFormat *formats; ret = av_hwframe_transfer_get_formats(src->hw_frames_ctx, AV_HWFRAME_TRANSFER_DIRECTION_FROM, &formats, 0); if (ret < 0) goto fail; frame_tmp->format = formats[0]; av_freep(&formats); } frame_tmp->width = ctx->width; frame_tmp->height = ctx->height; ret = av_frame_get_buffer(frame_tmp, 32); if (ret < 0) goto fail; ret = av_hwframe_transfer_data(frame_tmp, src, flags); if (ret < 0) goto fail; frame_tmp->width = src->width; frame_tmp->height = src->height; av_frame_move_ref(dst, frame_tmp); fail: av_frame_free(&frame_tmp); return ret; }
static int hwdownload_config_output(AVFilterLink *outlink) { AVFilterContext *avctx = outlink->src; AVFilterLink *inlink = avctx->inputs[0]; HWDownloadContext *ctx = avctx->priv; enum AVPixelFormat *formats; int err, i, found; if (!ctx->hwframes_ref) return AVERROR(EINVAL); err = av_hwframe_transfer_get_formats(ctx->hwframes_ref, AV_HWFRAME_TRANSFER_DIRECTION_FROM, &formats, 0); if (err < 0) return err; found = 0; for (i = 0; formats[i] != AV_PIX_FMT_NONE; i++) { if (formats[i] == outlink->format) { found = 1; break; } } av_freep(&formats); if (!found) { av_log(ctx, AV_LOG_ERROR, "Invalid output format %s for hwframe " "download.\n", av_get_pix_fmt_name(outlink->format)); return AVERROR(EINVAL); } outlink->w = inlink->w; outlink->h = inlink->h; return 0; }