/* initialize the new element * instantiate pads and add them to element * set functions * initialize structure */ static void gst_x265_enc_init (GstX265Enc * encoder) { x265_param_default (&encoder->x265param); encoder->push_header = TRUE; encoder->bitrate = PROP_BITRATE_DEFAULT; encoder->qp = PROP_QP_DEFAULT; encoder->option_string_prop = g_string_new (PROP_OPTION_STRING_DEFAULT); encoder->log_level = PROP_LOG_LEVEL_DEFAULT; encoder->speed_preset = PROP_SPEED_PRESET_DEFAULT; encoder->tune = PROP_TUNE_DEFAULT; }
static int set_params(struct videnc_state *st, unsigned fps, unsigned bitrate) { st->param = x265_param_alloc(); if (!st->param) { warning("h265: x265_param_alloc failed\n"); return ENOMEM; } x265_param_default(st->param); if (0 != x265_param_apply_profile(st->param, "main")) { warning("h265: x265_param_apply_profile failed\n"); return EINVAL; } if (0 != x265_param_default_preset(st->param, "ultrafast", "zerolatency")) { warning("h265: x265_param_default_preset error\n"); return EINVAL; } st->param->fpsNum = fps; st->param->fpsDenom = 1; /* VPS, SPS and PPS headers should be output with each keyframe */ st->param->bRepeatHeaders = 1; /* Rate Control */ st->param->rc.rateControlMode = X265_RC_CRF; st->param->rc.bitrate = bitrate / 1000; st->param->rc.vbvMaxBitrate = bitrate / 1000; st->param->rc.vbvBufferSize = 2 * bitrate / fps; return 0; }
static av_cold int libx265_encode_init(AVCodecContext *avctx) { libx265Context *ctx = avctx->priv_data; x265_nal *nal; uint8_t *buf; int nnal; int ret; int i; avctx->coded_frame = av_frame_alloc(); if (!avctx->coded_frame) { av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); return AVERROR(ENOMEM); } ctx->params = x265_param_alloc(); if (!ctx->params) { av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n"); return AVERROR(ENOMEM); } x265_param_default(ctx->params); if (x265_param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid preset or tune.\n"); return AVERROR(EINVAL); } ctx->params->frameNumThreads = avctx->thread_count; ctx->params->frameRate = (int) (avctx->time_base.den / avctx->time_base.num); ctx->params->sourceWidth = avctx->width; ctx->params->sourceHeight = avctx->height; ctx->params->inputBitDepth = av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1; if (avctx->bit_rate > 0) { ctx->params->rc.bitrate = avctx->bit_rate / 1000; ctx->params->rc.rateControlMode = X265_RC_ABR; } if (ctx->x265_opts) { AVDictionary *dict = NULL; AVDictionaryEntry *en = NULL; if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) { while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) { int parse_ret = x265_param_parse(ctx->params, en->key, en->value); switch (parse_ret) { case X265_PARAM_BAD_NAME: av_log(avctx, AV_LOG_WARNING, "Unknown option: %s.\n", en->key); break; case X265_PARAM_BAD_VALUE: av_log(avctx, AV_LOG_WARNING, "Invalid value for %s: %s.\n", en->key, en->value); break; default: break; } } av_dict_free(&dict); } } ctx->encoder = x265_encoder_open(ctx->params); if (!ctx->encoder) { av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n"); libx265_encode_close(avctx); return AVERROR_INVALIDDATA; } ret = x265_encoder_headers(ctx->encoder, &nal, &nnal); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n"); libx265_encode_close(avctx); return AVERROR_INVALIDDATA; } for (i = 0; i < nnal; i++) ctx->header_size += nal[i].sizeBytes; ctx->header = av_malloc(ctx->header_size); if (!ctx->header) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate HEVC header of size %d.\n", ctx->header_size); libx265_encode_close(avctx); return AVERROR(ENOMEM); } buf = ctx->header; for (i = 0; i < nnal; i++) { memcpy(buf, nal[i].payload, nal[i].sizeBytes); buf += nal[i].sizeBytes; } return 0; }
/** \fn setup */ bool x265Encoder::setup(void) { ADM_info("=============x265, setting up==============\n"); MMSET(param); x265_param_default( ¶m); firstIdr=true; image=new ADMImageDefault(getWidth(),getHeight()); // -------------- preset, tune, idc ------------ if(!x265Settings.useAdvancedConfiguration) { char tune[200] = {0}; strcat(tune, x265Settings.general.tuning); x265_param_default_preset(¶m, x265Settings.general.preset, tune); } param.logLevel=x265Settings.level; // Threads.. #if X265_BUILD < 47 switch(x265Settings.general.poolThreads) { case 0: case 1: case 2: param.poolNumThreads = x265Settings.general.poolThreads; break; case 99: break; //auto default: ADM_error("UNKNOWN NB OF THREADS\n"); break; } #endif switch(x265Settings.general.frameThreads) { case 0: case 1: case 2: param.frameNumThreads = x265Settings.general.frameThreads; break; case 99: break; //auto default: ADM_error("UNKNOWN NB OF THREADS\n"); break; } param.sourceWidth = getWidth(); param.sourceHeight = getHeight(); param.internalCsp = X265_CSP_I420; param.internalBitDepth = 8; param.logLevel=X265_LOG_INFO; //DEBUG; //INFO; //Framerate int n,d; uint64_t f=source->getInfo()->frameIncrement; usSecondsToFrac(f,&n,&d); param.fpsNum = d; param.fpsDenom = n; // -------------- vui------------ #undef MKPARAM #undef MKPARAMD #undef MKPARAMB #define MKPARAM(x,y) {param.vui.x = x265Settings.vui.y;aprintf("[x265] vui."#x" = %d\n",param.vui.x);} #define MKPARAMD(x,y) {param.vui.x = (double)x265Settings.vui.y; aprintf("[x265] vui."#x" = %.2f\n",param.vui.x);} #define MKPARAMB(x,y) {param.vui.x = x265Settings.vui.y ;aprintf("[x265] vui."#x" = %s\n",TrueFalse[param.vui.x&1]);} MKPARAM (sarWidth,sar_width) MKPARAM (sarHeight,sar_height) // -------------- rate control------------ switch(x265Settings.general.params.mode) { case COMPRESS_2PASS: case COMPRESS_2PASS_BITRATE: uint32_t bitrate; if(passNumber!=1 && passNumber!=2) { ADM_error("No pass number specified! (%d)\n",(int)passNumber); return false; } ADM_info("Starting pass :%d\n",passNumber); if(x265Settings.general.params.mode==COMPRESS_2PASS) { uint64_t duration=source->getInfo()->totalDuration; // in us ADM_info("Source duration :%s\n",ADM_us2plain(duration)); ADM_info("Target size :%d\n",(int)x265Settings.general.params.finalsize); uint32_t avg; if(false==ADM_computeAverageBitrateFromDuration(duration, x265Settings.general.params.finalsize, &avg)) { ADM_error("[x265] No source duration!\n"); return false; } bitrate=(uint32_t)avg; } else bitrate=x265Settings.general.params.avg_bitrate; ADM_info("Using average bitrate of %d kb/s\n",(int)bitrate); param.rc.rateControlMode = X265_RC_ABR; param.rc.bitrate = bitrate; if(passNumber==1) { param.rc.bStatWrite=1; param.rc.bStatRead=0; param.rc.statFileName=strdup(logFile); } else { param.rc.bStatWrite=0; param.rc.bStatRead=1; param.rc.statFileName=strdup(logFile); if(!ADM_fileExist(logFile)) { ADM_error("Logfile %s does not exist \n",logFile); return false; } } break; case COMPRESS_AQ: param.rc.rateControlMode = X265_RC_CRF; param.rc.rfConstant = x265Settings.general.params.qz; break; case COMPRESS_CQ: param.rc.rateControlMode = X265_RC_CQP; param.rc.qp = x265Settings.general.params.qz; break; case COMPRESS_CBR: param.rc.rateControlMode = X265_RC_ABR; param.rc.bitrate = x265Settings.general.params.bitrate; param.rc.qp = 0; param.rc.rfConstant = 0; break; default: GUI_Error_HIG("Not coded","this mode has notbeen implemented\n"); return false; break; } if(globalHeader) param.bRepeatHeaders=0; else param.bRepeatHeaders=1; if(x265Settings.useAdvancedConfiguration) { #undef MKPARAM #undef MKPARAMD #undef MKPARAMB #define MKPARAM(x,y) {param.x = x265Settings.y;aprintf("[x265] "#x" = %d\n",param.x);} #define MKPARAMD(x,y) {param.x = (double)x265Settings.y; aprintf("[x265] "#x" = %.2f\n",param.x);} #define MKPARAMB(x,y) {param.x = x265Settings.y ;aprintf("[x265] "#x" = %s\n",TrueFalse[param.x&1]);} MKPARAM(maxNumReferences,MaxRefFrames); MKPARAM(keyframeMin,MinIdr); MKPARAM(keyframeMax,MaxIdr); MKPARAM(scenecutThreshold,i_scenecut_threshold); MKPARAM(bframes,MaxBFrame); MKPARAM(bFrameAdaptive,i_bframe_adaptive); MKPARAM(bFrameBias,i_bframe_bias); MKPARAM(bBPyramid,i_bframe_pyramid); MKPARAMB(bEnableLoopFilter,b_deblocking_filter); MKPARAMB(interlaceMode,interlaced_mode); MKPARAMB(bEnableConstrainedIntra,constrained_intra); MKPARAM(lookaheadDepth,lookahead); MKPARAMB(bEnableWeightedBiPred,weighted_bipred) MKPARAM (bEnableWeightedPred,weighted_pred) MKPARAM (cbQpOffset,cb_chroma_offset) MKPARAM (crQpOffset,cr_chroma_offset) MKPARAM (searchMethod,me_method) MKPARAM (searchRange,me_range) MKPARAM (subpelRefine,subpel_refine) MKPARAM (bFrameAdaptive,trellis) MKPARAMB(bEnableEarlySkip,fast_pskip) MKPARAMB(bEnableTSkipFast,dct_decimate) MKPARAMD(psyRd,psy_rd) #if X265_BUILD >= 40 MKPARAM (noiseReductionIntra,noise_reduction_intra) MKPARAM (noiseReductionInter,noise_reduction_inter) #else MKPARAM (noiseReduction,noise_reduction) #endif //---------------- ratecontrol ------------------- #undef MKPARAM #undef MKPARAMD #undef MKPARAMB #define MKPARAM(x,y) {param.rc.x = x265Settings.ratecontrol.y;aprintf("[x265] rc."#x" = %d\n",param.rc.x);} #define MKPARAMD(x,y) {param.rc.x = (double)x265Settings.ratecontrol.y; aprintf("[x265] rc."#x" = %.2f\n",param.rc.x);} #define MKPARAMB(x,y) {param.rc.x = x265Settings.ratecontrol.y ;aprintf("[x265] rc."#x" = %s\n",TrueFalse[param.rc.x&1]);} MKPARAM(qpStep,qp_step); #if X265_BUILD >= 41 MKPARAMB(bStrictCbr,strict_cbr); #else MKPARAM(rateTolerance,rate_tolerance); #endif MKPARAM(ipFactor,ip_factor); MKPARAM(pbFactor,pb_factor); MKPARAMB(cuTree,cu_tree); MKPARAM(aqMode,aq_mode); MKPARAMD(aqStrength,aq_strength); } if(!param.bframes) encoderDelay=0; else { if(2>=param.maxNumReferences) { encoderDelay=f*2*2; } else { encoderDelay=2*f*(x265Settings.MaxRefFrames-1); } } if(!x265Settings.useAdvancedConfiguration) { x265_param_apply_profile(¶m, x265Settings.general.profile); } dumpx265Setup(¶m); ADM_info("Creating x265 encoder\n"); handle = x265_encoder_open (¶m); if (!handle) { ADM_error("Cannot initialize x265\n"); return 0; } ADM_info("x265, setup ok\n"); if (globalHeader) { ADM_info("Creating global header\n"); return createHeader (); } else ADM_info("No need for global header\n"); return true; }
static int Open (vlc_object_t *p_this) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys; if (p_enc->fmt_out.i_codec != VLC_CODEC_HEVC && !p_enc->b_force) return VLC_EGENERIC; p_enc->fmt_out.i_cat = VIDEO_ES; p_enc->fmt_out.i_codec = VLC_CODEC_HEVC; p_enc->p_sys = p_sys = malloc(sizeof(encoder_sys_t)); if (!p_sys) return VLC_ENOMEM; p_enc->fmt_in.i_codec = VLC_CODEC_I420; x265_param *param = &p_sys->param; x265_param_default(param); param->frameNumThreads = vlc_GetCPUCount(); param->bEnableWavefront = 0; // buggy in x265, use frame threading for now param->maxCUSize = 16; /* use smaller macroblock */ #if X265_BUILD >= 6 param->fpsNum = p_enc->fmt_in.video.i_frame_rate; param->fpsDenom = p_enc->fmt_in.video.i_frame_rate_base; if (!param->fpsNum) { param->fpsNum = 25; param->fpsDenom = 1; } #else if (p_enc->fmt_in.video.i_frame_rate_base) { param->frameRate = p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base; } else { param->frameRate = 25; } #endif param->sourceWidth = p_enc->fmt_in.video.i_visible_width; param->sourceHeight = p_enc->fmt_in.video.i_visible_height; if (param->sourceWidth & (param->maxCUSize - 1)) { msg_Err(p_enc, "Width (%d) must be a multiple of %d", param->sourceWidth, param->maxCUSize); free(p_sys); return VLC_EGENERIC; } if (param->sourceHeight & 7) { msg_Err(p_enc, "Height (%d) must be a multiple of 8", param->sourceHeight); free(p_sys); return VLC_EGENERIC; } if (p_enc->fmt_out.i_bitrate > 0) { param->rc.bitrate = p_enc->fmt_out.i_bitrate / 1000; param->rc.rateControlMode = X265_RC_ABR; } p_sys->h = x265_encoder_open(param); if (p_sys->h == NULL) { msg_Err(p_enc, "cannot open x265 encoder"); free(p_sys); return VLC_EGENERIC; } x265_nal *nal; uint32_t i_nal; if (x265_encoder_headers(p_sys->h, &nal, &i_nal) < 0) { msg_Err(p_enc, "cannot get x265 headers"); Close(VLC_OBJECT(p_enc)); return VLC_EGENERIC; } size_t i_extra = 0; for (uint32_t i = 0; i < i_nal; i++) i_extra += nal[i].sizeBytes; p_enc->fmt_out.i_extra = i_extra; uint8_t *p_extra = p_enc->fmt_out.p_extra = malloc(i_extra); if (!p_extra) { Close(VLC_OBJECT(p_enc)); return VLC_ENOMEM; } for (uint32_t i = 0; i < i_nal; i++) { memcpy(p_extra, nal[i].payload, nal[i].sizeBytes); p_extra += nal[i].sizeBytes; } p_sys->dts = 0; p_sys->initial_date = 0; p_sys->i_initial_delay = 0; p_enc->pf_encode_video = Encode; p_enc->pf_encode_audio = NULL; return VLC_SUCCESS; }