FFmpeg
aptxdec.c
Go to the documentation of this file.
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 
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  */
37  const int32_t coeffs[NB_FILTERS][FILTER_TAPS],
38  int shift,
39  int32_t low_subband_input,
40  int32_t high_subband_input,
42 {
44  int i;
45 
46  subbands[0] = low_subband_input + high_subband_input;
47  subbands[1] = low_subband_input - high_subband_input;
48 
49  for (i = 0; i < NB_FILTERS; i++) {
51  samples[i] = aptx_qmf_convolution(&signal[i], coeffs[i], shift);
52  }
53 }
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  */
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  for (i = 0; i < 2; i++)
71  subband_samples[2*i+0],
72  subband_samples[2*i+1],
73  &intermediate_samples[2*i]);
74 
75  /* Join 2 samples from intermediate subbands upsampled to 4 samples. */
76  for (i = 0; i < 2; i++)
79  intermediate_samples[0+i],
80  intermediate_samples[2+i],
81  &samples[2*i]);
82 }
83 
84 
86 {
87  int32_t subband_samples[4];
88  int subband;
89  for (subband = 0; subband < NB_SUBBANDS; subband++)
90  subband_samples[subband] = channel->prediction[subband].previous_reconstructed_sample;
91  aptx_qmf_tree_synthesis(&channel->qmf, subband_samples, samples);
92 }
93 
94 static void aptx_unpack_codeword(Channel *channel, uint16_t codeword)
95 {
96  channel->quantize[0].quantized_sample = sign_extend(codeword >> 0, 7);
97  channel->quantize[1].quantized_sample = sign_extend(codeword >> 7, 4);
98  channel->quantize[2].quantized_sample = sign_extend(codeword >> 11, 2);
99  channel->quantize[3].quantized_sample = sign_extend(codeword >> 13, 3);
100  channel->quantize[3].quantized_sample = (channel->quantize[3].quantized_sample & ~1)
102 }
103 
104 static void aptxhd_unpack_codeword(Channel *channel, uint32_t codeword)
105 {
106  channel->quantize[0].quantized_sample = sign_extend(codeword >> 0, 9);
107  channel->quantize[1].quantized_sample = sign_extend(codeword >> 9, 6);
108  channel->quantize[2].quantized_sample = sign_extend(codeword >> 15, 4);
109  channel->quantize[3].quantized_sample = sign_extend(codeword >> 19, 5);
110  channel->quantize[3].quantized_sample = (channel->quantize[3].quantized_sample & ~1)
112 }
113 
115  const uint8_t *input,
117 {
118  int channel, ret;
119 
120  for (channel = 0; channel < NB_CHANNELS; channel++) {
121  ff_aptx_generate_dither(&ctx->channels[channel]);
122 
123  if (ctx->hd)
124  aptxhd_unpack_codeword(&ctx->channels[channel],
125  AV_RB24(input + 3*channel));
126  else
127  aptx_unpack_codeword(&ctx->channels[channel],
128  AV_RB16(input + 2*channel));
130  }
131 
132  ret = aptx_check_parity(ctx->channels, &ctx->sync_idx);
133 
134  for (channel = 0; channel < NB_CHANNELS; channel++)
136 
137  return ret;
138 }
139 
141  int *got_frame_ptr, AVPacket *avpkt)
142 {
143  AptXContext *s = avctx->priv_data;
144  int pos, opos, channel, sample, ret;
145 
146  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 */
154  frame->nb_samples = 4 * (avpkt->size / s->block_size);
155  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
156  return ret;
157 
158  for (pos = 0, opos = 0; opos < frame->nb_samples; pos += s->block_size, opos += 4) {
160 
161  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  for (channel = 0; channel < NB_CHANNELS; channel++)
167  for (sample = 0; sample < 4; sample++)
168  AV_WN32A(&frame->data[channel][4*(opos+sample)],
169  samples[channel][sample] * 256);
170  }
171 
172  *got_frame_ptr = 1;
173  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,
185  .p.capabilities = AV_CODEC_CAP_DR1,
187  .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
188  .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
190 };
191 #endif
192 
193 #if CONFIG_APTX_HD_DECODER
194 const FFCodec ff_aptx_hd_decoder = {
195  .p.name = "aptx_hd",
196  CODEC_LONG_NAME("aptX HD (Audio Processing Technology for Bluetooth)"),
197  .p.type = AVMEDIA_TYPE_AUDIO,
198  .p.id = AV_CODEC_ID_APTX_HD,
199  .priv_data_size = sizeof(AptXContext),
200  .init = ff_aptx_init,
202  .p.capabilities = AV_CODEC_CAP_DR1,
204  .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_STEREO, { 0 } },
205  .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
207 };
208 #endif
Channel
Definition: aptx.h:81
FILTER_TAPS
#define FILTER_TAPS
Definition: aptx.h:46
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:389
aptx_quantized_parity
static int32_t aptx_quantized_parity(Channel *channel)
Definition: aptx.h:188
QMFAnalysis
Definition: aptx.h:53
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVPacket::data
uint8_t * data
Definition: packet.h:522
ff_aptx_generate_dither
void ff_aptx_generate_dither(Channel *channel)
Definition: aptx.c:385
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:65
aptx_decode_channel
static void aptx_decode_channel(Channel *channel, int32_t samples[4])
Definition: aptxdec.c:85
FFCodec
Definition: codec_internal.h:127
AV_WN32A
#define AV_WN32A(p, v)
Definition: intreadwrite.h:536
subbands
subbands
Definition: aptx.h:37
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:323
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
AptXContext
Definition: aptx.h:92
QMFAnalysis::inner_filter_signal
FilterSignal inner_filter_signal[NB_FILTERS][NB_FILTERS]
Definition: aptx.h:55
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
NB_FILTERS
@ NB_FILTERS
Definition: vf_waveform.c:54
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:802
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:215
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:306
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
NB_CHANNELS
@ NB_CHANNELS
Definition: aptx.h:34
CODEC_OLD_CHANNEL_LAYOUTS
#define CODEC_OLD_CHANNEL_LAYOUTS(...)
Definition: codec_internal.h:302
ctx
AVFormatContext * ctx
Definition: movenc.c:48
aptx_qmf_tree_synthesis
static void aptx_qmf_tree_synthesis(QMFAnalysis *qmf, int32_t subband_samples[4], int32_t samples[4])
Definition: aptxdec.c:60
decode.h
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
frame
static AVFrame * frame
Definition: demux_decode.c:54
ff_aptx_decoder
const FFCodec ff_aptx_decoder
QMFAnalysis::outer_filter_signal
FilterSignal outer_filter_signal[NB_FILTERS]
Definition: aptx.h:54
aptx_qmf_convolution
static av_always_inline int32_t aptx_qmf_convolution(FilterSignal *signal, const int32_t coeffs[FILTER_TAPS], int shift)
Definition: aptx.h:174
aptx_qmf_outer_coeffs
static const int32_t aptx_qmf_outer_coeffs[NB_FILTERS][FILTER_TAPS]
Definition: aptx.h:132
FilterSignal
Definition: aptx.h:48
aptx.h
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1618
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:523
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:313
codec_internal.h
shift
static int shift(int a, int b)
Definition: bonk.c:262
aptx_qmf_inner_coeffs
static const int32_t aptx_qmf_inner_coeffs[NB_FILTERS][FILTER_TAPS]
Definition: aptx.h:147
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
sample
#define sample
Definition: flacdsp_template.c:44
aptx_decode_frame
static int aptx_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)
Definition: aptxdec.c:140
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:427
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:420
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
aptx_unpack_codeword
static void aptx_unpack_codeword(Channel *channel, uint16_t codeword)
Definition: aptxdec.c:94
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
av_always_inline
#define av_always_inline
Definition: attributes.h:49
aptxhd_unpack_codeword
static void aptxhd_unpack_codeword(Channel *channel, uint32_t codeword)
Definition: aptxdec.c:104
aptx_qmf_filter_signal_push
static av_always_inline void aptx_qmf_filter_signal_push(FilterSignal *signal, int32_t sample)
Definition: aptx.h:162
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
ret
ret
Definition: filter_design.txt:187
pos
unsigned int pos
Definition: spdifenc.c:413
ff_aptx_init
av_cold int ff_aptx_init(AVCodecContext *avctx)
Definition: aptx.c:508
AVCodecContext
main external API structure.
Definition: avcodec.h:445
channel_layout.h
ff_aptx_invert_quantize_and_prediction
void ff_aptx_invert_quantize_and_prediction(Channel *channel, int hd)
Definition: aptx.c:497
aptx_decode_samples
static int aptx_decode_samples(AptXContext *ctx, const uint8_t *input, int32_t samples[NB_CHANNELS][4])
Definition: aptxdec.c:114
sign_extend
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:133
ff_aptx_hd_decoder
const FFCodec ff_aptx_hd_decoder
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVPacket
This structure stores compressed data.
Definition: packet.h:499
int32_t
int32_t
Definition: audioconvert.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_CODEC_ID_APTX
@ AV_CODEC_ID_APTX
Definition: codec_id.h:528
NB_SUBBANDS
@ NB_SUBBANDS
Definition: aptx.h:42
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
AV_CODEC_ID_APTX_HD
@ AV_CODEC_ID_APTX_HD
Definition: codec_id.h:529
channel
channel
Definition: ebur128.h:39
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
aptx_qmf_polyphase_synthesis
static av_always_inline void aptx_qmf_polyphase_synthesis(FilterSignal signal[NB_FILTERS], const int32_t coeffs[NB_FILTERS][FILTER_TAPS], int shift, int32_t low_subband_input, int32_t high_subband_input, int32_t samples[NB_FILTERS])
Definition: aptxdec.c:36
aptx_check_parity
static int aptx_check_parity(Channel channels[NB_CHANNELS], int32_t *idx)
Definition: aptx.h:201