diff options
| author | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2017-06-30 07:12:49 +0000 |
|---|---|---|
| committer | trialuser02 <trialuser02@90c681e8-e032-0410-971d-27865f9a5e38> | 2017-06-30 07:12:49 +0000 |
| commit | d0b331da0f1f1d2465d3f895fa13ef1389b559ad (patch) | |
| tree | a39470a508aa0c9644d176e2fef096b474023d53 /src | |
| parent | 627c20692eb11eeecb7628c812480fe46db3191d (diff) | |
| download | qmmp-d0b331da0f1f1d2465d3f895fa13ef1389b559ad.tar.gz qmmp-d0b331da0f1f1d2465d3f895fa13ef1389b559ad.tar.bz2 qmmp-d0b331da0f1f1d2465d3f895fa13ef1389b559ad.zip | |
flac: fixed segmentation fault on Ogg FLAC streams (#920)
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@7272 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src')
| -rw-r--r-- | src/plugins/Input/flac/decoder_flac.cpp | 57 | ||||
| -rw-r--r-- | src/plugins/Input/flac/decoder_flac.h | 7 |
2 files changed, 50 insertions, 14 deletions
diff --git a/src/plugins/Input/flac/decoder_flac.cpp b/src/plugins/Input/flac/decoder_flac.cpp index 43124ec5f..ca43c92bb 100644 --- a/src/plugins/Input/flac/decoder_flac.cpp +++ b/src/plugins/Input/flac/decoder_flac.cpp @@ -41,6 +41,8 @@ #include "cueparser.h" #include "decoder_flac.h" +#define BITRATE_CALC_TIME_MS 2000 + static size_t pack_pcm_signed (FLAC__byte *output, const FLAC__int32 * const input[], unsigned samples, @@ -122,10 +124,12 @@ static FLAC__StreamDecoderReadStatus flac_callback_read (const FLAC__StreamDecod { DecoderFLAC *dflac = (DecoderFLAC *) client_data; qint64 res = dflac->data()->input->read((char *)buffer, *bytes); + qDebug("%lld", res); if (res > 0) { *bytes = res; + dflac->data()->read_bytes += res; return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; } if (res == 0) @@ -145,20 +149,33 @@ static FLAC__StreamDecoderWriteStatus flac_callback_write (const FLAC__StreamDec { DecoderFLAC *dflac = (DecoderFLAC *) client_data; const unsigned wide_samples = frame->header.blocksize; + qDebug("wid %u", wide_samples); if (dflac->data()->abort) return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; //bitrate calculation FLAC__uint64 decode_position = 0; - if(FLAC__stream_decoder_get_decode_position(d, &decode_position) && - decode_position > dflac->data()->last_decode_position) + if(FLAC__stream_decoder_get_decode_position(d, &decode_position)) { - dflac->data()->bitrate = (decode_position - dflac->data()->last_decode_position) * 8.0 * frame->header.sample_rate / - frame->header.blocksize / 1000.0; - } + if(decode_position > dflac->data()->last_decode_position) + { + dflac->data()->bitrate = (decode_position - dflac->data()->last_decode_position) * 8 * frame->header.sample_rate / + frame->header.blocksize / 1000; + } - dflac->data()->last_decode_position = decode_position; + dflac->data()->last_decode_position = decode_position; + } + else + { + dflac->data()->frame_counter += wide_samples; + if(dflac->data()->frame_counter * 1000 / frame->header.sample_rate > BITRATE_CALC_TIME_MS) + { + dflac->data()->bitrate = dflac->data()->read_bytes * 8 * frame->header.sample_rate / dflac->data()->frame_counter / 1000; + dflac->data()->frame_counter = 0; + dflac->data()->read_bytes = 0; + } + } dflac->data()->sample_buffer_fill = pack_pcm_signed ( dflac->data()->sample_buffer, @@ -174,6 +191,9 @@ static FLAC__StreamDecoderTellStatus flac_callback_tell (const FLAC__StreamDecod void *client_data) { DecoderFLAC *dflac = (DecoderFLAC *) client_data; + if(dflac->data()->input->isSequential()) + return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; + *offset = dflac->data()->input->pos (); return FLAC__STREAM_DECODER_TELL_STATUS_OK; } @@ -183,6 +203,8 @@ static FLAC__StreamDecoderSeekStatus flac_callback_seek (const FLAC__StreamDecod void *client_data) { DecoderFLAC *dflac = (DecoderFLAC *) client_data; + if(dflac->data()->input->isSequential()) + return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; return dflac->data()->input->seek(offset) ? FLAC__STREAM_DECODER_SEEK_STATUS_OK @@ -194,6 +216,9 @@ static FLAC__StreamDecoderLengthStatus flac_callback_length (const FLAC__StreamD void *client_data) { DecoderFLAC *dflac = (DecoderFLAC *) client_data; + if(dflac->data()->input->isSequential()) + return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; + *stream_length = dflac->data()->input->size(); return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; } @@ -216,8 +241,15 @@ static void flac_callback_metadata (const FLAC__StreamDecoder *, dflac->data()->channels = metadata->data.stream_info.channels; dflac->data()->sample_rate = metadata->data.stream_info.sample_rate; dflac->data()->length = dflac->data()->total_samples * 1000 / dflac->data()->sample_rate; - dflac->data()->bitrate = dflac->data()->input->size() * 8 * metadata->data.stream_info.sample_rate / - metadata->data.stream_info.total_samples / 1000; + + if(metadata->data.stream_info.total_samples > 0 && dflac->data()->length > 0) + { + dflac->data()->bitrate = dflac->data()->input->size() * 8 / dflac->data()->length; + } + else + { + dflac->data()->bitrate = 0; + } } } @@ -328,6 +360,10 @@ bool DecoderFLAC::initialize() m_data->abort = 0; m_data->sample_buffer_fill = 0; m_data->last_decode_position = 0; + m_data->read_bytes = 0; + m_data->frame_counter = 0; + + if (!m_data->decoder) { qDebug("DecoderFLAC: creating FLAC__StreamDecoder"); @@ -364,9 +400,9 @@ bool DecoderFLAC::initialize() flac_callback_error, this) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { - data()->ok = 0; return false; } + qDebug("DecoderFLAC: Ogg FLAC stream found"); } else if (!memcmp(buf, "fLaC", 4)) { @@ -382,9 +418,9 @@ bool DecoderFLAC::initialize() flac_callback_error, this) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { - data()->ok = 0; return false; } + qDebug("DecoderFLAC: native FLAC stream found"); } else { @@ -395,7 +431,6 @@ bool DecoderFLAC::initialize() if (!FLAC__stream_decoder_process_until_end_of_metadata( data()->decoder)) { - data()->ok = 0; return false; } diff --git a/src/plugins/Input/flac/decoder_flac.h b/src/plugins/Input/flac/decoder_flac.h index ad0203f66..5147d5da0 100644 --- a/src/plugins/Input/flac/decoder_flac.h +++ b/src/plugins/Input/flac/decoder_flac.h @@ -35,7 +35,6 @@ struct flac_data { //FLAC__SeekableStreamDecoder *decoder; FLAC__StreamDecoder *decoder; - struct io_stream *stream; int bitrate; int abort; /* abort playing (due to an error) */ @@ -52,8 +51,10 @@ struct flac_data FLAC__uint64 last_decode_position; - int ok; /* was this stream successfully opened? */ - //struct decoder_error error; + //counters + qint64 read_bytes; + qint64 frame_counter; + QIODevice *input; }; |
