/**
 * Sends a chunk of silence to the audio outputs.  This is called when
 * there is not enough decoded data in the pipe yet, to prevent
 * underruns in the hardware buffers.
 *
 * The player lock is not held.
 */
static bool
player_send_silence(struct player *player)
{
	assert(audio_format_defined(&player->play_audio_format));

	struct music_chunk *chunk = music_buffer_allocate(player_buffer);
	if (chunk == NULL) {
		g_warning("Failed to allocate silence buffer");
		return false;
	}

#ifndef NDEBUG
	chunk->audio_format = player->play_audio_format;
#endif

	size_t frame_size =
		audio_format_frame_size(&player->play_audio_format);
	/* this formula ensures that we don't send
	   partial frames */
	unsigned num_frames = sizeof(chunk->data) / frame_size;

	chunk->times = -1.0; /* undefined time stamp */
	chunk->length = num_frames * frame_size;
	memset(chunk->data, 0, chunk->length);

	if (!audio_output_all_play(chunk)) {
		music_buffer_return(player_buffer, chunk);
		return false;
	}

	return true;
}
struct music_chunk *
decoder_get_chunk(struct decoder *decoder, struct input_stream *is)
{
	struct decoder_control *dc = decoder->dc;
	enum decoder_command cmd;

	assert(decoder != NULL);

	if (decoder->chunk != NULL)
		return decoder->chunk;

	do {
		decoder->chunk = music_buffer_allocate(dc->buffer);
		if (decoder->chunk != NULL) {
			decoder->chunk->replay_gain_serial =
				decoder->replay_gain_serial;
			if (decoder->replay_gain_serial != 0)
				decoder->chunk->replay_gain_info =
					decoder->replay_gain_info;

			return decoder->chunk;
		}

		decoder_lock(dc);
		cmd = need_chunks(dc, is, true);
		decoder_unlock(dc);
	} while (cmd == DECODE_COMMAND_NONE);

	return NULL;
}