summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/qsv_filter.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/libhb/qsv_filter.c b/libhb/qsv_filter.c
index 5bc61fd9e..c2e328e48 100644
--- a/libhb/qsv_filter.c
+++ b/libhb/qsv_filter.c
@@ -47,6 +47,12 @@ struct hb_filter_private_s
int deinterlace;
int is_frc_used;
+ // set during init, used to configure input surfaces' "area of interest"
+ mfxU16 CropX;
+ mfxU16 CropY;
+ mfxU16 CropH;
+ mfxU16 CropW;
+
av_qsv_space *vpp_space;
// FRC param(s)
@@ -145,31 +151,56 @@ static int filter_init( av_qsv_context* qsv, hb_filter_private_t * pv ){
qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.FrameRateExtD = pv->job->title->rate_base;
}
+ /*
+ * In theory, input width/height and decode CropW/CropH should be the
+ * same; however, due to some versions of Libav not applying the H.264
+ * "crop rect" properly, there can be a mismatch.
+ *
+ * Since we want the same bahevior regardless of whether we're using
+ * software or hardware-accelerated decoding, prefer the Libav values.
+ *
+ * Note that since CropW/CropH may be higher than the decode values, we
+ * need to adjust CropX/CropY to make sure we don't exceed the input's
+ * Width/Height boundaries.
+ */
+ pv->CropW = pv-> width_in;
+ pv->CropH = pv->height_in;
+ pv->CropX = FFMIN(qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.CropX,
+ qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.Width - pv->CropW);
+ pv->CropY = FFMIN(qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.CropY,
+ qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.Height - pv->CropH);
+ /* Then, apply additional cropping requested by the user, if any */
+ pv->CropX += pv->crop[2];
+ pv->CropY += pv->crop[0];
+ pv->CropW -= pv->crop[2] + pv->crop[3];
+ pv->CropH -= pv->crop[0] + pv->crop[1];
+
+
qsv_vpp->m_mfxVideoParam.vpp.In.FourCC = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.FourCC;
qsv_vpp->m_mfxVideoParam.vpp.In.ChromaFormat = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.ChromaFormat;
- qsv_vpp->m_mfxVideoParam.vpp.In.CropX = pv->crop[2];
- qsv_vpp->m_mfxVideoParam.vpp.In.CropY = pv->crop[0];
- qsv_vpp->m_mfxVideoParam.vpp.In.CropW = pv-> width_in - pv->crop[3] - pv->crop[2];
- qsv_vpp->m_mfxVideoParam.vpp.In.CropH = pv->height_in - pv->crop[1] - pv->crop[0];
qsv_vpp->m_mfxVideoParam.vpp.In.FrameRateExtN = pv->job->vrate;
qsv_vpp->m_mfxVideoParam.vpp.In.FrameRateExtD = pv->job->vrate_base;
qsv_vpp->m_mfxVideoParam.vpp.In.AspectRatioW = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.AspectRatioW;
qsv_vpp->m_mfxVideoParam.vpp.In.AspectRatioH = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.AspectRatioH;
qsv_vpp->m_mfxVideoParam.vpp.In.Width = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.Width;
qsv_vpp->m_mfxVideoParam.vpp.In.Height = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.Height;
+ qsv_vpp->m_mfxVideoParam.vpp.In.CropX = pv->CropX;
+ qsv_vpp->m_mfxVideoParam.vpp.In.CropY = pv->CropY;
+ qsv_vpp->m_mfxVideoParam.vpp.In.CropW = pv->CropW;
+ qsv_vpp->m_mfxVideoParam.vpp.In.CropH = pv->CropH;
qsv_vpp->m_mfxVideoParam.vpp.Out.FourCC = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.FourCC;
qsv_vpp->m_mfxVideoParam.vpp.Out.ChromaFormat = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.ChromaFormat;
- qsv_vpp->m_mfxVideoParam.vpp.Out.CropX = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.CropX;
- qsv_vpp->m_mfxVideoParam.vpp.Out.CropY = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.CropY;
- qsv_vpp->m_mfxVideoParam.vpp.Out.CropW = pv->width_out;
- qsv_vpp->m_mfxVideoParam.vpp.Out.CropH = pv->height_out;
qsv_vpp->m_mfxVideoParam.vpp.Out.FrameRateExtN = pv->job->vrate;
qsv_vpp->m_mfxVideoParam.vpp.Out.FrameRateExtD = pv->job->vrate_base;
qsv_vpp->m_mfxVideoParam.vpp.Out.AspectRatioW = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.AspectRatioW;
qsv_vpp->m_mfxVideoParam.vpp.Out.AspectRatioH = qsv->dec_space->m_mfxVideoParam.mfx.FrameInfo.AspectRatioH;
qsv_vpp->m_mfxVideoParam.vpp.Out.Width = pv->job->qsv.enc_info.align_width;
qsv_vpp->m_mfxVideoParam.vpp.Out.Height = pv->job->qsv.enc_info.align_height;
+ qsv_vpp->m_mfxVideoParam.vpp.Out.CropX = 0; // no letterboxing
+ qsv_vpp->m_mfxVideoParam.vpp.Out.CropY = 0; // no pillarboxing
+ qsv_vpp->m_mfxVideoParam.vpp.Out.CropW = pv-> width_out;
+ qsv_vpp->m_mfxVideoParam.vpp.Out.CropH = pv->height_out;
qsv_vpp->m_mfxVideoParam.IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY | MFX_IOPATTERN_OUT_OPAQUE_MEMORY;
@@ -463,11 +494,12 @@ int process_frame(av_qsv_list* received_item, av_qsv_context* qsv, hb_filter_pri
ret = 0;
break;
}
- if (work_surface) {
- work_surface->Info.CropX = pv->crop[2];
- work_surface->Info.CropY = pv->crop[0];
- work_surface->Info.CropW = pv->width_in - pv->crop[3] - pv->crop[2];
- work_surface->Info.CropH = pv->height_in - pv->crop[1] - pv->crop[0];
+ if (work_surface != NULL)
+ {
+ work_surface->Info.CropX = pv->CropX;
+ work_surface->Info.CropY = pv->CropY;
+ work_surface->Info.CropW = pv->CropW;
+ work_surface->Info.CropH = pv->CropH;
}
sts = MFXVideoVPP_RunFrameVPPAsync(qsv->mfx_session, work_surface, qsv_vpp->p_surfaces[surface_idx] , NULL, qsv_vpp->p_syncp[sync_idx]->p_sync);