diff options
Diffstat (limited to 'apps/codecs/libcook/rm.c')
-rw-r--r-- | apps/codecs/libcook/rm.c | 73 |
1 files changed, 70 insertions, 3 deletions
diff --git a/apps/codecs/libcook/rm.c b/apps/codecs/libcook/rm.c index 92b6428462..b2ccfc2480 100644 --- a/apps/codecs/libcook/rm.c +++ b/apps/codecs/libcook/rm.c | |||
@@ -38,6 +38,21 @@ | |||
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | /* Some Rockbox-like functions (these should be implemented in metadata_common.[ch] */ | 40 | /* Some Rockbox-like functions (these should be implemented in metadata_common.[ch] */ |
41 | static uint8_t get_uint8(uint8_t *buf) | ||
42 | { | ||
43 | return (uint8_t)buf[0]; | ||
44 | } | ||
45 | |||
46 | static uint16_t get_uint16be(uint8_t *buf) | ||
47 | { | ||
48 | return (uint16_t)((buf[0] << 8)|buf[1]); | ||
49 | } | ||
50 | |||
51 | static uint32_t get_uint32be(uint8_t *buf) | ||
52 | { | ||
53 | return (uint32_t)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); | ||
54 | } | ||
55 | |||
41 | static int read_uint8(int fd, uint8_t* buf) | 56 | static int read_uint8(int fd, uint8_t* buf) |
42 | { | 57 | { |
43 | unsigned char tmp[1]; | 58 | unsigned char tmp[1]; |
@@ -79,6 +94,11 @@ off_t filesize(int fd) | |||
79 | } | 94 | } |
80 | } | 95 | } |
81 | 96 | ||
97 | void advance_buffer(uint8_t **buf, int val) | ||
98 | { | ||
99 | *buf += val; | ||
100 | } | ||
101 | |||
82 | int read_cook_extradata(int fd, RMContext *rmctx) { | 102 | int read_cook_extradata(int fd, RMContext *rmctx) { |
83 | read_uint32be(fd, &rmctx->cook_version); | 103 | read_uint32be(fd, &rmctx->cook_version); |
84 | read_uint16be(fd, &rmctx->samples_pf_pc); | 104 | read_uint16be(fd, &rmctx->samples_pf_pc); |
@@ -273,7 +293,6 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
273 | uint32_t duration; | 293 | uint32_t duration; |
274 | uint32_t preroll; | 294 | uint32_t preroll; |
275 | uint32_t index_offset; | 295 | uint32_t index_offset; |
276 | uint32_t data_offset; | ||
277 | uint16_t num_streams; | 296 | uint16_t num_streams; |
278 | uint16_t flags = 0; | 297 | uint16_t flags = 0; |
279 | 298 | ||
@@ -331,7 +350,7 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
331 | read_uint32be(fd, &duration); | 350 | read_uint32be(fd, &duration); |
332 | read_uint32be(fd, &preroll); | 351 | read_uint32be(fd, &preroll); |
333 | read_uint32be(fd, &index_offset); | 352 | read_uint32be(fd, &index_offset); |
334 | read_uint32be(fd, &data_offset); | 353 | read_uint32be(fd, &rmctx->data_offset); |
335 | read_uint16be(fd, &num_streams); | 354 | read_uint16be(fd, &num_streams); |
336 | read_uint16be(fd, &rmctx->flags); | 355 | read_uint16be(fd, &rmctx->flags); |
337 | skipped += 40; | 356 | skipped += 40; |
@@ -344,7 +363,7 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
344 | printf(" duration = %d\n",duration); | 363 | printf(" duration = %d\n",duration); |
345 | printf(" preroll = %d\n",preroll); | 364 | printf(" preroll = %d\n",preroll); |
346 | printf(" index_offset = %d\n",index_offset); | 365 | printf(" index_offset = %d\n",index_offset); |
347 | printf(" data_offset = %d\n",data_offset); | 366 | printf(" data_offset = %d\n",rmctx->data_offset); |
348 | printf(" num_streams = %d\n",num_streams); | 367 | printf(" num_streams = %d\n",num_streams); |
349 | printf(" flags=0x%04x\n",flags); | 368 | printf(" flags=0x%04x\n",flags); |
350 | break; | 369 | break; |
@@ -474,6 +493,54 @@ void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt) | |||
474 | 493 | ||
475 | //return pkt->data; | 494 | //return pkt->data; |
476 | } | 495 | } |
496 | |||
497 | /** | ||
498 | * Another version of rm_get_packet which reads from a memory buffer | ||
499 | * instead of readind from a file descriptor. | ||
500 | **/ | ||
501 | void rm_get_packet_membuf(uint8_t **filebuf,RMContext *rmctx, RMPacket *pkt) | ||
502 | { | ||
503 | uint8_t unknown; | ||
504 | uint16_t x, place; | ||
505 | uint16_t sps = rmctx->sub_packet_size; | ||
506 | uint16_t h = rmctx->sub_packet_h; | ||
507 | uint16_t y = rmctx->sub_packet_cnt; | ||
508 | uint16_t w = rmctx->audio_framesize; | ||
509 | do | ||
510 | { | ||
511 | y = rmctx->sub_packet_cnt; | ||
512 | pkt->version = get_uint16be(*filebuf); | ||
513 | pkt->length = get_uint16be(*filebuf+2); | ||
514 | pkt->stream_number = get_uint16be(*filebuf+4); | ||
515 | pkt->timestamp = get_uint32be(*filebuf+6); | ||
516 | DEBUGF(" version = %d\n" | ||
517 | " length = %d\n" | ||
518 | " stream = %d\n" | ||
519 | " timestamp= %d\n",pkt->version,pkt->length,pkt->stream_number,pkt->timestamp); | ||
520 | |||
521 | unknown = get_uint8(*filebuf+10); | ||
522 | pkt->flags = get_uint8(*filebuf+11); | ||
523 | |||
524 | if(pkt->version == 1) | ||
525 | unknown = get_uint8(*filebuf+10); | ||
526 | |||
527 | if (pkt->flags & 2) /* keyframe */ | ||
528 | y = rmctx->sub_packet_cnt = 0; | ||
529 | if (!y) /* if keyframe update playback elapsed time */ | ||
530 | rmctx->audiotimestamp = pkt->timestamp; | ||
531 | |||
532 | advance_buffer(filebuf,12); | ||
533 | |||
534 | for(x = 0 ; x < w/sps; x++) | ||
535 | { | ||
536 | place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); | ||
537 | pkt->frames[place/sps] = *filebuf; | ||
538 | advance_buffer(filebuf,sps); | ||
539 | } | ||
540 | rmctx->audio_pkt_cnt++; | ||
541 | }while(++(rmctx->sub_packet_cnt) < h); | ||
542 | } | ||
543 | |||
477 | #ifdef DEBUG | 544 | #ifdef DEBUG |
478 | void dump_rm_context(RMContext *rmctx) | 545 | void dump_rm_context(RMContext *rmctx) |
479 | { | 546 | { |