diff options
author | 2010-06-13 20:13:34 +0200 | |
---|---|---|
committer | 2010-06-13 20:13:34 +0200 | |
commit | 9eca6a34eab9a38ab3c44f7f4ccd1a6439080a34 (patch) | |
tree | 3404afacc6e3a726e1f54f9701ccc23df2cacf9f /plugins | |
parent | f7d5d195e8f5442adf0284bdb1c1f612a484761b (diff) |
aac plugin WIP
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/aac/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/aac/aac.c | 480 | ||||
-rw-r--r-- | plugins/aac/aac_parser.c | 102 | ||||
-rw-r--r-- | plugins/aac/aac_parser.h | 30 | ||||
-rw-r--r-- | plugins/ffmpeg/ffmpeg.c | 26 |
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; } |