summaryrefslogtreecommitdiff
path: root/libavcodec/tak.h
blob: fa91149793455ac49259e35f25e5759a73e976b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * TAK decoder/demuxer common code
 * Copyright (c) 2012 Paul B Mahol
 *
 * This file is part of Libav.
 *
 * Libav is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Libav is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Libav; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * TAK (Tom's lossless Audio Kompressor) decoder/demuxer common functions
 */

#ifndef AVCODEC_TAK_H
#define AVCODEC_TAK_H

#include <stdint.h>

#define BITSTREAM_READER_LE
#include "get_bits.h"
#include "avcodec.h"

#define TAK_FORMAT_DATA_TYPE_BITS               3
#define TAK_FORMAT_SAMPLE_RATE_BITS            18
#define TAK_FORMAT_BPS_BITS                     5
#define TAK_FORMAT_CHANNEL_BITS                 4
#define TAK_FORMAT_VALID_BITS                   5
#define TAK_FORMAT_CH_LAYOUT_BITS               6
#define TAK_SIZE_FRAME_DURATION_BITS            4
#define TAK_SIZE_SAMPLES_NUM_BITS              35
#define TAK_LAST_FRAME_POS_BITS                40
#define TAK_LAST_FRAME_SIZE_BITS               24
#define TAK_ENCODER_CODEC_BITS                  6
#define TAK_ENCODER_PROFILE_BITS                4
#define TAK_ENCODER_VERSION_BITS               24
#define TAK_SAMPLE_RATE_MIN                  6000
#define TAK_CHANNELS_MIN                        1
#define TAK_BPS_MIN                             8
#define TAK_FRAME_HEADER_FLAGS_BITS             3
#define TAK_FRAME_HEADER_SYNC_ID           0xA0FF
#define TAK_FRAME_HEADER_SYNC_ID_BITS          16
#define TAK_FRAME_HEADER_SAMPLE_COUNT_BITS     14
#define TAK_FRAME_HEADER_NO_BITS               21
#define TAK_FRAME_DURATION_QUANT_SHIFT          5
#define TAK_CRC24_BITS                         24


#define TAK_FRAME_FLAG_IS_LAST                0x1
#define TAK_FRAME_FLAG_HAS_INFO               0x2
#define TAK_FRAME_FLAG_HAS_METADATA           0x4

#define TAK_MAX_CHANNELS               (1 << TAK_FORMAT_CHANNEL_BITS)

#define TAK_MIN_FRAME_HEADER_BITS      (TAK_FRAME_HEADER_SYNC_ID_BITS + \
                                        TAK_FRAME_HEADER_FLAGS_BITS   + \
                                        TAK_FRAME_HEADER_NO_BITS      + \
                                        TAK_CRC24_BITS)

#define TAK_MIN_FRAME_HEADER_LAST_BITS (TAK_MIN_FRAME_HEADER_BITS + 2 + \
                                        TAK_FRAME_HEADER_SAMPLE_COUNT_BITS)

#define TAK_ENCODER_BITS               (TAK_ENCODER_CODEC_BITS + \
                                        TAK_ENCODER_PROFILE_BITS)

#define TAK_SIZE_BITS                  (TAK_SIZE_SAMPLES_NUM_BITS + \
                                        TAK_SIZE_FRAME_DURATION_BITS)

#define TAK_FORMAT_BITS                (TAK_FORMAT_DATA_TYPE_BITS   + \
                                        TAK_FORMAT_SAMPLE_RATE_BITS + \
                                        TAK_FORMAT_BPS_BITS         + \
                                        TAK_FORMAT_CHANNEL_BITS + 1 + \
                                        TAK_FORMAT_VALID_BITS   + 1 + \
                                        TAK_FORMAT_CH_LAYOUT_BITS   * \
                                        TAK_MAX_CHANNELS)

#define TAK_STREAMINFO_BITS            (TAK_ENCODER_BITS + \
                                        TAK_SIZE_BITS    + \
                                        TAK_FORMAT_BITS)

#define TAK_MAX_FRAME_HEADER_BITS      (TAK_MIN_FRAME_HEADER_LAST_BITS + \
                                        TAK_STREAMINFO_BITS + 31)

#define TAK_STREAMINFO_BYTES           ((TAK_STREAMINFO_BITS       + 7) / 8)
#define TAK_MAX_FRAME_HEADER_BYTES     ((TAK_MAX_FRAME_HEADER_BITS + 7) / 8)
#define TAK_MIN_FRAME_HEADER_BYTES     ((TAK_MIN_FRAME_HEADER_BITS + 7) / 8)

enum TAKCodecType {
    TAK_CODEC_MONO_STEREO  = 2,
    TAK_CODEC_MULTICHANNEL = 4
};

enum TAKMetaDataType {
    TAK_METADATA_END = 0,
    TAK_METADATA_STREAMINFO,
    TAK_METADATA_SEEKTABLE,
    TAK_METADATA_SIMPLE_WAVE_DATA,
    TAK_METADATA_ENCODER,
    TAK_METADATA_PADDING,
    TAK_METADATA_MD5,
    TAK_METADATA_LAST_FRAME,
};

enum TAKFrameSizeType {
    TAK_FST_94ms = 0,
    TAK_FST_125ms,
    TAK_FST_188ms,
    TAK_FST_250ms,
    TAK_FST_4096,
    TAK_FST_8192,
    TAK_FST_16384,
    TAK_FST_512,
    TAK_FST_1024,
    TAK_FST_2048,
};

typedef struct TAKStreamInfo {
    int               flags;
    enum TAKCodecType codec;
    int               data_type;
    int               sample_rate;
    int               channels;
    int               bps;
    int               frame_num;
    int               frame_samples;
    int               last_frame_samples;
    uint64_t          ch_layout;
    int64_t           samples;
} TAKStreamInfo;

void ff_tak_init_crc(void);

int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size);

/**
 * Parse the Streaminfo metadata block.
 * @param[in]  gb pointer to GetBitContext
 * @param[out] s  storage for parsed information
 */
void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s);

/**
 * Validate and decode a frame header.
 * @param      avctx             AVCodecContext to use as av_log() context
 * @param[in]  gb                GetBitContext from which to read frame header
 * @param[out] s                 frame information
 * @param      log_level_offset  log level offset, can be used to silence
 *                               error messages.
 * @return non-zero on error, 0 if OK
 */
int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
                               TAKStreamInfo *s, int log_level_offset);

#endif /* AVCODEC_TAK_H */