1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * SMPTE 302M encoder 3cabdff1aSopenharmony_ci * Copyright (c) 2010 Google, Inc. 4cabdff1aSopenharmony_ci * Copyright (c) 2013 Darryl Wallace <wallacdj@gmail.com> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 24cabdff1aSopenharmony_ci#include "libavutil/reverse.h" 25cabdff1aSopenharmony_ci#include "avcodec.h" 26cabdff1aSopenharmony_ci#include "codec_internal.h" 27cabdff1aSopenharmony_ci#include "encode.h" 28cabdff1aSopenharmony_ci#include "mathops.h" 29cabdff1aSopenharmony_ci#include "put_bits.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#define AES3_HEADER_LEN 4 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_citypedef struct S302MEncContext { 34cabdff1aSopenharmony_ci uint8_t framing_index; /* Set for even channels on multiple of 192 samples */ 35cabdff1aSopenharmony_ci} S302MEncContext; 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_cistatic av_cold int s302m_encode_init(AVCodecContext *avctx) 38cabdff1aSopenharmony_ci{ 39cabdff1aSopenharmony_ci S302MEncContext *s = avctx->priv_data; 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels & 1 || avctx->ch_layout.nb_channels > 8) { 42cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 43cabdff1aSopenharmony_ci "Encoding %d channel(s) is not allowed. Only 2, 4, 6 and 8 channels are supported.\n", 44cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels); 45cabdff1aSopenharmony_ci return AVERROR(EINVAL); 46cabdff1aSopenharmony_ci } 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci switch (avctx->sample_fmt) { 49cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_S16: 50cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 16; 51cabdff1aSopenharmony_ci break; 52cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_S32: 53cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample > 20) { 54cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample > 24) 55cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n"); 56cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 24; 57cabdff1aSopenharmony_ci } else if (!avctx->bits_per_raw_sample) { 58cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 24; 59cabdff1aSopenharmony_ci } else if (avctx->bits_per_raw_sample <= 20) { 60cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = 20; 61cabdff1aSopenharmony_ci } 62cabdff1aSopenharmony_ci } 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci avctx->frame_size = 0; 65cabdff1aSopenharmony_ci avctx->bit_rate = 48000 * avctx->ch_layout.nb_channels * 66cabdff1aSopenharmony_ci (avctx->bits_per_raw_sample + 4); 67cabdff1aSopenharmony_ci s->framing_index = 0; 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci return 0; 70cabdff1aSopenharmony_ci} 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_cistatic int s302m_encode2_frame(AVCodecContext *avctx, AVPacket *avpkt, 73cabdff1aSopenharmony_ci const AVFrame *frame, int *got_packet_ptr) 74cabdff1aSopenharmony_ci{ 75cabdff1aSopenharmony_ci S302MEncContext *s = avctx->priv_data; 76cabdff1aSopenharmony_ci const int nb_channels = avctx->ch_layout.nb_channels; 77cabdff1aSopenharmony_ci const int buf_size = AES3_HEADER_LEN + 78cabdff1aSopenharmony_ci (frame->nb_samples * nb_channels * 79cabdff1aSopenharmony_ci (avctx->bits_per_raw_sample + 4)) / 8; 80cabdff1aSopenharmony_ci int ret, c, channels; 81cabdff1aSopenharmony_ci uint8_t *o; 82cabdff1aSopenharmony_ci PutBitContext pb; 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci if (buf_size - AES3_HEADER_LEN > UINT16_MAX) { 85cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "number of samples in frame too big\n"); 86cabdff1aSopenharmony_ci return AVERROR(EINVAL); 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci if ((ret = ff_get_encode_buffer(avctx, avpkt, buf_size, 0)) < 0) 90cabdff1aSopenharmony_ci return ret; 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci o = avpkt->data; 93cabdff1aSopenharmony_ci init_put_bits(&pb, o, buf_size); 94cabdff1aSopenharmony_ci put_bits(&pb, 16, buf_size - AES3_HEADER_LEN); 95cabdff1aSopenharmony_ci put_bits(&pb, 2, (nb_channels - 2) >> 1); // number of channels 96cabdff1aSopenharmony_ci put_bits(&pb, 8, 0); // channel ID 97cabdff1aSopenharmony_ci put_bits(&pb, 2, (avctx->bits_per_raw_sample - 16) / 4); // bits per samples (0 = 16bit, 1 = 20bit, 2 = 24bit) 98cabdff1aSopenharmony_ci put_bits(&pb, 4, 0); // alignments 99cabdff1aSopenharmony_ci flush_put_bits(&pb); 100cabdff1aSopenharmony_ci o += AES3_HEADER_LEN; 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 24) { 103cabdff1aSopenharmony_ci const uint32_t *samples = (uint32_t *)frame->data[0]; 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci for (c = 0; c < frame->nb_samples; c++) { 106cabdff1aSopenharmony_ci uint8_t vucf = s->framing_index == 0 ? 0x10: 0; 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci for (channels = 0; channels < nb_channels; channels += 2) { 109cabdff1aSopenharmony_ci o[0] = ff_reverse[(samples[0] & 0x0000FF00) >> 8]; 110cabdff1aSopenharmony_ci o[1] = ff_reverse[(samples[0] & 0x00FF0000) >> 16]; 111cabdff1aSopenharmony_ci o[2] = ff_reverse[(samples[0] & 0xFF000000) >> 24]; 112cabdff1aSopenharmony_ci o[3] = ff_reverse[(samples[1] & 0x00000F00) >> 4] | vucf; 113cabdff1aSopenharmony_ci o[4] = ff_reverse[(samples[1] & 0x000FF000) >> 12]; 114cabdff1aSopenharmony_ci o[5] = ff_reverse[(samples[1] & 0x0FF00000) >> 20]; 115cabdff1aSopenharmony_ci o[6] = ff_reverse[(samples[1] & 0xF0000000) >> 28]; 116cabdff1aSopenharmony_ci o += 7; 117cabdff1aSopenharmony_ci samples += 2; 118cabdff1aSopenharmony_ci } 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci s->framing_index++; 121cabdff1aSopenharmony_ci if (s->framing_index >= 192) 122cabdff1aSopenharmony_ci s->framing_index = 0; 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci } else if (avctx->bits_per_raw_sample == 20) { 125cabdff1aSopenharmony_ci const uint32_t *samples = (uint32_t *)frame->data[0]; 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci for (c = 0; c < frame->nb_samples; c++) { 128cabdff1aSopenharmony_ci uint8_t vucf = s->framing_index == 0 ? 0x80: 0; 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci for (channels = 0; channels < nb_channels; channels += 2) { 131cabdff1aSopenharmony_ci o[0] = ff_reverse[ (samples[0] & 0x000FF000) >> 12]; 132cabdff1aSopenharmony_ci o[1] = ff_reverse[ (samples[0] & 0x0FF00000) >> 20]; 133cabdff1aSopenharmony_ci o[2] = ff_reverse[((samples[0] & 0xF0000000) >> 28) | vucf]; 134cabdff1aSopenharmony_ci o[3] = ff_reverse[ (samples[1] & 0x000FF000) >> 12]; 135cabdff1aSopenharmony_ci o[4] = ff_reverse[ (samples[1] & 0x0FF00000) >> 20]; 136cabdff1aSopenharmony_ci o[5] = ff_reverse[ (samples[1] & 0xF0000000) >> 28]; 137cabdff1aSopenharmony_ci o += 6; 138cabdff1aSopenharmony_ci samples += 2; 139cabdff1aSopenharmony_ci } 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci s->framing_index++; 142cabdff1aSopenharmony_ci if (s->framing_index >= 192) 143cabdff1aSopenharmony_ci s->framing_index = 0; 144cabdff1aSopenharmony_ci } 145cabdff1aSopenharmony_ci } else if (avctx->bits_per_raw_sample == 16) { 146cabdff1aSopenharmony_ci const uint16_t *samples = (uint16_t *)frame->data[0]; 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci for (c = 0; c < frame->nb_samples; c++) { 149cabdff1aSopenharmony_ci uint8_t vucf = s->framing_index == 0 ? 0x10 : 0; 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci for (channels = 0; channels < nb_channels; channels += 2) { 152cabdff1aSopenharmony_ci o[0] = ff_reverse[ samples[0] & 0xFF]; 153cabdff1aSopenharmony_ci o[1] = ff_reverse[(samples[0] & 0xFF00) >> 8]; 154cabdff1aSopenharmony_ci o[2] = ff_reverse[(samples[1] & 0x0F) << 4] | vucf; 155cabdff1aSopenharmony_ci o[3] = ff_reverse[(samples[1] & 0x0FF0) >> 4]; 156cabdff1aSopenharmony_ci o[4] = ff_reverse[(samples[1] & 0xF000) >> 12]; 157cabdff1aSopenharmony_ci o += 5; 158cabdff1aSopenharmony_ci samples += 2; 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci } 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci s->framing_index++; 163cabdff1aSopenharmony_ci if (s->framing_index >= 192) 164cabdff1aSopenharmony_ci s->framing_index = 0; 165cabdff1aSopenharmony_ci } 166cabdff1aSopenharmony_ci } 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci *got_packet_ptr = 1; 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_ci return 0; 171cabdff1aSopenharmony_ci} 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ciconst FFCodec ff_s302m_encoder = { 174cabdff1aSopenharmony_ci .p.name = "s302m", 175cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"), 176cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 177cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_S302M, 178cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_EXPERIMENTAL | 179cabdff1aSopenharmony_ci AV_CODEC_CAP_VARIABLE_FRAME_SIZE, 180cabdff1aSopenharmony_ci .priv_data_size = sizeof(S302MEncContext), 181cabdff1aSopenharmony_ci .init = s302m_encode_init, 182cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(s302m_encode2_frame), 183cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32, 184cabdff1aSopenharmony_ci AV_SAMPLE_FMT_S16, 185cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 186cabdff1aSopenharmony_ci .p.supported_samplerates = (const int[]) { 48000, 0 }, 187cabdff1aSopenharmony_ci /* .p.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_STEREO, 188cabdff1aSopenharmony_ci AV_CH_LAYOUT_QUAD, 189cabdff1aSopenharmony_ci AV_CH_LAYOUT_5POINT1_BACK, 190cabdff1aSopenharmony_ci AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX, 191cabdff1aSopenharmony_ci 0 }, */ 192cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 193cabdff1aSopenharmony_ci}; 194