summaryrefslogtreecommitdiff
path: root/plugins/wma
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2013-01-13 20:10:46 +0100
committerGravatar waker <wakeroid@gmail.com>2013-01-13 20:10:46 +0100
commitbe7fad9b79477270afce5544c6a18f7d6f518eca (patch)
tree8d024b4db0e17d9884ad09cc3dfcb5bba2b48b72 /plugins/wma
parent0415d009581f55e1ef931d870eea7f16a87776d6 (diff)
wma seeking
Diffstat (limited to 'plugins/wma')
-rw-r--r--plugins/wma/libasf/asf.c10
-rw-r--r--plugins/wma/wma_plugin.c76
2 files changed, 53 insertions, 33 deletions
diff --git a/plugins/wma/libasf/asf.c b/plugins/wma/libasf/asf.c
index fd71a2b5..ee07953a 100644
--- a/plugins/wma/libasf/asf.c
+++ b/plugins/wma/libasf/asf.c
@@ -409,9 +409,12 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
int time, duration, delta, temp, count=0;
/*estimate packet number from bitrate*/
- int initial_packet = deadbeef->ftell (fp)/wfx->packet_size;
+ int initial_packet = 0;//deadbeef->ftell (fp)/wfx->packet_size;
+ printf ("initial_packet=%d\n", initial_packet);
int packet_num = (((int64_t)ms)*(wfx->bitrate>>3))/wfx->packet_size/1000;
+ printf ("packet_num=%d (%d * %d / %d / 1000)\n", packet_num, ms, wfx->bitrate, wfx->packet_size);
int last_packet = deadbeef->fgetlength (fp) / wfx->packet_size;
+ printf ("last_packet=%d\n", last_packet);
if (packet_num > last_packet) {
packet_num = last_packet;
@@ -419,6 +422,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
/*calculate byte address of the start of that packet*/
int packet_offset = packet_num*wfx->packet_size;
+ printf ("packet_offset=%d (%d*%d)\n", packet_offset, packet_num, wfx->packet_size);
/*seek to estimated packet*/
deadbeef->fseek (fp, first_frame_offset+packet_offset, SEEK_SET);
@@ -430,7 +434,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
/*check the time stamp of our packet*/
time = asf_get_timestamp(&duration, fp);
- DEBUGF("seeked to %d ms with duration %d\n", time, duration);
+ DEBUGF("time %d ms with duration %d\n", time, duration);
if (time < 0) {
/*unknown error, try to recover*/
@@ -441,7 +445,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
}
if ((time+duration>=ms && time<=ms) || count > 10) {
- /*DEBUGF("Found our packet! Now at %d packet\n", packet_num);*/
+ DEBUGF("Found our packet! Now at %d packet\n", packet_num);
return time;
} else {
/*seek again*/
diff --git a/plugins/wma/wma_plugin.c b/plugins/wma/wma_plugin.c
index ddfd8eec..dbebc4e6 100644
--- a/plugins/wma/wma_plugin.c
+++ b/plugins/wma/wma_plugin.c
@@ -36,8 +36,8 @@
#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,...)
+//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+#define trace(fmt,...)
static DB_decoder_t plugin;
DB_functions_t *deadbeef;
@@ -57,6 +57,7 @@ typedef struct {
int currentsample;
int startsample;
int endsample;
+ int skipsamples;
char buffer[MAX_PACKET_SIZE];
int remaining;
} wmaplug_info_t;
@@ -91,7 +92,7 @@ wmaplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
info->wmadec.bit_rate = info->wfx.bitrate;
info->wmadec.block_align = info->wfx.blockalign;
info->wmadec.codec_id = info->wfx.codec_id;
- printf ("codec id: %x\n", info->wmadec.codec_id);
+ trace ("codec id: %x\n", info->wmadec.codec_id);
info->wmadec.extradata = info->wfx.data;
if (wma_decode_init (&info->wmadec)) {
trace ("wma_decode_init fail\n");
@@ -160,7 +161,7 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
int pos = deadbeef->ftell (info->fp);
res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp);
int endpos = deadbeef->ftell (info->fp);
-// printf ("packet pos: %d, packet size: %d, data size: %d, blockalign: %d\n", pos, endpos-pos, packetlength, info->wfx.blockalign);
+ trace ("packet pos: %d, packet size: %d, data size: %d, blockalign: %d\n", pos, endpos-pos, packetlength, info->wfx.blockalign);
}
if (res > 0) {
int nb = audiobufsize / info->wfx.blockalign;
@@ -197,16 +198,27 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
}
}
- int sz = min (size, info->remaining);
- if (sz == 0) {
- break;
- }
- memcpy (bytes, info->buffer, sz);
- if (info->remaining != sz) {
- memmove (info->buffer, info->buffer+sz, info->remaining-sz);
+// if (info->skipsamples > 0) {
+// int skip = info->skipsamples * samplesize;
+// skip = min (info->remaining, skip);
+// if (skip < info->remaining) {
+// memmove (info->buffer, info->buffer + skip, info->remaining - skip);
+// }
+// info->remaining -= skip;
+// info->skipsamples -= skip / samplesize;
+// }
+ if (info->remaining > 0) {
+ int sz = min (size, info->remaining);
+ if (sz == 0) {
+ break;
+ }
+ memcpy (bytes, info->buffer, sz);
+ if (info->remaining != sz) {
+ memmove (info->buffer, info->buffer+sz, info->remaining-sz);
+ }
+ info->remaining -= sz;
+ size -= sz;
}
- info->remaining -= sz;
- size -= sz;
}
#else
// {{{ ffmpeg
@@ -224,7 +236,7 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
int pos = deadbeef->ftell (info->fp);
res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp);
int endpos = deadbeef->ftell (info->fp);
- printf ("packet pos: %d, packet size: %d, data size: %d\n", pos, endpos-pos, packetlength);
+ trace ("packet pos: %d, packet size: %d, data size: %d\n", pos, endpos-pos, packetlength);
}
if (res > 0) {
int nblocks = audiobufsize / info->wfx.blockalign;
@@ -232,7 +244,7 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
int got_frame_ptr = 0;
char *data;
int bufsize = wma_decode_superframe (&info->wmadec, &got_frame_ptr, audiobuf + i * info->wfx.blockalign, info->wfx.blockalign);
- printf ("got frame ptr: %d, bufsize: %d\n", got_frame_ptr, info->wmadec.nb_samples * 4);
+ trace ("got frame ptr: %d, bufsize: %d\n", got_frame_ptr, info->wmadec.nb_samples * 4);
int16_t *p = (int16_t *)&info->buffer[info->remaining];
memcpy (p, info->wmadec.output_buffer, info->wmadec.nb_samples * 4);
@@ -243,7 +255,7 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) {
int sz = min (size, info->remaining);
if (sz == 0) {
- printf ("buffer is empty\n");
+ trace ("buffer is empty\n");
break;
}
memcpy (bytes, info->buffer, sz);
@@ -265,7 +277,11 @@ wmaplug_seek_sample (DB_fileinfo_t *_info, int sample) {
sample += info->startsample;
+// sample = 6703200;
+ trace ("seek sample: %d\n", sample);
+
/*flush the wma decoder state*/
+ info->remaining = 0;
info->wmadec.last_superframe_len = 0;
info->wmadec.last_bitoffset = 0;
@@ -274,18 +290,18 @@ wmaplug_seek_sample (DB_fileinfo_t *_info, int sample) {
memset(info->wmadec.frame_out, 0,
sizeof(fixed32) * MAX_CHANNELS * BLOCK_MAX_SIZE * 2);
- int elapsedtime = asf_seek(sample * 1000 / _info->fmt.samplerate, &info->wfx, info->fp, info->first_frame_offset);
- if (elapsedtime <= 0) {
- // restart track
- info->currentsample = 0;
- printf ("seek failed\n");
- }
- else {
- // seek successful
- info->currentsample = elapsedtime * _info->fmt.samplerate / 1000;
- _info->readpos = (float)(info->currentsample - info->startsample)/_info->fmt.samplerate;
- printf ("seek success, sample=%d, pos=%f\n", info->currentsample, _info->readpos);
- }
+ int n_subframes = info->wfx.packet_size / info->wfx.blockalign;
+
+ int frame = sample / (info->wmadec.frame_len * n_subframes);
+ int64_t offs = frame * info->wfx.packet_size + info->first_frame_offset;
+// trace ("frame: %d/%d (%d), offs: %lld/%lld\n", frame, (int)((deadbeef->fgetlength (info->fp)-info->first_frame_offset) / info->wfx.packet_size - 1), info->wmadec.frame_len, offs, deadbeef->fgetlength (info->fp));
+ deadbeef->fseek (info->fp, offs, SEEK_SET);
+
+ // seek successful
+ info->currentsample = sample;
+ info->skipsamples = sample - frame * info->wmadec.frame_len * n_subframes;
+ _info->readpos = (float)(info->currentsample - info->startsample)/_info->fmt.samplerate;
+// trace ("seek success, sample=%d, pos=%f\n", info->currentsample, _info->readpos);
return 0;
}
@@ -314,7 +330,7 @@ wmaplug_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.plugin.id);
get_asf_metadata (fp, it, &wfx, &first_frame_offset);
- //printf ("datalen %d, channels %d, bps %d, rate %d\n", wfx.datalen, wfx.channels, wfx.bitspersample, wfx.rate);
+ //trace ("datalen %d, channels %d, bps %d, rate %d\n", wfx.datalen, wfx.channels, wfx.bitspersample, wfx.rate);
deadbeef->fseek (fp, first_frame_offset, SEEK_SET);
@@ -323,7 +339,7 @@ wmaplug_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
i_count / wfx.numpackets - wfx.preroll * 1000;
int64_t totalsamples = i_length / 1000 * wfx.rate / 1000;
-// printf ("totalsamples: %lld\n", totalsamples);
+// trace ("totalsamples: %lld\n", totalsamples);
deadbeef->plt_set_item_duration (plt, it, totalsamples / (float)wfx.rate);
deadbeef->pl_append_meta (it, ":FILETYPE", "WMA");