-
-int qsv_transcode_init(OutputStream *ost)
-{
- InputStream *ist;
- const enum AVPixelFormat *pix_fmt;
-
- int err, i;
- AVBufferRef *encode_frames_ref = NULL;
- AVHWFramesContext *encode_frames;
- AVQSVFramesContext *qsv_frames;
-
- /* check if the encoder supports QSV */
- if (!ost->enc->pix_fmts)
- return 0;
- for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
- if (*pix_fmt == AV_PIX_FMT_QSV)
- break;
- if (*pix_fmt == AV_PIX_FMT_NONE)
- return 0;
-
- if (strcmp(ost->avfilter, "null") || ost->source_index < 0)
- return 0;
-
- /* check if the decoder supports QSV and the output only goes to this stream */
- ist = input_streams[ost->source_index];
- if (ist->hwaccel_id != HWACCEL_QSV || !ist->dec || !ist->dec->pix_fmts)
- return 0;
- for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)
- if (*pix_fmt == AV_PIX_FMT_QSV)
- break;
- if (*pix_fmt == AV_PIX_FMT_NONE)
- return 0;
-
- for (i = 0; i < nb_output_streams; i++)
- if (output_streams[i] != ost &&
- output_streams[i]->source_index == ost->source_index)
- return 0;
-
- av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n");
-
- if (!hw_device_ctx) {
- err = qsv_device_init(ist);
- if (err < 0)
- goto fail;
- }
-
- // This creates a dummy hw_frames_ctx for the encoder to be
- // suitably initialised. It only contains one real frame, so
- // hopefully doesn't waste too much memory.
-
- encode_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx);
- if (!encode_frames_ref) {
- err = AVERROR(ENOMEM);
- goto fail;
- }
- encode_frames = (AVHWFramesContext*)encode_frames_ref->data;
- qsv_frames = encode_frames->hwctx;
-
- encode_frames->width = FFALIGN(ist->resample_width, 32);
- encode_frames->height = FFALIGN(ist->resample_height, 32);
- encode_frames->format = AV_PIX_FMT_QSV;
- encode_frames->sw_format = AV_PIX_FMT_NV12;
- encode_frames->initial_pool_size = 1;
-
- qsv_frames->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
-
- err = av_hwframe_ctx_init(encode_frames_ref);
- if (err < 0)
- goto fail;
-
- ist->dec_ctx->pix_fmt = AV_PIX_FMT_QSV;
- ist->resample_pix_fmt = AV_PIX_FMT_QSV;
-
- ost->enc_ctx->pix_fmt = AV_PIX_FMT_QSV;
- ost->enc_ctx->hw_frames_ctx = encode_frames_ref;
-
- return 0;
-
-fail:
- av_buffer_unref(&encode_frames_ref);
- return err;
-}