FFmpeg
Loading...
Searching...
No Matches
libcodec2.c
Go to the documentation of this file.
1/*
2 * codec2 encoder/decoder using libcodec2
3 * Copyright (c) 2017 Tomas Härdin
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#include <codec2/codec2.h>
24#include "libavutil/mem.h"
25#include "avcodec.h"
26#include "libavutil/opt.h"
27#include "codec_internal.h"
28#include "decode.h"
29#include "encode.h"
30#include "codec2utils.h"
31
32typedef struct {
33 const AVClass *class;
34 struct CODEC2 *codec;
35 int mode;
37
38static const AVOption options[] = {
39 //not AV_OPT_FLAG_DECODING_PARAM since mode should come from the demuxer
40 //1300 (aka FreeDV 1600) is the most common mode on-the-air, default to it here as well
42 { NULL },
43};
44
46 .class_name = "libcodec2 encoder",
47 .item_name = av_default_item_name,
48 .option = options,
49 .version = LIBAVUTIL_VERSION_INT,
50};
51
53{
55 //Grab mode name from options, unless it's some weird number.
56 const char *modename = mode >= 0 && mode <= CODEC2_MODE_MAX ? options[mode+1].name : "?";
57
58 c2->codec = codec2_create(mode);
59 if (!c2->codec) {
60 //Out of memory or unsupported mode. The latter seems most likely,
61 //but we can't tell for sure with the current API.
62 goto libcodec2_init_common_error;
63 }
64
65 avctx->frame_size = codec2_samples_per_frame(c2->codec);
66 avctx->block_align = (codec2_bits_per_frame(c2->codec) + 7) / 8;
67
68 if (avctx->frame_size <= 0 || avctx->block_align <= 0) {
69 //codec2_create() may succeed for some modes but still fail at codec2_samples_per_frame()
70 //example is -mode 700C on libcodec2 0.4
71 codec2_destroy(c2->codec);
72 c2->codec = NULL;
73 goto libcodec2_init_common_error;
74 }
75
76 codec2_set_natural_or_gray(c2->codec, 1);
77
78 return 0;
79
80libcodec2_init_common_error:
81 av_log(avctx, AV_LOG_ERROR,
82 "Mode %i (%s) not supported with the linked version of libcodec2\n",
83 mode, modename);
84 return AVERROR(EINVAL);
85}
86
88{
89 avctx->sample_rate = 8000;
93
95 av_log(avctx, AV_LOG_ERROR, "must have exactly %i bytes of extradata (got %i)\n",
98 }
99
101}
102
104{
105 LibCodec2Context *c2 = avctx->priv_data;
106
108 if (!avctx->extradata) {
109 return AVERROR(ENOMEM);
110 }
111
113 codec2_make_extradata(avctx->extradata, c2->mode);
114
115 return libcodec2_init_common(avctx, c2->mode);
116}
117
119{
120 LibCodec2Context *c2 = avctx->priv_data;
121
122 codec2_destroy(c2->codec);
123 return 0;
124}
125
127 int *got_frame_ptr, AVPacket *pkt)
128{
129 LibCodec2Context *c2 = avctx->priv_data;
130 int ret, nframes, i;
131 const uint8_t *input;
132 int16_t *output;
133
134 nframes = pkt->size / avctx->block_align;
135 if (nframes > INT_MAX / avctx->frame_size)
136 return AVERROR_INVALIDDATA;
137 frame->nb_samples = avctx->frame_size * nframes;
138
139 ret = ff_get_buffer(avctx, frame, 0);
140 if (ret < 0) {
141 return ret;
142 }
143
144 input = pkt->data;
145 output = (int16_t *)frame->data[0];
146
147 for (i = 0; i < nframes; i++) {
148 codec2_decode(c2->codec, output, input);
149 input += avctx->block_align;
150 output += avctx->frame_size;
151 }
152
153 *got_frame_ptr = nframes > 0;
154 return nframes * avctx->block_align;
155}
156
157static int libcodec2_encode(AVCodecContext *avctx, AVPacket *avpkt,
158 const AVFrame *frame, int *got_packet_ptr)
159{
160 LibCodec2Context *c2 = avctx->priv_data;
161 int16_t *samples = (int16_t *)frame->data[0];
162
163 int ret = ff_get_encode_buffer(avctx, avpkt, avctx->block_align, 0);
164 if (ret < 0) {
165 return ret;
166 }
167
168 codec2_encode(c2->codec, avpkt->data, samples);
169 *got_packet_ptr = 1;
170
171 return 0;
172}
173
175 .p.name = "libcodec2",
176 CODEC_LONG_NAME("codec2 decoder using libcodec2"),
177 .p.type = AVMEDIA_TYPE_AUDIO,
178 .p.id = AV_CODEC_ID_CODEC2,
179 .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF,
180 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
181 .priv_data_size = sizeof(LibCodec2Context),
185};
186
188 .p.name = "libcodec2",
189 CODEC_LONG_NAME("codec2 encoder using libcodec2"),
190 .p.type = AVMEDIA_TYPE_AUDIO,
191 .p.id = AV_CODEC_ID_CODEC2,
192 .p.capabilities = AV_CODEC_CAP_DR1 |
194 CODEC_SAMPLERATES(8000),
197 .p.priv_class = &libcodec2_enc_class,
198 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
199 .priv_data_size = sizeof(LibCodec2Context),
203};
const FFCodec ff_libcodec2_encoder
Definition libcodec2.c:187
const FFCodec ff_libcodec2_decoder
Definition libcodec2.c:174
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
Public libavutil channel layout APIs header.
#define CODEC2_AVOPTIONS(desc, classname, min_val, default_val, option_flags)
Definition codec2utils.h:36
static uint8_t codec2_mode_from_extradata(uint8_t *ptr)
Definition codec2utils.h:59
#define CODEC2_EXTRADATA_SIZE
Definition codec2utils.h:48
#define CODEC2_MODE_MAX
Definition codec2utils.h:30
static void codec2_make_extradata(uint8_t *ptr, int mode)
Definition codec2utils.h:51
#define CODEC_CH_LAYOUTS(...)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_DECODE_CB(func)
#define CODEC_SAMPLERATES(...)
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define CODEC_SAMPLEFMTS(...)
#define NULL
Definition coverity.c:32
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
static AVPacket * pkt
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
#define AV_OPT_FLAG_AUDIO_PARAM
Definition opt.h:356
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition codec.h:94
@ AV_CODEC_ID_CODEC2
Definition codec_id.h:520
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AV_CHANNEL_LAYOUT_MONO
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define av_cold
Definition attributes.h:117
static av_cold int libcodec2_init_encoder(AVCodecContext *avctx)
Definition libcodec2.c:103
static av_cold int libcodec2_init_common(AVCodecContext *avctx, int mode)
Definition libcodec2.c:52
static int libcodec2_encode(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition libcodec2.c:157
static int libcodec2_decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *pkt)
Definition libcodec2.c:126
static av_cold int libcodec2_init_decoder(AVCodecContext *avctx)
Definition libcodec2.c:87
static av_cold int libcodec2_close(AVCodecContext *avctx)
Definition libcodec2.c:118
static const AVClass libcodec2_enc_class
Definition libcodec2.c:45
Memory handling functions.
static const uint64_t c2
Definition murmur3.c:53
AVOptions.
An AVChannelLayout holds information about the channel layout of audio data.
Describe the class of an AVClass context structure.
Definition log.h:76
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
int sample_rate
samples per second
Definition avcodec.h:1040
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
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs.
Definition avcodec.h:1075
int frame_size
Number of samples per channel in an audio frame.
Definition avcodec.h:1068
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
uint8_t * data
Definition packet.h:603
struct CODEC2 * codec
Definition libcodec2.c:34
Definition swscale.c:71
#define av_mallocz(s)
#define av_log(a,...)