1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * SMPTE 302M decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2008 Laurent Aimar <fenrir@videolan.org> 4cabdff1aSopenharmony_ci * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@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/intreadwrite.h" 25cabdff1aSopenharmony_ci#include "libavutil/opt.h" 26cabdff1aSopenharmony_ci#include "libavutil/log.h" 27cabdff1aSopenharmony_ci#include "libavutil/reverse.h" 28cabdff1aSopenharmony_ci#include "avcodec.h" 29cabdff1aSopenharmony_ci#include "codec_internal.h" 30cabdff1aSopenharmony_ci#include "internal.h" 31cabdff1aSopenharmony_ci#include "mathops.h" 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#define AES3_HEADER_LEN 4 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_citypedef struct S302Context { 36cabdff1aSopenharmony_ci AVClass *class; 37cabdff1aSopenharmony_ci int non_pcm_mode; 38cabdff1aSopenharmony_ci} S302Context; 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_cistatic int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf, 41cabdff1aSopenharmony_ci int buf_size) 42cabdff1aSopenharmony_ci{ 43cabdff1aSopenharmony_ci uint32_t h; 44cabdff1aSopenharmony_ci int frame_size, channels, bits; 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_ci if (buf_size <= AES3_HEADER_LEN) { 47cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "frame is too short\n"); 48cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 49cabdff1aSopenharmony_ci } 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci /* 52cabdff1aSopenharmony_ci * AES3 header : 53cabdff1aSopenharmony_ci * size: 16 54cabdff1aSopenharmony_ci * number channels 2 55cabdff1aSopenharmony_ci * channel_id 8 56cabdff1aSopenharmony_ci * bits per samples 2 57cabdff1aSopenharmony_ci * alignments 4 58cabdff1aSopenharmony_ci */ 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci h = AV_RB32(buf); 61cabdff1aSopenharmony_ci frame_size = (h >> 16) & 0xffff; 62cabdff1aSopenharmony_ci channels = ((h >> 14) & 0x0003) * 2 + 2; 63cabdff1aSopenharmony_ci bits = ((h >> 4) & 0x0003) * 4 + 16; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci if (AES3_HEADER_LEN + frame_size != buf_size || bits > 24) { 66cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "frame has invalid header\n"); 67cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 68cabdff1aSopenharmony_ci } 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci /* Set output properties */ 71cabdff1aSopenharmony_ci avctx->bits_per_raw_sample = bits; 72cabdff1aSopenharmony_ci if (bits > 16) 73cabdff1aSopenharmony_ci avctx->sample_fmt = AV_SAMPLE_FMT_S32; 74cabdff1aSopenharmony_ci else 75cabdff1aSopenharmony_ci avctx->sample_fmt = AV_SAMPLE_FMT_S16; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 78cabdff1aSopenharmony_ci switch(channels) { 79cabdff1aSopenharmony_ci case 2: 80cabdff1aSopenharmony_ci avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; 81cabdff1aSopenharmony_ci break; 82cabdff1aSopenharmony_ci case 4: 83cabdff1aSopenharmony_ci avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD; 84cabdff1aSopenharmony_ci break; 85cabdff1aSopenharmony_ci case 6: 86cabdff1aSopenharmony_ci avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK; 87cabdff1aSopenharmony_ci break; 88cabdff1aSopenharmony_ci case 8: 89cabdff1aSopenharmony_ci av_channel_layout_from_mask(&avctx->ch_layout, 90cabdff1aSopenharmony_ci AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX); 91cabdff1aSopenharmony_ci break; 92cabdff1aSopenharmony_ci default: 93cabdff1aSopenharmony_ci avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 94cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels = channels; 95cabdff1aSopenharmony_ci break; 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci return frame_size; 99cabdff1aSopenharmony_ci} 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_cistatic int s302m_decode_frame(AVCodecContext *avctx, AVFrame *frame, 102cabdff1aSopenharmony_ci int *got_frame_ptr, AVPacket *avpkt) 103cabdff1aSopenharmony_ci{ 104cabdff1aSopenharmony_ci S302Context *s = avctx->priv_data; 105cabdff1aSopenharmony_ci const uint8_t *buf = avpkt->data; 106cabdff1aSopenharmony_ci int buf_size = avpkt->size; 107cabdff1aSopenharmony_ci int block_size, ret, channels; 108cabdff1aSopenharmony_ci int i; 109cabdff1aSopenharmony_ci int non_pcm_data_type = -1; 110cabdff1aSopenharmony_ci 111cabdff1aSopenharmony_ci int frame_size = s302m_parse_frame_header(avctx, buf, buf_size); 112cabdff1aSopenharmony_ci if (frame_size < 0) 113cabdff1aSopenharmony_ci return frame_size; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci buf_size -= AES3_HEADER_LEN; 116cabdff1aSopenharmony_ci buf += AES3_HEADER_LEN; 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci /* get output buffer */ 119cabdff1aSopenharmony_ci block_size = (avctx->bits_per_raw_sample + 4) / 4; 120cabdff1aSopenharmony_ci channels = avctx->ch_layout.nb_channels; 121cabdff1aSopenharmony_ci frame->nb_samples = 2 * (buf_size / block_size) / channels; 122cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) 123cabdff1aSopenharmony_ci return ret; 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci avctx->bit_rate = 48000 * channels * (avctx->bits_per_raw_sample + 4) + 126cabdff1aSopenharmony_ci 32 * 48000 / frame->nb_samples; 127cabdff1aSopenharmony_ci buf_size = (frame->nb_samples * channels / 2) * block_size; 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci if (avctx->bits_per_raw_sample == 24) { 130cabdff1aSopenharmony_ci uint32_t *o = (uint32_t *)frame->data[0]; 131cabdff1aSopenharmony_ci for (; buf_size > 6; buf_size -= 7) { 132cabdff1aSopenharmony_ci *o++ = ((unsigned)ff_reverse[buf[2]] << 24) | 133cabdff1aSopenharmony_ci (ff_reverse[buf[1]] << 16) | 134cabdff1aSopenharmony_ci (ff_reverse[buf[0]] << 8); 135cabdff1aSopenharmony_ci *o++ = ((unsigned)ff_reverse[buf[6] & 0xf0] << 28) | 136cabdff1aSopenharmony_ci (ff_reverse[buf[5]] << 20) | 137cabdff1aSopenharmony_ci (ff_reverse[buf[4]] << 12) | 138cabdff1aSopenharmony_ci (ff_reverse[buf[3] & 0x0f] << 4); 139cabdff1aSopenharmony_ci buf += 7; 140cabdff1aSopenharmony_ci } 141cabdff1aSopenharmony_ci o = (uint32_t *)frame->data[0]; 142cabdff1aSopenharmony_ci if (channels == 2) 143cabdff1aSopenharmony_ci for (i=0; i<frame->nb_samples * 2 - 6; i+=2) { 144cabdff1aSopenharmony_ci if (o[i] || o[i+1] || o[i+2] || o[i+3]) 145cabdff1aSopenharmony_ci break; 146cabdff1aSopenharmony_ci if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) { 147cabdff1aSopenharmony_ci non_pcm_data_type = (o[i+6] >> 16) & 0x1F; 148cabdff1aSopenharmony_ci break; 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } 151cabdff1aSopenharmony_ci } else if (avctx->bits_per_raw_sample == 20) { 152cabdff1aSopenharmony_ci uint32_t *o = (uint32_t *)frame->data[0]; 153cabdff1aSopenharmony_ci for (; buf_size > 5; buf_size -= 6) { 154cabdff1aSopenharmony_ci *o++ = ((unsigned)ff_reverse[buf[2] & 0xf0] << 28) | 155cabdff1aSopenharmony_ci (ff_reverse[buf[1]] << 20) | 156cabdff1aSopenharmony_ci (ff_reverse[buf[0]] << 12); 157cabdff1aSopenharmony_ci *o++ = ((unsigned)ff_reverse[buf[5] & 0xf0] << 28) | 158cabdff1aSopenharmony_ci (ff_reverse[buf[4]] << 20) | 159cabdff1aSopenharmony_ci (ff_reverse[buf[3]] << 12); 160cabdff1aSopenharmony_ci buf += 6; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci o = (uint32_t *)frame->data[0]; 163cabdff1aSopenharmony_ci if (channels == 2) 164cabdff1aSopenharmony_ci for (i=0; i<frame->nb_samples * 2 - 6; i+=2) { 165cabdff1aSopenharmony_ci if (o[i] || o[i+1] || o[i+2] || o[i+3]) 166cabdff1aSopenharmony_ci break; 167cabdff1aSopenharmony_ci if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) { 168cabdff1aSopenharmony_ci non_pcm_data_type = (o[i+6] >> 16) & 0x1F; 169cabdff1aSopenharmony_ci break; 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci } 172cabdff1aSopenharmony_ci } else { 173cabdff1aSopenharmony_ci uint16_t *o = (uint16_t *)frame->data[0]; 174cabdff1aSopenharmony_ci for (; buf_size > 4; buf_size -= 5) { 175cabdff1aSopenharmony_ci *o++ = (ff_reverse[buf[1]] << 8) | 176cabdff1aSopenharmony_ci ff_reverse[buf[0]]; 177cabdff1aSopenharmony_ci *o++ = (ff_reverse[buf[4] & 0xf0] << 12) | 178cabdff1aSopenharmony_ci (ff_reverse[buf[3]] << 4) | 179cabdff1aSopenharmony_ci (ff_reverse[buf[2]] >> 4); 180cabdff1aSopenharmony_ci buf += 5; 181cabdff1aSopenharmony_ci } 182cabdff1aSopenharmony_ci o = (uint16_t *)frame->data[0]; 183cabdff1aSopenharmony_ci if (channels == 2) 184cabdff1aSopenharmony_ci for (i=0; i<frame->nb_samples * 2 - 6; i+=2) { 185cabdff1aSopenharmony_ci if (o[i] || o[i+1] || o[i+2] || o[i+3]) 186cabdff1aSopenharmony_ci break; 187cabdff1aSopenharmony_ci if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) { 188cabdff1aSopenharmony_ci non_pcm_data_type = (o[i+6] & 0x1F); 189cabdff1aSopenharmony_ci break; 190cabdff1aSopenharmony_ci } 191cabdff1aSopenharmony_ci } 192cabdff1aSopenharmony_ci } 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci if (non_pcm_data_type != -1) { 195cabdff1aSopenharmony_ci if (s->non_pcm_mode == 3) { 196cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 197cabdff1aSopenharmony_ci "S302 non PCM mode with data type %d not supported\n", 198cabdff1aSopenharmony_ci non_pcm_data_type); 199cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci if (s->non_pcm_mode & 1) { 202cabdff1aSopenharmony_ci return avpkt->size; 203cabdff1aSopenharmony_ci } 204cabdff1aSopenharmony_ci } 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci avctx->sample_rate = 48000; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci *got_frame_ptr = 1; 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci return avpkt->size; 211cabdff1aSopenharmony_ci} 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_ci#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM 214cabdff1aSopenharmony_cistatic const AVOption s302m_options[] = { 215cabdff1aSopenharmony_ci {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"}, 216cabdff1aSopenharmony_ci {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, "non_pcm_mode"}, 217cabdff1aSopenharmony_ci {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, "non_pcm_mode"}, 218cabdff1aSopenharmony_ci {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, "non_pcm_mode"}, 219cabdff1aSopenharmony_ci {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"}, 220cabdff1aSopenharmony_ci {NULL} 221cabdff1aSopenharmony_ci}; 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_cistatic const AVClass s302m_class = { 224cabdff1aSopenharmony_ci .class_name = "SMPTE 302M Decoder", 225cabdff1aSopenharmony_ci .item_name = av_default_item_name, 226cabdff1aSopenharmony_ci .option = s302m_options, 227cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 228cabdff1aSopenharmony_ci}; 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ciconst FFCodec ff_s302m_decoder = { 231cabdff1aSopenharmony_ci .p.name = "s302m", 232cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"), 233cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 234cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_S302M, 235cabdff1aSopenharmony_ci .p.priv_class = &s302m_class, 236cabdff1aSopenharmony_ci .priv_data_size = sizeof(S302Context), 237cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(s302m_decode_frame), 238cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF | 239cabdff1aSopenharmony_ci AV_CODEC_CAP_DR1, 240cabdff1aSopenharmony_ci}; 241