aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder')
-rw-r--r--src/decoder/mp4ff_plugin.c118
1 files changed, 65 insertions, 53 deletions
diff --git a/src/decoder/mp4ff_plugin.c b/src/decoder/mp4ff_plugin.c
index e12e82d6e..fb0f00776 100644
--- a/src/decoder/mp4ff_plugin.c
+++ b/src/decoder/mp4ff_plugin.c
@@ -94,6 +94,65 @@ mp4_seek(void *user_data, uint64_t position)
? 0 : -1;
}
+static faacDecHandle
+mp4_faad_new(mp4ff_t *mp4fh, int track, struct audio_format *audio_format)
+{
+ faacDecHandle decoder;
+ faacDecConfigurationPtr config;
+ unsigned char *mp4_buffer;
+ unsigned int mp4_buffer_size;
+ uint32_t sample_rate;
+#ifdef HAVE_FAAD_LONG
+ /* neaacdec.h declares all arguments as "unsigned long", but
+ internally expects uint32_t pointers. To avoid gcc
+ warnings, use this workaround. */
+ unsigned long *sample_rate_r = (unsigned long*)&sample_rate;
+#else
+ uint32_t *sample_rate_r = &sample_rate;
+#endif
+ unsigned char channels;
+
+ decoder = faacDecOpen();
+
+ config = faacDecGetCurrentConfiguration(decoder);
+ config->outputFormat = FAAD_FMT_16BIT;
+#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX
+ config->downMatrix = 1;
+#endif
+#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
+ config->dontUpSampleImplicitSBR = 0;
+#endif
+ faacDecSetConfiguration(decoder, config);
+
+ mp4_buffer = NULL;
+ mp4_buffer_size = 0;
+ mp4ff_get_decoder_config(mp4fh, track, &mp4_buffer, &mp4_buffer_size);
+
+ if (faacDecInit2(decoder, mp4_buffer, mp4_buffer_size,
+ sample_rate_r, &channels) < 0) {
+ g_warning("Not an AAC stream.\n");
+ faacDecClose(decoder);
+ return NULL;
+ }
+
+ *audio_format = (struct audio_format){
+ .bits = 16,
+ .channels = channels,
+ .sample_rate = sample_rate,
+ };
+
+ if (!audio_format_valid(audio_format)) {
+ g_warning("Invalid audio format: %u:%u:%u\n",
+ audio_format->sample_rate,
+ audio_format->bits,
+ audio_format->channels);
+ faacDecClose(decoder);
+ return NULL;
+ }
+
+ return decoder;
+}
+
static void
mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
{
@@ -113,19 +172,8 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
faacDecHandle decoder;
struct audio_format audio_format;
faacDecFrameInfo frame_info;
- faacDecConfigurationPtr config;
unsigned char *mp4_buffer;
unsigned int mp4_buffer_size;
- uint32_t sample_rate;
-#ifdef HAVE_FAAD_LONG
- /* neaacdec.h declares all arguments as "unsigned long", but
- internally expects uint32_t pointers. To avoid gcc
- warnings, use this workaround. */
- unsigned long *sample_rate_r = (unsigned long*)&sample_rate;
-#else
- uint32_t *sample_rate_r = &sample_rate;
-#endif
- unsigned char channels;
long sample_id;
long num_samples;
long dur;
@@ -155,26 +203,8 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
return;
}
- decoder = faacDecOpen();
-
- config = faacDecGetCurrentConfiguration(decoder);
- config->outputFormat = FAAD_FMT_16BIT;
-#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX
- config->downMatrix = 1;
-#endif
-#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
- config->dontUpSampleImplicitSBR = 0;
-#endif
- faacDecSetConfiguration(decoder, config);
-
- mp4_buffer = NULL;
- mp4_buffer_size = 0;
- mp4ff_get_decoder_config(mp4fh, track, &mp4_buffer, &mp4_buffer_size);
-
- if (faacDecInit2(decoder, mp4_buffer, mp4_buffer_size,
- sample_rate_r, &channels) < 0) {
- g_warning("Not an AAC stream.\n");
- faacDecClose(decoder);
+ decoder = mp4_faad_new(mp4fh, track, &audio_format);
+ if (decoder == NULL) {
mp4ff_close(mp4fh);
return;
}
@@ -182,8 +212,6 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
file_time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
scale = mp4ff_time_scale(mp4fh, track);
- free(mp4_buffer);
-
if (scale < 0) {
g_warning("Error getting audio format of mp4 AAC track.\n");
faacDecClose(decoder);
@@ -204,22 +232,6 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
seek_table = g_malloc(sizeof(float) * num_samples);
- audio_format = (struct audio_format){
- .bits = 16,
- .channels = channels,
- .sample_rate = sample_rate,
- };
-
- if (!audio_format_valid(&audio_format)) {
- g_warning("Invalid audio format: %u:%u:%u\n",
- audio_format.sample_rate,
- audio_format.bits,
- audio_format.channels);
- faacDecClose(decoder);
- mp4ff_close(mp4fh);
- return;
- }
-
decoder_initialized(mpd_decoder, &audio_format,
input_stream->seekable,
total_time);
@@ -303,12 +315,12 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
}
#endif
- if (channels * (unsigned long)(dur + offset) > frame_info.samples) {
- dur = frame_info.samples / channels;
+ if (audio_format.channels * (unsigned long)(dur + offset) > frame_info.samples) {
+ dur = frame_info.samples / audio_format.channels;
offset = 0;
}
- sample_count = (unsigned long)(dur * channels);
+ sample_count = (unsigned long)(dur * audio_format.channels);
if (sample_count > 0) {
initial = 0;
@@ -319,7 +331,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
sample_buffer_length = sample_count * 2;
- sample_buffer += offset * channels * 2;
+ sample_buffer += offset * audio_format.channels * 2;
cmd = decoder_data(mpd_decoder, input_stream,
sample_buffer, sample_buffer_length,