Beispiel #1
0
static char *gf_af_fetch_frame(void *callback, u32 *size, u32 audio_delay_ms)
{
	GF_AudioFilterItem *af = (GF_AudioFilterItem *)callback;

	*size = 0;
	if (!af->nb_used) {
		/*force filling the filter chain output until no data is available, otherwise we may end up
		with data in input and no data as output because of block framing of the filter chain*/
		while (!af->nb_filled) {
			u32 nb_bytes;
			char *data = af->src->FetchFrame(af->src->callback, &nb_bytes, audio_delay_ms + af->filter_chain.delay_ms);
			/*no input data*/
			if (!data || !nb_bytes) 
				return NULL;

			if (nb_bytes > af->filter_chain.min_block_size) nb_bytes = af->filter_chain.min_block_size;
			memcpy(af->filter_chain.tmp_block1, data, nb_bytes);
			af->src->ReleaseFrame(af->src->callback, nb_bytes);

			af->nb_filled = gf_afc_process(&af->filter_chain, nb_bytes);
		}
	}

	*size = af->nb_filled - af->nb_used;
	return af->filter_chain.tmp_block1 + af->nb_used;
}
Beispiel #2
0
static u32 gf_ar_fill_output(void *ptr, char *buffer, u32 buffer_size)
{
	u32 written;
	GF_AudioRenderer *ar = (GF_AudioRenderer *) ptr;
	if (!ar->need_reconfig) {
		u32 delay_ms = ar->disable_resync ?	0 : ar->audio_delay;

		if (ar->filter_chain.enable_filters) {
			char *ptr = buffer;
			u32 res = buffer_size;
			written = 0;
			delay_ms += ar->filter_chain.delay_ms;

			while (buffer_size) {
				u32 to_copy;
				if (!ar->nb_used) {
					u32 nb_bytes;

					/*fill input block*/
					nb_bytes = gf_mixer_get_output(ar->mixer, ar->filter_chain.tmp_block1, ar->filter_chain.min_block_size, delay_ms);
					if (!nb_bytes) 
						return written;

					/*delay used to check for late frames - we only use it on the first call to gf_mixer_get_output()*/
					delay_ms = 0;

					ar->nb_filled = gf_afc_process(&ar->filter_chain, nb_bytes);
					if (!ar->nb_filled) continue;
				}
				to_copy = ar->nb_filled - ar->nb_used;
				if (to_copy>buffer_size) to_copy = buffer_size;
				memcpy(ptr, ar->filter_chain.tmp_block1 + ar->nb_used, to_copy);
				ptr += to_copy;
				buffer_size -= to_copy;
				written += to_copy;
				ar->nb_used += to_copy;
				if (ar->nb_used==ar->nb_filled) ar->nb_used = 0;
			}
			assert(res==written);
		} else {
			written = gf_mixer_get_output(ar->mixer, buffer, buffer_size, delay_ms);
		}
		if (ar->audio_listeners) {
			u32 k=0;
			GF_AudioListener *l;
			while ((l = gf_list_enum(ar->audio_listeners, &k))) {
				l->on_audio_frame(l->udta, buffer, written, gf_sc_ar_get_clock(ar), delay_ms);
			}
		}
		return written;
	}
	return 0;
}
Beispiel #3
0
static u32 gf_ar_fill_output(void *ptr, char *buffer, u32 buffer_size)
{
	u32 written;
	GF_AudioRenderer *ar = (GF_AudioRenderer *) ptr;
	if (!ar->need_reconfig) {
		u32 delay_ms = ar->disable_resync ?	0 : ar->audio_delay;

		if (ar->Frozen) {
			memset(buffer, 0, buffer_size);
			return buffer_size;
		}

		gf_mixer_lock(ar->mixer, GF_TRUE);

		if (ar->filter_chain.enable_filters) {
			char *ptr = buffer;
			written = 0;
			delay_ms += ar->filter_chain.delay_ms;

			while (buffer_size) {
				u32 to_copy;
				if (!ar->nb_used) {
					u32 nb_bytes;

					/*fill input block*/
					nb_bytes = gf_mixer_get_output(ar->mixer, ar->filter_chain.tmp_block1, ar->filter_chain.min_block_size, delay_ms);
					if (!nb_bytes)
						return written;

					/*delay used to check for late frames - we only use it on the first call to gf_mixer_get_output()*/
					delay_ms = 0;

					ar->nb_filled = gf_afc_process(&ar->filter_chain, nb_bytes);
					if (!ar->nb_filled) continue;
				}
				to_copy = ar->nb_filled - ar->nb_used;
				if (to_copy>buffer_size) to_copy = buffer_size;
				memcpy(ptr, ar->filter_chain.tmp_block1 + ar->nb_used, to_copy);
				ptr += to_copy;
				buffer_size -= to_copy;
				written += to_copy;
				ar->nb_used += to_copy;
				if (ar->nb_used==ar->nb_filled) ar->nb_used = 0;
			}
		} else {
			written = gf_mixer_get_output(ar->mixer, buffer, buffer_size, delay_ms);
		}
		gf_mixer_lock(ar->mixer, GF_FALSE);

		//done with one sim step, go back in pause
		if (ar->step_mode) {
			ar->step_mode = GF_FALSE;
			gf_ar_pause(ar, GF_TRUE, GF_FALSE, GF_FALSE);
		}

		if (!ar->need_reconfig) {
			if (ar->audio_listeners) {
				u32 k=0;
				GF_AudioListener *l;
				while ((l = (GF_AudioListener*)gf_list_enum(ar->audio_listeners, &k))) {
					l->on_audio_frame(l->udta, buffer, buffer_size, gf_sc_ar_get_clock(ar), delay_ms);
				}
			}

			ar->bytes_requested += buffer_size;
			ar->current_time = ar->time_at_last_config + (u32) (ar->bytes_requested * 1000 / ar->bytes_per_second);
		}
		//always return buffer size (eg requested input size to be filled), since the clock is always increased by buffer_size (cf above line)
		return buffer_size;
	}
	return 0;
}