diff options
Diffstat (limited to 'src/decoder/FaadDecoderPlugin.cxx')
-rw-r--r-- | src/decoder/FaadDecoderPlugin.cxx | 169 |
1 files changed, 68 insertions, 101 deletions
diff --git a/src/decoder/FaadDecoderPlugin.cxx b/src/decoder/FaadDecoderPlugin.cxx index 9fd20167d..a37bc88bf 100644 --- a/src/decoder/FaadDecoderPlugin.cxx +++ b/src/decoder/FaadDecoderPlugin.cxx @@ -24,6 +24,7 @@ #include "InputStream.hxx" #include "CheckAudioFormat.hxx" #include "tag/TagHandler.hxx" +#include "util/ConstBuffer.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -66,16 +67,11 @@ adts_check_frame(const unsigned char *data) static size_t adts_find_frame(DecoderBuffer *buffer) { - size_t length, frame_length; - bool ret; - while (true) { - const uint8_t *data = (const uint8_t *) - decoder_buffer_read(buffer, &length); - if (data == nullptr || length < 8) { + auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer)); + if (data.size < 8) { /* not enough data yet */ - ret = decoder_buffer_fill(buffer); - if (!ret) + if (!decoder_buffer_fill(buffer)) /* failed */ return 0; @@ -83,21 +79,22 @@ adts_find_frame(DecoderBuffer *buffer) } /* find the 0xff marker */ - const uint8_t *p = (const uint8_t *)memchr(data, 0xff, length); + const uint8_t *p = (const uint8_t *) + memchr(data.data, 0xff, data.size); if (p == nullptr) { /* no marker - discard the buffer */ - decoder_buffer_consume(buffer, length); + decoder_buffer_clear(buffer); continue; } - if (p > data) { + if (p > data.data) { /* discard data before 0xff */ - decoder_buffer_consume(buffer, p - data); + decoder_buffer_consume(buffer, p - data.data); continue; } /* is it a frame? */ - frame_length = adts_check_frame(data); + size_t frame_length = adts_check_frame(data.data); if (frame_length == 0) { /* it's just some random 0xff byte; discard it and continue searching */ @@ -105,19 +102,15 @@ adts_find_frame(DecoderBuffer *buffer) continue; } - if (length < frame_length) { + if (data.size < frame_length) { /* available buffer size is smaller than the frame will be - attempt to read more data */ - ret = decoder_buffer_fill(buffer); - if (!ret) { + if (!decoder_buffer_fill(buffer)) { /* not enough data; discard this frame to prevent a possible buffer overflow */ - data = (const uint8_t *) - decoder_buffer_read(buffer, &length); - if (data != nullptr) - decoder_buffer_consume(buffer, length); + decoder_buffer_clear(buffer); } continue; @@ -131,31 +124,27 @@ adts_find_frame(DecoderBuffer *buffer) static float adts_song_duration(DecoderBuffer *buffer) { - unsigned int frames, frame_length; unsigned sample_rate = 0; - float frames_per_second; /* Read all frames to ensure correct time and bitrate */ - for (frames = 0;; frames++) { - frame_length = adts_find_frame(buffer); + unsigned frames = 0; + for (;; frames++) { + unsigned frame_length = adts_find_frame(buffer); if (frame_length == 0) break; - if (frames == 0) { - size_t buffer_length; - const uint8_t *data = (const uint8_t *) - decoder_buffer_read(buffer, &buffer_length); - assert(data != nullptr); - assert(frame_length <= buffer_length); + auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer)); + assert(!data.IsEmpty()); + assert(frame_length <= data.size); - sample_rate = adts_sample_rates[(data[2] & 0x3c) >> 2]; + sample_rate = adts_sample_rates[(data.data[2] & 0x3c) >> 2]; } decoder_buffer_consume(buffer, frame_length); } - frames_per_second = (float)sample_rate / 1024.0; + float frames_per_second = (float)sample_rate / 1024.0; if (frames_per_second <= 0) return -1; @@ -165,66 +154,58 @@ adts_song_duration(DecoderBuffer *buffer) static float faad_song_duration(DecoderBuffer *buffer, InputStream &is) { - size_t fileread; - size_t tagsize; - size_t length; - bool success; - const auto size = is.GetSize(); - fileread = size >= 0 ? size : 0; + const size_t fileread = size >= 0 ? size : 0; decoder_buffer_fill(buffer); - const uint8_t *data = (const uint8_t *) - decoder_buffer_read(buffer, &length); - if (data == nullptr) + auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer)); + if (data.IsEmpty()) return -1; - tagsize = 0; - if (length >= 10 && !memcmp(data, "ID3", 3)) { + size_t tagsize = 0; + if (data.size >= 10 && !memcmp(data.data, "ID3", 3)) { /* skip the ID3 tag */ - tagsize = (data[6] << 21) | (data[7] << 14) | - (data[8] << 7) | (data[9] << 0); + tagsize = (data.data[6] << 21) | (data.data[7] << 14) | + (data.data[8] << 7) | (data.data[9] << 0); tagsize += 10; - success = decoder_buffer_skip(buffer, tagsize) && + bool success = decoder_buffer_skip(buffer, tagsize) && decoder_buffer_fill(buffer); if (!success) return -1; - data = (const uint8_t *)decoder_buffer_read(buffer, &length); - if (data == nullptr) + data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer)); + if (data.IsEmpty()) return -1; } - if (is.IsSeekable() && length >= 2 && - data[0] == 0xFF && ((data[1] & 0xF6) == 0xF0)) { + if (is.IsSeekable() && data.size >= 2 && + data.data[0] == 0xFF && ((data.data[1] & 0xF6) == 0xF0)) { /* obtain the duration from the ADTS header */ float song_length = adts_song_duration(buffer); is.LockSeek(tagsize, SEEK_SET, IgnoreError()); - data = (const uint8_t *)decoder_buffer_read(buffer, &length); - if (data != nullptr) - decoder_buffer_consume(buffer, length); + decoder_buffer_clear(buffer); decoder_buffer_fill(buffer); return song_length; - } else if (length >= 5 && memcmp(data, "ADIF", 4) == 0) { + } else if (data.size >= 5 && memcmp(data.data, "ADIF", 4) == 0) { /* obtain the duration from the ADIF header */ unsigned bit_rate; - size_t skip_size = (data[4] & 0x80) ? 9 : 0; + size_t skip_size = (data.data[4] & 0x80) ? 9 : 0; - if (8 + skip_size > length) + if (8 + skip_size > data.size) /* not enough data yet; skip parsing this header */ return -1; - bit_rate = ((data[4 + skip_size] & 0x0F) << 19) | - (data[5 + skip_size] << 11) | - (data[6 + skip_size] << 3) | - (data[7 + skip_size] & 0xE0); + bit_rate = ((data.data[4 + skip_size] & 0x0F) << 19) | + (data.data[5 + skip_size] << 11) | + (data.data[6 + skip_size] << 3) | + (data.data[7 + skip_size] & 0xE0); if (fileread != 0 && bit_rate != 0) return fileread * 8.0 / bit_rate; @@ -242,9 +223,7 @@ static bool faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer *buffer, AudioFormat &audio_format, Error &error) { - int32_t nbytes; uint32_t sample_rate; - uint8_t channels; #ifdef HAVE_FAAD_LONG /* neaacdec.h declares all arguments as "unsigned long", but internally expects uint32_t pointers. To avoid gcc @@ -254,19 +233,18 @@ faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer *buffer, uint32_t *sample_rate_p = &sample_rate; #endif - size_t length; - const unsigned char *data = (const unsigned char *) - decoder_buffer_read(buffer, &length); - if (data == nullptr) { + auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer)); + if (data.IsEmpty()) { error.Set(faad_decoder_domain, "Empty file"); return false; } - nbytes = NeAACDecInit(decoder, - /* deconst hack, libfaad requires this */ - const_cast<unsigned char *>(data), - length, - sample_rate_p, &channels); + uint8_t channels; + int32_t nbytes = NeAACDecInit(decoder, + /* deconst hack, libfaad requires this */ + const_cast<uint8_t *>(data.data), + data.size, + sample_rate_p, &channels); if (nbytes < 0) { error.Set(faad_decoder_domain, "Not an AAC stream"); return false; @@ -286,16 +264,14 @@ static const void * faad_decoder_decode(NeAACDecHandle decoder, DecoderBuffer *buffer, NeAACDecFrameInfo *frame_info) { - size_t length; - const unsigned char *data = (const unsigned char *) - decoder_buffer_read(buffer, &length); - if (data == nullptr) + auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer)); + if (data.IsEmpty()) return nullptr; return NeAACDecDecode(decoder, frame_info, /* deconst hack, libfaad requires this */ - const_cast<unsigned char *>(data), - length); + const_cast<uint8_t *>(data.data), + data.size); } /** @@ -306,17 +282,12 @@ faad_decoder_decode(NeAACDecHandle decoder, DecoderBuffer *buffer, static float faad_get_file_time_float(InputStream &is) { - DecoderBuffer *buffer; - float length; - - buffer = decoder_buffer_new(nullptr, is, - FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); - length = faad_song_duration(buffer, is); + DecoderBuffer *buffer = + decoder_buffer_new(nullptr, is, + FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); + float length = faad_song_duration(buffer, is); if (length < 0) { - bool ret; - AudioFormat audio_format; - NeAACDecHandle decoder = NeAACDecOpen(); NeAACDecConfigurationPtr config = @@ -326,9 +297,9 @@ faad_get_file_time_float(InputStream &is) decoder_buffer_fill(buffer); - ret = faad_decoder_init(decoder, buffer, audio_format, - IgnoreError()); - if (ret) + AudioFormat audio_format; + if (faad_decoder_init(decoder, buffer, audio_format, + IgnoreError())) length = 0; NeAACDecClose(decoder); @@ -359,15 +330,10 @@ faad_get_file_time(InputStream &is) static void faad_stream_decode(Decoder &mpd_decoder, InputStream &is) { - float total_time = 0; - AudioFormat audio_format; - bool ret; - uint16_t bit_rate = 0; - DecoderBuffer *buffer; - - buffer = decoder_buffer_new(&mpd_decoder, is, - FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); - total_time = faad_song_duration(buffer, is); + DecoderBuffer *buffer = + decoder_buffer_new(&mpd_decoder, is, + FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); + const float total_time = faad_song_duration(buffer, is); /* create the libfaad decoder */ @@ -389,8 +355,8 @@ faad_stream_decode(Decoder &mpd_decoder, InputStream &is) /* initialize it */ Error error; - ret = faad_decoder_init(decoder, buffer, audio_format, error); - if (!ret) { + AudioFormat audio_format; + if (!faad_decoder_init(decoder, buffer, audio_format, error)) { LogError(error); NeAACDecClose(decoder); decoder_buffer_free(buffer); @@ -404,6 +370,7 @@ faad_stream_decode(Decoder &mpd_decoder, InputStream &is) /* the decoder loop */ DecoderCommand cmd; + unsigned bit_rate = 0; do { size_t frame_size; const void *decoded; @@ -483,7 +450,7 @@ static const char *const faad_mime_types[] = { "audio/aac", "audio/aacp", nullptr }; -const struct DecoderPlugin faad_decoder_plugin = { +const DecoderPlugin faad_decoder_plugin = { "faad", nullptr, nullptr, |