diff options
-rw-r--r-- | contrib/x265/A01-x265-multiple-inclusion.patch | 12 | ||||
-rw-r--r-- | contrib/x265/module.defs | 2 | ||||
-rw-r--r-- | libhb/enc_qsv.c | 23 | ||||
-rw-r--r-- | libhb/encx265.c | 126 |
4 files changed, 99 insertions, 64 deletions
diff --git a/contrib/x265/A01-x265-multiple-inclusion.patch b/contrib/x265/A01-x265-multiple-inclusion.patch deleted file mode 100644 index b88a7e0ee..000000000 --- a/contrib/x265/A01-x265-multiple-inclusion.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -r 527d03c56d68 source/x265.h ---- a/source/x265.h Tue Mar 04 03:13:00 2014 +0530 -+++ b/source/x265.h Fri Mar 14 16:08:12 2014 +0100 -@@ -240,7 +240,7 @@ - int height[3]; - } x265_cli_csp; - --const x265_cli_csp x265_cli_csps[] = -+static const x265_cli_csp x265_cli_csps[] = - { - { 1, { 0, 0, 0 }, { 0, 0, 0 } }, /* i400 */ - { 3, { 0, 1, 1 }, { 0, 1, 1 } }, /* i420 */ diff --git a/contrib/x265/module.defs b/contrib/x265/module.defs index e744549a8..1606c9629 100644 --- a/contrib/x265/module.defs +++ b/contrib/x265/module.defs @@ -1,7 +1,7 @@ $(eval $(call import.MODULE.defs,X265,x265,YASM)) $(eval $(call import.CONTRIB.defs,X265)) -X265.FETCH.url = http://download.handbrake.fr/contrib/x265-6356-527d03c56d68-0.8.tar.bz2 +X265.FETCH.url = http://download.handbrake.fr/contrib/x265-6657-82bbd2bf3b49-0.9.tar.bz2 X265.CONFIGURE.exe = cmake X265.CONFIGURE.args.prefix = -DCMAKE_INSTALL_PREFIX="$(X265.CONFIGURE.prefix)" diff --git a/libhb/enc_qsv.c b/libhb/enc_qsv.c index a545c8960..e036c8115 100644 --- a/libhb/enc_qsv.c +++ b/libhb/enc_qsv.c @@ -77,7 +77,6 @@ struct hb_work_private_s av_qsv_space enc_space; hb_qsv_info_t *qsv_info; - mfxEncodeCtrl force_keyframe; hb_list_t *delayed_chapters; int64_t next_chapter_pts; @@ -406,14 +405,6 @@ int encqsvInit(hb_work_object_t *w, hb_job_t *job) pv->encoded_frames = hb_list_init(); pv->last_start = INT64_MIN; - // set up a re-usable mfxEncodeCtrl to force keyframes (e.g. for chapters) - pv->force_keyframe.QP = 0; - pv->force_keyframe.FrameType = MFX_FRAMETYPE_I|MFX_FRAMETYPE_IDR|MFX_FRAMETYPE_REF; - pv->force_keyframe.NumExtParam = 0; - pv->force_keyframe.NumPayload = 0; - pv->force_keyframe.ExtParam = NULL; - pv->force_keyframe.Payload = NULL; - pv->next_chapter_pts = AV_NOPTS_VALUE; pv->delayed_chapters = hb_list_init(); @@ -1565,8 +1556,9 @@ fail: *pv->job->die = 1; } -static int qsv_enc_work(hb_work_private_t *pv, av_qsv_list *qsv_atom, - mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface) +static int qsv_enc_work(hb_work_private_t *pv, + av_qsv_list *qsv_atom, + mfxFrameSurface1 *surface) { mfxStatus sts; av_qsv_context *qsv_ctx = pv->job->qsv.ctx; @@ -1586,7 +1578,7 @@ static int qsv_enc_work(hb_work_private_t *pv, av_qsv_list *qsv_atom, do { sts = MFXVideoENCODE_EncodeFrameAsync(qsv_ctx->mfx_session, - ctrl, surface, task->bs, + NULL, surface, task->bs, qsv_enc_space->p_syncp[sync_idx]->p_sync); if (sts == MFX_ERR_MORE_DATA || (sts >= MFX_ERR_NONE && @@ -1741,14 +1733,13 @@ int encqsvWork(hb_work_object_t *w, hb_buffer_t **buf_in, hb_buffer_t **buf_out) */ if (in->size <= 0) { - qsv_enc_work(pv, NULL, NULL, NULL); + qsv_enc_work(pv, NULL, NULL); hb_list_add(pv->encoded_frames, in); *buf_out = link_buffer_list(pv->encoded_frames); *buf_in = NULL; // don't let 'work_loop' close this buffer return HB_WORK_DONE; } - mfxEncodeCtrl *ctrl = NULL; mfxFrameSurface1 *surface = NULL; av_qsv_list *qsv_atom = NULL; av_qsv_context *qsv_ctx = job->qsv.ctx; @@ -1823,7 +1814,7 @@ int encqsvWork(hb_work_object_t *w, hb_buffer_t **buf_in, hb_buffer_t **buf_out) { mfxStatus sts; - if (encode_loop(pv, NULL, NULL) < 0) + if (qsv_enc_work(pv, NULL, NULL) < 0) { goto fail; } @@ -1861,7 +1852,7 @@ int encqsvWork(hb_work_object_t *w, hb_buffer_t **buf_in, hb_buffer_t **buf_out) /* * Now that the input surface is setup, we can encode it. */ - if (qsv_enc_work(pv, qsv_atom, ctrl, surface) < 0) + if (qsv_enc_work(pv, qsv_atom, surface) < 0) { goto fail; } diff --git a/libhb/encx265.c b/libhb/encx265.c index 7ed280371..37f4a2a4e 100644 --- a/libhb/encx265.c +++ b/libhb/encx265.c @@ -76,7 +76,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) pv->delayed_chapters = hb_list_init(); pv->job = job; w->private_data = pv; - int i, vrate, vrate_base; + int ret, vrate, vrate_base; x265_nal *nal; uint32_t nnal; @@ -85,9 +85,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) if (x265_param_default_preset(param, job->encoder_preset, job->encoder_tune) < 0) { - free(pv); - pv = NULL; - return 1; + goto fail; } /* If the PSNR or SSIM tunes are in use, enable the relevant metric */ @@ -123,13 +121,56 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) param->keyframeMin = (int)((double)vrate / (double)vrate_base + 0.5); param->keyframeMax = param->keyframeMin * 10; + /* + * Video Signal Type (color description only). + * + * Use x265_param_parse (let x265 determine which bEnable + * flags, if any, should be set in the x264_param struct). + */ + char colorprim[11], transfer[11], colormatrix[11]; + switch (job->color_matrix_code) + { + case 1: // ITU BT.601 DVD or SD TV content (NTSC) + strcpy(colorprim, "smpte170m"); + strcpy(transfer, "bt709"); + strcpy(colormatrix, "smpte170m"); + break; + case 2: // ITU BT.601 DVD or SD TV content (PAL) + strcpy(colorprim, "bt470bg"); + strcpy(transfer, "bt709"); + strcpy(colormatrix, "smpte170m"); + break; + case 3: // ITU BT.709 HD content + strcpy(colorprim, "bt709"); + strcpy(transfer, "bt709"); + strcpy(colormatrix, "bt709"); + break; + case 4: // custom + snprintf(colorprim, sizeof(colorprim), "%d", job->color_prim); + snprintf(transfer, sizeof(transfer), "%d", job->color_transfer); + snprintf(colormatrix, sizeof(colormatrix), "%d", job->color_matrix); + break; + default: // detected during scan + snprintf(colorprim, sizeof(colorprim), "%d", job->title->color_prim); + snprintf(transfer, sizeof(transfer), "%d", job->title->color_transfer); + snprintf(colormatrix, sizeof(colormatrix), "%d", job->title->color_matrix); + break; + } + if (x265_param_parse(param, "colorprim", colorprim) || + x265_param_parse(param, "transfer", transfer) || + x265_param_parse(param, "colormatrix", colormatrix)) + { + hb_error("encx265: failed to set VUI color description"); + goto fail; + } + /* iterate through x265_opts and parse the options */ hb_dict_entry_t *entry = NULL; hb_dict_t *x265_opts = hb_encopts_to_dict(job->encoder_options, job->vcodec); while ((entry = hb_dict_next(x265_opts, entry)) != NULL) { // here's where the strings are passed to libx265 for parsing - int ret = x265_param_parse(param, entry->key, entry->value); + ret = x265_param_parse(param, entry->key, entry->value); // let x265 sanity check the options for us switch (ret) { @@ -147,11 +188,36 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) hb_dict_free(&x265_opts); /* + * Reload colorimetry settings in case custom + * values were set in the encoder_options string. + */ + job->color_matrix_code = 4; + job->color_prim = param->vui.colorPrimaries; + job->color_transfer = param->vui.transferCharacteristics; + job->color_matrix = param->vui.matrixCoeffs; + + /* * Settings which can't be overriden in the encodeer_options string * (muxer-specific settings, resolution, ratecontrol, etc.). */ - param->sourceWidth = job->width; - param->sourceHeight = job->height; + param->bRepeatHeaders = 0; + param->sourceWidth = job->width; + param->sourceHeight = job->height; + if (job->anamorphic.mode) + { + /* + * Let x265 determnine whether to use an aspect ratio + * index vs. the extended SAR index + SAR width/height. + */ + char sar[22]; + snprintf(sar, sizeof(sar), "%d:%d", + job->anamorphic.par_width, job->anamorphic.par_height); + if (x265_param_parse(param, "sar", sar)) + { + hb_error("encx265: failed to set SAR"); + goto fail; + } + } if (job->vquality > 0) { @@ -182,9 +248,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) /* Apply profile and level settings last. */ if (x265_param_apply_profile(param, job->encoder_profile) < 0) { - free(pv); - pv = NULL; - return 1; + goto fail; } /* we should now know whether B-frames are enabled */ @@ -195,17 +259,7 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) if (pv->x265 == NULL) { hb_error("encx265: x265_encoder_open failed."); - free(pv); - pv = NULL; - return 1; - } - - if (x265_encoder_headers(pv->x265, &nal, &nnal) < 0) - { - hb_error("encx265: x265_encoder_headers failed."); - free(pv); - pv = NULL; - return 1; + goto fail; } /* @@ -214,24 +268,26 @@ int encx265Init(hb_work_object_t *w, hb_job_t *job) * Write the header as is, and let the muxer reformat * the extradata and output bitstream properly for us. */ - w->config->h265.headers_length = 0; - for (i = 0; i < nnal; i++) + ret = x265_encoder_headers(pv->x265, &nal, &nnal); + if (ret < 0) { - if (w->config->h265.headers_length + - nal[i].sizeBytes > HB_CONFIG_MAX_SIZE) - { - hb_error("encx265: bitstream headers too large"); - free(pv); - pv = NULL; - return 1; - } - memcpy(w->config->h265.headers + - w->config->h265.headers_length, - nal[i].payload, nal[i].sizeBytes); - w->config->h265.headers_length += nal[i].sizeBytes; + hb_error("encx265: x265_encoder_headers failed (%d)", ret); + goto fail; + } + if (ret > sizeof(w->config->h265.headers)) + { + hb_error("encx265: bitstream headers too large (%d)", ret); + goto fail; } + memcpy(w->config->h265.headers, nal->payload, ret); + w->config->h265.headers_length = ret; return 0; + +fail: + w->private_data = NULL; + free(pv); + return 1; } void encx265Close(hb_work_object_t *w) |