summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/opus.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/opus.c')
-rw-r--r--lib/rbcodec/codecs/opus.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/lib/rbcodec/codecs/opus.c b/lib/rbcodec/codecs/opus.c
index 6f4a5644fb..d30a9cf714 100644
--- a/lib/rbcodec/codecs/opus.c
+++ b/lib/rbcodec/codecs/opus.c
@@ -216,7 +216,7 @@ static int64_t seek_backwards(ogg_sync_state *oy, ogg_page *og,
216 offset = ret; 216 offset = ret;
217 continue; 217 continue;
218 } 218 }
219 } else if (ret == -3) 219 } else if (ret == -3)
220 return(-3); 220 return(-3);
221 else if (ret<=0) 221 else if (ret<=0)
222 break; 222 break;
@@ -235,8 +235,8 @@ static int64_t seek_backwards(ogg_sync_state *oy, ogg_page *og,
235static int opus_seek_page_granule(int64_t pos, int64_t curpos, 235static int opus_seek_page_granule(int64_t pos, int64_t curpos,
236 ogg_sync_state *oy, ogg_stream_state *os) 236 ogg_sync_state *oy, ogg_stream_state *os)
237{ 237{
238 /* TODO: Someone may want to try to implement seek to packet, 238 /* TODO: Someone may want to try to implement seek to packet,
239 instead of just to page (should be more accurate, not be any 239 instead of just to page (should be more accurate, not be any
240 faster) */ 240 faster) */
241 241
242 int64_t crofs; 242 int64_t crofs;
@@ -253,7 +253,7 @@ static int opus_seek_page_granule(int64_t pos, int64_t curpos,
253 /* if seeking for more that 10sec, 253 /* if seeking for more that 10sec,
254 headersize is known & more than 10kb is played, 254 headersize is known & more than 10kb is played,
255 try to guess a place to seek from the number of 255 try to guess a place to seek from the number of
256 bytes playe for this position, this works best when 256 bytes playe for this position, this works best when
257 the bitrate is relativly constant. 257 the bitrate is relativly constant.
258 */ 258 */
259 259
@@ -324,7 +324,7 @@ static int opus_seek_page_granule(int64_t pos, int64_t curpos,
324 324
325 lastgranule = ogg_page_granulepos(&og); 325 lastgranule = ogg_page_granulepos(&og);
326 326
327 if ( ((lastgranule - (avgpagelen/4)) < pos && ( lastgranule + 327 if ( ((lastgranule - (avgpagelen/4)) < pos && ( lastgranule +
328 avgpagelen + (avgpagelen / 4)) > pos) || 328 avgpagelen + (avgpagelen / 4)) > pos) ||
329 lastgranule > pos) { 329 lastgranule > pos) {
330 330
@@ -360,15 +360,15 @@ enum codec_status codec_run(void)
360 int error = CODEC_ERROR; 360 int error = CODEC_ERROR;
361 long action; 361 long action;
362 intptr_t param; 362 intptr_t param;
363 ogg_sync_state oy; 363 ogg_sync_state *oy;
364 ogg_stream_state *os;
364 ogg_page og; 365 ogg_page og;
365 ogg_packet op; 366 ogg_packet op;
366 ogg_stream_state os;
367 int64_t page_granule = 0; 367 int64_t page_granule = 0;
368 int stream_init = -1; 368 int stream_init = -1;
369 int sample_rate = 48000; 369 int sample_rate = 48000;
370 OpusDecoder *st = NULL; 370 OpusDecoder *st = NULL;
371 OpusHeader header; 371 OpusHeader *header;
372 int ret; 372 int ret;
373 unsigned long strtoffset; 373 unsigned long strtoffset;
374 int skip = 0; 374 int skip = 0;
@@ -387,10 +387,15 @@ enum codec_status codec_run(void)
387 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); 387 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
388#endif 388#endif
389 389
390 /* Allocate some stuff off the heap */
391 header = _ogg_malloc(sizeof(*header));
392 os = _ogg_malloc(sizeof(*os));
393 oy = _ogg_malloc(sizeof(*oy));
394
390 /* pre-init the ogg_sync_state buffer, so it won't need many reallocs */ 395 /* pre-init the ogg_sync_state buffer, so it won't need many reallocs */
391 ogg_sync_init(&oy); 396 ogg_sync_init(oy);
392 oy.storage = 64*1024; 397 oy->storage = 64*1024;
393 oy.data = _ogg_malloc(oy.storage); 398 oy->data = _ogg_malloc(oy->storage);
394 399
395 /* allocate output buffer */ 400 /* allocate output buffer */
396 uint16_t *output = (uint16_t*) _ogg_malloc(MAX_FRAME_SIZE*sizeof(uint16_t)); 401 uint16_t *output = (uint16_t*) _ogg_malloc(MAX_FRAME_SIZE*sizeof(uint16_t));
@@ -407,13 +412,13 @@ enum codec_status codec_run(void)
407 if (action == CODEC_ACTION_SEEK_TIME) { 412 if (action == CODEC_ACTION_SEEK_TIME) {
408 if (st != NULL) { 413 if (st != NULL) {
409 /* calculate granule to seek to (including seek rewind) */ 414 /* calculate granule to seek to (including seek rewind) */
410 seek_target = (48LL * param) + header.preskip; 415 seek_target = (48LL * param) + header->preskip;
411 skip = MIN(seek_target, SEEK_REWIND); 416 skip = MIN(seek_target, SEEK_REWIND);
412 seek_target -= skip; 417 seek_target -= skip;
413 418
414 LOGF("Opus seek page:%lld,%lld,%ld\n", (long long int)seek_target, 419 LOGF("Opus seek page:%lld,%lld,%ld\n", (long long int)seek_target,
415 (long long int)page_granule, (long)param); 420 (long long int)page_granule, (long)param);
416 opus_seek_page_granule(seek_target, page_granule, &oy, &os); 421 opus_seek_page_granule(seek_target, page_granule, oy, os);
417 /* reset the state to help ensure that subsequent packets won't 422 /* reset the state to help ensure that subsequent packets won't
418 use state set by unrelated packets processed before seek */ 423 use state set by unrelated packets processed before seek */
419 opus_decoder_ctl(st, OPUS_RESET_STATE); 424 opus_decoder_ctl(st, OPUS_RESET_STATE);
@@ -427,14 +432,14 @@ enum codec_status codec_run(void)
427 432
428 next_page: 433 next_page:
429 /*Get the ogg buffer for writing*/ 434 /*Get the ogg buffer for writing*/
430 if (get_more_data(&oy) < 1) { 435 if (get_more_data(oy) < 1) {
431 goto done; 436 goto done;
432 } 437 }
433 438
434 /* Loop for all complete pages we got (most likely only one) */ 439 /* Loop for all complete pages we got (most likely only one) */
435 while (ogg_sync_pageout(&oy, &og) == 1) { 440 while (ogg_sync_pageout(oy, &og) == 1) {
436 if (stream_init != 0) { 441 if (stream_init != 0) {
437 stream_init = ogg_stream_init(&os, ogg_page_serialno(&og)); 442 stream_init = ogg_stream_init(os, ogg_page_serialno(&og));
438 if (stream_init != 0) { 443 if (stream_init != 0) {
439 LOGF("Stream init failed"); 444 LOGF("Stream init failed");
440 goto done; 445 goto done;
@@ -442,22 +447,22 @@ enum codec_status codec_run(void)
442 } 447 }
443 448
444 /* Add page to the bitstream */ 449 /* Add page to the bitstream */
445 ogg_stream_pagein(&os, &og); 450 ogg_stream_pagein(os, &og);
446 451
447 page_granule = ogg_page_granulepos(&og); 452 page_granule = ogg_page_granulepos(&og);
448 granule_pos = page_granule; 453 granule_pos = page_granule;
449 454
450 while ((ogg_stream_packetout(&os, &op) == 1) && !op.e_o_s) { 455 while ((ogg_stream_packetout(os, &op) == 1) && !op.e_o_s) {
451 if (op.packetno == 0){ 456 if (op.packetno == 0){
452 /* identification header */ 457 /* identification header */
453 458
454 if (opus_header_parse(op.packet, op.bytes, &header) == 0) { 459 if (opus_header_parse(op.packet, op.bytes, header) == 0) {
455 LOGF("Could not parse header"); 460 LOGF("Could not parse header");
456 goto done; 461 goto done;
457 } 462 }
458 skip = header.preskip; 463 skip = header->preskip;
459 464
460 st = opus_decoder_create(sample_rate, header.channels, &ret); 465 st = opus_decoder_create(sample_rate, header->channels, &ret);
461 if (ret != OPUS_OK) { 466 if (ret != OPUS_OK) {
462 LOGF("opus_decoder_create failed %d", ret); 467 LOGF("opus_decoder_create failed %d", ret);
463 goto done; 468 goto done;
@@ -466,11 +471,11 @@ enum codec_status codec_run(void)
466 471
467 codec_set_replaygain(ci->id3); 472 codec_set_replaygain(ci->id3);
468 473
469 opus_decoder_ctl(st, OPUS_SET_GAIN(header.gain)); 474 opus_decoder_ctl(st, OPUS_SET_GAIN(header->gain));
470 475
471 ci->configure(DSP_SET_FREQUENCY, sample_rate); 476 ci->configure(DSP_SET_FREQUENCY, sample_rate);
472 ci->configure(DSP_SET_SAMPLE_DEPTH, 16); 477 ci->configure(DSP_SET_SAMPLE_DEPTH, 16);
473 ci->configure(DSP_SET_STEREO_MODE, (header.channels == 2) ? 478 ci->configure(DSP_SET_STEREO_MODE, (header->channels == 2) ?
474 STEREO_INTERLEAVED : STEREO_MONO); 479 STEREO_INTERLEAVED : STEREO_MONO);
475 480
476 if (strtoffset) 481 if (strtoffset)
@@ -479,7 +484,7 @@ enum codec_status codec_run(void)
479 action = CODEC_ACTION_SEEK_TIME; 484 action = CODEC_ACTION_SEEK_TIME;
480 goto process_action; 485 goto process_action;
481 } else { 486 } else {
482 /* seek buffer directly to the first audio packet to avoid 487 /* seek buffer directly to the first audio packet to avoid
483 allocating space for huge comment packets 488 allocating space for huge comment packets
484 (embedded Album Art) */ 489 (embedded Album Art) */
485 if (seek_opus_tags()) 490 if (seek_opus_tags())
@@ -490,12 +495,12 @@ enum codec_status codec_run(void)
490 } 495 }
491 } 496 }
492 LOGF("sync reset"); 497 LOGF("sync reset");
493 ogg_sync_reset(&oy); /* next page */ 498 ogg_sync_reset(oy); /* next page */
494 break; 499 break;
495 } else { 500 } else {
496 /* report progress */ 501 /* report progress */
497 ci->set_offset((size_t) ci->curpos); 502 ci->set_offset((size_t) ci->curpos);
498 ci->set_elapsed((granule_pos - header.preskip) / 48); 503 ci->set_elapsed((granule_pos - header->preskip) / 48);
499 504
500 /* Decode audio packets */ 505 /* Decode audio packets */
501 ret = opus_decode(st, op.packet, op.bytes, output, MAX_FRAME_SIZE, 0); 506 ret = opus_decode(st, op.packet, op.bytes, output, MAX_FRAME_SIZE, 0);
@@ -503,7 +508,7 @@ enum codec_status codec_run(void)
503 if (ret > skip) { 508 if (ret > skip) {
504 /* part of or entire output buffer is played */ 509 /* part of or entire output buffer is played */
505 ret -= skip; 510 ret -= skip;
506 ci->pcmbuf_insert(&output[skip * header.channels], NULL, ret); 511 ci->pcmbuf_insert(&output[skip * header->channels], NULL, ret);
507 skip = 0; 512 skip = 0;
508 } else { 513 } else {
509 if (ret < 0) { 514 if (ret < 0) {