diff options
author | Rodeo <[email protected]> | 2014-04-08 15:20:06 +0000 |
---|---|---|
committer | Rodeo <[email protected]> | 2014-04-08 15:20:06 +0000 |
commit | 3dc8be2e871d3ce026c359b08d0f5d81f675e8e3 (patch) | |
tree | 415d1768e31d51fc92199a36e96cb937e3c6f2c5 | |
parent | f838015dd636281979e2e4335f7fb0ad91d3013b (diff) |
QSV: always use our own DTS.
Previously, the DTS provided by MSDK was used
if it was available and the frame rate was constant.
Our own DTS is indentical to MSDK's (when the
frame rate is constant), but MSDK will sometimes
provide 1 or 2 bogus DTS over the duration of a
file, causing the encode to abort (lavf is picky).
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6158 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/enc_qsv.c | 98 |
1 files changed, 40 insertions, 58 deletions
diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c index 42f398188..04d3bf99b 100644 --- a/libhb/enc_qsv.c +++ b/libhb/enc_qsv.c @@ -79,10 +79,8 @@ struct hb_work_private_s int64_t next_chapter_pts; #define BFRM_DELAY_MAX 16 - // for DTS generation (when MSDK API < 1.6 or VFR) uint32_t *init_delay; int bfrm_delay; - int bfrm_workaround; int64_t init_pts[BFRM_DELAY_MAX + 1]; hb_list_t *list_dts; @@ -113,7 +111,6 @@ struct chapter_s int64_t start; }; -// for DTS generation (when MSDK API < 1.6 or VFR) static void hb_qsv_add_new_dts(hb_list_t *list, int64_t new_dts) { if (list != NULL) @@ -126,6 +123,7 @@ static void hb_qsv_add_new_dts(hb_list_t *list, int64_t new_dts) } } } + static int64_t hb_qsv_pop_next_dts(hb_list_t *list) { int64_t next_dts = INT64_MIN; @@ -1382,60 +1380,51 @@ static void compute_init_delay(hb_work_private_t *pv, mfxBitstream *bs) /* compute init_delay (in ticks) based on the DTS provided by MSDK. */ int64_t init_delay = bs->TimeStamp - bs->DecodeTimeStamp; - if (pv->job->cfr != 1) - { - /* variable frame rate video, so we need to generate our own DTS */ - pv->bfrm_workaround = 1; + /* + * we also need to know the delay in frames to generate DTS. + * + * compute it based on the init_delay and average frame duration, + * and account for potential rounding errors due to the timebase. + */ + double avg_frame_dur = ((double)pv->job->vrate_base / + (double)pv->job->vrate * 90000.); - /* - * we also need to know the delay in frames to generate DTS. - * - * compute it based on the init_delay and average frame duration, - * and account for potential rounding errors due to the timebase. - */ - double avg_frame_dur = ((double)pv->job->vrate_base / - (double)pv->job->vrate * 90000.); + pv->bfrm_delay = (init_delay + (avg_frame_dur / 2)) / avg_frame_dur; - pv->bfrm_delay = (init_delay + (avg_frame_dur / 2)) / avg_frame_dur; + if (pv->bfrm_delay < 1 || pv->bfrm_delay > BFRM_DELAY_MAX) + { + hb_log("compute_init_delay: " + "invalid delay %d (PTS: %"PRIu64", DTS: %"PRId64")", + pv->bfrm_delay, bs->TimeStamp, bs->DecodeTimeStamp); - if (pv->bfrm_delay < 1 || pv->bfrm_delay > BFRM_DELAY_MAX) + /* we have B-frames, the frame delay should be at least 1 */ + if (pv->bfrm_delay < 1) { - hb_log("compute_init_delay: " - "invalid delay %d (PTS: %"PRIu64", DTS: %"PRId64")", - pv->bfrm_delay, bs->TimeStamp, bs->DecodeTimeStamp); - - /* we have B-frames, the frame delay should be at least 1 */ - if (pv->bfrm_delay < 1) - { - mfxStatus sts; - mfxVideoParam videoParam; - mfxSession session = pv->job->qsv.ctx->mfx_session; + mfxStatus sts; + mfxVideoParam videoParam; + mfxSession session = pv->job->qsv.ctx->mfx_session; - memset(&videoParam, 0, sizeof(mfxVideoParam)); + memset(&videoParam, 0, sizeof(mfxVideoParam)); - sts = MFXVideoENCODE_GetVideoParam(session, &videoParam); - if (sts != MFX_ERR_NONE) - { - hb_log("compute_init_delay: " - "MFXVideoENCODE_GetVideoParam failed (%d)", sts); - pv->bfrm_delay = 1; - } - else - { - /* usually too large, but should cover all cases */ - pv->bfrm_delay = videoParam.mfx.GopRefDist - 1; - } + sts = MFXVideoENCODE_GetVideoParam(session, &videoParam); + if (sts != MFX_ERR_NONE) + { + hb_log("compute_init_delay: " + "MFXVideoENCODE_GetVideoParam failed (%d)", sts); + pv->bfrm_delay = 1; + } + else + { + /* usually too large, but should cover all cases */ + pv->bfrm_delay = FFMIN(pv->frames_in - 1, + videoParam.mfx.GopRefDist - 1); } - - pv->bfrm_delay = FFMIN(BFRM_DELAY_MAX, pv->bfrm_delay); } - pv->init_delay[0] = pv->init_pts[pv->bfrm_delay] - pv->init_pts[0]; - } - else - { - pv->init_delay[0] = init_delay; + pv->bfrm_delay = FFMIN(BFRM_DELAY_MAX, pv->bfrm_delay); } + + pv->init_delay[0] = pv->init_pts[pv->bfrm_delay] - pv->init_pts[0]; } else { @@ -1444,7 +1433,7 @@ static void compute_init_delay(hb_work_private_t *pv, mfxBitstream *bs) * * B-pyramid not possible here, so the delay in frames is always 1. */ - pv->bfrm_delay = pv->bfrm_workaround = 1; + pv->bfrm_delay = 1; pv->init_delay[0] = pv->init_pts[1] - pv->init_pts[0]; } @@ -1503,12 +1492,6 @@ static void qsv_bitstream_slurp(hb_work_private_t *pv, mfxBitstream *bs) { buf->s.renderOffset = hb_qsv_pop_next_dts(pv->list_dts); } - - /* if the DTS provided by MSDK is trustworthy, use it */ - if (!pv->bfrm_workaround) - { - buf->s.renderOffset = bs->DecodeTimeStamp; - } } /* check if B-pyramid is used even though it's disabled */ @@ -1525,10 +1508,9 @@ static void qsv_bitstream_slurp(hb_work_private_t *pv, mfxBitstream *bs) /* check for PTS < DTS */ if (buf->s.start < buf->s.renderOffset) { - hb_log("encqsv: PTS %"PRId64" < DTS %"PRId64" for " - "frame %d with type '%s' (bfrm_workaround: %d)", + hb_log("encqsv: PTS %"PRId64" < DTS %"PRId64" for frame %d with type '%s'", buf->s.start, buf->s.renderOffset, pv->frames_out + 1, - hb_qsv_frametype_name(bs->FrameType), pv->bfrm_workaround); + hb_qsv_frametype_name(bs->FrameType)); } /* @@ -1778,7 +1760,7 @@ int encqsvWork(hb_work_object_t *w, hb_buffer_t **buf_in, hb_buffer_t **buf_out) } pv->last_start = in->s.start; - /* for DTS generation (when MSDK API < 1.6 or VFR) */ + /* for DTS generation */ if (pv->frames_in <= BFRM_DELAY_MAX) { pv->init_pts[pv->frames_in] = in->s.start; |