decoder/flac: support streams without STREAMINFO block
This commit is contained in:
parent
de0cdee4aa
commit
a942384fbf
1
NEWS
1
NEWS
|
@ -23,6 +23,7 @@ ver 0.16 (20??/??/??)
|
|||
- ffmpeg: convert metadata to generic format
|
||||
- sndfile: new decoder plugin based on libsndfile
|
||||
- flac: moved CUE sheet support to a playlist plugin
|
||||
- flac: support streams without STREAMINFO block
|
||||
- mikmod: sample rate is configurable
|
||||
- mpg123: new decoder plugin based on libmpg123
|
||||
- sidplay: support sub-tunes
|
||||
|
|
|
@ -161,16 +161,55 @@ void flac_error_common_cb(const char *plugin,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function attempts to call decoder_initialized() in case there
|
||||
* was no STREAMINFO block. This is allowed for nonseekable streams,
|
||||
* where the server sends us only a part of the file, without
|
||||
* providing the STREAMINFO block from the beginning of the file
|
||||
* (e.g. when seeking with SqueezeBox Server).
|
||||
*/
|
||||
static bool
|
||||
flac_got_first_frame(struct flac_data *data, const FLAC__FrameHeader *header)
|
||||
{
|
||||
if (data->unsupported)
|
||||
return false;
|
||||
|
||||
GError *error = NULL;
|
||||
if (!audio_format_init_checked(&data->audio_format,
|
||||
header->sample_rate,
|
||||
flac_sample_format(header->bits_per_sample),
|
||||
header->channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
data->unsupported = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
data->frame_size = audio_format_frame_size(&data->audio_format);
|
||||
|
||||
decoder_initialized(data->decoder, &data->audio_format,
|
||||
data->input_stream->seekable,
|
||||
(float)data->total_frames /
|
||||
(float)data->audio_format.sample_rate);
|
||||
|
||||
data->initialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FLAC__StreamDecoderWriteStatus
|
||||
flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
|
||||
const FLAC__int32 *const buf[],
|
||||
FLAC__uint64 nbytes)
|
||||
{
|
||||
enum decoder_command cmd;
|
||||
size_t buffer_size = frame->header.blocksize * data->frame_size;
|
||||
void *buffer;
|
||||
unsigned bit_rate;
|
||||
|
||||
if (!data->initialized && !flac_got_first_frame(data, &frame->header))
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
|
||||
|
||||
size_t buffer_size = frame->header.blocksize * data->frame_size;
|
||||
buffer = pcm_buffer_get(&data->buffer, buffer_size);
|
||||
|
||||
flac_convert(buffer, frame->header.channels,
|
||||
|
|
|
@ -247,6 +247,18 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (data->initialized)
|
||||
/* done */
|
||||
return true;
|
||||
|
||||
if (data->input_stream->seekable)
|
||||
/* allow the workaround below only for nonseekable
|
||||
streams*/
|
||||
return false;
|
||||
|
||||
/* no stream_info packet found; try to initialize the decoder
|
||||
from the first frame header */
|
||||
FLAC__stream_decoder_process_single(sd);
|
||||
return data->initialized;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue