Example #1
0
static GF_Err HEVC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd)
{
	GF_SystemRTInfo rti;
	const char *sOpt;
	u32 nb_threads = 1;
	HEVCDec *ctx = (HEVCDec*) ifcg->privateStack;

	if (gf_sys_get_rti(0, &rti, 0) ) {
		nb_threads = (rti.nb_cores>1) ? rti.nb_cores-1 : 1;
	}

	sOpt = gf_modules_get_option((GF_BaseInterface *)ifcg, "OpenHEVC", "NumThreads");
	if (!sOpt) {
		char szO[100];
		sprintf(szO, "%d", nb_threads);
		gf_modules_set_option((GF_BaseInterface *)ifcg, "OpenHEVC", "NumThreads", szO);
		ctx->nb_threads = nb_threads;
		GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[OpenHEVC] Initializing with %d threads\n", ctx->nb_threads));
	} else {
		ctx->nb_threads = atoi(sOpt);
		if (ctx->nb_threads > nb_threads) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[OpenHEVC] Initializing with %d threads but only %d available cores detected on the system\n", ctx->nb_threads, rti.nb_cores));
		}
	}

	sOpt = gf_modules_get_option((GF_BaseInterface *)ifcg, "OpenHEVC", "ThreadingType");
	if (sOpt && !strcmp(sOpt, "wpp")) ctx->threading_type = 2;
	else if (sOpt && !strcmp(sOpt, "frame+wpp")) ctx->threading_type = 4;
	else {
		ctx->threading_type = 1;
		if (!sOpt) gf_modules_set_option((GF_BaseInterface *)ifcg, "OpenHEVC", "ThreadingType", "frame");
	}
	sOpt = gf_modules_get_option((GF_BaseInterface *)ifcg, "Systems", "Output8bit");
	if (!sOpt) gf_modules_set_option((GF_BaseInterface *)ifcg, "Systems", "Output8bit", (ctx->display_bpp>8) ? "no" : "yes");
	if (sOpt && !strcmp(sOpt, "yes")) ctx->output_as_8bit = GF_TRUE;

	sOpt = gf_modules_get_option((GF_BaseInterface *)ifcg, "OpenHEVC", "CBUnits");
	if (!sOpt) gf_modules_set_option((GF_BaseInterface *)ifcg, "OpenHEVC", "CBUnits", "4");
	if (sOpt) ctx->output_cb_size = atoi(sOpt);
	if (!ctx->output_cb_size) ctx->output_cb_size = 4;

	sOpt = gf_modules_get_option((GF_BaseInterface *)ifcg, "OpenHEVC", "PackHFR");
	if (sOpt && !strcmp(sOpt, "yes") ) ctx->pack_mode = GF_TRUE;
	else if (!sOpt) gf_modules_set_option((GF_BaseInterface *)ifcg, "OpenHEVC", "PackHFR", "no");

	if (!ctx->raw_out) {
		sOpt = gf_modules_get_option((GF_BaseInterface *)ifcg, "OpenHEVC", "InputRipFile");
		if (sOpt) ctx->raw_out = fopen(sOpt, "wb");
	}


	/*RTP case: configure enhancement now*/
	if (esd->dependsOnESID) {
		HEVC_ConfigurationScalableStream(ctx, esd);
		return GF_OK;
	}

	ctx->esd = esd;
	return HEVC_ConfigureStream(ctx, esd);
}
Example #2
0
static GF_Err HEVC_ProcessData(GF_MediaDecoder *ifcg,
                               char *inBuffer, u32 inBufferLength,
                               u16 ES_ID, u32 *CTS,
                               char *outBuffer, u32 *outBufferLength,
                               u8 PaddingBits, u32 mmlevel)
{
	GF_Err e;
	int got_pic;
	HEVCDec *ctx = (HEVCDec*) ifcg->privateStack;

	if (!inBuffer) {
		if ( libOpenHevcDecode(ctx->openHevcHandle, NULL, 0, 0) ) {
			return HEVC_flush_picture(ctx, outBuffer, outBufferLength, CTS);
		}
		//quick hack, we have an issue with openHEVC resuming after being flushed ...
		ctx->had_pic = GF_FALSE;
		libOpenHevcClose(ctx->openHevcHandle);
		ctx->openHevcHandle = NULL;
		ctx->is_init = GF_FALSE;
		HEVC_ConfigureStream(ctx, ctx->esd);

		return GF_OK;
	}

	if (!ES_ID) {
		*outBufferLength = 0;
		return GF_OK;
	}

	if (*outBufferLength < ctx->out_size) {
		*outBufferLength = ctx->out_size;
		return GF_BUFFER_TOO_SMALL;
	}

	*outBufferLength = 0;

	if (ctx->had_pic) {
		ctx->had_pic = GF_FALSE;
		return HEVC_flush_picture(ctx, outBuffer, outBufferLength, CTS);
	}
	ctx->dec_frames++;
	got_pic = libOpenHevcDecode(ctx->openHevcHandle, (u8 *) inBuffer, inBufferLength, *CTS);

	if (ctx->raw_out) fwrite((u8 *) inBuffer, 1, inBufferLength, ctx->raw_out);

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[HEVC Decoder] Decode CTS %d - size %d - got pic %d\n", *CTS, inBufferLength, got_pic));
	if (got_pic>0) {
		e = HEVC_flush_picture(ctx, outBuffer, outBufferLength, CTS);
		if (e) return e;
		got_pic = 0;
	}

	return GF_OK;
}
Example #3
0
static GF_Err HEVC_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability)
{
	HEVCDec *ctx = (HEVCDec*) ifcg->privateStack;
	switch (capability.CapCode) {
	case GF_CODEC_DISPLAY_BPP:
		ctx->display_bpp = capability.cap.valueInt;
		return GF_OK;
	case GF_CODEC_WAIT_RAP:
		if (ctx->dec_frames) {
			//quick hack, we have an issue with openHEVC resuming after being flushed ...
			ctx->had_pic = GF_FALSE;
			libOpenHevcClose(ctx->openHevcHandle);
			ctx->openHevcHandle = NULL;
			ctx->is_init = GF_FALSE;
			HEVC_ConfigureStream(ctx, ctx->esd);
		}
		return GF_OK;
	case GF_CODEC_MEDIA_SWITCH_QUALITY:
	if (ctx->nb_layers==1) return GF_OK;
		/*switch up*/
		if (capability.cap.valueInt > 0) {
			libOpenHevcSetViewLayers(ctx->openHevcHandle, 1);
			libOpenHevcSetActiveDecoders(ctx->openHevcHandle, 1);
		} else {
			libOpenHevcSetViewLayers(ctx->openHevcHandle, 0);
			libOpenHevcSetActiveDecoders(ctx->openHevcHandle, 0);
		}
		return GF_OK;
	case GF_CODEC_RAW_MEMORY:
		ctx->direct_output = GF_TRUE;
		ctx->pack_mode = GF_FALSE;
		if (ctx->conv_to_8bit && ctx->out_size)
			ctx->conv_buffer = (char*)gf_realloc(ctx->conv_buffer, sizeof(char)*ctx->out_size);

		return GF_OK;
	}
	/*return unsupported to avoid confusion by the player (like color space changing ...) */
	return GF_NOT_SUPPORTED;

}