diff options
author | waker <wakeroid@gmail.com> | 2013-07-08 18:48:44 +0200 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2013-07-08 18:48:44 +0200 |
commit | 1cd3c2f589a3cc32a42e8991dbbd46435e24e1bb (patch) | |
tree | f83da08aa0bb9ad882e0d0dad793f31ba31b37c9 /plugins/wma | |
parent | 3e71fdc649f2d181d32187b00032895eab58bd3b (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.c | 32 | ||||
-rw-r--r-- | plugins/wma/libasf/asf.c | 5 | ||||
-rw-r--r-- | plugins/wma/libasf/asf.h | 1 | ||||
-rw-r--r-- | plugins/wma/wma_plugin.c | 7 |
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"); |