FFmpeg
Loading...
Searching...
No Matches
liblc3dec.c
Go to the documentation of this file.
1/*
2 * LC3 decoder 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
23#include "libavutil/mem.h"
24
25#include "avcodec.h"
26#include "codec.h"
27#include "codec_internal.h"
28#include "decode.h"
29#include "internal.h"
30
31#define DECODER_MAX_CHANNELS 2
32
38
40{
41 LibLC3DecContext *liblc3 = avctx->priv_data;
42 int channels = avctx->ch_layout.nb_channels;
43 int ep_mode;
44 unsigned decoder_size;
45
46 if (avctx->extradata_size < 6)
49 av_log(avctx, AV_LOG_ERROR,
50 "Invalid number of channels %d. Max %d channels are accepted\n",
52 return AVERROR(EINVAL);
53 }
54
55 liblc3->frame_us = AV_RL16(avctx->extradata + 0) * 10;
56 liblc3->srate_hz = avctx->sample_rate;
57 ep_mode = AV_RL16(avctx->extradata + 2);
58 liblc3->hr_mode = AV_RL16(avctx->extradata + 4);
59 if (ep_mode != 0) {
60 av_log(avctx, AV_LOG_ERROR,
61 "Error protection mode is not supported.\n");
62 return AVERROR(EINVAL);
63 }
64
65 av_log(avctx, AV_LOG_INFO,
66 "Decoding %.1f ms frames.\n", liblc3->frame_us / 1000.f);
67 if (liblc3->hr_mode)
68 av_log(avctx, AV_LOG_INFO, "High-resolution mode enabled.\n");
69
70 decoder_size = lc3_hr_decoder_size(
71 liblc3->hr_mode, liblc3->frame_us, liblc3->srate_hz);
72 if (!decoder_size)
74
75 liblc3->decoder_mem = av_malloc_array(channels, decoder_size);
76 if (!liblc3->decoder_mem)
77 return AVERROR(ENOMEM);
78
79 for (int ch = 0; ch < channels; ch++) {
80 liblc3->decoder[ch] = lc3_hr_setup_decoder(
81 liblc3->hr_mode, liblc3->frame_us, liblc3->srate_hz, 0,
82 (char *)liblc3->decoder_mem + ch * decoder_size);
83 }
84
87
88 avctx->delay = lc3_hr_delay_samples(
89 liblc3->hr_mode, liblc3->frame_us, liblc3->srate_hz);
90
91 return 0;
92}
93
95{
96 LibLC3DecContext *liblc3 = avctx->priv_data;
97
98 av_freep(&liblc3->decoder_mem);
99
100 return 0;
101}
102
104 int *got_frame_ptr, AVPacket *avpkt)
105{
106 LibLC3DecContext *liblc3 = avctx->priv_data;
107 int channels = avctx->ch_layout.nb_channels;
108 uint8_t *in = avpkt->data;
109 int block_bytes, ret;
110
111 frame->nb_samples = av_rescale(
112 liblc3->frame_us, liblc3->srate_hz, 1000*1000);
113 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
114 return ret;
115
116 block_bytes = avpkt->size;
117 int is_planar = avctx->sample_fmt == AV_SAMPLE_FMT_FLTP;
118
119 for (int ch = 0; ch < channels; ch++) {
120 int nbytes = block_bytes / channels + (ch < block_bytes % channels);
121 float *pcm_data = is_planar ? (float*)frame->extended_data[ch] :
122 (float*)frame->extended_data[0] + ch;
123 int stride = is_planar ? 1 : channels;
124
125 ret = lc3_decode(liblc3->decoder[ch], in, nbytes,
126 LC3_PCM_FORMAT_FLOAT, pcm_data, stride);
127 if (ret < 0)
128 return AVERROR_INVALIDDATA;
129
130 in += nbytes;
131 }
132
133 frame->nb_samples = FFMIN(frame->nb_samples, avpkt->duration);
134
135 *got_frame_ptr = 1;
136
137 return avpkt->size;
138}
139
141 .p.name = "liblc3",
142 CODEC_LONG_NAME("LC3 (Low Complexity Communication Codec)"),
143 .p.type = AVMEDIA_TYPE_AUDIO,
144 .p.id = AV_CODEC_ID_LC3,
145 .p.capabilities = AV_CODEC_CAP_DR1,
146 .p.wrapper_name = "liblc3",
147 .priv_data_size = sizeof(LibLC3DecContext),
148 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
152};
const FFCodec ff_liblc3_decoder
Definition liblc3dec.c:140
channels
Definition aptx.h:31
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
Libavcodec external API header.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_LC3
Definition codec_id.h:559
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition samplefmt.h:66
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
#define AV_RL16(p)
common internal api header.
#define av_cold
Definition attributes.h:117
#define DECODER_MAX_CHANNELS
static av_cold int liblc3_decode_init(AVCodecContext *avctx)
Definition liblc3dec.c:39
static av_cold int liblc3_decode_close(AVCodecContext *avctx)
Definition liblc3dec.c:94
static int liblc3_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)
Definition liblc3dec.c:103
#define DECODER_MAX_CHANNELS
Definition liblc3dec.c:31
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
int nb_channels
Number of channels in this layout.
main external API structure.
Definition avcodec.h:443
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
enum AVSampleFormat request_sample_fmt
desired sample format
Definition avcodec.h:1097
int sample_rate
samples per second
Definition avcodec.h:1040
int delay
Codec delay.
Definition avcodec.h:587
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition packet.h:621
uint8_t * data
Definition packet.h:603
void * decoder_mem
Definition liblc3dec.c:35
lc3_decoder_t decoder[DECODER_MAX_CHANNELS]
Definition liblc3dec.c:36
#define stride
#define av_malloc_array(a, b)
#define av_freep(p)
#define av_log(a,...)