/src/ffmpeg/libavcodec/tak.c
Line | Count | Source |
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/channel_layout.h" |
23 | | #include "libavutil/crc.h" |
24 | | #include "libavutil/intreadwrite.h" |
25 | | |
26 | | #define CACHED_BITSTREAM_READER !ARCH_X86_32 |
27 | | #define BITSTREAM_READER_LE |
28 | | #include "tak.h" |
29 | | |
30 | | static const int64_t tak_channel_layouts[] = { |
31 | | 0, |
32 | | AV_CH_FRONT_LEFT, |
33 | | AV_CH_FRONT_RIGHT, |
34 | | AV_CH_FRONT_CENTER, |
35 | | AV_CH_LOW_FREQUENCY, |
36 | | AV_CH_BACK_LEFT, |
37 | | AV_CH_BACK_RIGHT, |
38 | | AV_CH_FRONT_LEFT_OF_CENTER, |
39 | | AV_CH_FRONT_RIGHT_OF_CENTER, |
40 | | AV_CH_BACK_CENTER, |
41 | | AV_CH_SIDE_LEFT, |
42 | | AV_CH_SIDE_RIGHT, |
43 | | AV_CH_TOP_CENTER, |
44 | | AV_CH_TOP_FRONT_LEFT, |
45 | | AV_CH_TOP_FRONT_CENTER, |
46 | | AV_CH_TOP_FRONT_RIGHT, |
47 | | AV_CH_TOP_BACK_LEFT, |
48 | | AV_CH_TOP_BACK_CENTER, |
49 | | AV_CH_TOP_BACK_RIGHT, |
50 | | }; |
51 | | |
52 | | static const uint16_t frame_duration_type_quants[] = { |
53 | | 3, 4, 6, 8, 4096, 8192, 16384, 512, 1024, 2048, |
54 | | }; |
55 | | |
56 | | static int tak_get_nb_samples(int sample_rate, enum TAKFrameSizeType type) |
57 | 150k | { |
58 | 150k | int nb_samples, max_nb_samples; |
59 | | |
60 | 150k | if (type <= TAK_FST_250ms) { |
61 | 111k | nb_samples = sample_rate * frame_duration_type_quants[type] >> |
62 | 111k | TAK_FRAME_DURATION_QUANT_SHIFT; |
63 | 111k | max_nb_samples = 16384; |
64 | 111k | } else if (type < FF_ARRAY_ELEMS(frame_duration_type_quants)) { |
65 | 21.3k | nb_samples = frame_duration_type_quants[type]; |
66 | 21.3k | max_nb_samples = sample_rate * |
67 | 21.3k | frame_duration_type_quants[TAK_FST_250ms] >> |
68 | 21.3k | TAK_FRAME_DURATION_QUANT_SHIFT; |
69 | 21.3k | } else { |
70 | 17.9k | return AVERROR_INVALIDDATA; |
71 | 17.9k | } |
72 | | |
73 | 132k | if (nb_samples <= 0 || nb_samples > max_nb_samples) |
74 | 10.4k | return AVERROR_INVALIDDATA; |
75 | | |
76 | 122k | return nb_samples; |
77 | 132k | } |
78 | | |
79 | | int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size) |
80 | 5.25M | { |
81 | 5.25M | uint32_t crc, CRC; |
82 | | |
83 | 5.25M | if (buf_size < 4) |
84 | 1.55k | return AVERROR_INVALIDDATA; |
85 | 5.25M | buf_size -= 3; |
86 | | |
87 | 5.25M | CRC = AV_RB24(buf + buf_size); |
88 | 5.25M | crc = av_crc(av_crc_get_table(AV_CRC_24_IEEE), 0xCE04B7U, buf, buf_size); |
89 | 5.25M | if (CRC != crc) |
90 | 553k | return AVERROR_INVALIDDATA; |
91 | | |
92 | 4.69M | return 0; |
93 | 5.25M | } |
94 | | |
95 | | static int tak_parse_streaminfo(TAKStreamInfo *s, GetBitContext *gb) |
96 | 150k | { |
97 | 150k | uint64_t channel_mask = 0; |
98 | 150k | int frame_type, i, ret; |
99 | | |
100 | 150k | s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS); |
101 | 150k | skip_bits(gb, TAK_ENCODER_PROFILE_BITS); |
102 | | |
103 | 150k | frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS); |
104 | 150k | s->samples = get_bits64(gb, TAK_SIZE_SAMPLES_NUM_BITS); |
105 | | |
106 | 150k | s->data_type = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS); |
107 | 150k | s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) + |
108 | 150k | TAK_SAMPLE_RATE_MIN; |
109 | 150k | s->bps = get_bits(gb, TAK_FORMAT_BPS_BITS) + |
110 | 150k | TAK_BPS_MIN; |
111 | 150k | s->channels = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) + |
112 | 150k | TAK_CHANNELS_MIN; |
113 | | |
114 | 150k | if (get_bits1(gb)) { |
115 | 33.0k | skip_bits(gb, TAK_FORMAT_VALID_BITS); |
116 | 33.0k | if (get_bits1(gb)) { |
117 | 288k | for (i = 0; i < s->channels; i++) { |
118 | 266k | int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS); |
119 | | |
120 | 266k | if (value < FF_ARRAY_ELEMS(tak_channel_layouts)) |
121 | 70.0k | channel_mask |= tak_channel_layouts[value]; |
122 | 266k | } |
123 | 22.2k | } |
124 | 33.0k | } |
125 | | |
126 | 150k | s->ch_layout = channel_mask; |
127 | | |
128 | 150k | ret = tak_get_nb_samples(s->sample_rate, frame_type); |
129 | 150k | if (ret < 0) |
130 | 28.3k | return ret; |
131 | 122k | s->frame_samples = ret; |
132 | | |
133 | 122k | return 0; |
134 | 150k | } |
135 | | |
136 | | int avpriv_tak_parse_streaminfo(TAKStreamInfo *s, const uint8_t *buf, int size) |
137 | 1.21k | { |
138 | 1.21k | GetBitContext gb; |
139 | 1.21k | int ret = init_get_bits8(&gb, buf, size); |
140 | | |
141 | 1.21k | if (ret < 0) |
142 | 0 | return AVERROR_INVALIDDATA; |
143 | | |
144 | 1.21k | return tak_parse_streaminfo(s, &gb); |
145 | 1.21k | } |
146 | | |
147 | | int ff_tak_decode_frame_header(void *logctx, GetBitContext *gb, |
148 | | TAKStreamInfo *ti, int log_level_offset) |
149 | 5.50M | { |
150 | 5.50M | if (get_bits(gb, TAK_FRAME_HEADER_SYNC_ID_BITS) != TAK_FRAME_HEADER_SYNC_ID) { |
151 | 6.68k | av_log(logctx, AV_LOG_ERROR + log_level_offset, "missing sync id\n"); |
152 | 6.68k | return AVERROR_INVALIDDATA; |
153 | 6.68k | } |
154 | | |
155 | 5.50M | ti->flags = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS); |
156 | 5.50M | ti->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS); |
157 | | |
158 | 5.50M | if (ti->flags & TAK_FRAME_FLAG_IS_LAST) { |
159 | 78.1k | ti->last_frame_samples = get_bits(gb, TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1; |
160 | 78.1k | skip_bits(gb, 2); |
161 | 5.42M | } else { |
162 | 5.42M | ti->last_frame_samples = 0; |
163 | 5.42M | } |
164 | | |
165 | 5.50M | if (ti->flags & TAK_FRAME_FLAG_HAS_INFO) { |
166 | 149k | int ret = tak_parse_streaminfo(ti, gb); |
167 | 149k | if (ret < 0) |
168 | 28.3k | return ret; |
169 | | |
170 | 121k | if (get_bits(gb, 6)) |
171 | 29.7k | skip_bits(gb, 25); |
172 | 121k | align_get_bits(gb); |
173 | 121k | } |
174 | | |
175 | 5.47M | if (ti->flags & TAK_FRAME_FLAG_HAS_METADATA) |
176 | 16.9k | return AVERROR_INVALIDDATA; |
177 | | |
178 | 5.45M | if (get_bits_left(gb) < 24) |
179 | 2.14k | return AVERROR_INVALIDDATA; |
180 | | |
181 | 5.45M | skip_bits(gb, 24); |
182 | | |
183 | 5.45M | return 0; |
184 | 5.45M | } |