Exemplo n.º 1
0
void FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
	// If the previous block has the same Start sample as this one, then
	// we got multiple frames of audio out of a single package and should
	// combine them
	auto block = pos;
	if (pos == Cache.begin() || (--block)->Start != CurrentSample)
		block = Cache.insert(pos, AudioBlock(CurrentSample));

	block->Samples += DecodeFrame->nb_samples;

	if (NeedsResample)
		ResampleAndCache(block);
	else {
		const uint8_t *data = DecodeFrame->extended_data[0];
		block->Data.insert(block->Data.end(), data, data + DecodeFrame->nb_samples * BytesPerSample);
	}

	if (Cache.size() >= MaxCacheBlocks) {
		// Kill the oldest one
		auto min = CacheNoDelete;
		// Never drop the first one as the first packet decoded after a seek
		// is often decoded incorrectly and we can't seek to before the first one
		++min;
		for (auto it = min; it != Cache.end(); ++it)
			if (it->Age < min->Age) min = it;
		if (min == pos) ++pos;
		Cache.erase(min);
	}
}
Exemplo n.º 2
0
void FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
	if (NeedsResample)
		ResampleAndCache(pos);
	else
		Cache.insert(pos, AudioBlock(CurrentSample, DecodeFrame->nb_samples, DecodeFrame->extended_data[0], DecodeFrame->nb_samples * BytesPerSample));

	if (Cache.size() >= MaxCacheBlocks) {
		// Kill the oldest one
		CacheIterator min = CacheNoDelete;
		// Never drop the first one as the first packet decoded after a seek
		// is often decoded incorrectly and we can't seek to before the first one
		++min;
		for (CacheIterator it = min; it != Cache.end(); ++it)
			if (it->Age < min->Age) min = it;
		if (min == pos) ++pos;
		Cache.erase(min);
	}
}
Exemplo n.º 3
0
void FFMS_AudioSource::ResampleAndCache(CacheIterator pos) {
	AudioBlock& block = *Cache.insert(pos, AudioBlock(CurrentSample, DecodeFrame->nb_samples));
	block.Data.reserve(DecodeFrame->nb_samples * BytesPerSample);

#ifdef WITH_AVRESAMPLE
	block.Data.resize(block.Data.capacity());

	uint8_t *OutPlanes[1] = { static_cast<uint8_t *>(&block.Data[0]) };
	avresample_convert(ResampleContext,
		OutPlanes, block.Data.size(), DecodeFrame->nb_samples,
		DecodeFrame->extended_data, DecodeFrame->nb_samples * av_get_bytes_per_sample(CodecContext->sample_fmt), DecodeFrame->nb_samples);
#else
	int width = av_get_bytes_per_sample(CodecContext->sample_fmt);
	uint8_t **Data = DecodeFrame->extended_data;

	for (int s = 0; s < DecodeFrame->nb_samples; ++s) {
		for (int c = 0; c < CodecContext->channels; ++c)
			block.Data.insert(block.Data.end(), &Data[c][s * width], &Data[c][(s + 1) * width]);
	}
#endif
}