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); } } }
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; }