static int filter_frame(AVFilterLink *link, AVFrame *input_frame) { AVFilterContext *avctx = link->dst; AVFilterLink *outlink = avctx->outputs[0]; ColorkeyOpenCLContext *colorkey_ctx = avctx->priv; AVFrame *output_frame = NULL; int err; cl_int cle; size_t global_work[2]; cl_mem src, dst; if (!input_frame->hw_frames_ctx) return AVERROR(EINVAL); if (!colorkey_ctx->initialized) { AVHWFramesContext *input_frames_ctx = (AVHWFramesContext*)input_frame->hw_frames_ctx->data; int fmt = input_frames_ctx->sw_format; // Make sure the input is a format we support if (fmt != AV_PIX_FMT_ARGB && fmt != AV_PIX_FMT_RGBA && fmt != AV_PIX_FMT_ABGR && fmt != AV_PIX_FMT_BGRA ) { av_log(avctx, AV_LOG_ERROR, "unsupported (non-RGB) format in colorkey_opencl.\n"); err = AVERROR(ENOSYS); goto fail; } err = colorkey_opencl_init(avctx); if (err < 0) goto fail; } // This filter only operates on RGB data and we know that will be on the first plane src = (cl_mem)input_frame->data[0]; output_frame = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!output_frame) { err = AVERROR(ENOMEM); goto fail; } dst = (cl_mem)output_frame->data[0]; CL_SET_KERNEL_ARG(colorkey_ctx->kernel_colorkey, 0, cl_mem, &src); CL_SET_KERNEL_ARG(colorkey_ctx->kernel_colorkey, 1, cl_mem, &dst); CL_SET_KERNEL_ARG(colorkey_ctx->kernel_colorkey, 2, cl_float4, &colorkey_ctx->colorkey_rgba_float); CL_SET_KERNEL_ARG(colorkey_ctx->kernel_colorkey, 3, float, &colorkey_ctx->similarity); if (colorkey_ctx->blend > 0.0001) { CL_SET_KERNEL_ARG(colorkey_ctx->kernel_colorkey, 4, float, &colorkey_ctx->blend); }
static int neighbor_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input) { AVFilterContext *avctx = inlink->dst; AVFilterLink *outlink = avctx->outputs[0]; NeighborOpenCLContext *ctx = avctx->priv; AVFrame *output = NULL; cl_int cle; size_t global_work[2]; cl_mem src, dst; int err, p; size_t origin[3] = {0, 0, 0}; size_t region[3] = {0, 0, 1}; av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(input->format), input->width, input->height, input->pts); if (!input->hw_frames_ctx) return AVERROR(EINVAL); if (!ctx->initialised) { err = neighbor_opencl_init(avctx); if (err < 0) goto fail; err = neighbor_opencl_make_filter_params(avctx); if (err < 0) goto fail; } output = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!output) { err = AVERROR(ENOMEM); goto fail; } for (p = 0; p < FF_ARRAY_ELEMS(output->data); p++) { src = (cl_mem) input->data[p]; dst = (cl_mem)output->data[p]; if (!dst) break; if (ctx->threshold[p] == 0) { err = ff_opencl_filter_work_size_from_image(avctx, region, output, p, 0); if (err < 0) goto fail; cle = clEnqueueCopyImage(ctx->command_queue, src, dst, origin, origin, region, 0, NULL, NULL); CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to copy plane %d: %d.\n", p, cle); } else { CL_SET_KERNEL_ARG(ctx->kernel, 0, cl_mem, &dst); CL_SET_KERNEL_ARG(ctx->kernel, 1, cl_mem, &src); CL_SET_KERNEL_ARG(ctx->kernel, 2, cl_float, &ctx->threshold[p]); CL_SET_KERNEL_ARG(ctx->kernel, 3, cl_mem, &ctx->coord); err = ff_opencl_filter_work_size_from_image(avctx, global_work, output, p, 0); if (err < 0) goto fail; av_log(avctx, AV_LOG_DEBUG, "Run kernel on plane %d " "(%"SIZE_SPECIFIER"x%"SIZE_SPECIFIER").\n", p, global_work[0], global_work[1]); cle = clEnqueueNDRangeKernel(ctx->command_queue, ctx->kernel, 2, NULL, global_work, NULL, 0, NULL, NULL); CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to enqueue " "kernel: %d.\n", cle); } } cle = clFinish(ctx->command_queue); CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to finish command queue: %d.\n", cle); err = av_frame_copy_props(output, input); if (err < 0) goto fail; av_frame_free(&input); av_log(ctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(output->format), output->width, output->height, output->pts); return ff_filter_frame(outlink, output); fail: clFinish(ctx->command_queue); av_frame_free(&input); av_frame_free(&output); return err; }
static int convolution_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input) { AVFilterContext *avctx = inlink->dst; AVFilterLink *outlink = avctx->outputs[0]; ConvolutionOpenCLContext *ctx = avctx->priv; AVFrame *output = NULL; cl_int cle; size_t global_work[2]; cl_mem src, dst; int err, p; av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(input->format), input->width, input->height, input->pts); if (!input->hw_frames_ctx) return AVERROR(EINVAL); if (!ctx->initialised) { err = convolution_opencl_init(avctx); if (err < 0) goto fail; err = convolution_opencl_make_filter_params(avctx); if (err < 0) goto fail; } output = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!output) { err = AVERROR(ENOMEM); goto fail; } for (p = 0; p < FF_ARRAY_ELEMS(output->data); p++) { src = (cl_mem) input->data[p]; dst = (cl_mem)output->data[p]; if (!dst) break; CL_SET_KERNEL_ARG(ctx->kernel, 0, cl_mem, &dst); CL_SET_KERNEL_ARG(ctx->kernel, 1, cl_mem, &src); CL_SET_KERNEL_ARG(ctx->kernel, 2, cl_int, &ctx->dims[p]); CL_SET_KERNEL_ARG(ctx->kernel, 3, cl_mem, &ctx->matrix[p]); CL_SET_KERNEL_ARG(ctx->kernel, 4, cl_float, &ctx->rdivs[p]); CL_SET_KERNEL_ARG(ctx->kernel, 5, cl_float, &ctx->biases[p]); err = ff_opencl_filter_work_size_from_image(avctx, global_work, output, p, 0); if (err < 0) goto fail; av_log(avctx, AV_LOG_DEBUG, "Run kernel on plane %d " "(%"SIZE_SPECIFIER"x%"SIZE_SPECIFIER").\n", p, global_work[0], global_work[1]); cle = clEnqueueNDRangeKernel(ctx->command_queue, ctx->kernel, 2, NULL, global_work, NULL, 0, NULL, NULL); if (cle != CL_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to enqueue kernel: %d.\n", cle); err = AVERROR(EIO); goto fail; } } cle = clFinish(ctx->command_queue); if (cle != CL_SUCCESS) { av_log(avctx, AV_LOG_ERROR, "Failed to finish command queue: %d.\n", cle); err = AVERROR(EIO); goto fail; } err = av_frame_copy_props(output, input); if (err < 0) goto fail; av_frame_free(&input); av_log(ctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(output->format), output->width, output->height, output->pts); return ff_filter_frame(outlink, output); fail: clFinish(ctx->command_queue); av_frame_free(&input); av_frame_free(&output); return err; }