summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-16 20:32:37 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-16 20:32:37 +0200
commit3a53e93153ef7cdf3054bdabdbba5b2aee6d9cdd (patch)
treed1bc223a7e83ca80177e8880ba50d290ac8b1e60 /plugins
parent5fd10493923e9d3d3028b522736816aa95eca788 (diff)
raw aac seeking
Diffstat (limited to 'plugins')
-rw-r--r--plugins/aac/aac.c139
-rw-r--r--plugins/aac/aac_parser.c4
-rw-r--r--plugins/aac/aac_parser.h2
3 files changed, 111 insertions, 34 deletions
diff --git a/plugins/aac/aac.c b/plugins/aac/aac.c
index 8a8f0895..ab3e30ce 100644
--- a/plugins/aac/aac.c
+++ b/plugins/aac/aac.c
@@ -83,47 +83,54 @@ aac_fs_seek (void *user_data, uint64_t position) {
static int
parse_aac_stream(DB_FILE *fp, int *samplerate, int *channels, float *duration, int *totalsamples)
{
+ int offs = deadbeef->ftell (fp);
int fsize = deadbeef->fgetlength (fp);
- uint8_t buf[8192];
+ uint8_t buf[ADTS_HEADER_SIZE*8];
- int nframesfound = 0;
int nsamples = 0;
int stream_sr = 0;
int stream_ch = 0;
int eof = 0;
int bufsize = 0;
+ int remaining = 0;
+
+ int frame = 0;
+
do {
+ int size = sizeof (buf) - bufsize;
+ if (deadbeef->fread (buf + bufsize, 1, size, fp) != size) {
+ trace ("parse_aac_stream: eof\n");
+ break;
+ }
bufsize = sizeof (buf);
- int bytesread = deadbeef->fread (buf, 1, bufsize, fp);
- if (bytesread != bufsize) {
- eof = 1;
+
+ int channels, samplerate, bitrate, samples;
+ size = aac_sync (buf, &channels, &samplerate, &bitrate, &samples);
+ if (size == 0) {
+ memmove (buf, buf+1, sizeof (buf)-1);
+ bufsize--;
+ continue;
}
- 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: frame #%d sync: %d %d %d %d %d\n", frame, channels, samplerate, bitrate, samples, size);
+ frame++;
+ nsamples += samples;
+ if (!stream_sr) {
+ stream_sr = samplerate;
}
- 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;
+ if (!stream_ch) {
+ stream_ch = channels;
}
+ if (deadbeef->fseek (fp, size-sizeof(buf), SEEK_CUR) == -1) {
+ trace ("parse_aac_stream: invalid seek %d\n", size-sizeof(buf));
+ break;
+ }
+ bufsize = 0;
}
- } while (totalsamples && !eof);
+ } while (totalsamples || frame < 100);
- if (!nframesfound || !stream_sr || !nsamples || !bufsize) {
+ if (!frame || !stream_sr || !nsamples) {
return -1;
}
@@ -133,11 +140,13 @@ parse_aac_stream(DB_FILE *fp, int *samplerate, int *channels, float *duration, i
if (totalsamples) {
*totalsamples = nsamples;
*duration = nsamples / (float)stream_sr;
+ trace ("aac: duration=%f (%d samples @ %d Hz), fsize=%d\n", *duration, *totalsamples, stream_sr, fsize);
}
else {
- int totalsamples = fsize / bufsize * nsamples;
+ int pos = deadbeef->ftell (fp);
+ int totalsamples = fsize / (pos-offs) * 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);
+ trace ("aac: duration=%f (%d samples @ %d Hz), fsize=%d\n", *duration, totalsamples, stream_sr, fsize);
}
return 0;
@@ -456,10 +465,13 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
if (res == 0) {
eof = 1;
}
+ info->remaining += res;
}
+ //trace ("NeAACDecDecode %d bytes %d offs\n", info->remaining, deadbeef->ftell (info->file));
samples = NeAACDecDecode (info->dec, &frame_info, info->buffer, info->remaining);
if (!samples) {
+ trace ("NeAACDecDecode failed\n");
break;
}
int consumed = frame_info.bytesconsumed;
@@ -483,9 +495,68 @@ aac_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
info->currentsample += (initsize-size) / sample_size;
+ if (size != 0) {
+ trace ("aac_read_int16 eof\n");
+ }
return initsize-size;
}
+// returns -1 on error, 0 on success
+int
+seek_raw_aac (aac_info_t *info, int sample) {
+ deadbeef->rewind (info->file);
+
+ int offs = deadbeef->ftell (info->file);
+ int fsize = deadbeef->fgetlength (info->file);
+ uint8_t buf[ADTS_HEADER_SIZE*8];
+
+ int nsamples = 0;
+ int stream_sr = 0;
+ int stream_ch = 0;
+
+ int eof = 0;
+ int bufsize = 0;
+ int remaining = 0;
+
+ int frame = 0;
+
+ int frame_samples = 0;
+ int curr_sample = 0;
+
+ do {
+ curr_sample += frame_samples;
+ int size = sizeof (buf) - bufsize;
+ if (deadbeef->fread (buf + bufsize, 1, size, info->file) != size) {
+ trace ("seek_raw_aac: eof\n");
+ break;
+ }
+ bufsize = sizeof (buf);
+
+ int channels, samplerate, bitrate;
+ size = aac_sync (buf, &channels, &samplerate, &bitrate, &frame_samples);
+ if (size == 0) {
+ memmove (buf, buf+1, sizeof (buf)-1);
+ bufsize--;
+ continue;
+ }
+ else {
+ //trace ("aac: frame #%d sync: %d %d %d %d %d\n", frame, channels, samplerate, bitrate, samples, size);
+ frame++;
+ if (deadbeef->fseek (info->file, size-sizeof(buf), SEEK_CUR) == -1) {
+ trace ("seek_raw_aac: invalid seek %d\n", size-sizeof(buf));
+ break;
+ }
+ bufsize = 0;
+ }
+ } while (curr_sample + frame_samples < sample);
+
+ if (curr_sample + frame_samples < sample) {
+ return -1;
+ }
+
+ return sample - curr_sample;
+}
+
static int
aac_seek_sample (DB_fileinfo_t *_info, int sample) {
aac_info_t *info = (aac_info_t *)_info;
@@ -494,10 +565,16 @@ aac_seek_sample (DB_fileinfo_t *_info, int sample) {
if (info->mp4file) {
info->mp4sample = sample / (info->mp4framesize-1);
info->skipsamples = sample - info->mp4sample * (info->mp4framesize-1);
- info->remaining = 0;
- info->out_remaining = 0;
}
-
+ else {
+ int res = seek_raw_aac (info, sample);
+ if (res < 0) {
+ return -1;
+ }
+ info->skipsamples = res;
+ }
+ info->remaining = 0;
+ info->out_remaining = 0;
info->currentsample = sample - info->startsample;
_info->readpos = (float)info->currentsample / _info->samplerate;
return 0;
diff --git a/plugins/aac/aac_parser.c b/plugins/aac/aac_parser.c
index eea957df..32571aff 100644
--- a/plugins/aac/aac_parser.c
+++ b/plugins/aac/aac_parser.c
@@ -34,8 +34,6 @@ 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)
{
@@ -43,7 +41,7 @@ aac_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int
// 12 sync bits
if (buf[0] != 0xff || (buf[1]&0xf0) != 0xf0) {
- trace ("unsync\n");
+ //trace ("unsync\n");
return 0;
}
diff --git a/plugins/aac/aac_parser.h b/plugins/aac/aac_parser.h
index 4f872d4b..53e7916d 100644
--- a/plugins/aac/aac_parser.h
+++ b/plugins/aac/aac_parser.h
@@ -24,6 +24,8 @@
#define ADTS_HEADER_SIZE 7
+// 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);