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
|
- ffmpeg: convert metadata to generic format
|
||||||
- sndfile: new decoder plugin based on libsndfile
|
- sndfile: new decoder plugin based on libsndfile
|
||||||
- flac: moved CUE sheet support to a playlist plugin
|
- flac: moved CUE sheet support to a playlist plugin
|
||||||
|
- flac: support streams without STREAMINFO block
|
||||||
- mikmod: sample rate is configurable
|
- mikmod: sample rate is configurable
|
||||||
- mpg123: new decoder plugin based on libmpg123
|
- mpg123: new decoder plugin based on libmpg123
|
||||||
- sidplay: support sub-tunes
|
- 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__StreamDecoderWriteStatus
|
||||||
flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
|
flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
|
||||||
const FLAC__int32 *const buf[],
|
const FLAC__int32 *const buf[],
|
||||||
FLAC__uint64 nbytes)
|
FLAC__uint64 nbytes)
|
||||||
{
|
{
|
||||||
enum decoder_command cmd;
|
enum decoder_command cmd;
|
||||||
size_t buffer_size = frame->header.blocksize * data->frame_size;
|
|
||||||
void *buffer;
|
void *buffer;
|
||||||
unsigned bit_rate;
|
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);
|
buffer = pcm_buffer_get(&data->buffer, buffer_size);
|
||||||
|
|
||||||
flac_convert(buffer, frame->header.channels,
|
flac_convert(buffer, frame->header.channels,
|
||||||
|
@ -247,6 +247,18 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
|
|||||||
return false;
|
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;
|
return data->initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user