decoder/mad: eliminate the loop in SubmitPCM()
libmad has a hard-coded maximum PCM buffer size; if we make our output_buffer just as large, we can avoid the loop, because any possible size will fit.
This commit is contained in:
		| @@ -108,14 +108,13 @@ mad_plugin_init(const ConfigBlock &block) | |||||||
|  |  | ||||||
| class MadDecoder { | class MadDecoder { | ||||||
| 	static constexpr size_t READ_BUFFER_SIZE = 40960; | 	static constexpr size_t READ_BUFFER_SIZE = 40960; | ||||||
| 	static constexpr size_t MP3_DATA_OUTPUT_BUFFER_SIZE = 2048; |  | ||||||
|  |  | ||||||
| 	struct mad_stream stream; | 	struct mad_stream stream; | ||||||
| 	struct mad_frame frame; | 	struct mad_frame frame; | ||||||
| 	struct mad_synth synth; | 	struct mad_synth synth; | ||||||
| 	mad_timer_t timer; | 	mad_timer_t timer; | ||||||
| 	unsigned char input_buffer[READ_BUFFER_SIZE]; | 	unsigned char input_buffer[READ_BUFFER_SIZE]; | ||||||
| 	int32_t output_buffer[MP3_DATA_OUTPUT_BUFFER_SIZE]; | 	int32_t output_buffer[sizeof(mad_pcm::samples) / sizeof(mad_fixed_t)]; | ||||||
| 	SignedSongTime total_time; | 	SignedSongTime total_time; | ||||||
| 	SongTime elapsed_time; | 	SongTime elapsed_time; | ||||||
| 	SongTime seek_time; | 	SongTime seek_time; | ||||||
| @@ -847,30 +846,16 @@ MadDecoder::UpdateTimerNextFrame() noexcept | |||||||
| DecoderCommand | DecoderCommand | ||||||
| MadDecoder::SubmitPCM(unsigned i, unsigned pcm_length) noexcept | MadDecoder::SubmitPCM(unsigned i, unsigned pcm_length) noexcept | ||||||
| { | { | ||||||
| 	unsigned max_samples = sizeof(output_buffer) / |  | ||||||
| 		sizeof(output_buffer[0]) / |  | ||||||
| 		MAD_NCHANNELS(&frame.header); |  | ||||||
|  |  | ||||||
| 	while (i < pcm_length) { |  | ||||||
| 	unsigned int num_samples = pcm_length - i; | 	unsigned int num_samples = pcm_length - i; | ||||||
| 		if (num_samples > max_samples) |  | ||||||
| 			num_samples = max_samples; |  | ||||||
|  |  | ||||||
| 		i += num_samples; |  | ||||||
|  |  | ||||||
| 	mad_fixed_to_24_buffer(output_buffer, &synth, | 	mad_fixed_to_24_buffer(output_buffer, &synth, | ||||||
| 				       i - num_samples, i, | 			       i, i + num_samples, | ||||||
| 			       MAD_NCHANNELS(&frame.header)); | 			       MAD_NCHANNELS(&frame.header)); | ||||||
| 	num_samples *= MAD_NCHANNELS(&frame.header); | 	num_samples *= MAD_NCHANNELS(&frame.header); | ||||||
|  |  | ||||||
| 		auto cmd = client->SubmitData(input_stream, output_buffer, | 	return client->SubmitData(input_stream, output_buffer, | ||||||
| 				  sizeof(output_buffer[0]) * num_samples, | 				  sizeof(output_buffer[0]) * num_samples, | ||||||
| 				  frame.header.bitrate / 1000); | 				  frame.header.bitrate / 1000); | ||||||
| 		if (cmd != DecoderCommand::NONE) |  | ||||||
| 			return cmd; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return DecoderCommand::NONE; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| inline DecoderCommand | inline DecoderCommand | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann