summaryrefslogtreecommitdiff
path: root/plugins/wma
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2013-07-08 18:48:44 +0200
committerGravatar waker <wakeroid@gmail.com>2013-07-08 18:48:44 +0200
commit1cd3c2f589a3cc32a42e8991dbbd46435e24e1bb (patch)
treef83da08aa0bb9ad882e0d0dad793f31ba31b37c9 /plugins/wma
parent3e71fdc649f2d181d32187b00032895eab58bd3b (diff)
wma: correct duration and seeking in wma fragments (for example streaming radio dumps)
Diffstat (limited to 'plugins/wma')
-rw-r--r--plugins/wma/asfheader.c32
-rw-r--r--plugins/wma/libasf/asf.c5
-rw-r--r--plugins/wma/libasf/asf.h1
-rw-r--r--plugins/wma/wma_plugin.c7
4 files changed, 39 insertions, 6 deletions
diff --git a/plugins/wma/asfheader.c b/plugins/wma/asfheader.c
index 97c37256..0001f334 100644
--- a/plugins/wma/asfheader.c
+++ b/plugins/wma/asfheader.c
@@ -822,5 +822,37 @@ int get_asf_metadata(DB_FILE *fd, DB_playItem_t *it, asf_waveformatex_t *wfx, in
*/
*first_frame_offset = deadbeef->ftell(fd) + 26;
+ if (!fd->vfs->is_streaming ()) {
+ // check if we got a fragment
+ if (0 != deadbeef->fseek (fd, 26, SEEK_CUR)) {
+ DEBUGF("ASF: failed to seek to 1st frame\n");
+ return 0;
+ }
+ int duration = 0;
+ int time = asf_get_timestamp(&duration, fd);
+ if (time != 0) {
+ wfx->first_frame_timestamp = time;
+ // need to scan entire file to find out the duration
+ int pmn = (int)(time * 0.001f / 60);
+ int psc = time * 0.001f - pmn * 60;
+ trace ("wma: the file is a fragment, start time: %d:%02d\n", pmn, psc);
+ trace ("play_duration %lld, numpackets %lld, packet_size %d\n", wfx->play_duration, wfx->numpackets, wfx->packet_size);
+ }
+ if (wfx->play_duration == 0) {
+ wfx->preroll = 0;
+ wfx->numpackets = 1;
+ // calc duration from packets (scan the file)
+ wfx->play_duration += duration * 10000;
+ while (0 == deadbeef->fseek (fd, *first_frame_offset + wfx->packet_size * wfx->numpackets, SEEK_SET)) {
+ time = asf_get_timestamp(&duration, fd);
+ if (time < 0) {
+ break;
+ }
+ wfx->play_duration += duration * 10000;
+ wfx->numpackets++;
+ }
+ }
+ }
+
return 1;
}
diff --git a/plugins/wma/libasf/asf.c b/plugins/wma/libasf/asf.c
index 6a3700fb..096833a0 100644
--- a/plugins/wma/libasf/asf.c
+++ b/plugins/wma/libasf/asf.c
@@ -443,7 +443,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*/
int64_t pos = deadbeef->ftell (fp);
- time = asf_get_timestamp(&duration, fp);
+ time = asf_get_timestamp(&duration, fp) - wfx->first_frame_timestamp;
// DEBUGF("time %d ms with duration %d\n", time, duration);
if (time < 0) {
@@ -452,7 +452,7 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
deadbeef->fseek (fp, first_frame_offset+initial_packet*wfx->packet_size, SEEK_SET);
*skip_ms = 0;
/*seek failed so return time stamp of the initial packet*/
- return -1;//asf_get_timestamp(&duration, fp);
+ return -1;
}
DEBUGF("time: %d, duration: %d (ms: %d)\n", time, duration, ms);
@@ -476,3 +476,4 @@ int asf_seek(int ms, asf_waveformatex_t* wfx, DB_FILE *fp, int64_t first_frame_o
}
}
}
+
diff --git a/plugins/wma/libasf/asf.h b/plugins/wma/libasf/asf.h
index f49d38d1..29de0df6 100644
--- a/plugins/wma/libasf/asf.h
+++ b/plugins/wma/libasf/asf.h
@@ -41,6 +41,7 @@ struct asf_waveformatex_s {
uint64_t send_duration;
uint64_t preroll;
uint32_t flags;
+ int32_t first_frame_timestamp;
};
typedef struct asf_waveformatex_s asf_waveformatex_t;
diff --git a/plugins/wma/wma_plugin.c b/plugins/wma/wma_plugin.c
index f997d0a4..cf71e898 100644
--- a/plugins/wma/wma_plugin.c
+++ b/plugins/wma/wma_plugin.c
@@ -386,17 +386,16 @@ wmaplug_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) {
//trace ("datalen %d, channels %d, bps %d, rate %d\n", wfx.datalen, wfx.channels, wfx.bitspersample, wfx.rate);
trace ("packet_size: %d, max_packet_size: %d\n", wfx.packet_size, wfx.max_packet_size);
- deadbeef->fseek (fp, first_frame_offset, SEEK_SET);
int64_t l = deadbeef->fgetlength (fp);
deadbeef->fclose (fp);
int64_t i_count = (l - first_frame_offset) / wfx.packet_size;
- int64_t i_length = wfx.play_duration / 10 *
- i_count / wfx.numpackets - wfx.preroll * 1000;
+ int64_t i_length = wfx.play_duration / 10 * i_count / wfx.numpackets - wfx.preroll * 1000;
+ trace ("i_length: %lld (%lld / 10 * %lld / %lld - %lld * 1000)\n", i_length, wfx.play_duration, i_count, wfx.numpackets, wfx.preroll);
int64_t totalsamples = i_length / 1000 * wfx.rate / 1000;
-// trace ("totalsamples: %lld\n", totalsamples);
+ trace ("totalsamples: %lld (%lld / %d)\n", totalsamples, i_length, wfx.rate);
deadbeef->plt_set_item_duration (plt, it, totalsamples / (float)wfx.rate);
deadbeef->pl_append_meta (it, ":FILETYPE", "WMA");