1/* 2 * MLP codec common code 3 * Copyright (c) 2007-2008 Ian Caulfield 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 <stdint.h> 23 24#include "libavutil/channel_layout.h" 25#include "libavutil/crc.h" 26#include "libavutil/intreadwrite.h" 27#include "libavutil/thread.h" 28#include "mlp.h" 29 30const uint8_t ff_mlp_huffman_tables[3][18][2] = { 31 { /* Huffman table 0, -7 - +10 */ 32 {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, 33 {0x04, 3}, {0x05, 3}, {0x06, 3}, {0x07, 3}, 34 {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, 35 }, { /* Huffman table 1, -7 - +8 */ 36 {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, 37 {0x02, 2}, {0x03, 2}, 38 {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, 39 }, { /* Huffman table 2, -7 - +7 */ 40 {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3}, 41 {0x01, 1}, 42 {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9}, 43 } 44}; 45 46const ChannelInformation ff_mlp_ch_info[21] = { 47 { 0x01, 0x01, 0x00, 0x1f }, { 0x03, 0x02, 0x00, 0x1b }, 48 { 0x07, 0x02, 0x01, 0x1f }, { 0x0F, 0x02, 0x02, 0x19 }, 49 { 0x07, 0x02, 0x01, 0x03 }, { 0x0F, 0x02, 0x02, 0x1f }, 50 { 0x1F, 0x02, 0x03, 0x01 }, { 0x07, 0x02, 0x01, 0x1a }, 51 { 0x0F, 0x02, 0x02, 0x1f }, { 0x1F, 0x02, 0x03, 0x18 }, 52 { 0x0F, 0x02, 0x02, 0x02 }, { 0x1F, 0x02, 0x03, 0x1f }, 53 { 0x3F, 0x02, 0x04, 0x00 }, { 0x0F, 0x03, 0x01, 0x1f }, 54 { 0x1F, 0x03, 0x02, 0x18 }, { 0x0F, 0x03, 0x01, 0x02 }, 55 { 0x1F, 0x03, 0x02, 0x1f }, { 0x3F, 0x03, 0x03, 0x00 }, 56 { 0x1F, 0x04, 0x01, 0x01 }, { 0x1F, 0x04, 0x01, 0x18 }, 57 { 0x3F, 0x04, 0x02, 0x00 }, 58}; 59 60#if FF_API_OLD_CHANNEL_LAYOUT 61const uint64_t ff_mlp_channel_layouts[12] = { 62 AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_2_1, 63 AV_CH_LAYOUT_QUAD, AV_CH_LAYOUT_2POINT1, AV_CH_LAYOUT_SURROUND, 64 AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_3POINT1, 65 AV_CH_LAYOUT_4POINT1, AV_CH_LAYOUT_5POINT1_BACK, 0, 66}; 67#endif 68 69const AVChannelLayout ff_mlp_ch_layouts[12] = { 70 AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_2_1, 71 AV_CHANNEL_LAYOUT_QUAD, AV_CHANNEL_LAYOUT_2POINT1, AV_CHANNEL_LAYOUT_SURROUND, 72 AV_CHANNEL_LAYOUT_4POINT0, AV_CHANNEL_LAYOUT_5POINT0_BACK, AV_CHANNEL_LAYOUT_3POINT1, 73 AV_CHANNEL_LAYOUT_4POINT1, AV_CHANNEL_LAYOUT_5POINT1_BACK, { 0 }, 74}; 75 76#if CONFIG_SMALL 77#define CRC_TABLE_SIZE 257 78#else 79#define CRC_TABLE_SIZE 1024 80#endif 81static AVCRC crc_63[CRC_TABLE_SIZE]; 82static AVCRC crc_1D[CRC_TABLE_SIZE]; 83static AVCRC crc_2D[CRC_TABLE_SIZE]; 84 85static av_cold void mlp_init_crc(void) 86{ 87 av_crc_init(crc_63, 0, 8, 0x63, sizeof(crc_63)); 88 av_crc_init(crc_1D, 0, 8, 0x1D, sizeof(crc_1D)); 89 av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D)); 90} 91 92av_cold void ff_mlp_init_crc(void) 93{ 94 static AVOnce init_static_once = AV_ONCE_INIT; 95 ff_thread_once(&init_static_once, mlp_init_crc); 96} 97 98uint16_t ff_mlp_checksum16(const uint8_t *buf, unsigned int buf_size) 99{ 100 uint16_t crc; 101 102 crc = av_crc(crc_2D, 0, buf, buf_size - 2); 103 crc ^= AV_RL16(buf + buf_size - 2); 104 return crc; 105} 106 107uint8_t ff_mlp_checksum8(const uint8_t *buf, unsigned int buf_size) 108{ 109 uint8_t checksum = av_crc(crc_63, 0x3c, buf, buf_size - 1); // crc_63[0xa2] == 0x3c 110 checksum ^= buf[buf_size-1]; 111 return checksum; 112} 113 114uint8_t ff_mlp_restart_checksum(const uint8_t *buf, unsigned int bit_size) 115{ 116 int i; 117 int num_bytes = (bit_size + 2) / 8; 118 119 int crc = crc_1D[buf[0] & 0x3f]; 120 crc = av_crc(crc_1D, crc, buf + 1, num_bytes - 2); 121 crc ^= buf[num_bytes - 1]; 122 123 for (i = 0; i < ((bit_size + 2) & 7); i++) { 124 crc <<= 1; 125 if (crc & 0x100) 126 crc ^= 0x11D; 127 crc ^= (buf[num_bytes] >> (7 - i)) & 1; 128 } 129 130 return crc; 131} 132 133uint8_t ff_mlp_calculate_parity(const uint8_t *buf, unsigned int buf_size) 134{ 135 uint32_t scratch = 0; 136 const uint8_t *buf_end = buf + buf_size; 137 138 for (; ((intptr_t) buf & 3) && buf < buf_end; buf++) 139 scratch ^= *buf; 140 for (; buf < buf_end - 3; buf += 4) 141 scratch ^= *((const uint32_t*)buf); 142 143 scratch = xor_32_to_8(scratch); 144 145 for (; buf < buf_end; buf++) 146 scratch ^= *buf; 147 148 return scratch; 149} 150