1/* 2 * TAK common code 3 * Copyright (c) 2012 Paul B Mahol 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 "libavutil/crc.h" 23#include "libavutil/intreadwrite.h" 24#include "tak.h" 25 26static const int64_t tak_channel_layouts[] = { 27 0, 28 AV_CH_FRONT_LEFT, 29 AV_CH_FRONT_RIGHT, 30 AV_CH_FRONT_CENTER, 31 AV_CH_LOW_FREQUENCY, 32 AV_CH_BACK_LEFT, 33 AV_CH_BACK_RIGHT, 34 AV_CH_FRONT_LEFT_OF_CENTER, 35 AV_CH_FRONT_RIGHT_OF_CENTER, 36 AV_CH_BACK_CENTER, 37 AV_CH_SIDE_LEFT, 38 AV_CH_SIDE_RIGHT, 39 AV_CH_TOP_CENTER, 40 AV_CH_TOP_FRONT_LEFT, 41 AV_CH_TOP_FRONT_CENTER, 42 AV_CH_TOP_FRONT_RIGHT, 43 AV_CH_TOP_BACK_LEFT, 44 AV_CH_TOP_BACK_CENTER, 45 AV_CH_TOP_BACK_RIGHT, 46}; 47 48static const uint16_t frame_duration_type_quants[] = { 49 3, 4, 6, 8, 4096, 8192, 16384, 512, 1024, 2048, 50}; 51 52static int tak_get_nb_samples(int sample_rate, enum TAKFrameSizeType type) 53{ 54 int nb_samples, max_nb_samples; 55 56 if (type <= TAK_FST_250ms) { 57 nb_samples = sample_rate * frame_duration_type_quants[type] >> 58 TAK_FRAME_DURATION_QUANT_SHIFT; 59 max_nb_samples = 16384; 60 } else if (type < FF_ARRAY_ELEMS(frame_duration_type_quants)) { 61 nb_samples = frame_duration_type_quants[type]; 62 max_nb_samples = sample_rate * 63 frame_duration_type_quants[TAK_FST_250ms] >> 64 TAK_FRAME_DURATION_QUANT_SHIFT; 65 } else { 66 return AVERROR_INVALIDDATA; 67 } 68 69 if (nb_samples <= 0 || nb_samples > max_nb_samples) 70 return AVERROR_INVALIDDATA; 71 72 return nb_samples; 73} 74 75int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size) 76{ 77 uint32_t crc, CRC; 78 79 if (buf_size < 4) 80 return AVERROR_INVALIDDATA; 81 buf_size -= 3; 82 83 CRC = AV_RB24(buf + buf_size); 84 crc = av_crc(av_crc_get_table(AV_CRC_24_IEEE), 0xCE04B7U, buf, buf_size); 85 if (CRC != crc) 86 return AVERROR_INVALIDDATA; 87 88 return 0; 89} 90 91void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s) 92{ 93 uint64_t channel_mask = 0; 94 int frame_type, i; 95 96 s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS); 97 skip_bits(gb, TAK_ENCODER_PROFILE_BITS); 98 99 frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS); 100 s->samples = get_bits64(gb, TAK_SIZE_SAMPLES_NUM_BITS); 101 102 s->data_type = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS); 103 s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) + 104 TAK_SAMPLE_RATE_MIN; 105 s->bps = get_bits(gb, TAK_FORMAT_BPS_BITS) + 106 TAK_BPS_MIN; 107 s->channels = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) + 108 TAK_CHANNELS_MIN; 109 110 if (get_bits1(gb)) { 111 skip_bits(gb, TAK_FORMAT_VALID_BITS); 112 if (get_bits1(gb)) { 113 for (i = 0; i < s->channels; i++) { 114 int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS); 115 116 if (value < FF_ARRAY_ELEMS(tak_channel_layouts)) 117 channel_mask |= tak_channel_layouts[value]; 118 } 119 } 120 } 121 122 s->ch_layout = channel_mask; 123 s->frame_samples = tak_get_nb_samples(s->sample_rate, frame_type); 124} 125 126int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, 127 TAKStreamInfo *ti, int log_level_offset) 128{ 129 if (get_bits(gb, TAK_FRAME_HEADER_SYNC_ID_BITS) != TAK_FRAME_HEADER_SYNC_ID) { 130 av_log(avctx, AV_LOG_ERROR + log_level_offset, "missing sync id\n"); 131 return AVERROR_INVALIDDATA; 132 } 133 134 ti->flags = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS); 135 ti->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS); 136 137 if (ti->flags & TAK_FRAME_FLAG_IS_LAST) { 138 ti->last_frame_samples = get_bits(gb, TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1; 139 skip_bits(gb, 2); 140 } else { 141 ti->last_frame_samples = 0; 142 } 143 144 if (ti->flags & TAK_FRAME_FLAG_HAS_INFO) { 145 avpriv_tak_parse_streaminfo(gb, ti); 146 147 if (get_bits(gb, 6)) 148 skip_bits(gb, 25); 149 align_get_bits(gb); 150 } 151 152 if (ti->flags & TAK_FRAME_FLAG_HAS_METADATA) 153 return AVERROR_INVALIDDATA; 154 155 skip_bits(gb, 24); 156 157 return 0; 158} 159