summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-10-04 22:32:42 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-10-04 22:32:42 +0200
commit33783306bf5a108fd85604654ec52a99f8c3f16a (patch)
tree8d75a4b866f1b30345ed3ca8bdce98b3c1024555 /plugins
parented7b5e99bfb98d8ec57f4bccda0d691a1d19081c (diff)
added streaming over ftp support including seeking
added special-case for fseek+ftell when calculating file length
Diffstat (limited to 'plugins')
-rw-r--r--plugins/vfs_curl/vfs_curl.c20
-rw-r--r--plugins/vorbis/vorbis.c23
2 files changed, 25 insertions, 18 deletions
diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c
index ace14713..e1105b1d 100644
--- a/plugins/vfs_curl/vfs_curl.c
+++ b/plugins/vfs_curl/vfs_curl.c
@@ -46,6 +46,7 @@ typedef struct {
char *url;
uint8_t buffer[BUFFER_SIZE];
int64_t pos; // position in stream; use "& BUFFER_MASK" to make it index into ringbuffer
+ int seektoend; // indicates that next tell must return length
int64_t length;
int32_t remaining; // remaining bytes in buffer read from stream
int32_t skipbytes;
@@ -118,10 +119,6 @@ http_size_request_handler (void *ptr, size_t size, size_t nmemb, void *stream) {
fp->length = atoi (cl);
trace ("vfs_curl: file size is %d bytes\n", fp->length);
}
-// else {
-// trace ("vfs_curl: unable to get file size\n");
-// fp->length = -1; // infinite
-// }
return size * nmemb;
}
@@ -229,6 +226,7 @@ http_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) {
assert (stream);
assert (ptr);
HTTP_FILE *fp = (HTTP_FILE *)stream;
+ fp->seektoend = 0;
int sz = size * nmemb;
// assert (size * nmemb <= BUFFER_SIZE);
// trace ("readpos=%d, readsize=%d\n", fp->pos & BUFFER_SIZE, sz);
@@ -281,12 +279,17 @@ http_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) {
static int
http_seek (DB_FILE *stream, int64_t offset, int whence) {
trace ("http_seek %x %d\n", offset, whence);
+ assert (stream);
+ HTTP_FILE *fp = (HTTP_FILE *)stream;
+ fp->seektoend = 0;
if (whence == SEEK_END) {
+ if (offset == 0) {
+ fp->seektoend = 1;
+ return 0;
+ }
trace ("vfs_curl: can't seek in curl stream relative to EOF\n");
return -1;
}
- assert (stream);
- HTTP_FILE *fp = (HTTP_FILE *)stream;
if (!fp->tid) {
if (offset == 0 && (whence == SEEK_SET || whence == SEEK_CUR)) {
return 0;
@@ -334,6 +337,9 @@ static int64_t
http_tell (DB_FILE *stream) {
assert (stream);
HTTP_FILE *fp = (HTTP_FILE *)stream;
+ if (fp->seektoend) {
+ return fp->length;
+ }
return fp->pos + fp->skipbytes;
}
@@ -366,7 +372,7 @@ http_getlength (DB_FILE *stream) {
return fp->length;
}
-static const char *scheme_names[] = { "http://", NULL };
+static const char *scheme_names[] = { "http://", "ftp://", NULL };
// standard stdio vfs
static DB_vfs_t plugin = {
diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c
index 48b6c4c4..78496458 100644
--- a/plugins/vorbis/vorbis.c
+++ b/plugins/vorbis/vorbis.c
@@ -27,7 +27,7 @@
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(...) { fprintf (stderr, __VA_ARGS__); }
#define trace(fmt,...)
static DB_decoder_t plugin;
@@ -54,9 +54,6 @@ cvorbis_fread (void *ptr, size_t size, size_t nmemb, void *datasource) {
static int
cvorbis_fseek (void *datasource, ogg_int64_t offset, int whence) {
DB_FILE *f = (DB_FILE *)datasource;
- if (f->vfs->streaming) {
- return -1;
- }
return deadbeef->fseek (datasource, offset, whence);
}
@@ -119,7 +116,8 @@ cvorbis_init (DB_playItem_t *it) {
}
memset (&plugin.info, 0, sizeof (plugin.info));
- if (file->vfs->streaming) {
+ int ln = deadbeef->fgetlength (file);
+ if (file->vfs->streaming && ln == -1) {
ov_callbacks ovcb = {
.read_func = cvorbis_fread,
.seek_func = NULL,
@@ -134,6 +132,7 @@ cvorbis_init (DB_playItem_t *it) {
plugin.free ();
return -1;
}
+ it->duration = -1;
}
else
{
@@ -151,6 +150,7 @@ cvorbis_init (DB_playItem_t *it) {
plugin.free ();
return -1;
}
+ it->duration = ov_time_total (&vorbis_file, -1);
}
vi = ov_info (&vorbis_file, -1);
if (!vi) { // not a vorbis stream
@@ -177,11 +177,12 @@ cvorbis_init (DB_playItem_t *it) {
}
else {
startsample = 0;
- endsample = ov_pcm_total (&vorbis_file, -1)-1;
- if (endsample <= 0) {
+ if (it->duration < 0) {
endsample = -1;
}
- it->duration = -1;
+ else {
+ endsample = ov_pcm_total (&vorbis_file, -1)-1;
+ }
vorbis_comment *vc = ov_comment (&vorbis_file, -1);
update_vorbis_comments (it, vc);
}
@@ -285,7 +286,7 @@ cvorbis_seek_sample (int sample) {
return -1;
int tell = ov_pcm_tell (&vorbis_file);
if (tell != sample) {
- fprintf (stderr, "oggvorbis: failed to do sample-accurate seek (%d->%d)\n", sample, tell);
+ trace ("oggvorbis: failed to do sample-accurate seek (%d->%d)\n", sample, tell);
}
currentsample = sample;
plugin.info.readpos = (float)(ov_pcm_tell(&vorbis_file) - startsample)/vi->rate;
@@ -302,7 +303,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
// check for validity
DB_FILE *fp = deadbeef->fopen (fname);
if (!fp) {
- fprintf (stderr, "vorbis: failed to fopen %s\n", fname);
+ trace ("vorbis: failed to fopen %s\n", fname);
return NULL;
}
if (fp->vfs->streaming) {
@@ -326,7 +327,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
ov_open_callbacks (fp, &vorbis_file, NULL, 0, ovcb);
vi = ov_info (&vorbis_file, -1);
if (!vi) { // not a vorbis stream
- fprintf (stderr, "vorbis: failed to ov_open %s\n", fname);
+ trace ("vorbis: failed to ov_open %s\n", fname);
return NULL;
}
float duration = ov_time_total (&vorbis_file, -1);