1 /*
2 * LC3 encoder wrapper
3 * Copyright (C) 2024 Antoine Soulier <asoulier@google.com>
4 *
5 * This file is part of FFmpeg.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include <lc3.h>
21
25
30
31 #define ENCODER_MAX_CHANNELS 2
32
37
47
49 {
55 int effective_bit_rate;
56 unsigned encoder_size;
57
58 if (frame_us != 2500 && frame_us != 5000 &&
59 frame_us != 7500 && frame_us != 10000 ) {
61 "Unsupported frame duration %.1f ms.\n", frame_us / 1000.
f);
63 }
66 "Invalid number of channels %d. Max %d channels are accepted\n",
69 }
70
71 hr_mode |= srate_hz > 48000;
72 hr_mode &= srate_hz >= 48000;
73
74 if (frame_us == 7500 && hr_mode) {
76 "High-resolution mode is not supported with 7.5 ms frames.\n");
78 }
79
81 if (hr_mode)
83
86
87 effective_bit_rate = lc3_hr_resolve_bitrate(
89
90 if (avctx->
bit_rate != effective_bit_rate)
92 "Bitrate changed to %d bps.\n", effective_bit_rate);
93 avctx->
bit_rate = effective_bit_rate;
94
95 encoder_size = lc3_hr_encoder_size(hr_mode, frame_us, srate_hz);
96 if (!encoder_size)
98
102
103 for (
int ch = 0; ch <
channels; ch++) {
104 liblc3->
encoder[ch] = lc3_hr_setup_encoder(
105 hr_mode, frame_us, srate_hz, 0,
107 }
108
112
117
119 liblc3->
delay_samples = lc3_hr_delay_samples(hr_mode, frame_us, srate_hz);
121
122 return 0;
123 }
124
126 {
128
130
131 return 0;
132 }
133
136 {
140 uint8_t *data_ptr;
141 size_t sample_size;
142 int is_planar;
144
147
150
152 int padding =
frame->nb_samples -
frame->duration;
154 } else {
156 return 0;
157
159 }
160
162 for (
int ch = 0; ch <
channels; ch++) {
164
165 const void *pcm =
frame ?
166 (is_planar ?
frame->data[ch] :
167 frame->data[0] + ch * sample_size) :
168 (const void *)(const float[]){ 0 };
169
171
172 lc3_encode(liblc3->
encoder[ch],
173 LC3_PCM_FORMAT_FLOAT, pcm,
stride, nbytes, data_ptr);
174
175 data_ptr += nbytes;
176 }
177
178 *got_packet_ptr = 1;
179
180 return 0;
181 }
182
183 #define OFFSET(x) offsetof(LibLC3EncContext, opts.x)
184 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
186 { "frame_duration", "Duration of a frame in milliseconds",
188 { .dbl = 10.0 }, 2.5, 10.0,
FLAGS },
189 { "high_resolution", "Enable High-Resolution mode (48 KHz or 96 KHz)",
191 { .i64 = 0 }, 0, 1,
FLAGS },
193 };
194
200 };
201
208 .p.priv_class = &class,
209 .p.wrapper_name = "liblc3",
216 };