Example #1
0
static void 
hls_muxer_simulation_flush_delayed_streams(
	hls_muxer_state_t* state, 
	hls_muxer_stream_state_t* selected_stream, 
	uint64_t frame_dts)
{
	hls_muxer_stream_state_t* cur_stream;
	uint64_t buffer_dts;

	for (cur_stream = state->first_stream; cur_stream < state->last_stream; cur_stream++)
	{
		if (selected_stream == cur_stream || cur_stream->buffer_state == NULL)
		{
			continue;
		}

		if (buffer_filter_get_dts(cur_stream->buffer_state, &buffer_dts) &&
			frame_dts > buffer_dts + HLS_DELAY / 2)
		{
			vod_log_debug2(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
				"hls_muxer_simulation_flush_delayed_streams: flushing buffered frames buffer dts %L frame dts %L",
				buffer_dts,
				frame_dts);
			buffer_filter_simulated_force_flush(cur_stream->buffer_state, FALSE);
		}
	}
}
Example #2
0
vod_status_t
rate_filter_parse(
	void* ctx,
	vod_json_value_t* element,
	void** result)
{
	media_filter_parse_context_t* context = ctx;
	media_clip_rate_filter_t* filter;
	media_range_t* new_range;
	media_range_t* old_range;
	vod_json_value_t* params[RATE_FILTER_PARAM_COUNT];
	vod_json_value_t* source;
	vod_json_value_t* rate;
	uint32_t old_duration;
	vod_status_t rc;

	vod_log_debug0(VOD_LOG_DEBUG_LEVEL, context->request_context->log, 0,
		"rate_filter_parse: started");

	vod_memzero(params, sizeof(params));
		
	vod_json_get_object_values(
		element,
		&rate_filter_hash,
		params);

	rate = params[RATE_FILTER_PARAM_RATE];
	source = params[RATE_FILTER_PARAM_SOURCE];

	if (rate == NULL || source == NULL)
	{
		vod_log_error(VOD_LOG_ERR, context->request_context->log, 0,
			"rate_filter_parse: \"rate\" and \"source\" are mandatory for rate filter");
		return VOD_BAD_MAPPING;
	}

	if (rate->v.num.denom > 100)
	{
		vod_log_error(VOD_LOG_ERR, context->request_context->log, 0,
			"rate_filter_parse: invalid rate, only 2 decimal points are allowed");
		return VOD_BAD_MAPPING;
	}
	
	if (rate->v.num.nom < 0 ||
		rate->v.num.denom > (uint64_t)rate->v.num.nom * 2 || (uint64_t)rate->v.num.nom > rate->v.num.denom * 2)
	{
		vod_log_error(VOD_LOG_ERR, context->request_context->log, 0,
			"rate_filter_parse: invalid rate %L/%uL, must be between 0.5 and 2", rate->v.num.nom, rate->v.num.denom);
		return VOD_BAD_MAPPING;
	}

	filter = vod_alloc(context->request_context->pool, sizeof(*filter) + sizeof(filter->base.sources[0]));
	if (filter == NULL)
	{
		vod_log_debug0(VOD_LOG_DEBUG_LEVEL, context->request_context->log, 0,
			"rate_filter_parse: vod_alloc failed (1)");
		return VOD_ALLOC_FAILED;
	}
	filter->base.sources = (void*)(filter + 1);
	filter->base.source_count = 1;

	filter->base.type = MEDIA_CLIP_RATE_FILTER;
	filter->base.audio_filter = &rate_filter;
	filter->rate.nom = rate->v.num.nom;
	filter->rate.denom = rate->v.num.denom;

	old_range = context->range;
	if (old_range != NULL)
	{
		new_range = vod_alloc(context->request_context->pool, sizeof(*new_range));
		if (new_range == NULL)
		{
			vod_log_debug0(VOD_LOG_DEBUG_LEVEL, context->request_context->log, 0,
				"rate_filter_parse: vod_alloc failed (2)");
			return VOD_ALLOC_FAILED;
		}

		new_range->start = (old_range->start * filter->rate.nom) / filter->rate.denom;
		new_range->end = (old_range->end * filter->rate.nom) / filter->rate.denom;
		new_range->timescale = old_range->timescale;

		context->range = new_range;
	}

	old_duration = context->duration;
	context->duration = ((uint64_t)old_duration * filter->rate.nom) / filter->rate.denom;

	rc = media_set_parse_clip(
		context, 
		source, 
		&filter->base,
		&filter->base.sources[0]);
	if (rc != VOD_JSON_OK)
	{
		return rc;
	}

	context->range = old_range;
	context->duration = old_duration;

	*result = &filter->base;

	vod_log_debug2(VOD_LOG_DEBUG_LEVEL, context->request_context->log, 0,
		"rate_filter_parse: done, rate=%uD/%uD", filter->rate.nom, filter->rate.denom);

	return VOD_OK;
}