return AVERROR_BUG;
q->param.mfx.CodecId = ret;
- q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
-
if (avctx->level > 0)
q->param.mfx.CodecLevel = avctx->level;
ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
- q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align);
- q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 32);
q->param.mfx.FrameInfo.CropX = 0;
q->param.mfx.FrameInfo.CropY = 0;
q->param.mfx.FrameInfo.CropW = avctx->width;
q->param.mfx.FrameInfo.CropH = avctx->height;
q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num;
q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den;
- q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
q->param.mfx.FrameInfo.BitDepthLuma = desc->comp[0].depth;
q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
q->param.mfx.FrameInfo.Shift = desc->comp[0].depth > 8;
+ // TODO: detect version of MFX--if the minor version is greater than
+ // or equal to 19, then can use the same alignment settings as H.264
+ // for HEVC
+ q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
+ q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align);
+
+ if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
+ // it is important that PicStruct be setup correctly from the
+ // start--otherwise, encoding doesn't work and results in a bunch
+ // of incompatible video parameter errors
+ q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
+ // height alignment always must be 32 for interlaced video
+ q->height_align = 32;
+ } else {
+ q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
+ // for progressive video, the height should be aligned to 16 for
+ // H.264. For HEVC, depending on the version of MFX, it should be
+ // either 32 or 16. The lower number is better if possible.
+ q->height_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
+ }
+ q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
+
if (avctx->hw_frames_ctx) {
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
if (!q->frames_ctx.hw_frames_ctx)
return AVERROR(ENOMEM);
- ret = ff_qsv_init_session_hwcontext(avctx, &q->internal_session,
- &q->frames_ctx, q->load_plugins,
- q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY);
+ ret = ff_qsv_init_session_frames(avctx, &q->internal_session,
+ &q->frames_ctx, q->load_plugins,
+ q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY);
if (ret < 0) {
av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
return ret;
}
+ q->session = q->internal_session;
+ } else if (avctx->hw_device_ctx) {
+ ret = ff_qsv_init_session_device(avctx, &q->internal_session,
+ avctx->hw_device_ctx, q->load_plugins);
+ if (ret < 0)
+ return ret;
+
q->session = q->internal_session;
} else {
ret = ff_qsv_init_internal_session(avctx, &q->internal_session,
if (ret < 0)
return ret;
+ ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param);
+ if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
+ av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
+ } else if (ret < 0) {
+ return ff_qsv_print_error(avctx, ret,
+ "Error querying encoder params");
+ }
+
ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
if (ret < 0)
return ff_qsv_print_error(avctx, ret,
- "Error querying the encoding parameters");
+ "Error querying (IOSurf) the encoding parameters");
if (opaque_alloc) {
ret = qsv_init_opaque_alloc(avctx, q);
} else {
/* make a copy if the input is not padded as libmfx requires */
if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) {
- qf->frame->height = FFALIGN(frame->height, 32);
+ qf->frame->height = FFALIGN(frame->height, q->height_align);
qf->frame->width = FFALIGN(frame->width, q->width_align);
ret = ff_get_buffer(q->avctx, qf->frame, AV_GET_BUFFER_FLAG_REF);