mp4ff: use faacDecInit2() to find the AAC track
Use faacDecInit2() instead of AudioSpecificConfig() to detect the AAC track in the MP4 file. This has a great advantage: it initializes the libfaad decoder, which the caller would normally do anyway - but now we can go without the AudioSpecificConfig() call. When decoder==NULL (called from mp4_tag_dup()), fall back to a mp4ff_get_track_type()==1 check, like other audio players do.
This commit is contained in:
parent
111c73e701
commit
51c59f6228
@ -812,7 +812,6 @@ int main() {
|
|||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
if test x$enable_aac = xyes; then
|
if test x$enable_aac = xyes; then
|
||||||
AC_CHECK_TYPES(mp4AudioSpecificConfig,,,[#include <faad.h>])
|
|
||||||
AC_CHECK_MEMBERS([faacDecConfiguration.downMatrix,faacDecConfiguration.dontUpSampleImplicitSBR,faacDecFrameInfo.samplerate],,,[#include <faad.h>])
|
AC_CHECK_MEMBERS([faacDecConfiguration.downMatrix,faacDecConfiguration.dontUpSampleImplicitSBR,faacDecFrameInfo.samplerate],,,[#include <faad.h>])
|
||||||
AC_DEFINE(HAVE_FAAD,1,[Define to use FAAD2 for AAC decoding])
|
AC_DEFINE(HAVE_FAAD,1,[Define to use FAAD2 for AAC decoding])
|
||||||
else
|
else
|
||||||
|
@ -38,39 +38,45 @@ struct mp4_context {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mp4_get_aac_track(mp4ff_t * infile)
|
mp4_get_aac_track(mp4ff_t * infile, faacDecHandle decoder,
|
||||||
|
uint32_t *sample_rate, unsigned char *channels_r)
|
||||||
{
|
{
|
||||||
/* find AAC track */
|
#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
|
||||||
int i, rc;
|
int i, rc;
|
||||||
int num_tracks = mp4ff_total_tracks(infile);
|
int num_tracks = mp4ff_total_tracks(infile);
|
||||||
|
|
||||||
for (i = 0; i < num_tracks; i++) {
|
for (i = 0; i < num_tracks; i++) {
|
||||||
unsigned char *buff = NULL;
|
unsigned char *buff = NULL;
|
||||||
unsigned int buff_size = 0;
|
unsigned int buff_size = 0;
|
||||||
#ifdef HAVE_MP4AUDIOSPECIFICCONFIG
|
|
||||||
mp4AudioSpecificConfig mp4ASC;
|
if (mp4ff_get_track_type(infile, i) != 1)
|
||||||
#else
|
/* not an audio track */
|
||||||
unsigned long dummy1_32;
|
continue;
|
||||||
unsigned char dummy2_8, dummy3_8, dummy4_8, dummy5_8, dummy6_8,
|
|
||||||
dummy7_8, dummy8_8;
|
if (decoder == NULL)
|
||||||
#endif
|
/* have don't have a decoder to initialize -
|
||||||
|
we're done now, because we found an audio
|
||||||
|
track */
|
||||||
|
return i;
|
||||||
|
|
||||||
mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
|
mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
|
||||||
|
if (buff == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (buff) {
|
rc = faacDecInit2(decoder, buff, buff_size,
|
||||||
#ifdef HAVE_MP4AUDIOSPECIFICCONFIG
|
sample_rate_r, channels_r);
|
||||||
rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
|
free(buff);
|
||||||
#else
|
|
||||||
rc = AudioSpecificConfig(buff, &dummy1_32, &dummy2_8,
|
if (rc >= 0)
|
||||||
&dummy3_8, &dummy4_8,
|
/* found a valid AAC track */
|
||||||
&dummy5_8, &dummy6_8,
|
|
||||||
&dummy7_8, &dummy8_8);
|
|
||||||
#endif
|
|
||||||
free(buff);
|
|
||||||
if (rc < 0)
|
|
||||||
continue;
|
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can't decode this */
|
/* can't decode this */
|
||||||
@ -95,21 +101,12 @@ mp4_seek(void *user_data, uint64_t position)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static faacDecHandle
|
static faacDecHandle
|
||||||
mp4_faad_new(mp4ff_t *mp4fh, int track, struct audio_format *audio_format)
|
mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
faacDecHandle decoder;
|
faacDecHandle decoder;
|
||||||
faacDecConfigurationPtr config;
|
faacDecConfigurationPtr config;
|
||||||
unsigned char *mp4_buffer;
|
int track;
|
||||||
unsigned int mp4_buffer_size;
|
|
||||||
uint32_t sample_rate;
|
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;
|
unsigned char channels;
|
||||||
|
|
||||||
decoder = faacDecOpen();
|
decoder = faacDecOpen();
|
||||||
@ -124,17 +121,14 @@ mp4_faad_new(mp4ff_t *mp4fh, int track, struct audio_format *audio_format)
|
|||||||
#endif
|
#endif
|
||||||
faacDecSetConfiguration(decoder, config);
|
faacDecSetConfiguration(decoder, config);
|
||||||
|
|
||||||
mp4_buffer = NULL;
|
track = mp4_get_aac_track(mp4fh, decoder, &sample_rate, &channels);
|
||||||
mp4_buffer_size = 0;
|
if (track < 0) {
|
||||||
mp4ff_get_decoder_config(mp4fh, track, &mp4_buffer, &mp4_buffer_size);
|
g_warning("No AAC track found");
|
||||||
|
|
||||||
if (faacDecInit2(decoder, mp4_buffer, mp4_buffer_size,
|
|
||||||
sample_rate_r, &channels) < 0) {
|
|
||||||
g_warning("Not an AAC stream.\n");
|
|
||||||
faacDecClose(decoder);
|
faacDecClose(decoder);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*track_r = track;
|
||||||
*audio_format = (struct audio_format){
|
*audio_format = (struct audio_format){
|
||||||
.bits = 16,
|
.bits = 16,
|
||||||
.channels = channels,
|
.channels = channels,
|
||||||
@ -196,14 +190,7 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
track = mp4_get_aac_track(mp4fh);
|
decoder = mp4_faad_new(mp4fh, &track, &audio_format);
|
||||||
if (track < 0) {
|
|
||||||
g_warning("No AAC track found in mp4 stream.\n");
|
|
||||||
mp4ff_close(mp4fh);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder = mp4_faad_new(mp4fh, track, &audio_format);
|
|
||||||
if (decoder == NULL) {
|
if (decoder == NULL) {
|
||||||
mp4ff_close(mp4fh);
|
mp4ff_close(mp4fh);
|
||||||
return;
|
return;
|
||||||
@ -374,7 +361,7 @@ mp4_tag_dup(const char *file)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
track = mp4_get_aac_track(mp4fh);
|
track = mp4_get_aac_track(mp4fh, NULL, NULL, NULL);
|
||||||
if (track < 0) {
|
if (track < 0) {
|
||||||
mp4ff_close(mp4fh);
|
mp4ff_close(mp4fh);
|
||||||
input_stream_close(&input_stream);
|
input_stream_close(&input_stream);
|
||||||
|
Loading…
Reference in New Issue
Block a user