Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Audio Processing Technology codec for Bluetooth (aptX) | ||
3 | * | ||
4 | * Copyright (C) 2017 Aurelien Jacobs <aurel@gnuage.org> | ||
5 | * | ||
6 | * This file is part of FFmpeg. | ||
7 | * | ||
8 | * FFmpeg is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2.1 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * FFmpeg is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with FFmpeg; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include "config_components.h" | ||
24 | |||
25 | #include "libavutil/channel_layout.h" | ||
26 | #include "aptx.h" | ||
27 | #include "codec_internal.h" | ||
28 | #include "decode.h" | ||
29 | |||
30 | /* | ||
31 | * Half-band QMF synthesis filter realized with a polyphase FIR filter. | ||
32 | * Join 2 subbands and upsample by 2. | ||
33 | * So for each 2 subbands sample that goes in, a pair of samples goes out. | ||
34 | */ | ||
35 | av_always_inline | ||
36 | 53248 | static void aptx_qmf_polyphase_synthesis(FilterSignal signal[NB_FILTERS], | |
37 | const int32_t coeffs[NB_FILTERS][FILTER_TAPS], | ||
38 | int shift, | ||
39 | int32_t low_subband_input, | ||
40 | int32_t high_subband_input, | ||
41 | int32_t samples[NB_FILTERS]) | ||
42 | { | ||
43 | int32_t subbands[NB_FILTERS]; | ||
44 | int i; | ||
45 | |||
46 | 53248 | subbands[0] = low_subband_input + high_subband_input; | |
47 | 53248 | subbands[1] = low_subband_input - high_subband_input; | |
48 | |||
49 |
2/2✓ Branch 0 taken 106496 times.
✓ Branch 1 taken 53248 times.
|
159744 | for (i = 0; i < NB_FILTERS; i++) { |
50 | 106496 | aptx_qmf_filter_signal_push(&signal[i], subbands[1-i]); | |
51 | 106496 | samples[i] = aptx_qmf_convolution(&signal[i], coeffs[i], shift); | |
52 | } | ||
53 | 53248 | } | |
54 | |||
55 | /* | ||
56 | * Two stage QMF synthesis tree. | ||
57 | * Join 4 subbands and upsample by 4. | ||
58 | * So for each 4 subbands sample that goes in, a group of 4 samples goes out. | ||
59 | */ | ||
60 | 13312 | static void aptx_qmf_tree_synthesis(QMFAnalysis *qmf, | |
61 | int32_t subband_samples[4], | ||
62 | int32_t samples[4]) | ||
63 | { | ||
64 | int32_t intermediate_samples[4]; | ||
65 | int i; | ||
66 | |||
67 | /* Join 4 subbands into 2 intermediate subbands upsampled to 2 samples. */ | ||
68 |
2/2✓ Branch 0 taken 26624 times.
✓ Branch 1 taken 13312 times.
|
39936 | for (i = 0; i < 2; i++) |
69 | 26624 | aptx_qmf_polyphase_synthesis(qmf->inner_filter_signal[i], | |
70 | aptx_qmf_inner_coeffs, 22, | ||
71 | 26624 | subband_samples[2*i+0], | |
72 | 26624 | subband_samples[2*i+1], | |
73 | 26624 | &intermediate_samples[2*i]); | |
74 | |||
75 | /* Join 2 samples from intermediate subbands upsampled to 4 samples. */ | ||
76 |
2/2✓ Branch 0 taken 26624 times.
✓ Branch 1 taken 13312 times.
|
39936 | for (i = 0; i < 2; i++) |
77 | 26624 | aptx_qmf_polyphase_synthesis(qmf->outer_filter_signal, | |
78 | aptx_qmf_outer_coeffs, 21, | ||
79 | intermediate_samples[0+i], | ||
80 | 26624 | intermediate_samples[2+i], | |
81 | 26624 | &samples[2*i]); | |
82 | 13312 | } | |
83 | |||
84 | |||
85 | 13312 | static void aptx_decode_channel(Channel *channel, int32_t samples[4]) | |
86 | { | ||
87 | int32_t subband_samples[4]; | ||
88 | int subband; | ||
89 |
2/2✓ Branch 0 taken 53248 times.
✓ Branch 1 taken 13312 times.
|
66560 | for (subband = 0; subband < NB_SUBBANDS; subband++) |
90 | 53248 | subband_samples[subband] = channel->prediction[subband].previous_reconstructed_sample; | |
91 | 13312 | aptx_qmf_tree_synthesis(&channel->qmf, subband_samples, samples); | |
92 | 13312 | } | |
93 | |||
94 | 6656 | static void aptx_unpack_codeword(Channel *channel, uint16_t codeword) | |
95 | { | ||
96 | 6656 | channel->quantize[0].quantized_sample = sign_extend(codeword >> 0, 7); | |
97 | 6656 | channel->quantize[1].quantized_sample = sign_extend(codeword >> 7, 4); | |
98 | 6656 | channel->quantize[2].quantized_sample = sign_extend(codeword >> 11, 2); | |
99 | 6656 | channel->quantize[3].quantized_sample = sign_extend(codeword >> 13, 3); | |
100 | 13312 | channel->quantize[3].quantized_sample = (channel->quantize[3].quantized_sample & ~1) | |
101 | 6656 | | aptx_quantized_parity(channel); | |
102 | 6656 | } | |
103 | |||
104 | 6656 | static void aptxhd_unpack_codeword(Channel *channel, uint32_t codeword) | |
105 | { | ||
106 | 6656 | channel->quantize[0].quantized_sample = sign_extend(codeword >> 0, 9); | |
107 | 6656 | channel->quantize[1].quantized_sample = sign_extend(codeword >> 9, 6); | |
108 | 6656 | channel->quantize[2].quantized_sample = sign_extend(codeword >> 15, 4); | |
109 | 6656 | channel->quantize[3].quantized_sample = sign_extend(codeword >> 19, 5); | |
110 | 13312 | channel->quantize[3].quantized_sample = (channel->quantize[3].quantized_sample & ~1) | |
111 | 6656 | | aptx_quantized_parity(channel); | |
112 | 6656 | } | |
113 | |||
114 | 6656 | static int aptx_decode_samples(AptXContext *ctx, | |
115 | const uint8_t *input, | ||
116 | int32_t samples[NB_CHANNELS][4]) | ||
117 | { | ||
118 | int channel, ret; | ||
119 | |||
120 |
2/2✓ Branch 0 taken 13312 times.
✓ Branch 1 taken 6656 times.
|
19968 | for (channel = 0; channel < NB_CHANNELS; channel++) { |
121 | 13312 | ff_aptx_generate_dither(&ctx->channels[channel]); | |
122 | |||
123 |
2/2✓ Branch 0 taken 6656 times.
✓ Branch 1 taken 6656 times.
|
13312 | if (ctx->hd) |
124 | 6656 | aptxhd_unpack_codeword(&ctx->channels[channel], | |
125 | 6656 | AV_RB24(input + 3*channel)); | |
126 | else | ||
127 | 6656 | aptx_unpack_codeword(&ctx->channels[channel], | |
128 | 6656 | AV_RB16(input + 2*channel)); | |
129 | 13312 | ff_aptx_invert_quantize_and_prediction(&ctx->channels[channel], ctx->hd); | |
130 | } | ||
131 | |||
132 | 6656 | ret = aptx_check_parity(ctx->channels, &ctx->sync_idx); | |
133 | |||
134 |
2/2✓ Branch 0 taken 13312 times.
✓ Branch 1 taken 6656 times.
|
19968 | for (channel = 0; channel < NB_CHANNELS; channel++) |
135 | 13312 | aptx_decode_channel(&ctx->channels[channel], samples[channel]); | |
136 | |||
137 | 6656 | return ret; | |
138 | } | ||
139 | |||
140 | 26 | static int aptx_decode_frame(AVCodecContext *avctx, AVFrame *frame, | |
141 | int *got_frame_ptr, AVPacket *avpkt) | ||
142 | { | ||
143 | 26 | AptXContext *s = avctx->priv_data; | |
144 | int pos, opos, channel, sample, ret; | ||
145 | |||
146 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
|
26 | if (avpkt->size < s->block_size) { |
147 | ✗ | av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); | |
148 | ✗ | return AVERROR_INVALIDDATA; | |
149 | } | ||
150 | |||
151 | /* get output buffer */ | ||
152 | 26 | frame->ch_layout.nb_channels = NB_CHANNELS; | |
153 | 26 | frame->format = AV_SAMPLE_FMT_S32P; | |
154 | 26 | frame->nb_samples = 4 * (avpkt->size / s->block_size); | |
155 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
|
26 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
156 | ✗ | return ret; | |
157 | |||
158 |
2/2✓ Branch 0 taken 6656 times.
✓ Branch 1 taken 26 times.
|
6682 | for (pos = 0, opos = 0; opos < frame->nb_samples; pos += s->block_size, opos += 4) { |
159 | int32_t samples[NB_CHANNELS][4]; | ||
160 | |||
161 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6656 times.
|
6656 | if (aptx_decode_samples(s, &avpkt->data[pos], samples)) { |
162 | ✗ | av_log(avctx, AV_LOG_ERROR, "Synchronization error\n"); | |
163 | ✗ | return AVERROR_INVALIDDATA; | |
164 | } | ||
165 | |||
166 |
2/2✓ Branch 0 taken 13312 times.
✓ Branch 1 taken 6656 times.
|
19968 | for (channel = 0; channel < NB_CHANNELS; channel++) |
167 |
2/2✓ Branch 0 taken 53248 times.
✓ Branch 1 taken 13312 times.
|
66560 | for (sample = 0; sample < 4; sample++) |
168 | 53248 | AV_WN32A(&frame->data[channel][4*(opos+sample)], | |
169 | samples[channel][sample] * 256); | ||
170 | } | ||
171 | |||
172 | 26 | *got_frame_ptr = 1; | |
173 | 26 | return s->block_size * frame->nb_samples / 4; | |
174 | } | ||
175 | |||
176 | #if CONFIG_APTX_DECODER | ||
177 | const FFCodec ff_aptx_decoder = { | ||
178 | .p.name = "aptx", | ||
179 | CODEC_LONG_NAME("aptX (Audio Processing Technology for Bluetooth)"), | ||
180 | .p.type = AVMEDIA_TYPE_AUDIO, | ||
181 | .p.id = AV_CODEC_ID_APTX, | ||
182 | .priv_data_size = sizeof(AptXContext), | ||
183 | .init = ff_aptx_init, | ||
184 | FF_CODEC_DECODE_CB(aptx_decode_frame), | ||
185 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
186 | .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } }, | ||
187 | .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P, | ||
188 | AV_SAMPLE_FMT_NONE }, | ||
189 | }; | ||
190 | #endif | ||
191 | |||
192 | #if CONFIG_APTX_HD_DECODER | ||
193 | const FFCodec ff_aptx_hd_decoder = { | ||
194 | .p.name = "aptx_hd", | ||
195 | CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"), | ||
196 | .p.type = AVMEDIA_TYPE_AUDIO, | ||
197 | .p.id = AV_CODEC_ID_APTX_HD, | ||
198 | .priv_data_size = sizeof(AptXContext), | ||
199 | .init = ff_aptx_init, | ||
200 | FF_CODEC_DECODE_CB(aptx_decode_frame), | ||
201 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
202 | .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } }, | ||
203 | .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P, | ||
204 | AV_SAMPLE_FMT_NONE }, | ||
205 | }; | ||
206 | #endif | ||
207 |