Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
tak.c
Go to the documentation of this file.
1
/*
2
* TAK common code
3
* Copyright (c) 2012 Paul B Mahol
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; 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/bswap.h
"
23
#include "
libavutil/crc.h
"
24
#include "
libavutil/intreadwrite.h
"
25
#include "
tak.h
"
26
27
static
const
uint16_t
frame_duration_type_quants
[] = {
28
3, 4, 6, 8, 4096, 8192, 16384, 512, 1024, 2048,
29
};
30
31
static
int
tak_get_nb_samples
(
int
sample_rate,
enum
TAKFrameSizeType
type)
32
{
33
int
nb_samples, max_nb_samples;
34
35
if
(type <=
TAK_FST_250ms
) {
36
nb_samples = sample_rate *
frame_duration_type_quants
[type] >>
37
TAK_FRAME_DURATION_QUANT_SHIFT
;
38
max_nb_samples = 16384;
39
}
else
if
(type <
FF_ARRAY_ELEMS
(
frame_duration_type_quants
)) {
40
nb_samples =
frame_duration_type_quants
[type];
41
max_nb_samples = sample_rate *
42
frame_duration_type_quants
[
TAK_FST_250ms
] >>
43
TAK_FRAME_DURATION_QUANT_SHIFT
;
44
}
else
{
45
return
AVERROR_INVALIDDATA
;
46
}
47
48
if
(nb_samples <= 0 || nb_samples > max_nb_samples)
49
return
AVERROR_INVALIDDATA
;
50
51
return
nb_samples;
52
}
53
54
static
int
crc_init
= 0;
55
#if CONFIG_SMALL
56
#define CRC_TABLE_SIZE 257
57
#else
58
#define CRC_TABLE_SIZE 1024
59
#endif
60
static
AVCRC
crc_24
[
CRC_TABLE_SIZE
];
61
62
av_cold
void
ff_tak_init_crc
(
void
)
63
{
64
if
(!
crc_init
) {
65
av_crc_init
(
crc_24
, 0, 24, 0x864CFBU,
sizeof
(
crc_24
));
66
crc_init
= 1;
67
}
68
}
69
70
int
ff_tak_check_crc
(
const
uint8_t
*buf,
unsigned
int
buf_size)
71
{
72
uint32_t crc, CRC;
73
74
if
(buf_size < 4)
75
return
AVERROR_INVALIDDATA
;
76
buf_size -= 3;
77
78
CRC =
av_bswap32
(
AV_RL24
(buf + buf_size)) >> 8;
79
crc =
av_crc
(
crc_24
, 0xCE04B7U, buf, buf_size);
80
if
(CRC != crc)
81
return
AVERROR_INVALIDDATA
;
82
83
return
0;
84
}
85
86
void
avpriv_tak_parse_streaminfo
(
GetBitContext
*gb,
TAKStreamInfo
*s)
87
{
88
uint64_t channel_mask = 0;
89
int
frame_type, i;
90
91
s->
codec
=
get_bits
(gb,
TAK_ENCODER_CODEC_BITS
);
92
skip_bits
(gb,
TAK_ENCODER_PROFILE_BITS
);
93
94
frame_type =
get_bits
(gb,
TAK_SIZE_FRAME_DURATION_BITS
);
95
s->
samples
=
get_bits64
(gb,
TAK_SIZE_SAMPLES_NUM_BITS
);
96
97
s->
data_type
=
get_bits
(gb,
TAK_FORMAT_DATA_TYPE_BITS
);
98
s->
sample_rate
=
get_bits
(gb,
TAK_FORMAT_SAMPLE_RATE_BITS
) +
99
TAK_SAMPLE_RATE_MIN
;
100
s->
bps
=
get_bits
(gb,
TAK_FORMAT_BPS_BITS
) +
101
TAK_BPS_MIN
;
102
s->
channels
=
get_bits
(gb,
TAK_FORMAT_CHANNEL_BITS
) +
103
TAK_CHANNELS_MIN
;
104
105
if
(
get_bits1
(gb)) {
106
skip_bits
(gb,
TAK_FORMAT_VALID_BITS
);
107
if
(
get_bits1
(gb)) {
108
for
(i = 0; i < s->
channels
; i++) {
109
int
value =
get_bits
(gb,
TAK_FORMAT_CH_LAYOUT_BITS
);
110
111
if
(value > 0 && value <= 18)
112
channel_mask |= 1 << (value - 1);
113
}
114
}
115
}
116
117
s->
ch_layout
= channel_mask;
118
s->
frame_samples
=
tak_get_nb_samples
(s->
sample_rate
, frame_type);
119
}
120
121
int
ff_tak_decode_frame_header
(
AVCodecContext
*avctx,
GetBitContext
*gb,
122
TAKStreamInfo
*ti,
int
log_level_offset)
123
{
124
if
(
get_bits
(gb,
TAK_FRAME_HEADER_SYNC_ID_BITS
) !=
TAK_FRAME_HEADER_SYNC_ID
) {
125
av_log
(avctx,
AV_LOG_ERROR
+ log_level_offset,
"missing sync id\n"
);
126
return
AVERROR_INVALIDDATA
;
127
}
128
129
ti->
flags
=
get_bits
(gb,
TAK_FRAME_HEADER_FLAGS_BITS
);
130
ti->
frame_num
=
get_bits
(gb,
TAK_FRAME_HEADER_NO_BITS
);
131
132
if
(ti->
flags
&
TAK_FRAME_FLAG_IS_LAST
) {
133
ti->
last_frame_samples
=
get_bits
(gb,
TAK_FRAME_HEADER_SAMPLE_COUNT_BITS
) + 1;
134
skip_bits
(gb, 2);
135
}
else
{
136
ti->
last_frame_samples
= 0;
137
}
138
139
if
(ti->
flags
&
TAK_FRAME_FLAG_HAS_INFO
) {
140
avpriv_tak_parse_streaminfo
(gb, ti);
141
142
if
(
get_bits
(gb, 6))
143
skip_bits
(gb, 25);
144
align_get_bits
(gb);
145
}
146
147
skip_bits
(gb, 24);
148
149
return
0;
150
}
Generated on Thu Sep 30 2021 23:03:15 for Libav by
1.8.1.2