summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohamed Tarek <mt@rockbox.org>2010-06-21 10:48:34 +0000
committerMohamed Tarek <mt@rockbox.org>2010-06-21 10:48:34 +0000
commit816fca820caa537a07c761f49d1f8ecf996a91ce (patch)
tree8ea2805d0536bd45c7a4f56fa39904e65829466a
parent9297a02d4964cae7727248665e278b251cac5533 (diff)
downloadrockbox-816fca820caa537a07c761f49d1f8ecf996a91ce.tar.gz
rockbox-816fca820caa537a07c761f49d1f8ecf996a91ce.zip
Wrote apps/codecs/wmapro.c and modified libwmapro to make the codec work in the sim. Neither libwmapro nor wmapro.c have been added to the main build yet, codecs.make should be edited to compile both with rockbox.
current status of the decoder : - Plays and seeks in the sim - Still in floating point git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27006 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libwmapro/SOURCES9
-rw-r--r--apps/codecs/libwmapro/bitstream.c2
-rw-r--r--apps/codecs/libwmapro/dsputil.h2
-rw-r--r--apps/codecs/libwmapro/fft.c4
-rw-r--r--apps/codecs/libwmapro/get_bits.h2
-rw-r--r--apps/codecs/libwmapro/libavutil/internal.h10
-rw-r--r--apps/codecs/libwmapro/libavutil/log.c4
-rw-r--r--apps/codecs/libwmapro/libavutil/mathematics.c8
-rw-r--r--apps/codecs/libwmapro/libwmapro.make18
-rw-r--r--apps/codecs/libwmapro/mdct_tablegen.h4
-rw-r--r--apps/codecs/libwmapro/put_bits.h10
-rw-r--r--apps/codecs/libwmapro/wma.c4
-rw-r--r--apps/codecs/libwmapro/wmaprodec.c33
-rw-r--r--apps/codecs/libwmapro/wmaprodec.h6
-rw-r--r--apps/codecs/wmapro.c156
-rw-r--r--apps/metadata/asf.c16
16 files changed, 246 insertions, 42 deletions
diff --git a/apps/codecs/libwmapro/SOURCES b/apps/codecs/libwmapro/SOURCES
new file mode 100644
index 0000000000..da2d2860d8
--- /dev/null
+++ b/apps/codecs/libwmapro/SOURCES
@@ -0,0 +1,9 @@
1wmaprodec.c
2wma.c
3dsputil.c
4mdct.c
5fft.c
6bitstream.c
7libavutil/log.c
8libavutil/mem.c
9libavutil/mathematics.c
diff --git a/apps/codecs/libwmapro/bitstream.c b/apps/codecs/libwmapro/bitstream.c
index 47234e10e1..deb1d631e2 100644
--- a/apps/codecs/libwmapro/bitstream.c
+++ b/apps/codecs/libwmapro/bitstream.c
@@ -296,7 +296,7 @@ int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
296 av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes); 296 av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes);
297#endif 297#endif
298 298
299 assert(symbols_size <= 2 || !symbols); 299 //assert(symbols_size <= 2 || !symbols);
300 j = 0; 300 j = 0;
301#define COPY(condition)\ 301#define COPY(condition)\
302 for (i = 0; i < nb_codes; i++) {\ 302 for (i = 0; i < nb_codes; i++) {\
diff --git a/apps/codecs/libwmapro/dsputil.h b/apps/codecs/libwmapro/dsputil.h
index d1816e66ba..80bc3ab262 100644
--- a/apps/codecs/libwmapro/dsputil.h
+++ b/apps/codecs/libwmapro/dsputil.h
@@ -443,7 +443,7 @@ typedef struct DSPContext {
443 * @param v2 second input vector, difference output, 16-byte aligned 443 * @param v2 second input vector, difference output, 16-byte aligned
444 * @param len length of vectors, multiple of 4 444 * @param len length of vectors, multiple of 4
445 */ 445 */
446 void (*butterflies_float)(float *restrict v1, float *restrict v2, int len); 446 void (*butterflies_float)(float * v1, float * v2, int len);
447 447
448 /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] 448 /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767]
449 * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ 449 * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */
diff --git a/apps/codecs/libwmapro/fft.c b/apps/codecs/libwmapro/fft.c
index bc1b4f1796..b0e6e11cd3 100644
--- a/apps/codecs/libwmapro/fft.c
+++ b/apps/codecs/libwmapro/fft.c
@@ -102,11 +102,11 @@ av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
102 102
103 s->fft_permute = ff_fft_permute_c; 103 s->fft_permute = ff_fft_permute_c;
104 s->fft_calc = ff_fft_calc_c; 104 s->fft_calc = ff_fft_calc_c;
105#if CONFIG_MDCT 105//#if CONFIG_MDCT
106 s->imdct_calc = ff_imdct_calc_c; 106 s->imdct_calc = ff_imdct_calc_c;
107 s->imdct_half = ff_imdct_half_c; 107 s->imdct_half = ff_imdct_half_c;
108 s->mdct_calc = ff_mdct_calc_c; 108 s->mdct_calc = ff_mdct_calc_c;
109#endif 109//#endif
110 s->exptab1 = NULL; 110 s->exptab1 = NULL;
111 s->split_radix = 1; 111 s->split_radix = 1;
112#if 0 112#if 0
diff --git a/apps/codecs/libwmapro/get_bits.h b/apps/codecs/libwmapro/get_bits.h
index c325778d67..a21d05210f 100644
--- a/apps/codecs/libwmapro/get_bits.h
+++ b/apps/codecs/libwmapro/get_bits.h
@@ -28,7 +28,7 @@
28 28
29#include <stdint.h> 29#include <stdint.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <assert.h> 31//#include <assert.h>
32#include "libavutil/bswap.h" 32#include "libavutil/bswap.h"
33#include "libavutil/common.h" 33#include "libavutil/common.h"
34#include "libavutil/intreadwrite.h" 34#include "libavutil/intreadwrite.h"
diff --git a/apps/codecs/libwmapro/libavutil/internal.h b/apps/codecs/libwmapro/libavutil/internal.h
index 2b8da1d8c2..97087e462a 100644
--- a/apps/codecs/libwmapro/libavutil/internal.h
+++ b/apps/codecs/libwmapro/libavutil/internal.h
@@ -33,7 +33,7 @@
33#include <limits.h> 33#include <limits.h>
34#include <stdint.h> 34#include <stdint.h>
35#include <stddef.h> 35#include <stddef.h>
36#include <assert.h> 36//#include <assert.h>
37//#include "config.h" 37//#include "config.h"
38#include "attributes.h" 38#include "attributes.h"
39//#include "timer.h" 39//#include "timer.h"
@@ -142,8 +142,8 @@
142#endif 142#endif
143 143
144/* avoid usage of dangerous/inappropriate system functions */ 144/* avoid usage of dangerous/inappropriate system functions */
145#undef malloc 145//#undef malloc
146#define malloc please_use_av_malloc 146//#define malloc please_use_av_malloc
147#undef free 147#undef free
148#define free please_use_av_free 148#define free please_use_av_free
149#undef realloc 149#undef realloc
@@ -163,8 +163,8 @@
163#undef exit 163#undef exit
164#define exit exit_is_forbidden 164#define exit exit_is_forbidden
165#ifndef LIBAVFORMAT_BUILD 165#ifndef LIBAVFORMAT_BUILD
166#undef printf 166//#undef printf
167#define printf please_use_av_log_instead_of_printf 167//#define printf please_use_av_log_instead_of_printf
168#undef fprintf 168#undef fprintf
169#define fprintf please_use_av_log_instead_of_fprintf 169#define fprintf please_use_av_log_instead_of_fprintf
170#undef puts 170#undef puts
diff --git a/apps/codecs/libwmapro/libavutil/log.c b/apps/codecs/libwmapro/libavutil/log.c
index 166e724b07..6cbe0da8b8 100644
--- a/apps/codecs/libwmapro/libavutil/log.c
+++ b/apps/codecs/libwmapro/libavutil/log.c
@@ -54,10 +54,10 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
54 return; 54 return;
55 } 55 }
56 if(count>0){ 56 if(count>0){
57 fprintf(stderr, " Last message repeated %d times\n", count); 57 //fprintf(stderr, " Last message repeated %d times\n", count);
58 count=0; 58 count=0;
59 } 59 }
60 fputs(line, stderr); 60 //fputs(line, stderr);
61 strcpy(prev, line); 61 strcpy(prev, line);
62} 62}
63 63
diff --git a/apps/codecs/libwmapro/libavutil/mathematics.c b/apps/codecs/libwmapro/libavutil/mathematics.c
index 04f3e870d1..7af0104516 100644
--- a/apps/codecs/libwmapro/libavutil/mathematics.c
+++ b/apps/codecs/libwmapro/libavutil/mathematics.c
@@ -23,7 +23,7 @@
23 * miscellaneous math routines and tables 23 * miscellaneous math routines and tables
24 */ 24 */
25 25
26#include <assert.h> 26//#include <assert.h>
27#include <stdint.h> 27#include <stdint.h>
28#include <limits.h> 28#include <limits.h>
29#include "mathematics.h" 29#include "mathematics.h"
@@ -76,9 +76,9 @@ int64_t av_gcd(int64_t a, int64_t b){
76 76
77int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ 77int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){
78 int64_t r=0; 78 int64_t r=0;
79 assert(c > 0); 79 //assert(c > 0);
80 assert(b >=0); 80 //assert(b >=0);
81 assert(rnd >=0 && rnd<=5 && rnd!=4); 81 //assert(rnd >=0 && rnd<=5 && rnd!=4);
82 82
83 if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); 83 if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1));
84 84
diff --git a/apps/codecs/libwmapro/libwmapro.make b/apps/codecs/libwmapro/libwmapro.make
new file mode 100644
index 0000000000..9177eafb20
--- /dev/null
+++ b/apps/codecs/libwmapro/libwmapro.make
@@ -0,0 +1,18 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10# libwmapro
11WMAPROLIB := $(CODECDIR)/libwmapro.a
12WMAPROLIB_SRC := $(call preprocess, $(APPSDIR)/codecs/libwmapro/SOURCES)
13WMAPROLIB_OBJ := $(call c2obj, $(WMAPROLIB_SRC))
14OTHER_SRC += $(WMAPROLIB_SRC)
15
16$(WMAPROLIB): $(WMAPROLIB_OBJ)
17 $(SILENT)$(shell rm -f $@)
18 $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null
diff --git a/apps/codecs/libwmapro/mdct_tablegen.h b/apps/codecs/libwmapro/mdct_tablegen.h
index 9f130aa6b5..998f86f283 100644
--- a/apps/codecs/libwmapro/mdct_tablegen.h
+++ b/apps/codecs/libwmapro/mdct_tablegen.h
@@ -20,7 +20,7 @@
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 21 */
22 22
23#include <assert.h> 23//#include <assert.h>
24// do not use libavutil/mathematics.h since this is compiled both 24// do not use libavutil/mathematics.h since this is compiled both
25// for the host and the target and config.h is only valid for the target 25// for the host and the target and config.h is only valid for the target
26#include <math.h> 26#include <math.h>
@@ -53,7 +53,7 @@ av_cold void ff_sine_window_init(float *window, int n) {
53} 53}
54 54
55av_cold void ff_init_ff_sine_windows(int index) { 55av_cold void ff_init_ff_sine_windows(int index) {
56 assert(index >= 0 && index < FF_ARRAY_ELEMS(ff_sine_windows)); 56 //assert(index >= 0 && index < FF_ARRAY_ELEMS(ff_sine_windows));
57#if !CONFIG_HARDCODED_TABLES 57#if !CONFIG_HARDCODED_TABLES
58 ff_sine_window_init(ff_sine_windows[index], 1 << index); 58 ff_sine_window_init(ff_sine_windows[index], 1 << index);
59#endif 59#endif
diff --git a/apps/codecs/libwmapro/put_bits.h b/apps/codecs/libwmapro/put_bits.h
index c0139661a5..9f66256b79 100644
--- a/apps/codecs/libwmapro/put_bits.h
+++ b/apps/codecs/libwmapro/put_bits.h
@@ -28,7 +28,7 @@
28 28
29#include <stdint.h> 29#include <stdint.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include <assert.h> 31//#include <assert.h>
32#include "libavutil/bswap.h" 32#include "libavutil/bswap.h"
33#include "libavutil/common.h" 33#include "libavutil/common.h"
34#include "libavutil/intreadwrite.h" 34#include "libavutil/intreadwrite.h"
@@ -153,7 +153,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
153 int bit_left; 153 int bit_left;
154 154
155 // printf("put_bits=%d %x\n", n, value); 155 // printf("put_bits=%d %x\n", n, value);
156 assert(n <= 31 && value < (1U << n)); 156 //assert(n <= 31 && value < (1U << n));
157 157
158 bit_buf = s->bit_buf; 158 bit_buf = s->bit_buf;
159 bit_left = s->bit_left; 159 bit_left = s->bit_left;
@@ -264,7 +264,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
264 264
265static inline void put_sbits(PutBitContext *pb, int n, int32_t value) 265static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
266{ 266{
267 assert(n >= 0 && n <= 31); 267 //assert(n >= 0 && n <= 31);
268 268
269 put_bits(pb, n, value & ((1<<n)-1)); 269 put_bits(pb, n, value & ((1<<n)-1));
270} 270}
@@ -304,12 +304,12 @@ static inline uint8_t* put_bits_ptr(PutBitContext *s)
304 */ 304 */
305static inline void skip_put_bytes(PutBitContext *s, int n) 305static inline void skip_put_bytes(PutBitContext *s, int n)
306{ 306{
307 assert((put_bits_count(s)&7)==0); 307 //assert((put_bits_count(s)&7)==0);
308#ifdef ALT_BITSTREAM_WRITER 308#ifdef ALT_BITSTREAM_WRITER
309 FIXME may need some cleaning of the buffer 309 FIXME may need some cleaning of the buffer
310 s->index += n<<3; 310 s->index += n<<3;
311#else 311#else
312 assert(s->bit_left==32); 312 //assert(s->bit_left==32);
313 s->buf_ptr += n; 313 s->buf_ptr += n;
314#endif 314#endif
315} 315}
diff --git a/apps/codecs/libwmapro/wma.c b/apps/codecs/libwmapro/wma.c
index 5306634c7c..4b36c84aad 100644
--- a/apps/codecs/libwmapro/wma.c
+++ b/apps/codecs/libwmapro/wma.c
@@ -23,8 +23,8 @@
23#include "wma.h" 23#include "wma.h"
24//#include "wmadata.h" 24//#include "wmadata.h"
25 25
26#undef NDEBUG 26//#undef NDEBUG
27#include <assert.h> 27//#include <assert.h>
28#if 0 28#if 0
29/* XXX: use same run/length optimization as mpeg decoders */ 29/* XXX: use same run/length optimization as mpeg decoders */
30//FIXME maybe split decode / encode or pass flag 30//FIXME maybe split decode / encode or pass flag
diff --git a/apps/codecs/libwmapro/wmaprodec.c b/apps/codecs/libwmapro/wmaprodec.c
index 88d317d5f6..e72919434c 100644
--- a/apps/codecs/libwmapro/wmaprodec.c
+++ b/apps/codecs/libwmapro/wmaprodec.c
@@ -93,13 +93,11 @@
93#include "wmaprodata.h" 93#include "wmaprodata.h"
94#include "dsputil.h" 94#include "dsputil.h"
95#include "wma.h" 95#include "wma.h"
96#include "wmaprodec.h"
96 97
97/* Some defines to make it compile */ 98/* Some defines to make it compile */
98#define AVERROR_INVALIDDATA -1 99#define AVERROR_INVALIDDATA -1
99#define AVERROR_PATCHWELCOME -2 100#define AVERROR_PATCHWELCOME -2
100#ifndef M_PI
101#define M_PI 3.14159265358979323846 /* pi */
102#endif
103#define av_log_ask_for_sample(...) 101#define av_log_ask_for_sample(...)
104 102
105/** current decoder limitations */ 103/** current decoder limitations */
@@ -238,8 +236,8 @@ typedef struct WMAProDecodeCtx {
238 */ 236 */
239static void av_cold dump_context(WMAProDecodeCtx *s) 237static void av_cold dump_context(WMAProDecodeCtx *s)
240{ 238{
241#define PRINT(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %d\n", a, b); 239#define PRINT(a, b) printf(" %s = %d\n", a, b);
242#define PRINT_HEX(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %x\n", a, b); 240#define PRINT_HEX(a, b) printf(" %s = %x\n", a, b);
243 241
244 PRINT("ed sample bit depth", s->bits_per_sample); 242 PRINT("ed sample bit depth", s->bits_per_sample);
245 PRINT_HEX("ed decode flags", s->decode_flags); 243 PRINT_HEX("ed decode flags", s->decode_flags);
@@ -255,7 +253,7 @@ static void av_cold dump_context(WMAProDecodeCtx *s)
255 *@param avctx codec context 253 *@param avctx codec context
256 *@return 0 on success, < 0 otherwise 254 *@return 0 on success, < 0 otherwise
257 */ 255 */
258static av_cold int decode_end(AVCodecContext *avctx) 256av_cold int decode_end(AVCodecContext *avctx)
259{ 257{
260 WMAProDecodeCtx *s = avctx->priv_data; 258 WMAProDecodeCtx *s = avctx->priv_data;
261 int i; 259 int i;
@@ -271,8 +269,10 @@ static av_cold int decode_end(AVCodecContext *avctx)
271 *@param avctx codec context 269 *@param avctx codec context
272 *@return 0 on success, -1 otherwise 270 *@return 0 on success, -1 otherwise
273 */ 271 */
274static av_cold int decode_init(AVCodecContext *avctx) 272av_cold int decode_init(AVCodecContext *avctx)
275{ 273{
274 avctx->priv_data = malloc(sizeof(WMAProDecodeCtx));
275 memset(avctx->priv_data, 0, sizeof(WMAProDecodeCtx));
276 WMAProDecodeCtx *s = avctx->priv_data; 276 WMAProDecodeCtx *s = avctx->priv_data;
277 uint8_t *edata_ptr = avctx->extradata; 277 uint8_t *edata_ptr = avctx->extradata;
278 unsigned int channel_mask; 278 unsigned int channel_mask;
@@ -454,7 +454,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
454 sin64[i] = sin(i*M_PI / 64.0); 454 sin64[i] = sin(i*M_PI / 64.0);
455#if 0 455#if 0
456 if (avctx->debug & FF_DEBUG_BITSTREAM) 456 if (avctx->debug & FF_DEBUG_BITSTREAM)
457 dump_context(s);
458#endif 457#endif
459 458
460 avctx->channel_layout = channel_mask; 459 avctx->channel_layout = channel_mask;
@@ -1379,7 +1378,7 @@ static int decode_frame(WMAProDecodeCtx *s)
1379 if (len != (get_bits_count(gb) - s->frame_offset) + 2) { 1378 if (len != (get_bits_count(gb) - s->frame_offset) + 2) {
1380 /** FIXME: not sure if this is always an error */ 1379 /** FIXME: not sure if this is always an error */
1381 av_log(s->avctx, AV_LOG_ERROR, "frame[%i] would have to skip %i bits\n", 1380 av_log(s->avctx, AV_LOG_ERROR, "frame[%i] would have to skip %i bits\n",
1382 s->frame_num, len - (get_bits_count(gb) - s->frame_offset) - 1); 1381 (int)s->frame_num, len - (get_bits_count(gb) - s->frame_offset) - 1);
1383 s->packet_loss = 1; 1382 s->packet_loss = 1;
1384 return 0; 1383 return 0;
1385 } 1384 }
@@ -1465,7 +1464,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
1465 *@param avpkt input packet 1464 *@param avpkt input packet
1466 *@return number of bytes that were read from the input buffer 1465 *@return number of bytes that were read from the input buffer
1467 */ 1466 */
1468static int decode_packet(AVCodecContext *avctx, 1467int decode_packet(AVCodecContext *avctx,
1469 void *data, int *data_size, AVPacket* avpkt) 1468 void *data, int *data_size, AVPacket* avpkt)
1470{ 1469{
1471 WMAProDecodeCtx *s = avctx->priv_data; 1470 WMAProDecodeCtx *s = avctx->priv_data;
@@ -1549,6 +1548,20 @@ static int decode_packet(AVCodecContext *avctx,
1549 *data_size = (int8_t *)s->samples - (int8_t *)data; 1548 *data_size = (int8_t *)s->samples - (int8_t *)data;
1550 s->packet_offset = get_bits_count(gb) & 7; 1549 s->packet_offset = get_bits_count(gb) & 7;
1551 1550
1551/* Convert the pcm samples to signed 16-bit integers. This is the format that
1552 * the rockbox simulator works with. */
1553#ifdef ROCKBOX
1554 float* fptr = data;
1555 int32_t* ptr = data;
1556 int x;
1557 for(x = 0; x < *data_size; x++)
1558 {
1559 fptr[x] *= ((float)(INT32_MAX));
1560 ptr[x] = (int32_t)fptr[x];
1561
1562 }
1563#endif
1564
1552 return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; 1565 return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;
1553} 1566}
1554 1567
diff --git a/apps/codecs/libwmapro/wmaprodec.h b/apps/codecs/libwmapro/wmaprodec.h
new file mode 100644
index 0000000000..045481b529
--- /dev/null
+++ b/apps/codecs/libwmapro/wmaprodec.h
@@ -0,0 +1,6 @@
1#include "avcodec.h"
2
3av_cold int decode_end(AVCodecContext *avctx);
4av_cold int decode_init(AVCodecContext *avctx);
5int decode_packet(AVCodecContext *avctx,
6 void *data, int *data_size, AVPacket* avpkt);
diff --git a/apps/codecs/wmapro.c b/apps/codecs/wmapro.c
index e15a610679..9e03555917 100644
--- a/apps/codecs/wmapro.c
+++ b/apps/codecs/wmapro.c
@@ -20,14 +20,166 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "codeclib.h" 22#include "codeclib.h"
23#include "libasf/asf.h"
24#include "libwmapro/wmaprodec.h"
23 25
24CODEC_HEADER 26CODEC_HEADER
25 27
28#define MAXSAMPLES (1L << 12) /* Max number of samples in a wma pro subframe */
29#define MAXCHANNELS 8
30#define BUFSIZE MAXCHANNELS * MAXSAMPLES
31static int32_t decoded[BUFSIZE] IBSS_ATTR;
32
33AVCodecContext avctx;
34AVPacket avpkt;
35
36/* This function initialises AVCodecContext with the data needed for the wmapro
37 * decoder to work. The required data is taken from asf_waveformatex_t because that's
38 * what the rockbox asf metadata parser fill/work with. In the future, when the
39 * codec is being optimised for on-target playback this function should not be needed,
40 * as we will be working directly with WMAProDecodeCtx (declared in wmaprodec.c) */
41static void init_codec_ctx(AVCodecContext *avctx, asf_waveformatex_t *wfx)
42{
43 /* Copy the extra-data */
44 avctx->extradata_size = wfx->datalen;
45 avctx->extradata = (uint8_t *)malloc(wfx->datalen*sizeof(uint8_t));
46 memcpy(avctx->extradata, wfx->data, wfx->datalen*sizeof(uint8_t));
47
48 avctx->block_align = wfx->blockalign;
49 avctx->sample_rate = wfx->rate;
50 avctx->channels = wfx->channels;
51
52}
53
26/* this is the codec entry point */ 54/* this is the codec entry point */
27enum codec_status codec_main(void) 55enum codec_status codec_main(void)
28{ 56{
29 DEBUGF("WMA: WMA Professional has not been implemented yet\n"); 57 uint32_t elapsedtime;
58 int retval;
59 asf_waveformatex_t wfx; /* Holds the stream properties */
60 size_t resume_offset;
61 int res; /* Return values from asf_read_packet() and decode_packet() */
62 uint8_t* audiobuf; /* Pointer to the payload of one wma pro packet */
63 int audiobufsize; /* Payload size */
64 int packetlength = 0; /* Logical packet size (minus the header size) */
65 int outlen = 0; /* Number of bytes written to the output buffer */
66 int pktcnt = 0; /* Count of the packets played */
67
68 /* Generic codec initialisation */
69 ci->configure(DSP_SET_SAMPLE_DEPTH, 32);
70
71
72next_track:
73
74 /* Wait for the metadata to be read */
75 while (!*ci->taginfo_ready && !ci->stop_codec)
76 ci->sleep(1);
77
78 retval = CODEC_OK;
79
80 /* Remember the resume position */
81 resume_offset = ci->id3->offset;
82 restart_track:
83 if (codec_init()) {
84 LOGF("(WMA PRO) Error: Error initialising codec\n");
85 retval = CODEC_ERROR;
86 goto done;
87 }
88
89 /* Copy the format metadata we've stored in the id3 TOC field. This
90 saves us from parsing it again here. */
91 memcpy(&wfx, ci->id3->toc, sizeof(wfx));
92
93 ci->configure(DSP_SWITCH_FREQUENCY, wfx.rate);
94 ci->configure(DSP_SET_STEREO_MODE, wfx.channels == 1 ?
95 STEREO_MONO : STEREO_INTERLEAVED);
96 codec_set_replaygain(ci->id3);
97
98 /* Initialise the AVCodecContext */
99 init_codec_ctx(&avctx, &wfx);
100
101 if (decode_init(&avctx) < 0) {
102 LOGF("(WMA PRO) Error: Unsupported or corrupt file\n");
103 retval = CODEC_ERROR;
104 goto done;
105 }
106
107 /* Now advance the file position to the first frame */
108 ci->seek_buffer(ci->id3->first_frame_offset);
109
110 elapsedtime = 0;
111 resume_offset = 0;
112
113 /* The main decoding loop */
114
115 while (pktcnt < wfx.numpackets)
116 {
117 ci->yield();
118 if (ci->stop_codec || ci->new_track) {
119 goto done;
120 }
121
122 /* Deal with any pending seek requests */
123 if (ci->seek_time){
124
125 if (ci->seek_time == 1) {
126 ci->seek_complete();
127 goto restart_track; /* Pretend you never saw this... */
128 }
129
130 elapsedtime = asf_seek(ci->seek_time, &wfx);
131 if (elapsedtime < 1){
132 ci->seek_complete();
133 goto next_track;
134 }
135
136 ci->set_elapsed(elapsedtime);
137 ci->seek_complete();
138 }
139
140 res = asf_read_packet(&audiobuf, &audiobufsize, &packetlength, &wfx);
141
142 if (res < 0) {
143 LOGF("(WMA PRO) Warning: asf_read_packet returned %d", res);
144 goto done;
145 } else {
146 avpkt.data = audiobuf;
147 avpkt.size = audiobufsize;
148 pktcnt++;
149
150 /* We now loop on the packet, decoding and outputting the subframes
151 * one-by-one. For more information about how wma pro structures its
152 * audio frames, see libwmapro/wmaprodec.c */
153 while(avpkt.size > 0)
154 {
155 outlen = BUFSIZE; /* decode_packet needs to know the size of the output buffer */
156 res = decode_packet(&avctx, decoded, &outlen, &avpkt);
157 avpkt.data += res;
158 avpkt.size -= res;
159 avctx.frame_number++;
160 if(outlen) {
161 ci->yield ();
162 /* outlen now holds the size of the data in bytes - we want the
163 * number of samples. */
164 outlen /= (sizeof(int32_t) * wfx.channels);
165 ci->pcmbuf_insert(decoded, NULL, outlen);
166 elapsedtime += outlen*10/(wfx.rate/100);
167 ci->set_elapsed(elapsedtime);
168 ci->yield ();
169 }
170 }
171
172 }
173
174 /* Advance to the next logical packet */
175 ci->advance_buffer(packetlength);
176 }
177 retval = CODEC_OK;
178
179done:
180 if (ci->request_next_track())
181 goto next_track;
30 182
31 return CODEC_ERROR; 183 return retval;
32} 184}
33 185
diff --git a/apps/metadata/asf.c b/apps/metadata/asf.c
index db806ea17f..ba1b8972af 100644
--- a/apps/metadata/asf.c
+++ b/apps/metadata/asf.c
@@ -274,9 +274,14 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
274 } 274 }
275 275
276 fileprop = 1; 276 fileprop = 1;
277 /* All we want is the play duration - uint64_t at offset 40 */ 277
278 lseek(fd, 40, SEEK_CUR); 278 /* Get the number of logical packets - uint16_t at offset 31
279 279 * (Big endian byte order) */
280 lseek(fd, 31, SEEK_CUR);
281 read_uint16be(fd, &wfx->numpackets);
282
283 /* Now get the play duration - uint64_t at offset 40 */
284 lseek(fd, 7, SEEK_CUR);
280 read_uint64le(fd, &play_duration); 285 read_uint64le(fd, &play_duration);
281 id3->length = play_duration / 10000; 286 id3->length = play_duration / 10000;
282 287
@@ -346,8 +351,9 @@ static int asf_parse_header(int fd, struct mp3entry* id3,
346 lseek(fd,current.size - 24 - 72 - 6,SEEK_CUR); 351 lseek(fd,current.size - 24 - 72 - 6,SEEK_CUR);
347 wfx->audiostream = flags&0x7f; 352 wfx->audiostream = flags&0x7f;
348 } else if (wfx->codec_id == ASF_CODEC_ID_WMAPRO) { 353 } else if (wfx->codec_id == ASF_CODEC_ID_WMAPRO) {
349 read(fd, wfx->data, 10); 354 /* wma pro decoder needs the extra-data */
350 lseek(fd,current.size - 24 - 72 - 10,SEEK_CUR); 355 read(fd, wfx->data, wfx->datalen);
356 lseek(fd,current.size - 24 - 72 - wfx->datalen,SEEK_CUR);
351 wfx->audiostream = flags&0x7f; 357 wfx->audiostream = flags&0x7f;
352 /* Correct codectype to redirect playback to the proper .codec */ 358 /* Correct codectype to redirect playback to the proper .codec */
353 id3->codectype = AFMT_WMAPRO; 359 id3->codectype = AFMT_WMAPRO;