diff options
-rw-r--r-- | deadbeef.h | 2 | ||||
-rw-r--r-- | plugins.c | 2 | ||||
-rw-r--r-- | plugins/mpgmad/mpgmad.c | 13 | ||||
-rw-r--r-- | plugins/vfs_curl/vfs_curl.c | 91 |
4 files changed, 56 insertions, 52 deletions
@@ -354,6 +354,8 @@ typedef struct { int (*junk_read_ape) (DB_playItem_t *it, DB_FILE *fp); int (*junk_get_leading_size) (DB_FILE *fp); void (*junk_copy) (DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last); + const char * (*junk_detect_charset) (const char *s); + void (*junk_recode) (const char *in, int inlen, char *out, int outlen, const char *cs); // vfs DB_FILE* (*fopen) (const char *fname); void (*fclose) (DB_FILE *f); @@ -160,6 +160,8 @@ static DB_functions_t deadbeef_api = { .junk_read_ape = (int (*)(DB_playItem_t *it, DB_FILE *fp))junk_read_ape, .junk_get_leading_size = junk_get_leading_size, .junk_copy = (void (*)(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last))junk_copy, + .junk_detect_charset = junk_detect_charset, + .junk_recode = junk_recode, // vfs .fopen = vfs_fopen, .fclose = vfs_fclose, diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c index ea09cc8e..6ad884e4 100644 --- a/plugins/mpgmad/mpgmad.c +++ b/plugins/mpgmad/mpgmad.c @@ -839,8 +839,17 @@ cmp3_stream_frame (void) { buffer.last_comment_update = buffer.currentsample; const char *vfs_tit = deadbeef->fget_content_name (buffer.file); if (vfs_tit) { - deadbeef->pl_replace_meta (buffer.it, "title", vfs_tit); - deadbeef->sendmessage (M_TRACKCHANGED, 0, idx, 0); + const char *cs = deadbeef->junk_detect_charset (vfs_tit); + if (cs) { + char out[1024]; + deadbeef->junk_recode (vfs_tit, strlen (vfs_tit), out, sizeof (out), cs); + deadbeef->pl_replace_meta (buffer.it, "title", out); + deadbeef->sendmessage (M_TRACKCHANGED, 0, idx, 0); + } + else { + deadbeef->pl_replace_meta (buffer.it, "title", vfs_tit); + deadbeef->sendmessage (M_TRACKCHANGED, 0, idx, 0); + } } } } diff --git a/plugins/vfs_curl/vfs_curl.c b/plugins/vfs_curl/vfs_curl.c index ca30024b..fc1a172e 100644 --- a/plugins/vfs_curl/vfs_curl.c +++ b/plugins/vfs_curl/vfs_curl.c @@ -103,21 +103,11 @@ http_curl_write_wrapper (HTTP_FILE *fp, void *ptr, size_t size) { if (sz > 5000) { // wait until there are at least 5k bytes free int cp = min (avail, sz); -#if 0 - if (fp->wait_meta - cp <= 0) { - printf ("cp=%d->%d\n", cp, fp->wait_meta); - cp = fp->wait_meta; - } - fp->wait_meta -= cp; -#endif - int writepos = (fp->pos + fp->remaining) & BUFFER_MASK; // copy 1st portion (before end of buffer int part1 = BUFFER_SIZE - writepos; // may not be more than total part1 = min (part1, cp); - //trace ("part1=%d\n", part1); -// trace ("writepos=%d, remaining=%d, avail=%d, free=%d, writing=%d, part1=%d, part2=%d\n", writepos, fp->remaining, avail, sz, cp, part1, cp-part1); memcpy (fp->buffer+writepos, ptr, part1); ptr += part1; avail -= part1; @@ -175,9 +165,9 @@ http_parse_shoutcast_meta (HTTP_FILE *fp, const char *meta, int size) { static size_t http_curl_write (void *ptr, size_t size, size_t nmemb, void *stream) { -// trace ("http_curl_write %d bytes\n", size * nmemb); int avail = size * nmemb; HTTP_FILE *fp = (HTTP_FILE *)stream; + trace ("http_curl_write %d bytes, wait_meta=%d\n", size * nmemb, fp->wait_meta); gettimeofday (&fp->last_read_time, NULL); if (fp->status == STATUS_ABORTED) { trace ("vfs_curl STATUS_ABORTED at start of packet\n"); @@ -198,32 +188,25 @@ http_curl_write (void *ptr, size_t size, size_t nmemb, void *stream) { fp->gotheader = 1; } else { - trace ("parsing icy headers:\n%s\n", ptr); +// trace ("parsing icy headers:\n%s\n", ptr); fp->nheaderpackets++; - http_content_header_handler (ptr, size, nmemb, stream); - if (fp->gotheader) { - fp->gotheader = 0; // don't reset icy header - } - uint8_t *p = ptr; - int i; - for (i = 0; i < avail-3; i++) { - const char end[4] = { 0x0d, 0x0a, 0x0d, 0x0a }; - if (!memcmp (p, end, 4)) { - trace ("icy headers end\n"); - fp->gotheader = 1; - break; + avail = http_content_header_handler (ptr, size, nmemb, stream); + if (avail == size * nmemb) { + if (fp->gotheader) { + fp->gotheader = 0; // don't reset icy header } - p++; } -// if (fp->icy_metaint > 0) { -// fp->wait_meta -= nmemb * size; -// } - avail = 0; + else { + fp->gotheader = 1; + } } } else { fp->gotheader = 1; } + if (!avail) { + return nmemb*size; + } } deadbeef->mutex_lock (fp->mutex); @@ -233,31 +216,32 @@ http_curl_write (void *ptr, size_t size, size_t nmemb, void *stream) { deadbeef->mutex_unlock (fp->mutex); if (fp->icy_metaint > 0) { - if (fp->wait_meta < avail) { + while (fp->wait_meta < avail) { + trace ("http_curl_write_wrapper [1] %d\n", fp->wait_meta); size_t res1 = http_curl_write_wrapper (fp, ptr, fp->wait_meta); + if (res1 != fp->wait_meta) { + return 0; + } + avail -= res1; ptr += res1; uint32_t sz = (uint32_t)(*((uint8_t *)ptr)) * 16; - + ptr ++; if (sz > 0) { - http_parse_shoutcast_meta (fp, ptr+1, sz); + http_parse_shoutcast_meta (fp, ptr, sz); } - - ptr += sz + 1; - size_t sz2 = (nmemb*size) - fp->wait_meta - (sz+1); - size_t res2 = http_curl_write_wrapper (fp, ptr, sz2); - fp->wait_meta = fp->icy_metaint - sz2; - return res1 + sz + 1 + res2; - } - else { - fp->wait_meta -= nmemb * size; + avail -= sz + 1; + fp->wait_meta = fp->icy_metaint; + trace ("avail: %d\n", avail); } } - size_t res = http_curl_write_wrapper (fp, ptr, nmemb * size); - return res; - -// trace ("returning %d\n", nmemb * size - avail); -// return nmemb * size - avail; + if (avail) { + trace ("http_curl_write_wrapper [2] %d\n", avail); + size_t res = http_curl_write_wrapper (fp, ptr, avail); + avail -= res; + fp->wait_meta -= res; + } + return nmemb * size - avail; } static const uint8_t * @@ -311,10 +295,6 @@ parse_header (const uint8_t *p, const uint8_t *e, uint8_t *key, int keysize, uin memcpy (value, p, sz); value[sz] = 0; - // skip linebreaks - while (v < e && (*v == 0x0d || *v == 0x0a)) { - v++; - } return v; } @@ -328,6 +308,16 @@ http_content_header_handler (void *ptr, size_t size, size_t nmemb, void *stream) uint8_t key[256]; uint8_t value[256]; while (p < end) { + if (p < end - 4) { + if (!memcmp (p, "\r\n\r\n", 4)) { + p += 4; + return size * nmemb - (size_t)(p-(const uint8_t *)ptr); + } + } + // skip linebreaks + while (p < end && (*p == 0x0d || *p == 0x0a)) { + p++; + } p = parse_header (p, end, key, sizeof (key), value, sizeof (value)); trace ("%skey=%s value=%s\n", fp->icyheader ? "[icy] " : "", key, value); if (!strcasecmp (key, "Content-Type")) { @@ -749,6 +739,7 @@ http_get_content_name (DB_FILE *stream) { return NULL; } if (fp->gotheader) { + trace ("returning %s\n", fp->content_name); return fp->content_name; } if (!fp->tid) { |