tak.h 5.9 KB
Newer Older
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 */