summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-13 20:13:34 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-13 20:13:34 +0200
commit9eca6a34eab9a38ab3c44f7f4ccd1a6439080a34 (patch)
tree3404afacc6e3a726e1f54f9701ccc23df2cacf9f /plugins
parentf7d5d195e8f5442adf0284bdb1c1f612a484761b (diff)
aac plugin WIP
Diffstat (limited to 'plugins')
-rw-r--r--plugins/aac/Makefile.am2
-rw-r--r--plugins/aac/aac.c480
-rw-r--r--plugins/aac/aac_parser.c102
-rw-r--r--plugins/aac/aac_parser.h30
-rw-r--r--plugins/ffmpeg/ffmpeg.c26
5 files changed, 442 insertions, 198 deletions
diff --git a/plugins/aac/Makefile.am b/plugins/aac/Makefile.am
index 5a6e1ec7..a10ff510 100644
--- a/plugins/aac/Makefile.am
+++ b/plugins/aac/Makefile.am
@@ -1,7 +1,7 @@
if HAVE_AAC
aacdir = $(libdir)/$(PACKAGE)
pkglib_LTLIBRARIES = aac.la
-aac_la_SOURCES = aac.c
+aac_la_SOURCES = aac.c aac_parser.c aac_parser.h
aac_la_LDFLAGS = -module
aac_la_LIBADD = $(LDADD) $(FAAD2_LIBS)
diff --git a/plugins/aac/aac.c b/plugins/aac/aac.c
index 2516aa23..150cc5f1 100644
--- a/plugins/aac/aac.c
+++ b/plugins/aac/aac.c
@@ -23,6 +23,7 @@
#include <mp4ff.h>
#include <stdlib.h>
#include "../../deadbeef.h"
+#include "aac_parser.h"
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
@@ -33,11 +34,22 @@
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
+#define AAC_BUFFER_SIZE 8192
+#define OUT_BUFFER_SIZE 100000
+
typedef struct {
DB_fileinfo_t info;
+ NeAACDecHandle dec;
+ DB_FILE *file;
int startsample;
int endsample;
int currentsample;
+ char buffer[AAC_BUFFER_SIZE];
+ int remaining;
+ int faad_channels;
+
+ char out_buffer[OUT_BUFFER_SIZE];
+ int out_remaining;
} aac_info_t;
// allocate codec control structure
@@ -49,15 +61,181 @@ aac_open (void) {
return _info;
}
+static uint32_t
+aac_fs_read (void *user_data, void *buffer, uint32_t length) {
+// trace ("aac_fs_read\n");
+ DB_FILE *fp = (DB_FILE *)user_data;
+ return deadbeef->fread (buffer, 1, length, fp);
+}
+
+static uint32_t
+aac_fs_seek (void *user_data, uint64_t position) {
+// trace ("aac_fs_seek\n");
+ DB_FILE *fp = (DB_FILE *)user_data;
+ return deadbeef->fseek (fp, position, SEEK_SET);
+}
+
+static int
+parse_aac_stream(DB_FILE *fp, int *samplerate, int *channels, float *duration, int *totalsamples)
+{
+ int fsize = deadbeef->fgetlength (fp);
+ uint8_t buf[8192];
+
+ int nframesfound = 0;
+ int nsamples = 0;
+ int stream_sr = 0;
+ int stream_ch = 0;
+
+ int eof = 0;
+ int bufsize = 0;
+ do {
+ bufsize = sizeof (buf);
+ int bytesread = deadbeef->fread (buf, 1, bufsize, fp);
+ if (bytesread != bufsize) {
+ eof = 1;
+ }
+ bufsize = bytesread;
+
+ uint8_t *ptr = buf;
+ while (ptr < buf + bufsize - ADTS_HEADER_SIZE*8) {
+ int channels, samplerate, bitrate, samples;
+ int size = aac_sync (ptr, &channels, &samplerate, &bitrate, &samples);
+ if (size == 0) {
+ ptr++;
+ }
+ else {
+ //trace ("aac: sync: %d %d %d %d %d\n", channels, samplerate, bitrate, samples, size);
+ nframesfound++;
+ nsamples += samples;
+ if (!stream_sr) {
+ stream_sr = samplerate;
+ }
+ if (!stream_ch) {
+ stream_ch = channels;
+ }
+ ptr += size;
+ }
+ }
+ } while (totalsamples && !eof);
+
+ if (!nframesfound || !stream_sr || !nsamples || !bufsize) {
+ return -1;
+ }
+
+ *samplerate = stream_sr;
+ *channels = stream_ch;
+
+ if (totalsamples) {
+ *totalsamples = nsamples;
+ *duration = nsamples / (float)stream_sr;
+ }
+ else {
+ int totalsamples = fsize / bufsize * nsamples;
+ *duration = totalsamples / (float)stream_sr;
+ trace ("aac: duration=%f (%d samples @ %d Hz), fsize=%d, bufsize=%d\n", *duration, totalsamples, stream_sr, fsize, bufsize);
+ }
+
+ return 0;
+}
+
+// returns -1 for error, 0 for mp4, 1 for aac
+int
+aac_probe (DB_FILE *fp, float *duration, int *samplerate, int *channels, int *totalsamples) {
+ // try mp4
+
+ mp4ff_callback_t cb = {
+ .read = aac_fs_read,
+ .write = NULL,
+ .seek = aac_fs_seek,
+ .truncate = NULL,
+ .user_data = fp
+ };
+
+ *duration = -1;
+ mp4ff_t *mp4 = mp4ff_open_read (&cb);
+ if (!mp4) {
+ trace ("not an mp4 file\n");
+ return -1;
+ }
+ int ntracks = mp4ff_total_tracks (mp4);
+ if (ntracks > 0) {
+ trace ("m4a container detected, ntracks=%d\n", ntracks);
+ int i = -1;
+ trace ("looking for mp4 data...\n");
+ for (i = 0; i < ntracks; i++) {
+ unsigned char* buff = 0;
+ unsigned int buff_size = 0;
+ mp4AudioSpecificConfig mp4ASC;
+ mp4ff_get_decoder_config(mp4, i, &buff, &buff_size);
+ if(buff){
+ int rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
+ free(buff);
+ if(rc < 0)
+ continue;
+ break;
+ }
+ }
+
+ if (i != ntracks)
+ {
+ trace ("mp4 track: %d\n", i);
+ *samplerate = mp4ff_get_sample_rate (mp4, i);
+ *channels = mp4ff_get_channel_count (mp4, i);
+ int64_t length = mp4ff_get_track_duration (mp4, i);
+ int scale = mp4ff_time_scale (mp4, i);
+ if (length > 0 && scale > 0) {
+ *duration = length * 1000 / scale;
+ }
+ return 0;
+ }
+ }
+ mp4ff_close (mp4);
+ trace ("mp4 track not found, looking for aac stream...\n");
+
+ // not an mp4, try raw aac
+ deadbeef->rewind (fp);
+ if (parse_aac_stream (fp, samplerate, channels, duration, totalsamples) == -1) {
+ trace ("aac stream not found\n");
+ return -1;
+ }
+ trace ("found aac stream\n");
+ return 1;
+}
+
+
static int
aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
aac_info_t *info = (aac_info_t *)_info;
-// _info->bps = ;
-// _info->channels = ;
-// _info->samplerate = ;
-// _info->readpos = 0;
-// _info->plugin = &plugin;
+ info->file = deadbeef->fopen (it->fname);
+ if (!info->file) {
+ return -1;
+ }
+
+ // probe
+ float duration;
+ int samplerate;
+ int channels;
+ int totalsamples = 0;
+
+ int skip = deadbeef->junk_get_leading_size (info->file);
+ if (skip >= 0) {
+ deadbeef->fseek (info->file, skip, SEEK_SET);
+ }
+ int offs = deadbeef->ftell (info->file);
+
+ int res = aac_probe (info->file, &duration, &samplerate, &channels, &totalsamples);
+ if (res == -1) {
+ return -1;
+ }
+
+ duration = (float)totalsamples / samplerate;
+ deadbeef->pl_set_item_duration (it, duration);
+
+ _info->bps = 16;
+ _info->channels = channels;
+ _info->samplerate = samplerate;
+ _info->plugin = &plugin;
if (it->endsample > 0) {
info->startsample = it->startsample;
@@ -66,8 +244,42 @@ aac_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
}
else {
info->startsample = 0;
-// info->endsample = TOTALSAMPLES-1;
+ info->endsample = totalsamples-1;
+ }
+
+ deadbeef->fseek (info->file, offs, SEEK_SET);
+
+ info->remaining = deadbeef->fread (info->buffer, 1, AAC_BUFFER_SIZE, info->file);
+
+ info->dec = NeAACDecOpen ();
+ NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration (info->dec);
+ conf->dontUpSampleImplicitSBR = 1;
+ NeAACDecSetConfiguration (info->dec, conf);
+ unsigned long srate;
+ unsigned char ch;
+ int consumed = NeAACDecInit (info->dec, info->buffer, info->remaining, &srate, &ch);
+ if (consumed < 0) {
+ trace ("NeAACDecInit returned %d\n", consumed);
+ return -1;
+ }
+ if (consumed > info->remaining) {
+ trace ("NeAACDecInit consumed more than available! wtf?\n");
+ return -1;
}
+ if (consumed == info->remaining) {
+ info->remaining = 0;
+ }
+ else if (consumed > 0) {
+ memmove (info->buffer, info->buffer + consumed, info->remaining - consumed);
+ info->remaining -= consumed;
+ }
+ info->faad_channels = ch;
+// _info->samplerate = srate;
+
+ // recalculate duration
+// trace ("duration=%f, totalsamples = %d\n", duration, totalsamples);
+// trace ("NeAACDecInit returned samplerate=%d, channels=%d\n", (int)srate, (int)ch);
+
return 0;
}
@@ -75,15 +287,82 @@ static void
aac_free (DB_fileinfo_t *_info) {
aac_info_t *info = (aac_info_t *)_info;
if (info) {
+ if (info->file) {
+ deadbeef->fclose (info->file);
+ }
+ if (info->dec) {
+ NeAACDecClose (info->dec);
+ }
free (info);
}
}
static int
aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+ int initsize = size;
aac_info_t *info = (aac_info_t *)_info;
- info->currentsample += size / (_info->channels * _info->bps/8);
- return size;
+ int eof = 0;
+ int ch = min (_info->channels, 2);
+ int sample_size = ch * (_info->bps >> 3);
+
+ while (size > 0) {
+ if (info->out_remaining > 0) {
+ int n = size / sample_size;
+ n = min (info->out_remaining, n);
+
+ char *src = info->out_buffer;
+ for (int i = 0; i < n; i++) {
+ memcpy (bytes, src, sample_size);
+ bytes += sample_size;
+ src += info->faad_channels * 2;
+ }
+
+ size -= n * sample_size;
+ if (n == info->out_remaining) {
+ info->out_remaining = 0;
+ }
+ else {
+ memmove (info->out_buffer, src, (info->out_remaining - n) * info->faad_channels * 2);
+ info->out_remaining -= n;
+ }
+ continue;
+ }
+
+ if (info->remaining < AAC_BUFFER_SIZE) {
+ size_t res = deadbeef->fread (info->buffer + info->remaining, 1, AAC_BUFFER_SIZE-info->remaining, info->file);
+ if (res == 0) {
+ eof = 1;
+ }
+ }
+ NeAACDecFrameInfo frame_info;
+ char *samples = NeAACDecDecode (info->dec, &frame_info, info->buffer, info->remaining);
+ if (!samples) {
+ //trace ("NeAACDecDecode returned NULL\n");
+ break;
+ }
+
+
+ int consumed = frame_info.bytesconsumed;
+ if (consumed > info->remaining) {
+ trace ("NeAACDecDecode consumed more than available! wtf?\n");
+ break;
+ }
+ if (consumed == info->remaining) {
+ info->remaining = 0;
+ }
+ else if (consumed > 0) {
+ memmove (info->buffer, info->buffer + consumed, info->remaining - consumed);
+ info->remaining -= consumed;
+ }
+
+ if (frame_info.samples > 0) {
+ memcpy (info->out_buffer, samples, frame_info.samples * 2);
+ info->out_remaining = frame_info.samples / frame_info.channels;
+ }
+ }
+
+ info->currentsample += (initsize-size) / sample_size;
+ return initsize-size;
}
static int
@@ -100,107 +379,6 @@ aac_seek (DB_fileinfo_t *_info, float t) {
return aac_seek_sample (_info, t * _info->samplerate);
}
-static uint32_t
-aac_fs_read (void *user_data, void *buffer, uint32_t length) {
-// trace ("aac_fs_read\n");
- DB_FILE *fp = (DB_FILE *)user_data;
- return deadbeef->fread (buffer, 1, length, fp);
-}
-
-static uint32_t
-aac_fs_seek (void *user_data, uint64_t position) {
-// trace ("aac_fs_seek\n");
- DB_FILE *fp = (DB_FILE *)user_data;
- return deadbeef->fseek (fp, position, SEEK_SET);
-}
-
-/*
- * These routines are derived from MPlayer.
- */
-
-/// \param srate (out) sample rate
-/// \param num (out) number of audio frames in this ADTS frame
-/// \return size of the ADTS frame in bytes
-/// aac_parse_frames needs a buffer at least 8 bytes long
-static int
-aac_parse_frame(uint8_t *buf, int *srate, int *num)
-{
- int i = 0, sr, fl = 0;
- static int srates[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0, 0, 0};
-
- if((buf[i] != 0xFF) || ((buf[i+1] & 0xF6) != 0xF0))
- return 0;
-
- /* We currently have no use for the id below.
- id = (buf[i+1] >> 3) & 0x01; //id=1 mpeg2, 0: mpeg4
- */
- sr = (buf[i+2] >> 2) & 0x0F;
- if(sr > 11)
- return 0;
- *srate = srates[sr];
-
- fl = ((buf[i+3] & 0x03) << 11) | (buf[i+4] << 3) | ((buf[i+5] >> 5) & 0x07);
- *num = (buf[i+6] & 0x02) + 1;
-
- return fl;
-}
-
-static int
-parse_aac_stream(DB_FILE *stream)
-{
- int totalframes = 0;
- int cnt = 0, len, srate, num;
- int8_t c;
- off_t init, probed;
- static uint8_t buf[8];
-
- init = probed = deadbeef->ftell(stream);
- while(probed-init <= 32768 && cnt < 8)
- {
- c = 0;
- while(probed-init <= 32768 && c != 0xFF)
- {
- if (deadbeef->fread (&c, 1, 1, stream) != 1) {
- trace ("parse_aac_stream: failed to read frame header\n");
- break;
-// trace ("aac: duration=%d samples (%f seconds), srate=%d\n", totalframes, (float)totalframes/(srate?srate:1), srate);
-// return 1;
- }
- if(c < 0) {
-// trace ("parse_aac_stream: header<0\n");
- continue;
-// trace ("aac: duration=%d samples (%f seconds), srate=%d\n", totalframes, (float)totalframes/(srate?srate:1), srate);
-// return 0;
- }
- probed = deadbeef->ftell(stream);
- }
- buf[0] = 0xFF;
- if(deadbeef->fread(&(buf[1]), 1, 7, stream) < 7) {
- trace ("parse_aac_stream: failed to read frame\n");
- break;
-// trace ("aac: duration=%d samples (%f seconds), srate=%d\n", totalframes, (float)totalframes/(srate?srate:1), srate);
-// return 0;
- }
-
- len = aac_parse_frame(buf, &srate, &num);
- trace ("parse_aac_stream: frame: srate=%d, numsamples=%d (%d)\n", srate, num, totalframes);
- if(len > 0)
- {
- cnt++;
- deadbeef->fseek(stream, len - 8, SEEK_CUR);
- totalframes += num;
- }
- probed = deadbeef->ftell(stream);
- }
-
- trace ("aac: duration=%d samples (%f seconds), srate=%d\n", totalframes, (float)totalframes/(srate?srate:1), srate);
- if(cnt < 8)
- return 0;
-
-
- return 1;
-}
-
static DB_playItem_t *
aac_insert (DB_playItem_t *after, const char *fname) {
trace ("adding %s\n", fname);
@@ -220,93 +398,27 @@ aac_insert (DB_playItem_t *after, const char *fname) {
deadbeef->fseek (fp, skip, SEEK_SET);
}
-#if 0
- char temp[8192];
- if (deadbeef->fread (temp, 1, sizeof (temp), fp) != sizeof (temp)) {
- return NULL;
- }
- NeAACDecHandle h = NeAACDecOpen ();
-
- unsigned long srate;
- unsigned char channels;
- const char *ftype = "aac";
- NeAACDecInit (h, temp, sizeof (temp), &srate, &channels);
- trace ("srate=%d, channels=%d\n", (int)srate, (int)channels);
- exit (-1);
-#endif
-
- // try mp4
-
- mp4ff_callback_t cb = {
- .read = aac_fs_read,
- .write = NULL,
- .seek = aac_fs_seek,
- .truncate = NULL,
- .user_data = fp
- };
-
- float duration = -1;
const char *ftype = NULL;
- mp4ff_t *mp4 = mp4ff_open_read (&cb);
- if (!mp4) {
- trace ("not an mp4 file\n");
+ float duration;
+ int samplerate;
+ int channels;
+ int res = aac_probe (fp, &duration, &samplerate, &channels, NULL);
+ if (res == -1) {
deadbeef->fclose (fp);
return NULL;
}
- int ntracks = mp4ff_total_tracks (mp4);
- trace ("m4a container detected, ntracks=%d\n", ntracks);
- int i = -1;
- trace ("looking for mp4 data...\n");
- for (i = 0; i < ntracks; i++) {
- unsigned char* buff = 0;
- unsigned int buff_size = 0;
- mp4AudioSpecificConfig mp4ASC;
- mp4ff_get_decoder_config(mp4, i, &buff, &buff_size);
- if(buff){
- int rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
- free(buff);
- if(rc < 0)
- continue;
- break;
- }
- }
-
- int samplerate = -1;
- int channels = -1;
- if (i != ntracks)
- {
- trace ("mp4 track: %d\n", i);
- samplerate = mp4ff_get_sample_rate (mp4, i);
- channels = mp4ff_get_channel_count (mp4, i);
- int64_t length = mp4ff_get_track_duration (mp4, i);
- int scale = mp4ff_time_scale (mp4, i);
- if (length > 0 && scale > 0) {
- duration = length * 1000 / scale;
- }
+ else if (res == 0) {
ftype = "mp4";
}
- else {
- mp4ff_close (mp4);
- trace ("mp4 track not found, looking for aac stream...\n");
-
- // not an mp4, try raw aac
- deadbeef->rewind (fp);
- if (parse_aac_stream (fp)) {
- trace ("aac stream not found\n");
- deadbeef->fclose (fp);
- return NULL;
- }
- else {
- trace ("found aac stream\n");
- ftype = "aac";
- }
+ else if (res == 1) {
+ ftype = "aac";
}
DB_playItem_t *it = deadbeef->pl_item_alloc ();
it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
it->fname = strdup (fname);
it->filetype = ftype;
-// deadbeef->pl_set_item_duration (it, duration);
+ deadbeef->pl_set_item_duration (it, duration);
// trace ("duration: %f sec\n", duration);
// read tags
diff --git a/plugins/aac/aac_parser.c b/plugins/aac/aac_parser.c
new file mode 100644
index 00000000..eea957df
--- /dev/null
+++ b/plugins/aac/aac_parser.c
@@ -0,0 +1,102 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+#include <stdio.h>
+#include "aac_parser.h"
+
+#define min(x,y) ((x)<(y)?(x):(y))
+#define max(x,y) ((x)>(y)?(x):(y))
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+static const int aac_sample_rates[16] = {
+ 96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000, 7350
+};
+
+static const int aac_channels[8] = {
+ 0, 1, 2, 3, 4, 5, 6, 8
+};
+
+// buf size must be at least ADTS_HEADER_SIZE*8
+// returns frame size
+int
+aac_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples)
+{
+ int size, rdb;
+
+ // 12 sync bits
+ if (buf[0] != 0xff || (buf[1]&0xf0) != 0xf0) {
+ trace ("unsync\n");
+ return 0;
+ }
+
+ int id = (buf[1] & 0x08) >> 7;
+
+ int version = id == 0 ? 4 : 2;
+
+ int layer = (buf[1] & 0x06) >> 5;
+ int protection_abs = (buf[1] & 0x01);
+
+ int header_size = protection_abs > 0 ? 7 : 9;
+
+ int profile_objecttype = (buf[2] & 0xC0) >> 6;
+
+ //const char *profiles[4] = {
+ // "0 Main profile AAC MAIN",
+ // "1 Low Complexity profile (LC)AAC LC",
+ // "2 Scalable Sample Rate profile (SSR)AAC SSR",
+ // "3 (reserved)AAC LTP"
+ //};
+ //trace ("profile: %s\n", profiles[profile_objecttype]);
+
+ int sample_freq_index = (buf[2] & 0x3C) >> 2;
+ if (!aac_sample_rates[sample_freq_index]) {
+ //trace ("invalid samplerate\n");
+ return 0;
+ }
+ //trace ("samplerate %d (#%d)\n", aac_sample_rates[sample_freq_index], sample_freq_index);
+ int private_bit = (buf[2] & 0x02) >> 1;
+
+ int channel_conf = ((buf[2] & 0x01) << 2) | ((buf[3] & 0xC0) >> 6);
+ if (!aac_channels[channel_conf]) {
+ //trace ("invalid channels\n");
+ return 0;
+ }
+ //trace ("channels %d\n", aac_channels[channel_conf]);
+ int orig_copy = (buf[3] & 0x20) >> 5;
+ int home = (buf[3] & 0x10) >> 4;
+ int copyright_ident_bit = (buf[3] & 0x08) >> 3;
+ int copyright_ident_start = (buf[3] & 0x04) >> 2;
+ size = ((buf[3] & 0x03) << 11) | (buf[4] << 3) | ((buf[5] & 0xE0) >> 5);
+ if(size < ADTS_HEADER_SIZE) {
+ //trace ("invalid size\n");
+ return 0;
+ }
+ int adts_buffer_fullness = ((buf[5] & 0x1F) << 3) | ((buf[6] & 0xFC) >> 2);
+ rdb = buf[7] & 0x03;
+
+ *channels = aac_channels[channel_conf];
+ *sample_rate = aac_sample_rates[sample_freq_index];
+ *samples = rdb * 1024;
+ *bit_rate = size * 8 * *sample_rate / *samples;
+
+ return size;
+}
+
diff --git a/plugins/aac/aac_parser.h b/plugins/aac/aac_parser.h
new file mode 100644
index 00000000..4f872d4b
--- /dev/null
+++ b/plugins/aac/aac_parser.h
@@ -0,0 +1,30 @@
+/*
+ DeaDBeeF - ultimate music player for GNU/Linux systems with X11
+ Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __AAC_PARSER_H
+#define __AAC_PARSER_H
+
+#include <stdint.h>
+
+#define ADTS_HEADER_SIZE 7
+
+int
+aac_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples);
+
+#endif
diff --git a/plugins/ffmpeg/ffmpeg.c b/plugins/ffmpeg/ffmpeg.c
index 447d2ebe..eb99ff9b 100644
--- a/plugins/ffmpeg/ffmpeg.c
+++ b/plugins/ffmpeg/ffmpeg.c
@@ -55,20 +55,20 @@
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
-static const char * exts[] = { "mp+", "mpp", "wma", "shn", "aa3", "oma", "ac3", "vqf", NULL };
+static const char * exts[] = { "m4a", "mp+", "mpp", "wma", "shn", "aa3", "oma", "ac3", "vqf", NULL };
enum {
// FT_AAC = 0,
-// FT_M4A = 1,
- FT_WMA = 0,
- FT_SHORTEN = 1,
- FT_ATRAC3 = 2,
- FT_VQF = 3,
- FT_TTA = 4,
- FT_UNKNOWN = 5
+ FT_M4A = 0,
+ FT_WMA = 1,
+ FT_SHORTEN = 2,
+ FT_ATRAC3 = 3,
+ FT_VQF = 4,
+ FT_TTA = 5,
+ FT_UNKNOWN = 6
};
-static const char *filetypes[] = { "WMA", "Shorten", "atrac3", "VQF", "TTA", "FFMPEG (unknown)", NULL };
+static const char *filetypes[] = { "M4A", "WMA", "Shorten", "atrac3", "VQF", "TTA", "FFMPEG (unknown)", NULL };
#define FF_PROTOCOL_NAME "deadbeef"
@@ -516,9 +516,9 @@ ffmpeg_insert (DB_playItem_t *after, const char *fname) {
ext++;
}
-// if (!strcasecmp (ext, "m4a")) {
-// filetype = filetypes[FT_M4A];
-// }
+ if (!strcasecmp (ext, "m4a")) {
+ filetype = filetypes[FT_M4A];
+ }
// if (!strcasecmp (ext, "aac")) {
// filetype = filetypes[FT_AAC];
// }
@@ -609,7 +609,7 @@ ffmpeg_vfs_read(URLContext *h, unsigned char *buf, int size)
}
static int
-ffmpeg_vfs_write(URLContext *h, unsigned char *buf, int size)
+ffmpeg_vfs_write(URLContext *h, const unsigned char *buf, int size)
{
return -1;
}