annotate mlp_parser.c @ 6170:8cbfc9d75833 libavcodec

Put some disabled functions that are only used in the test program in cabac.c under TEST as preprocessor conditional, same as the test program.
author diego
date Wed, 23 Jan 2008 10:19:39 +0000
parents 3055403f0e57
children f7cbb7733146
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
1 /*
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
2 * MLP parser
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
3 * Copyright (c) 2007 Ian Caulfield
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
4 *
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
5 * This file is part of FFmpeg.
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
6 *
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
11 *
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
15 * Lesser General Public License for more details.
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
16 *
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
20 */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
21
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
22 /**
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
23 * @file mlp_parser.c
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
24 * MLP parser
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
25 */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
26
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
27 #include "bitstream.h"
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
28 #include "parser.h"
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
29 #include "crc.h"
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
30 #include "mlp_parser.h"
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
31
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
32 static const uint8_t mlp_quants[16] = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
33 16, 20, 24, 0, 0, 0, 0, 0,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
34 0, 0, 0, 0, 0, 0, 0, 0,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
35 };
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
36
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
37 static const uint8_t mlp_channels[32] = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
38 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
39 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
40 };
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
41
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
42 static const uint8_t thd_chancount[13] = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
43 // LR C LFE LRs LRvh LRc LRrs Cs Ts LRsd LRw Cvh LFE2
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
44 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
45 };
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
46
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
47 static int mlp_samplerate(int in)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
48 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
49 if (in == 0xF)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
50 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
51
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
52 return (in & 8 ? 44100 : 48000) << (in & 7) ;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
53 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
54
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
55 static int truehd_channels(int chanmap)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
56 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
57 int channels = 0, i;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
58
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
59 for (i = 0; i < 13; i++)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
60 channels += thd_chancount[i] * ((chanmap >> i) & 1);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
61
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
62 return channels;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
63 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
64
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
65 static int crc_init = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
66 static AVCRC crc_2D[1024];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
67
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
68 /** MLP uses checksums that seem to be based on the standard CRC algorithm,
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
69 * but not (in implementation terms, the table lookup and XOR are reversed).
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
70 * We can implement this behavior using a standard av_crc on all but the
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
71 * last element, then XOR that with the last element.
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
72 */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
73
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
74 static uint16_t mlp_checksum16(const uint8_t *buf, unsigned int buf_size)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
75 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
76 uint16_t crc;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
77
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
78 if (!crc_init) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
79 av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D));
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
80 crc_init = 1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
81 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
82
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
83 crc = av_crc(crc_2D, 0, buf, buf_size - 2);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
84 crc ^= AV_RL16(buf + buf_size - 2);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
85 return crc;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
86 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
87
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
88 /** Read a major sync info header - contains high level information about
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
89 * the stream - sample rate, channel arrangement etc. Most of this
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
90 * information is not actually necessary for decoding, only for playback.
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
91 */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
92
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
93 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, const uint8_t *buf,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
94 unsigned int buf_size)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
95 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
96 GetBitContext gb;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
97 int ratebits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
98 uint16_t checksum;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
99
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
100 if (buf_size < 28) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
101 av_log(log, AV_LOG_ERROR, "Packet too short, unable to read major sync\n");
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
102 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
103 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
104
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
105 checksum = mlp_checksum16(buf, 26);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
106 if (checksum != AV_RL16(buf+26)) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
107 av_log(log, AV_LOG_ERROR, "Major sync info header checksum error\n");
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
108 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
109 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
110
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
111 init_get_bits(&gb, buf, buf_size * 8);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
112
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
113 if (get_bits_long(&gb, 24) != 0xf8726f) /* Sync words */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
114 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
115
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
116 mh->stream_type = get_bits(&gb, 8);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
117
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
118 if (mh->stream_type == 0xbb) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
119 mh->group1_bits = mlp_quants[get_bits(&gb, 4)];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
120 mh->group2_bits = mlp_quants[get_bits(&gb, 4)];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
121
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
122 ratebits = get_bits(&gb, 4);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
123 mh->group1_samplerate = mlp_samplerate(ratebits);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
124 mh->group2_samplerate = mlp_samplerate(get_bits(&gb, 4));
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
125
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
126 skip_bits(&gb, 11);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
127
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
128 mh->channels_mlp = get_bits(&gb, 5);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
129 } else if (mh->stream_type == 0xba) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
130 mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere?
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
131 mh->group2_bits = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
132
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
133 ratebits = get_bits(&gb, 4);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
134 mh->group1_samplerate = mlp_samplerate(ratebits);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
135 mh->group2_samplerate = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
136
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
137 skip_bits(&gb, 8);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
138
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
139 mh->channels_thd_stream1 = get_bits(&gb, 5);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
140
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
141 skip_bits(&gb, 2);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
142
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
143 mh->channels_thd_stream2 = get_bits(&gb, 13);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
144 } else
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
145 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
146
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
147 mh->access_unit_size = 40 << (ratebits & 7);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
148 mh->access_unit_size_pow2 = 64 << (ratebits & 7);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
149
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
150 skip_bits_long(&gb, 48);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
151
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
152 mh->is_vbr = get_bits1(&gb);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
153
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
154 mh->peak_bitrate = (get_bits(&gb, 15) * mh->group1_samplerate + 8) >> 4;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
155
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
156 mh->num_substreams = get_bits(&gb, 4);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
157
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
158 skip_bits_long(&gb, 4 + 11 * 8);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
159
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
160 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
161 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
162
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
163 typedef struct MLPParseContext
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
164 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
165 ParseContext pc;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
166
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
167 int bytes_left;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
168
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
169 int in_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
170
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
171 int num_substreams;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
172 } MLPParseContext;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
173
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
174 static int mlp_parse(AVCodecParserContext *s,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
175 AVCodecContext *avctx,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
176 const uint8_t **poutbuf, int *poutbuf_size,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
177 const uint8_t *buf, int buf_size)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
178 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
179 MLPParseContext *mp = s->priv_data;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
180 int sync_present;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
181 uint8_t parity_bits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
182 int next;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
183 int i, p = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
184
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
185 *poutbuf_size = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
186 if (buf_size == 0)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
187 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
188
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
189 if (!mp->in_sync) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
190 // Not in sync - find a major sync header
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
191
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
192 for (i = 0; i < buf_size; i++) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
193 mp->pc.state = (mp->pc.state << 8) | buf[i];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
194 if ((mp->pc.state & 0xfffffffe) == 0xf8726fba) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
195 mp->in_sync = 1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
196 mp->bytes_left = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
197 break;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
198 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
199 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
200
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
201 if (!mp->in_sync) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
202 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
203 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
204 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
205
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
206 ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
207
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
208 return i - 7;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
209 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
210
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
211 if (mp->bytes_left == 0) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
212 // Find length of this packet
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
213
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
214 /* Copy overread bytes from last frame into buffer. */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
215 for(; mp->pc.overread>0; mp->pc.overread--) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
216 mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
217 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
218
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
219 if (mp->pc.index + buf_size < 2) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
220 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
221 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
222 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
223
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
224 mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
225 | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
226 mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
227 mp->bytes_left -= mp->pc.index;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
228 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
229
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
230 next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
231
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
232 if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
233 mp->bytes_left -= buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
234 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
235 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
236
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
237 mp->bytes_left = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
238
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
239 sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
240
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
241 if (!sync_present) {
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
242 // First nibble of a frame is a parity check of the first few nibbles.
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
243 // Only check when this isn't a sync frame - syncs have a checksum.
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
244
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
245 parity_bits = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
246 for (i = 0; i <= mp->num_substreams; i++) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
247 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
248 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
249
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
250 if (i == 0 || buf[p-2] & 0x80) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
251 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
252 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
253 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
254 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
255
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
256 if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
257 av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
258 goto lost_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
259 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
260 } else {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
261 MLPHeaderInfo mh;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
262
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
263 if (ff_mlp_read_major_sync(avctx, &mh, buf + 4, buf_size - 4) < 0)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
264 goto lost_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
265
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
266 #ifdef CONFIG_AUDIO_NONSHORT
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
267 avctx->bits_per_sample = mh.group1_bits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
268 if (avctx->bits_per_sample > 16)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
269 avctx->sample_fmt = SAMPLE_FMT_S32;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
270 #endif
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
271 avctx->sample_rate = mh.group1_samplerate;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
272 avctx->frame_size = mh.access_unit_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
273
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
274 if (mh.stream_type == 0xbb) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
275 /* MLP stream */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
276 avctx->channels = mlp_channels[mh.channels_mlp];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
277 } else { /* mh.stream_type == 0xba */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
278 /* TrueHD stream */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
279 if (mh.channels_thd_stream2)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
280 avctx->channels = truehd_channels(mh.channels_thd_stream2);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
281 else
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
282 avctx->channels = truehd_channels(mh.channels_thd_stream1);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
283 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
284
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
285 if (!mh.is_vbr) /* Stream is CBR */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
286 avctx->bit_rate = mh.peak_bitrate;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
287
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
288 mp->num_substreams = mh.num_substreams;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
289 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
290
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
291 *poutbuf = buf;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
292 *poutbuf_size = buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
293
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
294 return next;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
295
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
296 lost_sync:
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
297 mp->in_sync = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
298 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
299 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
300
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
301 AVCodecParser mlp_parser = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
302 { CODEC_ID_MLP },
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
303 sizeof(MLPParseContext),
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
304 NULL,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
305 mlp_parse,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
306 NULL,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
307 };