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 &param)
{
    //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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}