VideoEncoderX265::VideoEncoderX265(FilterRole fRole, bool sharedFrames) : VideoEncoderX264or5(fRole, sharedFrames), encoder(NULL) { pts = 0; xparams = x265_param_alloc(); picIn = x265_picture_alloc(); picOut = x265_picture_alloc(); }
bool Video_Encoder_H265::init(Video_Encoder::NALU_CB *cb, const Encoder_Param ¶m) { //alloc & set param _x265_param = x265_param_alloc(); if(_x265_param == NULL) { printf("x265_param_alloc error~\n"); return false; } // x265_param_default(_x265_param); /* x265_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 }; x265_tune_names[] = { "psnr", "ssim", "grain", "zerolatency", "fastdecode", 0 };*/ int rc = x265_param_default_preset(_x265_param, x265_preset_names[4], x265_tune_names[3]); if(rc != 0) { //error... printf("x265_param_default_preset error~\n"); return false; } /*x265_profile_names[] = { "main", "main10", "mainstillpicture", 0 };*/ rc = x265_param_apply_profile(_x265_param, x265_profile_names[0]); if(rc != 0) { //error... printf("x265_param_apply_profile error~\n"); return false; } _x265_param->sourceHeight = param.height; _x265_param->sourceWidth = param.width; /*The output of the encoder is a series of NAL packets, which are always returned concatenated in consecutive memory. * HEVC streams have SPS and PPS and VPS headers which describe how the following packets are to be decoded. * If you specified --repeat-headers then those headers will be output with every keyframe. * Otherwise you must explicitly query those headers using:int x265_encoder_headers(x265_encoder *, x265_nal **pp_nal, uint32_t *pi_nal);*/ _x265_param->bRepeatHeaders = 1; _x265_param->internalCsp = X265_CSP_I420; _x265_param->fpsNum = param.fps; _x265_param->fpsDenom = 1; // x265_param_parse(_x265_param, const char *name, const char *value); /******* x265_encoder_parameters() may be used to get a copy of the param structure from the encoder after it has been opened, in order to see the changes made to the parameters for auto-detection and other reasons. x265_encoder_reconfig() may be used to reconfigure encoder parameters mid-encode: *********/ // rc = x265_encoder_reconfig(_x265_encoder, _x265_param); _x265_picture = x265_picture_alloc(); if(_x265_picture == NULL) { if(_x265_param) { x265_param_free(_x265_param); } printf("x265_picture_alloc error~\n"); return false; } x265_picture_init(_x265_param, _x265_picture); //Analysis Buffers // rc = x265_alloc_analysis_data(_x265_picture); // if(rc == 0) // { // //error... // } // x265_free_analysis_data(_x265_picture); // _x265_encoder = x265_encoder_open(_x265_param); if(_x265_encoder == NULL) { if(_x265_param) { x265_param_free(_x265_param); } if(_x265_picture) { x265_picture_free(_x265_picture); } printf("x265_encoder_open error~\n"); return false; } _callback = cb; gettimeofday(&_tv_start, NULL); return true; }
static HEVCEncoderContext *x265_open(const HEVCEncodeParams *params) { HEVCEncoderContext *s; x265_param *p; int preset_index; const char *preset; s = malloc(sizeof(HEVCEncoderContext)); memset(s, 0, sizeof(*s)); if (params->bit_depth != x265_max_bit_depth) { fprintf(stderr, "x265 is compiled to support only %d bit depth. Use the '-b %d' option to force the bit depth.\n", x265_max_bit_depth, x265_max_bit_depth); return NULL; } if (params->chroma_format == BPG_FORMAT_GRAY) { fprintf(stderr, "x265 does not support monochrome (or alpha) data yet. Plase use the jctvc encoder.\n"); return NULL; } p = x265_param_alloc(); preset_index = params->compress_level; /* 9 is placebo */ preset = x265_preset_names[preset_index]; if (params->verbose) printf("Using x265 preset: %s\n", preset); x265_param_default_preset(p, preset, "ssim"); p->bRepeatHeaders = 1; p->decodedPictureHashSEI = params->sei_decoded_picture_hash; p->sourceWidth = params->width; p->sourceHeight = params->height; switch(params->chroma_format) { case BPG_FORMAT_GRAY: p->internalCsp = X265_CSP_I400; break; case BPG_FORMAT_420: p->internalCsp = X265_CSP_I420; break; case BPG_FORMAT_422: p->internalCsp = X265_CSP_I422; break; case BPG_FORMAT_444: p->internalCsp = X265_CSP_I444; break; default: abort(); } if (params->intra_only) { p->keyframeMax = 1; /* only I frames */ p->totalFrames = 1; } else { p->keyframeMax = 250; p->totalFrames = 0; p->maxNumReferences = 1; p->bframes = 0; } p->bEnableRectInter = 1; p->bEnableAMP = 1; /* cannot use 0 due to header restriction */ p->internalBitDepth = params->bit_depth; p->bEmitInfoSEI = 0; if (params->verbose) p->logLevel = X265_LOG_INFO; else p->logLevel = X265_LOG_NONE; /* dummy frame rate */ p->fpsNum = 25; p->fpsDenom = 1; p->rc.rateControlMode = X265_RC_CQP; /* XXX: why do we need this offset to match the JCTVC quality ? */ if (params->bit_depth == 10) p->rc.qp = params->qp + 7; else p->rc.qp = params->qp + 1; p->bLossless = params->lossless; s->enc = x265_encoder_open(p); s->pic = x265_picture_alloc(); x265_picture_init(p, s->pic); s->pic->colorSpace = p->internalCsp; x265_param_free(p); return s; }
int h265_encode(struct videnc_state *st, bool update, const struct vidframe *frame, videnc_packet_h *pkth, void *arg) { x265_picture *pic_in = NULL, pic_out; x265_nal *nalv; uint32_t i, nalc = 0; int n, err = 0; if (!st || !frame || !pkth || frame->fmt != VID_FMT_YUV420P) return EINVAL; if (!st->x265 || !vidsz_cmp(&st->size, &frame->size)) { err = open_encoder(st, &frame->size); if (err) return err; st->size = frame->size; } if (update) { debug("h265: encode: picture update was requested\n"); } pic_in = x265_picture_alloc(); if (!pic_in) { warning("h265: x265_picture_alloc failed\n"); return ENOMEM; } x265_picture_init(st->param, pic_in); pic_in->sliceType = update ? X265_TYPE_IDR : X265_TYPE_AUTO; pic_in->pts = ++st->pts; /* XXX: add PTS to API */ pic_in->colorSpace = X265_CSP_I420; for (i=0; i<3; i++) { pic_in->planes[i] = frame->data[i]; pic_in->stride[i] = frame->linesize[i]; } /* NOTE: important to get the PTS of the "out" picture */ n = x265_encoder_encode(st->x265, &nalv, &nalc, pic_in, &pic_out); if (n <= 0) goto out; for (i=0; i<nalc; i++) { x265_nal *nal = &nalv[i]; uint8_t *p = nal->payload; size_t len = nal->sizeBytes; bool marker; #if 1 debug("h265: encode: %s type=%2d %s\n", h265_is_keyframe(nal->type) ? "<KEY>" : " ", nal->type, h265_nalunit_name(nal->type)); #endif h265_skip_startcode(&p, &len); /* XXX: use pic_out.pts */ marker = (i+1)==nalc; /* last NAL */ err = packetize(marker, p, len, st->pktsize, pkth, arg); if (err) goto out; } out: if (pic_in) x265_picture_free(pic_in); return err; }