1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * codec2 encoder/decoder using libcodec2 3cabdff1aSopenharmony_ci * Copyright (c) 2017 Tomas Härdin 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include <codec2/codec2.h> 23cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 24cabdff1aSopenharmony_ci#include "avcodec.h" 25cabdff1aSopenharmony_ci#include "libavutil/opt.h" 26cabdff1aSopenharmony_ci#include "codec_internal.h" 27cabdff1aSopenharmony_ci#include "encode.h" 28cabdff1aSopenharmony_ci#include "internal.h" 29cabdff1aSopenharmony_ci#include "codec2utils.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_citypedef struct { 32cabdff1aSopenharmony_ci const AVClass *class; 33cabdff1aSopenharmony_ci struct CODEC2 *codec; 34cabdff1aSopenharmony_ci int mode; 35cabdff1aSopenharmony_ci} LibCodec2Context; 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_cistatic const AVOption options[] = { 38cabdff1aSopenharmony_ci //not AV_OPT_FLAG_DECODING_PARAM since mode should come from the demuxer 39cabdff1aSopenharmony_ci //1300 (aka FreeDV 1600) is the most common mode on-the-air, default to it here as well 40cabdff1aSopenharmony_ci CODEC2_AVOPTIONS("codec2 mode", LibCodec2Context, 0, 4 /*CODEC2_MODE_1300*/, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_ENCODING_PARAM), 41cabdff1aSopenharmony_ci { NULL }, 42cabdff1aSopenharmony_ci}; 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_cistatic const AVClass libcodec2_enc_class = { 45cabdff1aSopenharmony_ci .class_name = "libcodec2 encoder", 46cabdff1aSopenharmony_ci .item_name = av_default_item_name, 47cabdff1aSopenharmony_ci .option = options, 48cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 49cabdff1aSopenharmony_ci}; 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_cistatic av_cold int libcodec2_init_common(AVCodecContext *avctx, int mode) 52cabdff1aSopenharmony_ci{ 53cabdff1aSopenharmony_ci LibCodec2Context *c2 = avctx->priv_data; 54cabdff1aSopenharmony_ci //Grab mode name from options, unless it's some weird number. 55cabdff1aSopenharmony_ci const char *modename = mode >= 0 && mode <= CODEC2_MODE_MAX ? options[mode+1].name : "?"; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci c2->codec = codec2_create(mode); 58cabdff1aSopenharmony_ci if (!c2->codec) { 59cabdff1aSopenharmony_ci //Out of memory or unsupported mode. The latter seems most likely, 60cabdff1aSopenharmony_ci //but we can't tell for sure with the current API. 61cabdff1aSopenharmony_ci goto libcodec2_init_common_error; 62cabdff1aSopenharmony_ci } 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci avctx->frame_size = codec2_samples_per_frame(c2->codec); 65cabdff1aSopenharmony_ci avctx->block_align = (codec2_bits_per_frame(c2->codec) + 7) / 8; 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci if (avctx->frame_size <= 0 || avctx->block_align <= 0) { 68cabdff1aSopenharmony_ci //codec2_create() may succeed for some modes but still fail at codec2_samples_per_frame() 69cabdff1aSopenharmony_ci //example is -mode 700C on libcodec2 0.4 70cabdff1aSopenharmony_ci codec2_destroy(c2->codec); 71cabdff1aSopenharmony_ci c2->codec = NULL; 72cabdff1aSopenharmony_ci goto libcodec2_init_common_error; 73cabdff1aSopenharmony_ci } 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci codec2_set_natural_or_gray(c2->codec, 1); 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci return 0; 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_cilibcodec2_init_common_error: 80cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 81cabdff1aSopenharmony_ci "Mode %i (%s) not supported with the linked version of libcodec2\n", 82cabdff1aSopenharmony_ci mode, modename); 83cabdff1aSopenharmony_ci return AVERROR(EINVAL); 84cabdff1aSopenharmony_ci} 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_cistatic av_cold int libcodec2_init_decoder(AVCodecContext *avctx) 87cabdff1aSopenharmony_ci{ 88cabdff1aSopenharmony_ci avctx->sample_rate = 8000; 89cabdff1aSopenharmony_ci avctx->sample_fmt = AV_SAMPLE_FMT_S16; 90cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 91cabdff1aSopenharmony_ci avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; 92cabdff1aSopenharmony_ci 93cabdff1aSopenharmony_ci if (avctx->extradata_size != CODEC2_EXTRADATA_SIZE) { 94cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "must have exactly %i bytes of extradata (got %i)\n", 95cabdff1aSopenharmony_ci CODEC2_EXTRADATA_SIZE, avctx->extradata_size); 96cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 97cabdff1aSopenharmony_ci } 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci return libcodec2_init_common(avctx, codec2_mode_from_extradata(avctx->extradata)); 100cabdff1aSopenharmony_ci} 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_cistatic av_cold int libcodec2_init_encoder(AVCodecContext *avctx) 103cabdff1aSopenharmony_ci{ 104cabdff1aSopenharmony_ci LibCodec2Context *c2 = avctx->priv_data; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci //will need to be smarter once we get wideband support 107cabdff1aSopenharmony_ci if (avctx->sample_rate != 8000 || 108cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels != 1 || 109cabdff1aSopenharmony_ci avctx->sample_fmt != AV_SAMPLE_FMT_S16) { 110cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "only 8 kHz 16-bit mono allowed\n"); 111cabdff1aSopenharmony_ci return AVERROR(EINVAL); 112cabdff1aSopenharmony_ci } 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci avctx->extradata = av_mallocz(CODEC2_EXTRADATA_SIZE + AV_INPUT_BUFFER_PADDING_SIZE); 115cabdff1aSopenharmony_ci if (!avctx->extradata) { 116cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 117cabdff1aSopenharmony_ci } 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci avctx->extradata_size = CODEC2_EXTRADATA_SIZE; 120cabdff1aSopenharmony_ci codec2_make_extradata(avctx->extradata, c2->mode); 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci return libcodec2_init_common(avctx, c2->mode); 123cabdff1aSopenharmony_ci} 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_cistatic av_cold int libcodec2_close(AVCodecContext *avctx) 126cabdff1aSopenharmony_ci{ 127cabdff1aSopenharmony_ci LibCodec2Context *c2 = avctx->priv_data; 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci codec2_destroy(c2->codec); 130cabdff1aSopenharmony_ci return 0; 131cabdff1aSopenharmony_ci} 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_cistatic int libcodec2_decode(AVCodecContext *avctx, AVFrame *frame, 134cabdff1aSopenharmony_ci int *got_frame_ptr, AVPacket *pkt) 135cabdff1aSopenharmony_ci{ 136cabdff1aSopenharmony_ci LibCodec2Context *c2 = avctx->priv_data; 137cabdff1aSopenharmony_ci int ret, nframes, i; 138cabdff1aSopenharmony_ci const uint8_t *input; 139cabdff1aSopenharmony_ci int16_t *output; 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci nframes = pkt->size / avctx->block_align; 142cabdff1aSopenharmony_ci frame->nb_samples = avctx->frame_size * nframes; 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_ci ret = ff_get_buffer(avctx, frame, 0); 145cabdff1aSopenharmony_ci if (ret < 0) { 146cabdff1aSopenharmony_ci return ret; 147cabdff1aSopenharmony_ci } 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci input = pkt->data; 150cabdff1aSopenharmony_ci output = (int16_t *)frame->data[0]; 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci for (i = 0; i < nframes; i++) { 153cabdff1aSopenharmony_ci codec2_decode(c2->codec, output, input); 154cabdff1aSopenharmony_ci input += avctx->block_align; 155cabdff1aSopenharmony_ci output += avctx->frame_size; 156cabdff1aSopenharmony_ci } 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci *got_frame_ptr = nframes > 0; 159cabdff1aSopenharmony_ci return nframes * avctx->block_align; 160cabdff1aSopenharmony_ci} 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_cistatic int libcodec2_encode(AVCodecContext *avctx, AVPacket *avpkt, 163cabdff1aSopenharmony_ci const AVFrame *frame, int *got_packet_ptr) 164cabdff1aSopenharmony_ci{ 165cabdff1aSopenharmony_ci LibCodec2Context *c2 = avctx->priv_data; 166cabdff1aSopenharmony_ci int16_t *samples = (int16_t *)frame->data[0]; 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci int ret = ff_get_encode_buffer(avctx, avpkt, avctx->block_align, 0); 169cabdff1aSopenharmony_ci if (ret < 0) { 170cabdff1aSopenharmony_ci return ret; 171cabdff1aSopenharmony_ci } 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ci codec2_encode(c2->codec, avpkt->data, samples); 174cabdff1aSopenharmony_ci *got_packet_ptr = 1; 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci return 0; 177cabdff1aSopenharmony_ci} 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ciconst FFCodec ff_libcodec2_decoder = { 180cabdff1aSopenharmony_ci .p.name = "libcodec2", 181cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("codec2 decoder using libcodec2"), 182cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 183cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_CODEC2, 184cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF, 185cabdff1aSopenharmony_ci .p.supported_samplerates = (const int[]){ 8000, 0 }, 186cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, 187cabdff1aSopenharmony_ci .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } }, 188cabdff1aSopenharmony_ci .priv_data_size = sizeof(LibCodec2Context), 189cabdff1aSopenharmony_ci .init = libcodec2_init_decoder, 190cabdff1aSopenharmony_ci .close = libcodec2_close, 191cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(libcodec2_decode), 192cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 193cabdff1aSopenharmony_ci .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 }, 194cabdff1aSopenharmony_ci#endif 195cabdff1aSopenharmony_ci}; 196cabdff1aSopenharmony_ci 197cabdff1aSopenharmony_ciconst FFCodec ff_libcodec2_encoder = { 198cabdff1aSopenharmony_ci .p.name = "libcodec2", 199cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("codec2 encoder using libcodec2"), 200cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 201cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_CODEC2, 202cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 203cabdff1aSopenharmony_ci .p.supported_samplerates = (const int[]){ 8000, 0 }, 204cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, 205cabdff1aSopenharmony_ci .p.ch_layouts = (const AVChannelLayout[]) { AV_CHANNEL_LAYOUT_MONO, { 0 } }, 206cabdff1aSopenharmony_ci .p.priv_class = &libcodec2_enc_class, 207cabdff1aSopenharmony_ci .priv_data_size = sizeof(LibCodec2Context), 208cabdff1aSopenharmony_ci .init = libcodec2_init_encoder, 209cabdff1aSopenharmony_ci .close = libcodec2_close, 210cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(libcodec2_encode), 211cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 212cabdff1aSopenharmony_ci .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 }, 213cabdff1aSopenharmony_ci#endif 214cabdff1aSopenharmony_ci}; 215