From 362c82591f489696d804bad3cab37e5a3184d4da Mon Sep 17 00:00:00 2001 From: waker Date: Sat, 6 Jul 2013 16:46:43 +0200 Subject: mms radio now works using the new wma plugin --- plugins/wma/asfheader.c | 69 ++++++++++++++++++++++++-------------------- plugins/wma/libasf/asf.c | 13 +++++++-- plugins/wma/libwma/wmadeci.c | 4 +++ plugins/wma/wma_plugin.c | 27 ++++++++++++----- 4 files changed, 71 insertions(+), 42 deletions(-) (limited to 'plugins/wma') diff --git a/plugins/wma/asfheader.c b/plugins/wma/asfheader.c index 6dff444b..c6e84e89 100644 --- a/plugins/wma/asfheader.c +++ b/plugins/wma/asfheader.c @@ -41,6 +41,13 @@ #define trace(fmt,...) #define DEBUGF trace +#define SKIP_BYTES(fd,x) {\ + if (x > 0) {\ + char buf[x];\ + deadbeef->fread (buf, x, 1, fd);\ + }\ +} + extern DB_functions_t *deadbeef; enum { @@ -271,15 +278,15 @@ static int asf_intdecode(DB_FILE *fd, int type, int length) if (type == 3) { read_uint32le(fd, &tmp32); - deadbeef->fseek(fd,length - 4,SEEK_CUR); + SKIP_BYTES(fd,length - 4); return (int)tmp32; } else if (type == 4) { read_uint64le(fd, &tmp64); - deadbeef->fseek(fd,length - 8,SEEK_CUR); + SKIP_BYTES(fd,length - 8); return (int)tmp64; } else if (type == 5) { read_uint16le(fd, &tmp16); - deadbeef->fseek(fd,length - 2,SEEK_CUR); + SKIP_BYTES(fd,length - 2); return (int)tmp16; } @@ -376,7 +383,7 @@ static void asf_utf16LEdecode(DB_FILE *fd, if (utf16bytes > 0) { /* Skip any remaining bytes */ - deadbeef->fseek(fd, utf16bytes, SEEK_CUR); + SKIP_BYTES(fd, utf16bytes); } return; } @@ -408,7 +415,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t read_uint32le(fd, &subobjects); /* Two reserved bytes - do we need to read them? */ - deadbeef->fseek(fd, 2, SEEK_CUR); + SKIP_BYTES(fd, 2); DEBUGF("Read header - size=%d, subobjects=%d\n",(int)header.size, (int)subobjects); @@ -446,7 +453,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t /* Get the number of logical packets - uint64_t at offset 32 * (Big endian byte order) */ - deadbeef->fseek(fd, 32, SEEK_CUR); + SKIP_BYTES(fd, 32); read_uint64le(fd, &wfx->numpackets); read_uint64le(fd, &wfx->play_duration); read_uint64le(fd, &wfx->send_duration); @@ -456,12 +463,12 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t // DEBUGF("****** length = %lld\n", wfx->play_duration); /* Read the packet size - uint32_t at offset 68 */ -// deadbeef->fseek(fd, 20, SEEK_CUR); +// SKIP_BYTES(fd, 20); read_uint32le(fd, &wfx->packet_size); read_uint32le(fd, &wfx->max_packet_size); /* Skip bytes remaining in object */ - deadbeef->fseek(fd, current.size - 24 - 72 - 4, SEEK_CUR); + SKIP_BYTES(fd, current.size - 24 - 72 - 4); } else if (asf_guid_match(¤t.guid, &asf_guid_stream_properties)) { guid_t guid; uint32_t propdatalen; @@ -477,16 +484,16 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t asf_readGUID(fd, &guid); - deadbeef->fseek(fd, 24, SEEK_CUR); + SKIP_BYTES(fd, 24); read_uint32le(fd, &propdatalen); - deadbeef->fseek(fd, 4, SEEK_CUR); + SKIP_BYTES(fd, 4); read_uint16le(fd, &flags); if (!asf_guid_match(&guid, &asf_guid_stream_type_audio)) { DEBUGF("Found stream properties for non audio stream, skipping\n"); - deadbeef->fseek(fd,current.size - 24 - 50,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24 - 50); } else if (wfx->audiostream == -1) { - deadbeef->fseek(fd, 4, SEEK_CUR); + SKIP_BYTES(fd, 4); DEBUGF("Found stream properties for audio stream %d\n",flags&0x7f); if (propdatalen < 18) { @@ -509,27 +516,27 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t if (wfx->codec_id == ASF_CODEC_ID_WMAV1) { deadbeef->fread(wfx->data, 4, 1, fd); - deadbeef->fseek(fd,current.size - 24 - 72 - 4,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24 - 72 - 4); wfx->audiostream = flags&0x7f; } else if (wfx->codec_id == ASF_CODEC_ID_WMAV2) { deadbeef->fread(wfx->data, 6, 1, fd); - deadbeef->fseek(fd,current.size - 24 - 72 - 6,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24 - 72 - 6); wfx->audiostream = flags&0x7f; } else if (wfx->codec_id == ASF_CODEC_ID_WMAPRO) { /* wma pro decoder needs the extra-data */ deadbeef->fread(wfx->data, wfx->datalen, 1, fd); - deadbeef->fseek(fd,current.size - 24 - 72 - wfx->datalen,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24 - 72 - wfx->datalen); wfx->audiostream = flags&0x7f; /* Correct codectype to redirect playback to the proper .codec */ codectype = AFMT_WMAPRO; } else if (wfx->codec_id == ASF_CODEC_ID_WMAVOICE) { deadbeef->fread(wfx->data, wfx->datalen, 1, fd); - deadbeef->fseek(fd,current.size - 24 - 72 - wfx->datalen,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24 - 72 - wfx->datalen); wfx->audiostream = flags&0x7f; codectype = AFMT_WMAVOICE; } else { trace("Unsupported WMA codec (Lossless, Voice, etc)\n"); - deadbeef->fseek(fd,current.size - 24 - 72,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24 - 72); } } } else if (it && asf_guid_match(¤t.guid, &asf_guid_content_description)) { @@ -559,7 +566,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t deadbeef->pl_append_meta (it, "artist", s); } - deadbeef->fseek(fd, strlength[2], SEEK_CUR); /* 2 - copyright */ + SKIP_BYTES(fd, strlength[2]); /* 2 - copyright */ if (strlength[3] > 0) { /* 3 - description */ unsigned char *s = id3buf; @@ -567,7 +574,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t deadbeef->pl_append_meta (it, "comment", s); } - deadbeef->fseek(fd, strlength[4], SEEK_CUR); /* 4 - rating */ + SKIP_BYTES(fd, strlength[4]); /* 4 - rating */ } else if (it && asf_guid_match(¤t.guid, &asf_guid_extended_content_description)) { uint16_t count; int i; @@ -602,7 +609,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t snprintf (n, sizeof (n), "%d", tracknum); deadbeef->pl_append_meta (it, "track", n); } else { - deadbeef->fseek(fd, length, SEEK_CUR); + SKIP_BYTES(fd, length); } } else if (!strcmp("TotalTracks",utf8buf)) { if (type == 0) { @@ -615,7 +622,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t snprintf (n, sizeof (n), "%d", tracknum); deadbeef->pl_append_meta (it, "numtracks", n); } else { - deadbeef->fseek(fd, length, SEEK_CUR); + SKIP_BYTES(fd, length); } } else if (!strcmp("WM/PartOfSet",utf8buf)) { if (type == 0) { @@ -628,7 +635,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t snprintf (n, sizeof (n), "%d", tracknum); deadbeef->pl_append_meta (it, "disc", n); } else { - deadbeef->fseek(fd, length, SEEK_CUR); + SKIP_BYTES(fd, length); } } else if ((!strcmp("WM/Genre", utf8buf)) && (type == 0)) { unsigned char *s = id3buf; @@ -657,7 +664,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t snprintf (n, sizeof (n), "%d", year); deadbeef->pl_append_meta (it, "year", n); } else { - deadbeef->fseek(fd, length, SEEK_CUR); + SKIP_BYTES(fd, length); } } else if (!strncmp("replaygain_", utf8buf, 11)) { char *s = utf8buf; @@ -687,10 +694,10 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t * "03 yy yy yy yy". xx is the size of the WM/Picture * container in bytes. yy equals the raw data length of * the embedded image. */ - deadbeef->fseek(fd, -4, SEEK_CUR); + SKIP_BYTES(fd, -4); deadbeef->fread(&type, 1, 1, fd); if (type == 1) { - deadbeef->fseek(fd, 3, SEEK_CUR); + SKIP_BYTES(fd, 3); deadbeef->fread(&type, 1, 1, fd); /* In case the parsing will fail in the next step we * might at least be able to skip the whole section. */ @@ -708,7 +715,7 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t * double zero-termination. */ asf_utf16LEdecode(fd, 32, &utf8, &utf8length); strlength = (strlen(utf8buf) + 2) * 2; - deadbeef->fseek(fd, strlength-32, SEEK_CUR); + SKIP_BYTES(fd, strlength-32); if (!strcmp("image/jpeg", utf8buf)) { id3->albumart.type = AA_TYPE_JPG; } else if (!strcmp("image/jpg", utf8buf)) { @@ -723,13 +730,13 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t /* Set the album art size and position. */ if (id3->albumart.type != AA_TYPE_UNKNOWN) { - id3->albumart.pos = deadbeef->fseek(fd, 0, SEEK_CUR); + id3->albumart.pos = SKIP_BYTES(fd, 0); id3->albumart.size = datalength; id3->has_embedded_albumart = true; } } - deadbeef->fseek(fd, datalength, SEEK_CUR); + SKIP_BYTES(fd, datalength); #endif } else { if (type == 0) { // FIXME: custom fields -- after others work @@ -738,20 +745,20 @@ static int asf_parse_header(DB_FILE *fd, asf_waveformatex_t* wfx, DB_playItem_t deadbeef->pl_append_meta (it, utf8buf, s); } else { - deadbeef->fseek(fd, length, SEEK_CUR); + SKIP_BYTES(fd, length); } } bytesleft -= 4 + length; } - deadbeef->fseek(fd, bytesleft, SEEK_CUR); + SKIP_BYTES(fd, bytesleft); } else if (asf_guid_match(¤t.guid, &asf_guid_content_encryption) || asf_guid_match(¤t.guid, &asf_guid_extended_content_encryption)) { DEBUGF("File is encrypted\n"); return ASF_ERROR_ENCRYPTED; } else { DEBUGF("Skipping %d bytes of object\n",(int)(current.size - 24)); - deadbeef->fseek(fd,current.size - 24,SEEK_CUR); + SKIP_BYTES(fd,current.size - 24); } DEBUGF("Parsed object - size = %d\n",(int)current.size); diff --git a/plugins/wma/libasf/asf.c b/plugins/wma/libasf/asf.c index 595a27ac..1e4c734c 100644 --- a/plugins/wma/libasf/asf.c +++ b/plugins/wma/libasf/asf.c @@ -33,6 +33,13 @@ extern DB_functions_t *deadbeef; #define trace(fmt,...) #define DEBUGF trace +#define SKIP_BYTES(fd,x) {\ + if (x > 0) {\ + char buf[x];\ + deadbeef->fread (buf, x, 1, fd);\ + }\ +} + /* Read an unaligned 32-bit little endian long from buffer. */ static unsigned long get_long_le(void* buf) { @@ -108,7 +115,7 @@ int asf_read_packet(uint8_t** audiobuf, int* audiobufsize, int* packetlength, } /* Skip ec_data */ - deadbeef->fseek(fp, ec_length, SEEK_CUR); + SKIP_BYTES(fp, ec_length); bytesread += ec_length; } else { ec_length = 0; @@ -355,7 +362,7 @@ int asf_get_timestamp(int *duration, DB_FILE *fp) } /* Skip ec_data */ - deadbeef->fseek (fp, ec_length, SEEK_CUR); + SKIP_BYTES(fp, ec_length); bytesread += ec_length; } else { ec_length = 0; @@ -398,7 +405,7 @@ int asf_get_timestamp(int *duration, DB_FILE *fp) /*the asf_get_timestamp function advances us 12-13 bytes past the packet start, need to undo this here so that we stay synced with the packet*/ - deadbeef->fseek(fp, -bytesread, SEEK_CUR); + deadbeef->fseek (fp, -bytesread, SEEK_CUR); return send_time; } diff --git a/plugins/wma/libwma/wmadeci.c b/plugins/wma/libwma/wmadeci.c index d7a6f9ae..3b93be10 100644 --- a/plugins/wma/libwma/wmadeci.c +++ b/plugins/wma/libwma/wmadeci.c @@ -226,6 +226,7 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) s->nb_channels = wfx->channels; s->bit_rate = wfx->bitrate; s->block_align = wfx->blockalign; + trace ("wma samplerate: %d\n", wfx->rate); if (wfx->codec_id == ASF_CODEC_ID_WMAV1) { s->version = 1; @@ -233,9 +234,12 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) s->version = 2; } else { /*one of those other wma flavors that don't have GPLed decoders */ + trace ("invalid wma codec id: %d\n", wfx->codec_id); return -1; } + trace ("wma version: %d\n", s->version); + /* extract flag infos */ flags2 = 0; extradata = wfx->data; diff --git a/plugins/wma/wma_plugin.c b/plugins/wma/wma_plugin.c index 76b469dd..aa1f691a 100644 --- a/plugins/wma/wma_plugin.c +++ b/plugins/wma/wma_plugin.c @@ -39,8 +39,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; @@ -85,9 +85,21 @@ wmaplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) { trace ("opened %s\n", deadbeef->pl_find_meta (it, ":URI")); +// char *buffer = malloc (2000000); +// deadbeef->fread (buffer, 200000, 1, info->fp); +// FILE *out = fopen ("out.wma", "w+b"); +// fwrite (buffer, 200000, 1, out); +// exit (0); + int res = get_asf_metadata (info->fp, NULL, &info->wfx, &info->first_frame_offset); trace ("get_asf_metadata returned %d, first_frame_offset: %lld\n", res, info->first_frame_offset); - deadbeef->fseek (info->fp, info->first_frame_offset, SEEK_SET); + int64_t pos = deadbeef->ftell (info->fp); + trace ("curr offs: %lld\n", pos); + if (info->first_frame_offset > pos) { + char buf[info->first_frame_offset-pos]; + trace ("skipping %d bytes\n", sizeof (buf)); + deadbeef->fread (buf, sizeof (buf), 1, info->fp); + } #if USE_FFMPEG info->wmadec.sample_rate = info->wfx.rate; info->wmadec.nb_channels = info->wfx.channels; @@ -154,7 +166,7 @@ static int wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) { wmaplug_info_t *info = (wmaplug_info_t *)_info; int samplesize = _info->fmt.channels * _info->fmt.bps / 8; - if (!info->fp->vfs->is_streaming ()) { + if (!info->fp->vfs->is_streaming () && info->endsample > info->startsample) { if (info->currentsample + size / samplesize > info->endsample) { size = (info->endsample - info->currentsample + 1) * samplesize; if (size <= 0) { @@ -179,7 +191,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); - trace ("packet pos: %d, packet size: %d (%d), data size: %d, blockalign: %d\n", pos, endpos-pos, info->wfx.packet_size, packetlength, info->wfx.blockalign); + trace ("[1] packet pos: %d, packet size: %d (%d), data size: %d, blockalign: %d, audiobufsize: %d\n", pos, endpos-pos, info->wfx.packet_size, packetlength, info->wfx.blockalign, audiobufsize); } if (res > 0) { int nb = audiobufsize / info->wfx.blockalign; @@ -256,12 +268,11 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) { int audiobufsize = 0; int packetlength = 0; new_packet: - //res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp); { int pos = deadbeef->ftell (info->fp); res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &info->wfx, info->fp); int endpos = deadbeef->ftell (info->fp); - trace ("packet pos: %d, packet size: %d, data size: %d\n", pos, endpos-pos, packetlength); + trace ("[2] packet pos: %d, packet size: %d, data size: %d\n", pos, endpos-pos, packetlength); } if (res > 0) { int nblocks = audiobufsize / info->wfx.blockalign; @@ -294,6 +305,7 @@ wmaplug_read (DB_fileinfo_t *_info, char *bytes, int size) { // }}} info->currentsample += (initsize-size) / samplesize; + trace ("read ret: %d, (initsize: %d)\n", initsize-size, initsize); return initsize-size; } @@ -334,7 +346,6 @@ wmaplug_seek_sample (DB_fileinfo_t *_info, int sample) { } #endif - _info->readpos = (float)(info->currentsample - info->startsample)/_info->fmt.samplerate; return 0; -- cgit v1.2.3