diff options
Diffstat (limited to 'apps/codecs/librm')
-rw-r--r-- | apps/codecs/librm/rm.c | 250 | ||||
-rw-r--r-- | apps/codecs/librm/rm.h | 32 |
2 files changed, 161 insertions, 121 deletions
diff --git a/apps/codecs/librm/rm.c b/apps/codecs/librm/rm.c index 86c4378d56..4f7ebe9bef 100644 --- a/apps/codecs/librm/rm.c +++ b/apps/codecs/librm/rm.c | |||
@@ -21,28 +21,34 @@ | |||
21 | ****************************************************************************/ | 21 | ****************************************************************************/ |
22 | #include <stdio.h> | 22 | #include <stdio.h> |
23 | #include <string.h> | 23 | #include <string.h> |
24 | #include <stdint.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <fcntl.h> | ||
28 | #include <unistd.h> | ||
29 | 24 | ||
30 | #include "rm.h" | 25 | #include "rm.h" |
26 | #ifdef ROCKBOX | ||
27 | #include "codeclib.h" | ||
28 | #endif | ||
31 | 29 | ||
30 | void advance_buffer(uint8_t **buf, int val) | ||
31 | { | ||
32 | *buf += val; | ||
33 | } | ||
32 | 34 | ||
33 | #if 0 | ||
34 | #define DEBUG | ||
35 | #define DEBUGF printf | ||
36 | #else | ||
37 | #define DEBUGF(...) | ||
38 | #endif | ||
39 | |||
40 | /* Some Rockbox-like functions (these should be implemented in metadata_common.[ch] */ | ||
41 | static uint8_t get_uint8(uint8_t *buf) | 35 | static uint8_t get_uint8(uint8_t *buf) |
42 | { | 36 | { |
43 | return (uint8_t)buf[0]; | 37 | return (uint8_t)buf[0]; |
44 | } | 38 | } |
45 | 39 | ||
40 | #ifdef ROCKBOX_BIG_ENDIAN | ||
41 | static uint16_t get_uint16be(uint8_t *buf) | ||
42 | { | ||
43 | return (uint16_t)((buf[1] << 8)|buf[0]); | ||
44 | } | ||
45 | |||
46 | static uint32_t get_uint32be(uint8_t *buf) | ||
47 | { | ||
48 | return (uint32_t)((buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]); | ||
49 | } | ||
50 | |||
51 | #else | ||
46 | static uint16_t get_uint16be(uint8_t *buf) | 52 | static uint16_t get_uint16be(uint8_t *buf) |
47 | { | 53 | { |
48 | return (uint16_t)((buf[0] << 8)|buf[1]); | 54 | return (uint16_t)((buf[0] << 8)|buf[1]); |
@@ -52,6 +58,24 @@ static uint32_t get_uint32be(uint8_t *buf) | |||
52 | { | 58 | { |
53 | return (uint32_t)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); | 59 | return (uint32_t)((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]); |
54 | } | 60 | } |
61 | #endif /* ROCKBOX_BIG_ENDIAN */ | ||
62 | |||
63 | #ifdef TEST | ||
64 | #include <fcntl.h> | ||
65 | #include <unistd.h> | ||
66 | #include <sys/types.h> | ||
67 | #include <sys/stat.h> | ||
68 | |||
69 | int filesize(int fd) | ||
70 | { | ||
71 | struct stat buf; | ||
72 | |||
73 | if (fstat(fd,&buf) == -1) { | ||
74 | return -1; | ||
75 | } else { | ||
76 | return (int)buf.st_size; | ||
77 | } | ||
78 | } | ||
55 | 79 | ||
56 | static int read_uint8(int fd, uint8_t* buf) | 80 | static int read_uint8(int fd, uint8_t* buf) |
57 | { | 81 | { |
@@ -83,23 +107,9 @@ static int read_uint32be(int fd, uint32_t* buf) | |||
83 | return res; | 107 | return res; |
84 | } | 108 | } |
85 | 109 | ||
86 | off_t filesize(int fd) | ||
87 | { | ||
88 | struct stat buf; | ||
89 | 110 | ||
90 | if (fstat(fd,&buf) == -1) { | ||
91 | return -1; | ||
92 | } else { | ||
93 | return buf.st_size; | ||
94 | } | ||
95 | } | ||
96 | 111 | ||
97 | void advance_buffer(uint8_t **buf, int val) | 112 | static int read_cook_extradata(int fd, RMContext *rmctx) { |
98 | { | ||
99 | *buf += val; | ||
100 | } | ||
101 | |||
102 | int read_cook_extradata(int fd, RMContext *rmctx) { | ||
103 | read_uint32be(fd, &rmctx->cook_version); | 113 | read_uint32be(fd, &rmctx->cook_version); |
104 | read_uint16be(fd, &rmctx->samples_pf_pc); | 114 | read_uint16be(fd, &rmctx->samples_pf_pc); |
105 | read_uint16be(fd, &rmctx->nb_subbands); | 115 | read_uint16be(fd, &rmctx->nb_subbands); |
@@ -111,14 +121,14 @@ int read_cook_extradata(int fd, RMContext *rmctx) { | |||
111 | return rmctx->extradata_size; /* for 'skipped' */ | 121 | return rmctx->extradata_size; /* for 'skipped' */ |
112 | } | 122 | } |
113 | 123 | ||
114 | void print_cook_extradata(RMContext *rmctx) { | 124 | static void print_cook_extradata(RMContext *rmctx) { |
115 | 125 | ||
116 | printf(" cook_version = 0x%08x\n", rmctx->cook_version); | 126 | DEBUGF(" cook_version = 0x%08x\n", rmctx->cook_version); |
117 | printf(" samples_per_frame_per_channel = %d\n", rmctx->samples_pf_pc); | 127 | DEBUGF(" samples_per_frame_per_channel = %d\n", rmctx->samples_pf_pc); |
118 | printf(" number_of_subbands_in_freq_domain = %d\n", rmctx->nb_subbands); | 128 | DEBUGF(" number_of_subbands_in_freq_domain = %d\n", rmctx->nb_subbands); |
119 | if(rmctx->extradata_size == 16) { | 129 | if(rmctx->extradata_size == 16) { |
120 | printf(" joint_stereo_subband_start = %d\n",rmctx->js_subband_start); | 130 | DEBUGF(" joint_stereo_subband_start = %d\n",rmctx->js_subband_start); |
121 | printf(" joint_stereo_vlc_bits = %d\n", rmctx->js_vlc_bits); | 131 | DEBUGF(" joint_stereo_vlc_bits = %d\n", rmctx->js_vlc_bits); |
122 | } | 132 | } |
123 | } | 133 | } |
124 | 134 | ||
@@ -196,7 +206,7 @@ static int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
196 | read_uint32be(fd, &version); | 206 | read_uint32be(fd, &version); |
197 | skipped += 4; | 207 | skipped += 4; |
198 | 208 | ||
199 | printf(" version=0x%04x\n",((version >> 16) & 0xff)); | 209 | DEBUGF(" version=0x%04x\n",((version >> 16) & 0xff)); |
200 | if (((version >> 16) & 0xff) == 3) { | 210 | if (((version >> 16) & 0xff) == 3) { |
201 | /* Very old version */ | 211 | /* Very old version */ |
202 | } else { | 212 | } else { |
@@ -205,7 +215,7 @@ static int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
205 | read_uint32be(fd, &header_size); | 215 | read_uint32be(fd, &header_size); |
206 | skipped += 4; | 216 | skipped += 4; |
207 | /* obj.size will be filled with an unknown value, replaced with header_size */ | 217 | /* obj.size will be filled with an unknown value, replaced with header_size */ |
208 | printf(" Object: %s, size: %d bytes, version: 0x%04x\n",fourcc2str(obj.fourcc),header_size,obj.version); | 218 | DEBUGF(" Object: %s, size: %d bytes, version: 0x%04x\n",fourcc2str(obj.fourcc),header_size,obj.version); |
209 | 219 | ||
210 | read_uint16be(fd, &flavor); | 220 | read_uint16be(fd, &flavor); |
211 | read_uint32be(fd, &coded_framesize); | 221 | read_uint32be(fd, &coded_framesize); |
@@ -253,20 +263,22 @@ static int real_read_audio_stream_info(int fd, RMContext *rmctx) | |||
253 | 263 | ||
254 | read_uint32be(fd, &rmctx->extradata_size); | 264 | read_uint32be(fd, &rmctx->extradata_size); |
255 | skipped += 4; | 265 | skipped += 4; |
256 | if(!strncmp(fourcc2str(fourcc),"cook",4)) | 266 | if(!strncmp(fourcc2str(fourcc),"cook",4)){ |
257 | skipped += read_cook_extradata(fd, rmctx); | 267 | skipped += read_cook_extradata(fd, rmctx); |
268 | rmctx->codec_type = cook; | ||
269 | } | ||
258 | 270 | ||
259 | 271 | ||
260 | printf(" flavor = %d\n",flavor); | 272 | DEBUGF(" flavor = %d\n",flavor); |
261 | printf(" coded_frame_size = %d\n",coded_framesize); | 273 | DEBUGF(" coded_frame_size = %d\n",coded_framesize); |
262 | printf(" sub_packet_h = %d\n",rmctx->sub_packet_h); | 274 | DEBUGF(" sub_packet_h = %d\n",rmctx->sub_packet_h); |
263 | printf(" frame_size = %d\n",rmctx->block_align); | 275 | DEBUGF(" frame_size = %d\n",rmctx->block_align); |
264 | printf(" sub_packet_size = %d\n",rmctx->sub_packet_size); | 276 | DEBUGF(" sub_packet_size = %d\n",rmctx->sub_packet_size); |
265 | printf(" sample_rate= %d\n",rmctx->sample_rate); | 277 | DEBUGF(" sample_rate= %d\n",rmctx->sample_rate); |
266 | printf(" channels= %d\n",rmctx->nb_channels); | 278 | DEBUGF(" channels= %d\n",rmctx->nb_channels); |
267 | printf(" fourcc = %s\n",fourcc2str(fourcc)); | 279 | DEBUGF(" fourcc = %s\n",fourcc2str(fourcc)); |
268 | printf(" codec_extra_data_length = %d\n",rmctx->extradata_size); | 280 | DEBUGF(" codec_extra_data_length = %d\n",rmctx->extradata_size); |
269 | printf(" codec_extradata :\n"); | 281 | DEBUGF(" codec_extradata :\n"); |
270 | print_cook_extradata(rmctx); | 282 | print_cook_extradata(rmctx); |
271 | 283 | ||
272 | } | 284 | } |
@@ -327,18 +339,18 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
327 | read_uint32be(fd, &unknown1); | 339 | read_uint32be(fd, &unknown1); |
328 | read_uint32be(fd, &unknown2); | 340 | read_uint32be(fd, &unknown2); |
329 | 341 | ||
330 | printf("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); | 342 | DEBUGF("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); |
331 | printf(" unknown1=%d (0x%08x)\n",unknown1,unknown1); | 343 | DEBUGF(" unknown1=%d (0x%08x)\n",unknown1,unknown1); |
332 | printf(" unknown2=%d (0x%08x)\n",unknown2,unknown2); | 344 | DEBUGF(" unknown2=%d (0x%08x)\n",unknown2,unknown2); |
333 | 345 | ||
334 | res = real_read_object_header(fd, &obj); | 346 | res = real_read_object_header(fd, &obj); |
335 | header_end = 0; | 347 | header_end = 0; |
336 | while(res) | 348 | while(res) |
337 | { | 349 | { |
338 | printf("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); | 350 | DEBUGF("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); |
339 | skipped = 10; | 351 | skipped = 10; |
340 | if(obj.fourcc == FOURCC('I','N','D','X')) | 352 | if(obj.fourcc == FOURCC('I','N','D','X')) |
341 | break; | 353 | break; |
342 | switch (obj.fourcc) | 354 | switch (obj.fourcc) |
343 | { | 355 | { |
344 | case FOURCC('P','R','O','P'): /* File properties */ | 356 | case FOURCC('P','R','O','P'): /* File properties */ |
@@ -347,7 +359,7 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
347 | read_uint32be(fd, &max_packet_size); | 359 | read_uint32be(fd, &max_packet_size); |
348 | read_uint32be(fd, &avg_packet_size); | 360 | read_uint32be(fd, &avg_packet_size); |
349 | read_uint32be(fd, &packet_count); | 361 | read_uint32be(fd, &packet_count); |
350 | read_uint32be(fd, &duration); | 362 | read_uint32be(fd, &rmctx->duration); |
351 | read_uint32be(fd, &preroll); | 363 | read_uint32be(fd, &preroll); |
352 | read_uint32be(fd, &index_offset); | 364 | read_uint32be(fd, &index_offset); |
353 | read_uint32be(fd, &rmctx->data_offset); | 365 | read_uint32be(fd, &rmctx->data_offset); |
@@ -355,17 +367,17 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
355 | read_uint16be(fd, &rmctx->flags); | 367 | read_uint16be(fd, &rmctx->flags); |
356 | skipped += 40; | 368 | skipped += 40; |
357 | 369 | ||
358 | printf(" max_bitrate = %d\n",max_bitrate); | 370 | DEBUGF(" max_bitrate = %d\n",max_bitrate); |
359 | printf(" avg_bitrate = %d\n",avg_bitrate); | 371 | DEBUGF(" avg_bitrate = %d\n",avg_bitrate); |
360 | printf(" max_packet_size = %d\n",max_packet_size); | 372 | DEBUGF(" max_packet_size = %d\n",max_packet_size); |
361 | printf(" avg_packet_size = %d\n",avg_packet_size); | 373 | DEBUGF(" avg_packet_size = %d\n",avg_packet_size); |
362 | printf(" packet_count = %d\n",packet_count); | 374 | DEBUGF(" packet_count = %d\n",packet_count); |
363 | printf(" duration = %d\n",duration); | 375 | DEBUGF(" duration = %d\n",rmctx->duration); |
364 | printf(" preroll = %d\n",preroll); | 376 | DEBUGF(" preroll = %d\n",preroll); |
365 | printf(" index_offset = %d\n",index_offset); | 377 | DEBUGF(" index_offset = %d\n",index_offset); |
366 | printf(" data_offset = %d\n",rmctx->data_offset); | 378 | DEBUGF(" data_offset = %d\n",rmctx->data_offset); |
367 | printf(" num_streams = %d\n",num_streams); | 379 | DEBUGF(" num_streams = %d\n",num_streams); |
368 | printf(" flags=0x%04x\n",flags); | 380 | DEBUGF(" flags=0x%04x\n",flags); |
369 | break; | 381 | break; |
370 | 382 | ||
371 | case FOURCC('C','O','N','T'): | 383 | case FOURCC('C','O','N','T'): |
@@ -375,10 +387,10 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
375 | skipped += read_str(fd,copyright); | 387 | skipped += read_str(fd,copyright); |
376 | skipped += read_str(fd,comment); | 388 | skipped += read_str(fd,comment); |
377 | 389 | ||
378 | printf(" title=\"%s\"\n",title); | 390 | DEBUGF(" title=\"%s\"\n",title); |
379 | printf(" author=\"%s\"\n",author); | 391 | DEBUGF(" author=\"%s\"\n",author); |
380 | printf(" copyright=\"%s\"\n",copyright); | 392 | DEBUGF(" copyright=\"%s\"\n",copyright); |
381 | printf(" comment=\"%s\"\n",comment); | 393 | DEBUGF(" comment=\"%s\"\n",comment); |
382 | break; | 394 | break; |
383 | 395 | ||
384 | case FOURCC('M','D','P','R'): /* Media properties */ | 396 | case FOURCC('M','D','P','R'): /* Media properties */ |
@@ -406,18 +418,18 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
406 | read_uint32be(fd,&v); | 418 | read_uint32be(fd,&v); |
407 | skipped += 4; | 419 | skipped += 4; |
408 | 420 | ||
409 | printf(" stream_id = 0x%04x\n",stream_id); | 421 | DEBUGF(" stream_id = 0x%04x\n",stream_id); |
410 | printf(" max_bitrate = %d\n",max_bitrate); | 422 | DEBUGF(" max_bitrate = %d\n",max_bitrate); |
411 | printf(" avg_bitrate = %d\n",avg_bitrate); | 423 | DEBUGF(" avg_bitrate = %d\n",avg_bitrate); |
412 | printf(" max_packet_size = %d\n",max_packet_size); | 424 | DEBUGF(" max_packet_size = %d\n",max_packet_size); |
413 | printf(" avg_packet_size = %d\n",avg_packet_size); | 425 | DEBUGF(" avg_packet_size = %d\n",avg_packet_size); |
414 | printf(" start_time = %d\n",start_time); | 426 | DEBUGF(" start_time = %d\n",start_time); |
415 | printf(" preroll = %d\n",preroll); | 427 | DEBUGF(" preroll = %d\n",preroll); |
416 | printf(" duration = %d\n",duration); | 428 | DEBUGF(" duration = %d\n",duration); |
417 | printf(" desc=\"%s\"\n",desc); | 429 | DEBUGF(" desc=\"%s\"\n",desc); |
418 | printf(" mimetype=\"%s\"\n",mimetype); | 430 | DEBUGF(" mimetype=\"%s\"\n",mimetype); |
419 | printf(" codec_data_size = %d\n",codec_data_size); | 431 | DEBUGF(" codec_data_size = %d\n",codec_data_size); |
420 | printf(" v=\"%s\"\n", fourcc2str(v)); | 432 | DEBUGF(" v=\"%s\"\n", fourcc2str(v)); |
421 | 433 | ||
422 | if (v == FOURCC('.','r','a',0xfd)) | 434 | if (v == FOURCC('.','r','a',0xfd)) |
423 | { | 435 | { |
@@ -428,10 +440,10 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
428 | 440 | ||
429 | case FOURCC('D','A','T','A'): | 441 | case FOURCC('D','A','T','A'): |
430 | 442 | ||
431 | read_uint32be(fd,&rmctx->nb_packets); | 443 | read_uint32be(fd,&rmctx->nb_packets); |
432 | skipped += 4; | 444 | skipped += 4; |
433 | read_uint32be(fd,&next_data_off); | 445 | read_uint32be(fd,&next_data_off); |
434 | skipped += 4; | 446 | skipped += 4; |
435 | if (!rmctx->nb_packets && (rmctx->flags & 4)) | 447 | if (!rmctx->nb_packets && (rmctx->flags & 4)) |
436 | rmctx->nb_packets = 3600 * 25; | 448 | rmctx->nb_packets = 3600 * 25; |
437 | 449 | ||
@@ -445,8 +457,8 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
445 | if(rmctx->nb_packets % rmctx->sub_packet_h) | 457 | if(rmctx->nb_packets % rmctx->sub_packet_h) |
446 | rmctx->nb_packets += rmctx->sub_packet_h - (rmctx->nb_packets % rmctx->sub_packet_h); | 458 | rmctx->nb_packets += rmctx->sub_packet_h - (rmctx->nb_packets % rmctx->sub_packet_h); |
447 | 459 | ||
448 | printf(" data_nb_packets = %d\n",rmctx->nb_packets); | 460 | DEBUGF(" data_nb_packets = %d\n",rmctx->nb_packets); |
449 | printf(" next DATA offset = %d\n",next_data_off); | 461 | DEBUGF(" next DATA offset = %d\n",next_data_off); |
450 | header_end = 1; | 462 | header_end = 1; |
451 | break; | 463 | break; |
452 | } | 464 | } |
@@ -459,7 +471,7 @@ int real_parse_header(int fd, RMContext *rmctx) | |||
459 | return 0; | 471 | return 0; |
460 | } | 472 | } |
461 | 473 | ||
462 | void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt) | 474 | void rm_get_packet_fd(int fd,RMContext *rmctx, RMPacket *pkt) |
463 | { | 475 | { |
464 | uint8_t unknown,packet_group; | 476 | uint8_t unknown,packet_group; |
465 | uint16_t x, place; | 477 | uint16_t x, place; |
@@ -467,10 +479,19 @@ void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt) | |||
467 | uint16_t h = rmctx->sub_packet_h; | 479 | uint16_t h = rmctx->sub_packet_h; |
468 | uint16_t y = rmctx->sub_packet_cnt; | 480 | uint16_t y = rmctx->sub_packet_cnt; |
469 | uint16_t w = rmctx->audio_framesize; | 481 | uint16_t w = rmctx->audio_framesize; |
482 | int res; | ||
470 | do | 483 | do |
471 | { | 484 | { |
472 | y = rmctx->sub_packet_cnt; | 485 | y = rmctx->sub_packet_cnt; |
473 | read_uint16be(fd,&pkt->version); | 486 | read_uint16be(fd,&pkt->version); |
487 | |||
488 | /* Simple error checking */ | ||
489 | if(pkt->version != 0 && pkt->version != 1) | ||
490 | { | ||
491 | DEBUGF("parsing packets failed\n"); | ||
492 | return -1; | ||
493 | } | ||
494 | |||
474 | read_uint16be(fd,&pkt->length); | 495 | read_uint16be(fd,&pkt->length); |
475 | read_uint16be(fd,&pkt->stream_number); | 496 | read_uint16be(fd,&pkt->stream_number); |
476 | read_uint32be(fd,&pkt->timestamp); | 497 | read_uint32be(fd,&pkt->timestamp); |
@@ -495,22 +516,17 @@ void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt) | |||
495 | 516 | ||
496 | for(x = 0 ; x < w/sps; x++) | 517 | for(x = 0 ; x < w/sps; x++) |
497 | { | 518 | { |
498 | place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); | 519 | res = read(fd,pkt->data+(sps*(h*x+((h+1)/2)*(y&1)+(y>>1))), sps); |
499 | read(fd,pkt->data+place, sps); | ||
500 | //DEBUGF("place = %d data[place] = %d\n",place,pkt->data[place]); | ||
501 | } | 520 | } |
502 | rmctx->audio_pkt_cnt++; | 521 | rmctx->audio_pkt_cnt++; |
503 | }while(++(rmctx->sub_packet_cnt) < h); | 522 | }while(++(rmctx->sub_packet_cnt) < h); |
504 | 523 | ||
505 | //return pkt->data; | ||
506 | } | 524 | } |
525 | #endif /*TEST*/ | ||
507 | 526 | ||
508 | /** | 527 | int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt) |
509 | * Another version of rm_get_packet which reads from a memory buffer | ||
510 | * instead of readind from a file descriptor. | ||
511 | **/ | ||
512 | void rm_get_packet_membuf(uint8_t **filebuf,RMContext *rmctx, RMPacket *pkt) | ||
513 | { | 528 | { |
529 | int consumed = 0; | ||
514 | uint8_t unknown; | 530 | uint8_t unknown; |
515 | uint16_t x, place; | 531 | uint16_t x, place; |
516 | uint16_t sps = rmctx->sub_packet_size; | 532 | uint16_t sps = rmctx->sub_packet_size; |
@@ -520,36 +536,46 @@ void rm_get_packet_membuf(uint8_t **filebuf,RMContext *rmctx, RMPacket *pkt) | |||
520 | do | 536 | do |
521 | { | 537 | { |
522 | y = rmctx->sub_packet_cnt; | 538 | y = rmctx->sub_packet_cnt; |
523 | pkt->version = get_uint16be(*filebuf); | 539 | pkt->version = get_uint16be(*src); |
524 | pkt->length = get_uint16be(*filebuf+2); | 540 | |
525 | pkt->stream_number = get_uint16be(*filebuf+4); | 541 | /* Simple error checking */ |
526 | pkt->timestamp = get_uint32be(*filebuf+6); | 542 | if(pkt->version != 0 && pkt->version != 1) |
527 | DEBUGF(" version = %d\n" | 543 | { |
544 | DEBUGF("parsing packets failed\n"); | ||
545 | return -1; | ||
546 | } | ||
547 | |||
548 | pkt->length = get_uint16be(*src+2); | ||
549 | pkt->stream_number = get_uint16be(*src+4); | ||
550 | pkt->timestamp = get_uint32be(*src+6); | ||
551 | /*DEBUGF(" version = %d\n" | ||
528 | " length = %d\n" | 552 | " length = %d\n" |
529 | " stream = %d\n" | 553 | " stream = %d\n" |
530 | " timestamp= %d\n",pkt->version,pkt->length,pkt->stream_number,pkt->timestamp); | 554 | " timestamp= %d\n\n",pkt->version,pkt->length,pkt->stream_number,pkt->timestamp);*/ |
531 | 555 | unknown = get_uint8(*src+10); | |
532 | unknown = get_uint8(*filebuf+10); | 556 | pkt->flags = get_uint8(*src+11); |
533 | pkt->flags = get_uint8(*filebuf+11); | ||
534 | 557 | ||
535 | if(pkt->version == 1) | 558 | if(pkt->version == 1) |
536 | unknown = get_uint8(*filebuf+10); | 559 | unknown = get_uint8(*src+10); |
537 | 560 | ||
538 | if (pkt->flags & 2) /* keyframe */ | 561 | if (pkt->flags & 2) /* keyframe */ |
539 | y = rmctx->sub_packet_cnt = 0; | 562 | y = rmctx->sub_packet_cnt = 0; |
540 | if (!y) /* if keyframe update playback elapsed time */ | 563 | if (!y) |
541 | rmctx->audiotimestamp = pkt->timestamp; | 564 | rmctx->audiotimestamp = pkt->timestamp; |
542 | 565 | ||
543 | advance_buffer(filebuf,12); | 566 | advance_buffer(src,12); |
544 | 567 | consumed += 12; | |
545 | for(x = 0 ; x < w/sps; x++) | 568 | for(x = 0 ; x < w/sps; x++) |
546 | { | 569 | { |
547 | place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); | 570 | place = sps*(h*x+((h+1)/2)*(y&1)+(y>>1)); |
548 | pkt->frames[place/sps] = *filebuf; | 571 | pkt->frames[place/sps] = *src; |
549 | advance_buffer(filebuf,sps); | 572 | advance_buffer(src,sps); |
573 | consumed += sps; | ||
550 | } | 574 | } |
551 | rmctx->audio_pkt_cnt++; | 575 | rmctx->audio_pkt_cnt++; |
552 | }while(++(rmctx->sub_packet_cnt) < h); | 576 | }while(++(rmctx->sub_packet_cnt) < h); |
577 | |||
578 | return consumed; | ||
553 | } | 579 | } |
554 | 580 | ||
555 | #ifdef DEBUG | 581 | #ifdef DEBUG |
diff --git a/apps/codecs/librm/rm.h b/apps/codecs/librm/rm.h index bdd03f3db2..a0c386e824 100644 --- a/apps/codecs/librm/rm.h +++ b/apps/codecs/librm/rm.h | |||
@@ -22,17 +22,21 @@ | |||
22 | #define _RM_H | 22 | #define _RM_H |
23 | 23 | ||
24 | #include <stdio.h> | 24 | #include <stdio.h> |
25 | #include <stdint.h> | 25 | #include <inttypes.h> |
26 | 26 | ||
27 | enum codecs{cook}; | ||
27 | typedef struct rm_packet | 28 | typedef struct rm_packet |
28 | { | 29 | { |
29 | uint8_t data[30000]; /* Reordered data. No malloc, hence the size */ | ||
30 | uint8_t *frames[100]; /* Pointers to ordered audio frames in buffer */ | 30 | uint8_t *frames[100]; /* Pointers to ordered audio frames in buffer */ |
31 | uint16_t version; | 31 | uint16_t version; |
32 | uint16_t length; | 32 | uint16_t length; |
33 | uint32_t timestamp; | 33 | uint32_t timestamp; |
34 | uint16_t stream_number; | 34 | uint16_t stream_number; |
35 | uint8_t flags; | 35 | uint8_t flags; |
36 | |||
37 | #ifdef TEST | ||
38 | uint8_t data[30000]; /* Reordered data. No malloc, hence the size */ | ||
39 | #endif | ||
36 | }RMPacket; | 40 | }RMPacket; |
37 | 41 | ||
38 | typedef struct rm_context | 42 | typedef struct rm_context |
@@ -46,6 +50,7 @@ typedef struct rm_context | |||
46 | 50 | ||
47 | /* Stream Variables */ | 51 | /* Stream Variables */ |
48 | uint32_t data_offset; | 52 | uint32_t data_offset; |
53 | uint32_t duration; | ||
49 | uint32_t audiotimestamp; /* Audio packet timestamp*/ | 54 | uint32_t audiotimestamp; /* Audio packet timestamp*/ |
50 | uint16_t sub_packet_cnt; /* Subpacket counter, used while reading */ | 55 | uint16_t sub_packet_cnt; /* Subpacket counter, used while reading */ |
51 | uint16_t sub_packet_size, sub_packet_h, coded_framesize; /* Descrambling parameters from container */ | 56 | uint16_t sub_packet_size, sub_packet_h, coded_framesize; /* Descrambling parameters from container */ |
@@ -53,6 +58,7 @@ typedef struct rm_context | |||
53 | uint16_t sub_packet_lengths[16]; /* Length of each subpacket */ | 58 | uint16_t sub_packet_lengths[16]; /* Length of each subpacket */ |
54 | 59 | ||
55 | /* Codec Context */ | 60 | /* Codec Context */ |
61 | enum codecs codec_type; | ||
56 | uint16_t block_align; | 62 | uint16_t block_align; |
57 | uint32_t nb_packets; | 63 | uint32_t nb_packets; |
58 | int frame_number; | 64 | int frame_number; |
@@ -66,18 +72,26 @@ typedef struct rm_context | |||
66 | uint32_t cook_version; | 72 | uint32_t cook_version; |
67 | uint16_t samples_pf_pc; /* samples per frame per channel */ | 73 | uint16_t samples_pf_pc; /* samples per frame per channel */ |
68 | uint16_t nb_subbands; /* number of subbands in the frequency domain */ | 74 | uint16_t nb_subbands; /* number of subbands in the frequency domain */ |
69 | /* extra 8 bytes for stereo data */ | 75 | /* extra 8 bytes for joint-stereo data */ |
70 | uint32_t unused; | 76 | uint32_t unused; |
71 | uint16_t js_subband_start; /* joint stereo subband start */ | 77 | uint16_t js_subband_start; /* joint stereo subband start */ |
72 | uint16_t js_vlc_bits; | 78 | uint16_t js_vlc_bits; |
73 | 79 | ||
74 | } RMContext; | 80 | } RMContext; |
75 | 81 | ||
76 | int open_wav(char* filename); | ||
77 | void close_wav(int fd, RMContext *rmctx); | ||
78 | int real_parse_header(int fd, RMContext *rmctx); | 82 | int real_parse_header(int fd, RMContext *rmctx); |
79 | void rm_get_packet(int fd,RMContext *rmctx, RMPacket *pkt); | 83 | |
80 | void rm_get_packet_membuf(uint8_t **filebuf,RMContext *rmctx, RMPacket *pkt); | 84 | /* Get a (sub_packet_h*frames_per_packet) number of audio frames from a memory buffer */ |
81 | off_t filesize(int fd); | 85 | int rm_get_packet(uint8_t **src,RMContext *rmctx, RMPacket *pkt); |
86 | |||
87 | #ifdef TEST | ||
88 | |||
89 | int filesize(int fd); | ||
82 | void advance_buffer(uint8_t **buf, int val); | 90 | void advance_buffer(uint8_t **buf, int val); |
83 | #endif | 91 | |
92 | /* Get a (sub_packet_h*frames_per_packet) number of audio frames from a file descriptor */ | ||
93 | void rm_get_packet_fd(int fd,RMContext *rmctx, RMPacket *pkt); | ||
94 | |||
95 | #endif /* TEST */ | ||
96 | |||
97 | #endif /* _RM_H */ | ||