+ const AVCodecHWConfig *config;
+ HWDevice *dev = NULL;
+ AVBufferRef *frames_ref = NULL;
+ int i;
+
+ if (ost->filter) {
+ frames_ref = av_buffersink_get_hw_frames_ctx(ost->filter->filter);
+ if (frames_ref &&
+ ((AVHWFramesContext*)frames_ref->data)->format ==
+ ost->enc_ctx->pix_fmt) {
+ // Matching format, will try to use hw_frames_ctx.
+ } else {
+ frames_ref = NULL;
+ }
+ }
+
+ for (i = 0;; i++) {
+ config = avcodec_get_hw_config(ost->enc, i);
+ if (!config)
+ break;
+
+ if (frames_ref &&
+ config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX &&
+ (config->pix_fmt == AV_PIX_FMT_NONE ||
+ config->pix_fmt == ost->enc_ctx->pix_fmt)) {
+ av_log(ost->enc_ctx, AV_LOG_VERBOSE, "Using input "
+ "frames context (format %s) with %s encoder.\n",
+ av_get_pix_fmt_name(ost->enc_ctx->pix_fmt),
+ ost->enc->name);
+ ost->enc_ctx->hw_frames_ctx = av_buffer_ref(frames_ref);
+ if (!ost->enc_ctx->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+ return 0;
+ }
+
+ if (!dev &&
+ config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)
+ dev = hw_device_get_by_type(config->device_type);
+ }