1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2011 Justin Ruggles 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavutil/common.h" 22cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 23cabdff1aSopenharmony_ci#include "libavutil/mathematics.h" 24cabdff1aSopenharmony_ci#include "adx.h" 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_civoid ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff) 27cabdff1aSopenharmony_ci{ 28cabdff1aSopenharmony_ci double a, b, c; 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci a = M_SQRT2 - cos(2.0 * M_PI * cutoff / sample_rate); 31cabdff1aSopenharmony_ci b = M_SQRT2 - 1.0; 32cabdff1aSopenharmony_ci c = (a - sqrt((a + b) * (a - b))) / b; 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci coeff[0] = lrintf(c * 2.0 * (1 << bits)); 35cabdff1aSopenharmony_ci coeff[1] = lrintf(-(c * c) * (1 << bits)); 36cabdff1aSopenharmony_ci} 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ciint ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, 39cabdff1aSopenharmony_ci int bufsize, int *header_size, int *coeff) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci int offset, cutoff, channels; 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_ci if (bufsize < 24) 44cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_ci if (AV_RB16(buf) != 0x8000) 47cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 48cabdff1aSopenharmony_ci offset = AV_RB16(buf + 2) + 4; 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ci /* if copyright string is within the provided data, validate it */ 51cabdff1aSopenharmony_ci if (bufsize >= offset && offset >= 6 && memcmp(buf + offset - 6, "(c)CRI", 6)) 52cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci /* check for encoding=3 block_size=18, sample_size=4 */ 55cabdff1aSopenharmony_ci if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) { 56cabdff1aSopenharmony_ci avpriv_request_sample(avctx, "Support for this ADX format"); 57cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 58cabdff1aSopenharmony_ci } 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci /* channels */ 61cabdff1aSopenharmony_ci channels = buf[7]; 62cabdff1aSopenharmony_ci if (channels <= 0 || channels > 2) 63cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels != channels) { 66cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 67cabdff1aSopenharmony_ci avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 68cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels = channels; 69cabdff1aSopenharmony_ci } 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci /* sample rate */ 72cabdff1aSopenharmony_ci avctx->sample_rate = AV_RB32(buf + 8); 73cabdff1aSopenharmony_ci if (avctx->sample_rate < 1 || 74cabdff1aSopenharmony_ci avctx->sample_rate > INT_MAX / (channels * BLOCK_SIZE * 8)) 75cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_ci /* bit rate */ 78cabdff1aSopenharmony_ci avctx->bit_rate = avctx->sample_rate * channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES; 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci /* LPC coefficients */ 81cabdff1aSopenharmony_ci if (coeff) { 82cabdff1aSopenharmony_ci cutoff = AV_RB16(buf + 16); 83cabdff1aSopenharmony_ci ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff); 84cabdff1aSopenharmony_ci } 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci *header_size = offset; 87cabdff1aSopenharmony_ci return 0; 88cabdff1aSopenharmony_ci} 89