static int x265_close(HEVCEncoderContext *s, uint8_t **pbuf) { int buf_len, ret, i; uint32_t nal_count; x265_nal *p_nal; /* get last compressed pictures */ for(;;) { ret = x265_encoder_encode(s->enc, &p_nal, &nal_count, NULL, NULL); if (ret <= 0) break; for(i = 0; i < nal_count; i++) { add_nal(s, p_nal[i].payload, p_nal[i].sizeBytes); } } if (s->buf_len < s->buf_size) { s->buf = realloc(s->buf, s->buf_len); } *pbuf = s->buf; buf_len = s->buf_len; x265_encoder_close(s->enc); x265_picture_free(s->pic); free(s); return buf_len; }
void Video_Encoder_H265::release() { if(_x265_param) { x265_param_free(_x265_param); } if(_x265_picture) { x265_picture_free(_x265_picture); } if(_x265_encoder) { x265_encoder_close(_x265_encoder); } x265_cleanup() ; }
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; }
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; }