diff options
author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2008-05-22 09:58:19 +0000 |
---|---|---|
committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2008-05-22 09:58:19 +0000 |
commit | 6a74a5dd3b625f1143e301b9d6a840e3b4969bd3 (patch) | |
tree | 76da0d77f0727f819521a0e18378f3d9d41e4908 | |
parent | 5f8bd63cba88186b05d22581ea9edf02b1538caf (diff) | |
download | rockbox-6a74a5dd3b625f1143e301b9d6a840e3b4969bd3.tar.gz rockbox-6a74a5dd3b625f1143e301b9d6a840e3b4969bd3.zip |
Commit FS#9015. Rework of musepack buffered seek. Now a static seek buffer of 8192 entries is used. The seeking precision is adapted to the length of the file (e.g. 26ms for files <=3.5min and 0.4s for files ~60min).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17604 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/libmusepack/decoder.h | 11 | ||||
-rw-r--r-- | apps/codecs/libmusepack/mpc_decoder.c | 181 |
2 files changed, 75 insertions, 117 deletions
diff --git a/apps/codecs/libmusepack/decoder.h b/apps/codecs/libmusepack/decoder.h index b035ae9574..41ffe1ca9a 100644 --- a/apps/codecs/libmusepack/decoder.h +++ b/apps/codecs/libmusepack/decoder.h | |||
@@ -49,7 +49,7 @@ | |||
49 | enum { | 49 | enum { |
50 | MPC_V_MEM = 2304, | 50 | MPC_V_MEM = 2304, |
51 | MPC_DECODER_MEMSIZE = 16384, // overall buffer size (words) | 51 | MPC_DECODER_MEMSIZE = 16384, // overall buffer size (words) |
52 | MPC_SEEK_BUFFER_SIZE = 65536, // seek buffer size (words) | 52 | MPC_SEEK_BUFFER_SIZE = 8192, // seek buffer size (words) |
53 | }; | 53 | }; |
54 | 54 | ||
55 | typedef struct { | 55 | typedef struct { |
@@ -78,9 +78,6 @@ typedef struct mpc_decoder_t { | |||
78 | 78 | ||
79 | mpc_uint32_t DecodedFrames; | 79 | mpc_uint32_t DecodedFrames; |
80 | mpc_uint32_t OverallFrames; | 80 | mpc_uint32_t OverallFrames; |
81 | mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries) | ||
82 | mpc_uint16_t SeekTableIndex; | ||
83 | mpc_uint32_t SeekTableCounter; | ||
84 | mpc_int32_t SampleRate; // Sample frequency | 81 | mpc_int32_t SampleRate; // Sample frequency |
85 | 82 | ||
86 | mpc_uint32_t StreamVersion; // version of bitstream | 83 | mpc_uint32_t StreamVersion; // version of bitstream |
@@ -110,8 +107,10 @@ typedef struct mpc_decoder_t { | |||
110 | mpc_int8_t SCFI_R [32]; // describes order of transmitted SCF | 107 | mpc_int8_t SCFI_R [32]; // describes order of transmitted SCF |
111 | mpc_bool_t MS_Flag[32]; // MS used? | 108 | mpc_bool_t MS_Flag[32]; // MS used? |
112 | 109 | ||
113 | mpc_uint32_t* SeekTable; | 110 | mpc_uint32_t SeekTableCounter; // used to sum up skip info, if SeekTable_Step != 1 |
114 | mpc_uint8_t SeekTable_Step; | 111 | mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries) |
112 | mpc_uint32_t* SeekTable; // seek table itself | ||
113 | mpc_uint8_t SeekTable_Step; // frames per seek table index | ||
115 | 114 | ||
116 | #ifdef MPC_FIXED_POINT | 115 | #ifdef MPC_FIXED_POINT |
117 | mpc_uint8_t SCF_shift[256]; | 116 | mpc_uint8_t SCF_shift[256]; |
diff --git a/apps/codecs/libmusepack/mpc_decoder.c b/apps/codecs/libmusepack/mpc_decoder.c index fa3295357c..f6aab66494 100644 --- a/apps/codecs/libmusepack/mpc_decoder.c +++ b/apps/codecs/libmusepack/mpc_decoder.c | |||
@@ -393,7 +393,6 @@ mpc_decoder_reset_globals(mpc_decoder *d) | |||
393 | mpc_decoder_reset_bitstream_decode(d); | 393 | mpc_decoder_reset_bitstream_decode(d); |
394 | 394 | ||
395 | d->DecodedFrames = 0; | 395 | d->DecodedFrames = 0; |
396 | d->SeekTableIndex = 0; | ||
397 | d->MaxDecodedFrames = 0; | 396 | d->MaxDecodedFrames = 0; |
398 | d->StreamVersion = 0; | 397 | d->StreamVersion = 0; |
399 | d->MS_used = 0; | 398 | d->MS_used = 0; |
@@ -470,7 +469,10 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) | |||
470 | } | 469 | } |
471 | 470 | ||
472 | if (d->DecodedFrames == 0) | 471 | if (d->DecodedFrames == 0) |
472 | { | ||
473 | d->SeekTable[0] = mpc_decoder_bits_read(d); | 473 | d->SeekTable[0] = mpc_decoder_bits_read(d); |
474 | d->SeekTableCounter = 0; | ||
475 | } | ||
474 | 476 | ||
475 | // read jump-info for validity check of frame | 477 | // read jump-info for validity check of frame |
476 | d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); | 478 | d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); |
@@ -499,15 +501,12 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) | |||
499 | d->DecodedFrames++; | 501 | d->DecodedFrames++; |
500 | 502 | ||
501 | /* update seek table */ | 503 | /* update seek table */ |
502 | if (d->SeekTable_Step == 1) { | 504 | d->SeekTableCounter += d->FwdJumpInfo + 20; |
503 | d->SeekTable [d->DecodedFrames] = d->FwdJumpInfo + 20; | 505 | if (0 == (d->DecodedFrames % d->SeekTable_Step)) |
504 | } else { | 506 | { |
505 | if ((d->DecodedFrames-1) % d->SeekTable_Step == 0) { | 507 | d->SeekTable[d->DecodedFrames/d->SeekTable_Step] = d->SeekTableCounter; |
506 | d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter; | 508 | d->MaxDecodedFrames = d->DecodedFrames; |
507 | d->SeekTableIndex += 1; | 509 | d->SeekTableCounter = 0; |
508 | d->SeekTableCounter = 0; | ||
509 | } | ||
510 | d->SeekTableCounter += d->FwdJumpInfo + 20; | ||
511 | } | 510 | } |
512 | 511 | ||
513 | // synthesize signal | 512 | // synthesize signal |
@@ -1436,9 +1435,7 @@ void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) | |||
1436 | d->Ring = 0; | 1435 | d->Ring = 0; |
1437 | d->WordsRead = 0; | 1436 | d->WordsRead = 0; |
1438 | d->Max_Band = 0; | 1437 | d->Max_Band = 0; |
1439 | d->SeekTable = NULL; | ||
1440 | d->SeekTable_Step = 1; | 1438 | d->SeekTable_Step = 1; |
1441 | d->SeekTableIndex = 0; | ||
1442 | d->SeekTableCounter = 0; | 1439 | d->SeekTableCounter = 0; |
1443 | 1440 | ||
1444 | mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); | 1441 | mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); |
@@ -1488,10 +1485,10 @@ static void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) | |||
1488 | 1485 | ||
1489 | memset(d->SeekTable, 0, sizeof(Seekbuffer)); | 1486 | memset(d->SeekTable, 0, sizeof(Seekbuffer)); |
1490 | 1487 | ||
1488 | // limit used table size to MPC_SEEK_BUFFER_SIZE | ||
1491 | seekTableSize = min(si->frames, MPC_SEEK_BUFFER_SIZE); | 1489 | seekTableSize = min(si->frames, MPC_SEEK_BUFFER_SIZE); |
1492 | d->SeekTable_Step = si->frames / seekTableSize; | 1490 | // frames per buffer to not exceed buffer and to be able to seek full file |
1493 | if (si->frames % seekTableSize) | 1491 | d->SeekTable_Step = (si->frames + seekTableSize - 1) / seekTableSize; |
1494 | d->SeekTable_Step+=1; | ||
1495 | } | 1492 | } |
1496 | 1493 | ||
1497 | mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si) | 1494 | mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si) |
@@ -1599,15 +1596,11 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) | |||
1599 | // seek direction (note: avoids casting to int64) | 1596 | // seek direction (note: avoids casting to int64) |
1600 | delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames)); | 1597 | delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames)); |
1601 | 1598 | ||
1602 | // update max decoded frames | ||
1603 | if (d->DecodedFrames > d->MaxDecodedFrames) | ||
1604 | d->MaxDecodedFrames = d->DecodedFrames; | ||
1605 | |||
1606 | if (seekFrame > 33) | 1599 | if (seekFrame > 33) |
1607 | lastFrame = seekFrame - 33 + 1 - d->SeekTable_Step; | 1600 | lastFrame = seekFrame - 33 + 1 - d->SeekTable_Step; |
1608 | 1601 | ||
1609 | if (d->MaxDecodedFrames == 0) { | 1602 | if (d->MaxDecodedFrames == 0) // nothing decoded yet, parse stream |
1610 | 1603 | { | |
1611 | mpc_decoder_reset_state(d); | 1604 | mpc_decoder_reset_state(d); |
1612 | 1605 | ||
1613 | // starts from the beginning since no frames have been decoded yet, or not using seek table | 1606 | // starts from the beginning since no frames have been decoded yet, or not using seek table |
@@ -1619,97 +1612,82 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) | |||
1619 | // reset number of decoded frames | 1612 | // reset number of decoded frames |
1620 | d->DecodedFrames = 0; | 1613 | d->DecodedFrames = 0; |
1621 | 1614 | ||
1622 | // jump to the last frame, updating seek table | 1615 | // jump to the last frame via parsing, updating seek table |
1623 | if (d->SeekTable_Step == 1) { | 1616 | d->SeekTable[0] = (mpc_uint32_t)fpos; |
1624 | d->SeekTable[0] = (mpc_uint32_t)fpos; | 1617 | d->SeekTableCounter = d->SeekTable[0]; |
1625 | for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) | 1618 | for (d->DecodedFrames = 1; d->DecodedFrames < lastFrame; d->DecodedFrames++) |
1626 | d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d); | 1619 | { |
1627 | } else { | 1620 | d->SeekTableCounter += mpc_decoder_jump_frame(d); |
1628 | d->SeekTableIndex = 0; | 1621 | if (0 == (d->DecodedFrames % d->SeekTable_Step)) |
1629 | d->SeekTableCounter = (mpc_uint32_t)fpos; | 1622 | { |
1630 | for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) { | 1623 | d->SeekTable[d->DecodedFrames/d->SeekTable_Step] = d->SeekTableCounter; |
1631 | if (d->DecodedFrames % d->SeekTable_Step == 0) { | 1624 | d->MaxDecodedFrames = d->DecodedFrames; |
1632 | d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter; | 1625 | d->SeekTableCounter = 0; |
1633 | d->SeekTableIndex += 1; | ||
1634 | d->SeekTableCounter = 0; | ||
1635 | } | ||
1636 | d->SeekTableCounter += mpc_decoder_jump_frame(d); | ||
1637 | } | 1626 | } |
1638 | } | 1627 | } |
1639 | 1628 | } | |
1640 | 1629 | else if (delta < 0) // jump backwards, seek table is already available | |
1641 | } else if (delta < 0) { | 1630 | { |
1642 | |||
1643 | mpc_decoder_reset_state(d); | 1631 | mpc_decoder_reset_state(d); |
1644 | 1632 | ||
1645 | // jumps backwards using the seek table | 1633 | // jumps backwards using the seek table |
1646 | fpos = d->SeekTable[0]; | 1634 | fpos = d->SeekTable[0]; |
1647 | if (d->SeekTable_Step == 1) { | 1635 | for (d->DecodedFrames = 0; d->DecodedFrames < lastFrame; d->DecodedFrames++) |
1648 | for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames++) | 1636 | { |
1649 | fpos += d->SeekTable[d->DecodedFrames+1]; | 1637 | if (0 == (d->DecodedFrames+1) % d->SeekTable_Step) |
1650 | } else { | 1638 | { |
1651 | d->SeekTableIndex = 0; | 1639 | fpos += d->SeekTable[(d->DecodedFrames+1)/d->SeekTable_Step]; |
1652 | //d->SeekTableCounter = 0; | 1640 | d->SeekTableCounter = 0; |
1653 | for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++) | 1641 | } |
1654 | fpos += d->SeekTable[d->SeekTableIndex+1]; | ||
1655 | d->SeekTableCounter = d->SeekTable[d->SeekTableIndex]; | ||
1656 | } | 1642 | } |
1657 | mpc_decoder_seek_to(d, fpos); | 1643 | mpc_decoder_seek_to(d, fpos); |
1658 | 1644 | } | |
1659 | } else if (delta > 33) { | 1645 | else if (delta > 33) // jump forward, seek table is available |
1660 | 1646 | { | |
1661 | mpc_decoder_reset_state(d); | 1647 | mpc_decoder_reset_state(d); |
1662 | 1648 | ||
1663 | // jumps forward from the current position | 1649 | // 1st loop: jump to the last usable position in the seek table |
1664 | if (d->MaxDecodedFrames > lastFrame) { // REVIEW: Correct?? or (d->MaxDecodedFrames > d->DecodedFrames) | 1650 | fpos = mpc_decoder_bits_read(d); |
1665 | // jump to the last usable position in the seek table | 1651 | for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++) |
1666 | if (d->SeekTable_Step == 1) { | 1652 | { |
1667 | fpos = mpc_decoder_bits_read(d); | 1653 | if (0 == (d->DecodedFrames+1) % d->SeekTable_Step) |
1668 | for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++) | 1654 | { |
1669 | fpos += d->SeekTable[d->DecodedFrames+1]; | 1655 | fpos += d->SeekTable[(d->DecodedFrames+1)/d->SeekTable_Step]; |
1670 | } else { | 1656 | d->SeekTableCounter = 0; |
1671 | // could test SeekTable offset and jump to next entry but this is easier for now... | ||
1672 | //d->SeekTableIndex = 0; | ||
1673 | //d->SeekTableCounter = 0; | ||
1674 | fpos = d->SeekTable[0]; | ||
1675 | d->SeekTableIndex = 0; | ||
1676 | for (d->DecodedFrames = 0;d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++) | ||
1677 | fpos += d->SeekTable[d->SeekTableIndex+1]; | ||
1678 | d->SeekTableCounter = d->SeekTable[d->SeekTableIndex]; | ||
1679 | } | 1657 | } |
1680 | |||
1681 | mpc_decoder_seek_to(d, fpos); | ||
1682 | } | 1658 | } |
1683 | if (d->SeekTable_Step == 1) { | 1659 | mpc_decoder_seek_to(d, fpos); |
1684 | for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) | 1660 | |
1685 | d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d); | 1661 | // 2nd loop: jump the residual frames via parsing, update seek table |
1686 | } else { | 1662 | for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) |
1687 | for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) { | 1663 | { |
1688 | if (d->DecodedFrames % d->SeekTable_Step == 0) { | 1664 | d->SeekTableCounter += mpc_decoder_jump_frame(d); |
1689 | d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter; | 1665 | if (0 == (d->DecodedFrames+1) % d->SeekTable_Step) |
1690 | d->SeekTableIndex += 1; | 1666 | { |
1691 | d->SeekTableCounter = 0; | 1667 | d->SeekTable[(d->DecodedFrames+1)/d->SeekTable_Step] = d->SeekTableCounter; |
1692 | } | 1668 | d->MaxDecodedFrames = d->DecodedFrames; |
1693 | d->SeekTableCounter += mpc_decoder_jump_frame(d); | 1669 | d->SeekTableCounter = 0; |
1694 | } | 1670 | } |
1695 | } | 1671 | } |
1696 | } | 1672 | } |
1697 | 1673 | // until here we jumped to desired position -33 frames | |
1698 | // REVIEW: Needed? | ||
1699 | mpc_decoder_update_buffer(d); | ||
1700 | |||
1701 | for (;d->DecodedFrames < seekFrame; d->DecodedFrames++) { | ||
1702 | 1674 | ||
1675 | // now we decode the last 33 frames until we reach the seek position | ||
1676 | // this is neccessary as mpc uses entropy coding in time domain | ||
1677 | for (;d->DecodedFrames < seekFrame; d->DecodedFrames++) | ||
1678 | { | ||
1703 | mpc_uint32_t FrameBitCnt; | 1679 | mpc_uint32_t FrameBitCnt; |
1704 | 1680 | ||
1705 | d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); // read jump-info | 1681 | d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); // read jump-info |
1706 | d->ActDecodePos = (d->Zaehler << 5) + d->pos; | 1682 | d->ActDecodePos = (d->Zaehler << 5) + d->pos; |
1707 | FrameBitCnt = mpc_decoder_bits_read(d); | 1683 | FrameBitCnt = mpc_decoder_bits_read(d); |
1708 | // scanning the scalefactors (and check for validity of frame) | 1684 | // scanning the scalefactors (and check for validity of frame) |
1709 | if (d->StreamVersion >= 7) { | 1685 | if (d->StreamVersion >= 7) |
1710 | mpc_decoder_read_bitstream_sv7(d, (d->DecodedFrames < seekFrame - 1)); | 1686 | { |
1687 | mpc_decoder_read_bitstream_sv7(d, (d->DecodedFrames < seekFrame - 1)); | ||
1711 | } | 1688 | } |
1712 | else { | 1689 | else |
1690 | { | ||
1713 | #ifdef MPC_SUPPORT_SV456 | 1691 | #ifdef MPC_SUPPORT_SV456 |
1714 | mpc_decoder_read_bitstream_sv6(d); | 1692 | mpc_decoder_read_bitstream_sv6(d); |
1715 | #else | 1693 | #else |
@@ -1725,34 +1703,15 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) | |||
1725 | // Bug in perform_jump; | 1703 | // Bug in perform_jump; |
1726 | return FALSE; | 1704 | return FALSE; |
1727 | 1705 | ||
1728 | // REVIEW: Only if decodedFrames < maxDecodedFrames?? | ||
1729 | if (d->SeekTable_Step == 1) { | ||
1730 | // check that the frame length corresponds with any data already in the seek table | ||
1731 | if (d->SeekTable[d->DecodedFrames+1] != 0 && d->SeekTable[d->DecodedFrames+1] != d->FwdJumpInfo + 20) | ||
1732 | return FALSE; | ||
1733 | d->SeekTable [d->DecodedFrames+1] = d->FwdJumpInfo + 20; | ||
1734 | } else { | ||
1735 | if (d->DecodedFrames % d->SeekTable_Step == 0) { | ||
1736 | if (d->SeekTable[d->SeekTableIndex] != 0 && d->SeekTable[d->SeekTableIndex] != d->SeekTableCounter) | ||
1737 | return FALSE; | ||
1738 | d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter; | ||
1739 | d->SeekTableIndex += 1; | ||
1740 | d->SeekTableCounter = 0; | ||
1741 | } | ||
1742 | d->SeekTableCounter += d->FwdJumpInfo + 20; | ||
1743 | } | ||
1744 | |||
1745 | // update buffer | 1706 | // update buffer |
1746 | mpc_decoder_update_buffer(d); | 1707 | mpc_decoder_update_buffer(d); |
1747 | 1708 | ||
1748 | if (d->DecodedFrames == seekFrame - 1) { | 1709 | if (d->DecodedFrames == seekFrame - 1) |
1749 | 1710 | { | |
1750 | // initialize the synth correctly for perfect decoding | 1711 | // initialize the synth correctly for perfect decoding |
1751 | mpc_decoder_requantisierung(d, d->Max_Band); | 1712 | mpc_decoder_requantisierung(d, d->Max_Band); |
1752 | mpc_decoder_synthese_filter_float(d, NULL); | 1713 | mpc_decoder_synthese_filter_float(d, NULL); |
1753 | |||
1754 | } | 1714 | } |
1755 | |||
1756 | } | 1715 | } |
1757 | 1716 | ||
1758 | return TRUE; | 1717 | return TRUE; |