aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/decoder/faad_plugin.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/decoder/faad_plugin.c b/src/decoder/faad_plugin.c
index 96a6bd0d4..7cb939ee5 100644
--- a/src/decoder/faad_plugin.c
+++ b/src/decoder/faad_plugin.c
@@ -171,6 +171,8 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is)
tagsize = 0;
if (length >= 10 && !memcmp(data, "ID3", 3)) {
+ /* skip the ID3 tag */
+
tagsize = (data[6] << 21) | (data[7] << 14) |
(data[8] << 7) | (data[9] << 0);
@@ -185,6 +187,7 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is)
if (is->seekable && length >= 2 &&
data[0] == 0xFF && ((data[1] & 0xF6) == 0xF0)) {
+ /* obtain the duration from the ADTS header */
float song_length = adts_song_duration(buffer);
input_stream_seek(is, tagsize, SEEK_SET);
@@ -196,6 +199,7 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is)
return song_length;
} else if (length >= 5 && memcmp(data, "ADIF", 4) == 0) {
+ /* obtain the duration from the ADIF header */
unsigned bit_rate;
size_t skip_size = (data[4] & 0x80) ? 9 : 0;
@@ -296,6 +300,11 @@ faad_decoder_decode(faacDecHandle decoder, struct decoder_buffer *buffer,
return result;
}
+/**
+ * Get a song file's total playing time in seconds, as a float.
+ * Returns 0 if the duration is unknown, and a negative value if the
+ * file is invalid.
+ */
static float
faad_get_file_time_float(const char *file)
{
@@ -337,6 +346,11 @@ faad_get_file_time_float(const char *file)
return length;
}
+/**
+ * Get a song file's total playing time in seconds, as an int.
+ * Returns 0 if the duration is unknown, and a negative value if the
+ * file is invalid.
+ */
static int
faad_get_file_time(const char *file)
{
@@ -370,6 +384,8 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
total_time = faad_song_duration(buffer, is);
+ /* create the libfaad decoder */
+
decoder = faacDecOpen();
config = faacDecGetCurrentConfiguration(decoder);
@@ -389,6 +405,8 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
decoder_buffer_fill(buffer);
}
+ /* initialize it */
+
ret = faad_decoder_init(decoder, buffer, &audio_format);
if (!ret) {
g_warning("Error not a AAC stream.\n");
@@ -402,15 +420,26 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
return;
}
+ /* initialize the MPD core */
+
decoder_initialized(mpd_decoder, &audio_format, false, total_time);
+ /* the decoder loop */
+
file_time = 0.0;
do {
- size_t frame_size = adts_find_frame(buffer);
+ size_t frame_size;
+
+ /* find the next frame */
+
+ frame_size = adts_find_frame(buffer);
if (frame_size == 0)
+ /* end of file */
break;
+ /* decode it */
+
decoded = faad_decoder_decode(decoder, buffer, &frame_info);
if (frame_info.error > 0) {
@@ -436,6 +465,8 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
decoder_buffer_consume(buffer, frame_info.bytesconsumed);
+ /* update bit rate and position */
+
sample_count = (unsigned long)frame_info.samples;
if (sample_count > 0) {
bit_rate = frame_info.bytesconsumed * 8.0 *
@@ -446,6 +477,8 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
audio_format.sample_rate;
}
+ /* send PCM samples to MPD */
+
decoded_length = sample_count * 2;
cmd = decoder_data(mpd_decoder, is, decoded,
@@ -453,6 +486,8 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
bit_rate, NULL);
} while (cmd != DECODE_COMMAND_STOP);
+ /* cleanup */
+
faacDecClose(decoder);
}