Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 1 | /* |
| 2 | * Musepack SV7 decoder |
| 3 | * Copyright (c) 2006 Konstantin Shishkov |
| 4 | * |
| 5 | * This file is part of FFmpeg. |
| 6 | * |
| 7 | * FFmpeg is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU Lesser General Public |
| 9 | * License as published by the Free Software Foundation; either |
| 10 | * version 2.1 of the License, or (at your option) any later version. |
| 11 | * |
| 12 | * FFmpeg is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * Lesser General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Lesser General Public |
| 18 | * License along with FFmpeg; if not, write to the Free Software |
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ |
| 21 | |
| 22 | /** |
Diego Biurrun | ba87f08 | 2010-04-20 14:45:34 | [diff] [blame] | 23 | * @file |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 24 | * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples |
| 25 | * divided into 32 subbands. |
| 26 | */ |
| 27 | |
Justin Ruggles | a903f8f | 2012-11-10 15:00:00 | [diff] [blame] | 28 | #include "libavutil/channel_layout.h" |
Diego Biurrun | 218aefc | 2013-02-07 23:31:13 | [diff] [blame] | 29 | #include "libavutil/internal.h" |
Kostya Shishkov | 74e2a07 | 2009-03-08 16:37:57 | [diff] [blame] | 30 | #include "libavutil/lfg.h" |
Andreas Rheinhardt | 790f793 | 2024-03-25 00:30:37 | [diff] [blame] | 31 | #include "libavutil/mem.h" |
Anton Khirnov | c8c2dfb | 2020-06-10 13:38:08 | [diff] [blame] | 32 | #include "libavutil/mem_internal.h" |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 33 | #include "libavutil/thread.h" |
Anton Khirnov | c8c2dfb | 2020-06-10 13:38:08 | [diff] [blame] | 34 | |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 35 | #include "avcodec.h" |
Andreas Rheinhardt | a688f3c | 2022-03-16 17:18:28 | [diff] [blame] | 36 | #include "codec_internal.h" |
Andreas Rheinhardt | 66b691f | 2022-08-24 19:28:16 | [diff] [blame] | 37 | #include "decode.h" |
Stefano Sabatini | 9106a69 | 2009-04-13 16:20:26 | [diff] [blame] | 38 | #include "get_bits.h" |
Mans Rullgard | c4f5c2d | 2011-05-16 15:52:01 | [diff] [blame] | 39 | #include "mpegaudiodsp.h" |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 40 | |
| 41 | #include "mpc.h" |
| 42 | #include "mpc7data.h" |
| 43 | |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 44 | static VLCElem scfi_vlc[1 << MPC7_SCFI_BITS]; |
| 45 | static VLCElem dscf_vlc[1 << MPC7_DSCF_BITS]; |
| 46 | static VLCElem hdr_vlc [1 << MPC7_HDR_BITS]; |
| 47 | static const VLCElem *quant_vlc[MPC7_QUANT_VLC_TABLES][2]; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 48 | |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 49 | static av_cold void mpc7_init_static(void) |
| 50 | { |
Andreas Rheinhardt | 2d76406 | 2022-06-13 21:02:57 | [diff] [blame] | 51 | static VLCElem quant_tables[7224]; |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 52 | VLCInitState state = VLC_INIT_STATE(quant_tables); |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 53 | const uint8_t *raw_quant_table = mpc7_quant_vlcs; |
| 54 | |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 55 | VLC_INIT_STATIC_TABLE_FROM_LENGTHS(scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE, |
| 56 | &mpc7_scfi[1], 2, |
| 57 | &mpc7_scfi[0], 2, 1, 0, 0); |
| 58 | VLC_INIT_STATIC_TABLE_FROM_LENGTHS(dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE, |
| 59 | &mpc7_dscf[1], 2, |
| 60 | &mpc7_dscf[0], 2, 1, -7, 0); |
| 61 | VLC_INIT_STATIC_TABLE_FROM_LENGTHS(hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE, |
| 62 | &mpc7_hdr[1], 2, |
| 63 | &mpc7_hdr[0], 2, 1, -5, 0); |
| 64 | for (int i = 0; i < MPC7_QUANT_VLC_TABLES; i++) { |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 65 | for (int j = 0; j < 2; j++) { |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 66 | quant_vlc[i][j] = |
| 67 | ff_vlc_init_tables_from_lengths(&state, 9, mpc7_quant_vlc_sizes[i], |
| 68 | &raw_quant_table[1], 2, |
| 69 | &raw_quant_table[0], 2, 1, |
| 70 | mpc7_quant_vlc_off[i], 0); |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 71 | raw_quant_table += 2 * mpc7_quant_vlc_sizes[i]; |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 72 | } |
| 73 | } |
| 74 | ff_mpa_synth_init_fixed(); |
| 75 | } |
| 76 | |
Zuxy Meng | 98a6fff | 2008-03-21 03:11:20 | [diff] [blame] | 77 | static av_cold int mpc7_decode_init(AVCodecContext * avctx) |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 78 | { |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 79 | static AVOnce init_static_once = AV_ONCE_INIT; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 80 | MPCContext *c = avctx->priv_data; |
| 81 | GetBitContext gb; |
Michael Niedermayer | 151ecc2 | 2012-01-31 00:14:58 | [diff] [blame] | 82 | LOCAL_ALIGNED_16(uint8_t, buf, [16]); |
Kostya Shishkov | bd4110f | 2009-04-17 14:09:56 | [diff] [blame] | 83 | |
Justin Ruggles | befc473 | 2011-11-03 03:02:52 | [diff] [blame] | 84 | /* Musepack SV7 is always stereo */ |
Anton Khirnov | edd7be9 | 2013-05-07 05:20:32 | [diff] [blame] | 85 | if (avctx->ch_layout.nb_channels != 2) { |
| 86 | avpriv_request_sample(avctx, "%d channels", avctx->ch_layout.nb_channels); |
Justin Ruggles | befc473 | 2011-11-03 03:02:52 | [diff] [blame] | 87 | return AVERROR_PATCHWELCOME; |
| 88 | } |
| 89 | |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 90 | if(avctx->extradata_size < 16){ |
| 91 | av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); |
Paul B Mahol | 6a6e20b | 2017-02-03 19:14:13 | [diff] [blame] | 92 | return AVERROR_INVALIDDATA; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 93 | } |
| 94 | memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); |
Kostya Shishkov | 74e2a07 | 2009-03-08 16:37:57 | [diff] [blame] | 95 | av_lfg_init(&c->rnd, 0xDEADBEEF); |
Diego Biurrun | c67b449 | 2014-02-13 16:57:05 | [diff] [blame] | 96 | ff_bswapdsp_init(&c->bdsp); |
Mans Rullgard | c4f5c2d | 2011-05-16 15:52:01 | [diff] [blame] | 97 | ff_mpadsp_init(&c->mpadsp); |
Diego Biurrun | c67b449 | 2014-02-13 16:57:05 | [diff] [blame] | 98 | c->bdsp.bswap_buf((uint32_t *) buf, (const uint32_t *) avctx->extradata, 4); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 99 | init_get_bits(&gb, buf, 128); |
| 100 | |
| 101 | c->IS = get_bits1(&gb); |
| 102 | c->MSS = get_bits1(&gb); |
| 103 | c->maxbands = get_bits(&gb, 6); |
| 104 | if(c->maxbands >= BANDS){ |
| 105 | av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->maxbands); |
Paul B Mahol | 6a6e20b | 2017-02-03 19:14:13 | [diff] [blame] | 106 | return AVERROR_INVALIDDATA; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 107 | } |
David Conrad | 0a8dedc | 2009-05-14 00:02:07 | [diff] [blame] | 108 | skip_bits_long(&gb, 88); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 109 | c->gapless = get_bits1(&gb); |
| 110 | c->lastframelen = get_bits(&gb, 11); |
| 111 | av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n", |
| 112 | c->IS, c->MSS, c->gapless, c->lastframelen, c->maxbands); |
| 113 | c->frames_to_skip = 0; |
| 114 | |
Justin Ruggles | 1a34590 | 2012-08-28 13:11:45 | [diff] [blame] | 115 | avctx->sample_fmt = AV_SAMPLE_FMT_S16P; |
Anton Khirnov | edd7be9 | 2013-05-07 05:20:32 | [diff] [blame] | 116 | av_channel_layout_uninit(&avctx->ch_layout); |
| 117 | avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; |
Attila Kinali | 76c4a64 | 2009-11-30 10:25:20 | [diff] [blame] | 118 | |
Andreas Rheinhardt | 3dee5fa | 2020-11-15 20:21:48 | [diff] [blame] | 119 | ff_thread_once(&init_static_once, mpc7_init_static); |
Justin Ruggles | 0eea212 | 2011-09-06 16:17:45 | [diff] [blame] | 120 | |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 121 | return 0; |
| 122 | } |
| 123 | |
| 124 | /** |
| 125 | * Fill samples for given subband |
| 126 | */ |
| 127 | static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int *dst) |
| 128 | { |
| 129 | int i, i1, t; |
| 130 | switch(idx){ |
| 131 | case -1: |
| 132 | for(i = 0; i < SAMPLES_PER_BAND; i++){ |
Kostya Shishkov | 74e2a07 | 2009-03-08 16:37:57 | [diff] [blame] | 133 | *dst++ = (av_lfg_get(&c->rnd) & 0x3FC) - 510; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 134 | } |
| 135 | break; |
| 136 | case 1: |
| 137 | i1 = get_bits1(gb); |
| 138 | for(i = 0; i < SAMPLES_PER_BAND/3; i++){ |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 139 | t = get_vlc2(gb, quant_vlc[0][i1], 9, 2); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 140 | *dst++ = mpc7_idx30[t]; |
| 141 | *dst++ = mpc7_idx31[t]; |
| 142 | *dst++ = mpc7_idx32[t]; |
| 143 | } |
| 144 | break; |
| 145 | case 2: |
| 146 | i1 = get_bits1(gb); |
| 147 | for(i = 0; i < SAMPLES_PER_BAND/2; i++){ |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 148 | t = get_vlc2(gb, quant_vlc[1][i1], 9, 2); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 149 | *dst++ = mpc7_idx50[t]; |
| 150 | *dst++ = mpc7_idx51[t]; |
| 151 | } |
| 152 | break; |
| 153 | case 3: case 4: case 5: case 6: case 7: |
| 154 | i1 = get_bits1(gb); |
| 155 | for(i = 0; i < SAMPLES_PER_BAND; i++) |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 156 | *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1], 9, 2); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 157 | break; |
| 158 | case 8: case 9: case 10: case 11: case 12: |
| 159 | case 13: case 14: case 15: case 16: case 17: |
| 160 | t = (1 << (idx - 2)) - 1; |
| 161 | for(i = 0; i < SAMPLES_PER_BAND; i++) |
| 162 | *dst++ = get_bits(gb, idx - 1) - t; |
| 163 | break; |
| 164 | default: // case 0 and -2..-17 |
| 165 | return; |
| 166 | } |
| 167 | } |
| 168 | |
Reimar Döffinger | 88517e9 | 2010-01-28 20:15:19 | [diff] [blame] | 169 | static int get_scale_idx(GetBitContext *gb, int ref) |
| 170 | { |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 171 | int t = get_vlc2(gb, dscf_vlc, MPC7_DSCF_BITS, 1); |
Reimar Döffinger | 88517e9 | 2010-01-28 20:15:19 | [diff] [blame] | 172 | if (t == 8) |
| 173 | return get_bits(gb, 6); |
| 174 | return ref + t; |
| 175 | } |
| 176 | |
Andreas Rheinhardt | ce7dbd0 | 2022-03-30 19:33:24 | [diff] [blame] | 177 | static int mpc7_decode_frame(AVCodecContext *avctx, AVFrame *frame, |
Justin Ruggles | 0eea212 | 2011-09-06 16:17:45 | [diff] [blame] | 178 | int *got_frame_ptr, AVPacket *avpkt) |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 179 | { |
Thilo Borgmann | 7a00bba | 2009-04-07 15:59:50 | [diff] [blame] | 180 | const uint8_t *buf = avpkt->data; |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 181 | int buf_size; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 182 | MPCContext *c = avctx->priv_data; |
| 183 | GetBitContext gb; |
Reimar Döffinger | 836fc77 | 2010-01-28 21:01:50 | [diff] [blame] | 184 | int i, ch; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 185 | int mb = -1; |
| 186 | Band *bands = c->bands; |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 187 | int off, ret, last_frame, skip; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 188 | int bits_used, bits_avail; |
| 189 | |
Alex Converse | 88b2436 | 2011-11-09 21:40:44 | [diff] [blame] | 190 | memset(bands, 0, sizeof(*bands) * (c->maxbands + 1)); |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 191 | |
| 192 | buf_size = avpkt->size & ~3; |
| 193 | if (buf_size <= 0) { |
| 194 | av_log(avctx, AV_LOG_ERROR, "packet size is too small (%i bytes)\n", |
| 195 | avpkt->size); |
| 196 | return AVERROR_INVALIDDATA; |
| 197 | } |
| 198 | if (buf_size != avpkt->size) { |
| 199 | av_log(avctx, AV_LOG_WARNING, "packet size is not a multiple of 4. " |
| 200 | "extra bytes at the end will be skipped.\n"); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 201 | } |
| 202 | |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 203 | skip = buf[0]; |
| 204 | last_frame = buf[1]; |
| 205 | buf += 4; |
| 206 | buf_size -= 4; |
| 207 | |
Justin Ruggles | 0eea212 | 2011-09-06 16:17:45 | [diff] [blame] | 208 | /* get output buffer */ |
Michael Niedermayer | 65da700 | 2013-02-13 11:21:00 | [diff] [blame] | 209 | frame->nb_samples = MPC_FRAME_SIZE; |
Clément Bœsch | 1ec94b0 | 2013-03-12 07:41:53 | [diff] [blame] | 210 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
Justin Ruggles | 0eea212 | 2011-09-06 16:17:45 | [diff] [blame] | 211 | return ret; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 212 | |
Justin Ruggles | 83ce51c | 2012-01-31 16:17:04 | [diff] [blame] | 213 | av_fast_padded_malloc(&c->bits, &c->buf_size, buf_size); |
| 214 | if (!c->bits) |
Reimar Döffinger | f9ced97 | 2012-01-17 21:20:23 | [diff] [blame] | 215 | return AVERROR(ENOMEM); |
Diego Biurrun | c67b449 | 2014-02-13 16:57:05 | [diff] [blame] | 216 | c->bdsp.bswap_buf((uint32_t *) c->bits, (const uint32_t *) buf, |
| 217 | buf_size >> 2); |
Paul B Mahol | f09afb4 | 2017-02-03 19:16:30 | [diff] [blame] | 218 | if ((ret = init_get_bits8(&gb, c->bits, buf_size)) < 0) |
| 219 | return ret; |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 220 | skip_bits_long(&gb, skip); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 221 | |
| 222 | /* read subband indexes */ |
| 223 | for(i = 0; i <= c->maxbands; i++){ |
| 224 | for(ch = 0; ch < 2; ch++){ |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 225 | int t = i ? get_vlc2(&gb, hdr_vlc, MPC7_HDR_BITS, 1) : 4; |
Reimar Döffinger | 836fc77 | 2010-01-28 21:01:50 | [diff] [blame] | 226 | if(t == 4) bands[i].res[ch] = get_bits(&gb, 4); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 227 | else bands[i].res[ch] = bands[i-1].res[ch] + t; |
Michael Niedermayer | 8e9a0a3 | 2012-03-10 21:36:15 | [diff] [blame] | 228 | if (bands[i].res[ch] < -1 || bands[i].res[ch] > 17) { |
| 229 | av_log(avctx, AV_LOG_ERROR, "subband index invalid\n"); |
| 230 | return AVERROR_INVALIDDATA; |
| 231 | } |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | if(bands[i].res[0] || bands[i].res[1]){ |
| 235 | mb = i; |
| 236 | if(c->MSS) bands[i].msf = get_bits1(&gb); |
| 237 | } |
| 238 | } |
| 239 | /* get scale indexes coding method */ |
| 240 | for(i = 0; i <= mb; i++) |
| 241 | for(ch = 0; ch < 2; ch++) |
Andreas Rheinhardt | 886fbec | 2023-09-20 20:09:22 | [diff] [blame] | 242 | if (bands[i].res[ch]) |
| 243 | bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc, MPC7_SCFI_BITS, 1); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 244 | /* get scale indexes */ |
| 245 | for(i = 0; i <= mb; i++){ |
| 246 | for(ch = 0; ch < 2; ch++){ |
| 247 | if(bands[i].res[ch]){ |
| 248 | bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i]; |
Reimar Döffinger | 88517e9 | 2010-01-28 20:15:19 | [diff] [blame] | 249 | bands[i].scf_idx[ch][0] = get_scale_idx(&gb, bands[i].scf_idx[ch][2]); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 250 | switch(bands[i].scfi[ch]){ |
| 251 | case 0: |
Reimar Döffinger | 88517e9 | 2010-01-28 20:15:19 | [diff] [blame] | 252 | bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]); |
| 253 | bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 254 | break; |
| 255 | case 1: |
Reimar Döffinger | 88517e9 | 2010-01-28 20:15:19 | [diff] [blame] | 256 | bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 257 | bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1]; |
| 258 | break; |
| 259 | case 2: |
| 260 | bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; |
Reimar Döffinger | 88517e9 | 2010-01-28 20:15:19 | [diff] [blame] | 261 | bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]); |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 262 | break; |
| 263 | case 3: |
| 264 | bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; |
| 265 | break; |
| 266 | } |
| 267 | c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2]; |
| 268 | } |
| 269 | } |
| 270 | } |
| 271 | /* get quantizers */ |
| 272 | memset(c->Q, 0, sizeof(c->Q)); |
| 273 | off = 0; |
| 274 | for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND) |
| 275 | for(ch = 0; ch < 2; ch++) |
| 276 | idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off); |
| 277 | |
Justin Ruggles | 3a23752 | 2012-12-24 00:38:34 | [diff] [blame] | 278 | ff_mpc_dequantize_and_synth(c, mb, (int16_t **)frame->extended_data, 2); |
Michael Niedermayer | e952337 | 2012-06-02 21:43:31 | [diff] [blame] | 279 | if(last_frame) |
Michael Niedermayer | 65da700 | 2013-02-13 11:21:00 | [diff] [blame] | 280 | frame->nb_samples = c->lastframelen; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 281 | |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 282 | bits_used = get_bits_count(&gb); |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 283 | bits_avail = buf_size * 8; |
| 284 | if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) { |
Ronald S. Bultje | c0994e3 | 2012-02-17 22:51:29 | [diff] [blame] | 285 | av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); |
Paul B Mahol | 6a6e20b | 2017-02-03 19:14:13 | [diff] [blame] | 286 | return AVERROR_INVALIDDATA; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 287 | } |
| 288 | if(c->frames_to_skip){ |
| 289 | c->frames_to_skip--; |
Justin Ruggles | 0eea212 | 2011-09-06 16:17:45 | [diff] [blame] | 290 | *got_frame_ptr = 0; |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 291 | return avpkt->size; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 292 | } |
Justin Ruggles | 0eea212 | 2011-09-06 16:17:45 | [diff] [blame] | 293 | |
Justin Ruggles | 3a23752 | 2012-12-24 00:38:34 | [diff] [blame] | 294 | *got_frame_ptr = 1; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 295 | |
Justin Ruggles | b5b825c | 2012-02-01 20:19:50 | [diff] [blame] | 296 | return avpkt->size; |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 297 | } |
| 298 | |
| 299 | static void mpc7_decode_flush(AVCodecContext *avctx) |
| 300 | { |
| 301 | MPCContext *c = avctx->priv_data; |
| 302 | |
| 303 | memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); |
| 304 | c->frames_to_skip = 32; |
| 305 | } |
| 306 | |
Reimar Döffinger | f9ced97 | 2012-01-17 21:20:23 | [diff] [blame] | 307 | static av_cold int mpc7_decode_close(AVCodecContext *avctx) |
| 308 | { |
| 309 | MPCContext *c = avctx->priv_data; |
Justin Ruggles | 83ce51c | 2012-01-31 16:17:04 | [diff] [blame] | 310 | av_freep(&c->bits); |
| 311 | c->buf_size = 0; |
Reimar Döffinger | f9ced97 | 2012-01-17 21:20:23 | [diff] [blame] | 312 | return 0; |
| 313 | } |
| 314 | |
Andreas Rheinhardt | 20f9727 | 2022-03-16 20:09:54 | [diff] [blame] | 315 | const FFCodec ff_mpc7_decoder = { |
| 316 | .p.name = "mpc7", |
Andreas Rheinhardt | 48286d4 | 2022-08-29 11:38:02 | [diff] [blame] | 317 | CODEC_LONG_NAME("Musepack SV7"), |
Andreas Rheinhardt | 20f9727 | 2022-03-16 20:09:54 | [diff] [blame] | 318 | .p.type = AVMEDIA_TYPE_AUDIO, |
| 319 | .p.id = AV_CODEC_ID_MUSEPACK7, |
Anton Khirnov | ec6402b | 2011-07-17 10:54:31 | [diff] [blame] | 320 | .priv_data_size = sizeof(MPCContext), |
| 321 | .init = mpc7_decode_init, |
Reimar Döffinger | f9ced97 | 2012-01-17 21:20:23 | [diff] [blame] | 322 | .close = mpc7_decode_close, |
Andreas Rheinhardt | 4243da4 | 2022-03-30 21:28:24 | [diff] [blame] | 323 | FF_CODEC_DECODE_CB(mpc7_decode_frame), |
Martin Storsjö | 00c3b67 | 2012-04-06 16:19:39 | [diff] [blame] | 324 | .flush = mpc7_decode_flush, |
Andreas Rheinhardt | 20f9727 | 2022-03-16 20:09:54 | [diff] [blame] | 325 | .p.capabilities = AV_CODEC_CAP_DR1, |
Andreas Rheinhardt | 0971fcf | 2025-03-07 00:19:27 | [diff] [blame] | 326 | CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16P), |
Kostya Shishkov | 24e649a | 2007-11-02 06:40:42 | [diff] [blame] | 327 | }; |