annotate mlp_parser.c @ 7922:ed0ebbb168b6 libavcodec

Do not use the generic "alloc missing references" code for h.264 as it does not work correctly in that case. Fixes issue652.
author michael
date Thu, 25 Sep 2008 14:34:14 +0000
parents fd24c8628221
children 45cfe1d44e86
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
7199
ae8c047d6be5 Add required stdint.h header #include.
diego
parents: 7198
diff changeset
27 #include <stdint.h>
ae8c047d6be5 Add required stdint.h header #include.
diego
parents: 7198
diff changeset
28
6763
f7cbb7733146 Use full path for #includes from another directory.
diego
parents: 5980
diff changeset
29 #include "libavutil/crc.h"
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
30 #include "bitstream.h"
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
31 #include "parser.h"
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
32 #include "mlp_parser.h"
7559
fd24c8628221 mlp: Split common code from parser and decoder to be used by encoder.
ramiro
parents: 7557
diff changeset
33 #include "mlp.h"
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
34
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
35 static const uint8_t mlp_quants[16] = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
36 16, 20, 24, 0, 0, 0, 0, 0,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
37 0, 0, 0, 0, 0, 0, 0, 0,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
38 };
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
39
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
40 static const uint8_t mlp_channels[32] = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
41 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
42 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
43 };
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
44
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
45 static const uint8_t thd_chancount[13] = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
46 // LR C LFE LRs LRvh LRc LRrs Cs Ts LRsd LRw Cvh LFE2
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
47 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
48 };
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
49
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
50 static int mlp_samplerate(int in)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
51 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
52 if (in == 0xF)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
53 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
54
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
55 return (in & 8 ? 44100 : 48000) << (in & 7) ;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
56 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
57
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
58 static int truehd_channels(int chanmap)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
59 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
60 int channels = 0, i;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
61
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
62 for (i = 0; i < 13; i++)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
63 channels += thd_chancount[i] * ((chanmap >> i) & 1);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
64
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
65 return channels;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
66 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
67
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
68 /** Read a major sync info header - contains high level information about
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
69 * the stream - sample rate, channel arrangement etc. Most of this
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
70 * information is not actually necessary for decoding, only for playback.
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
71 * gb must be a freshly initialized GetBitContext with no bits read.
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
72 */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
73
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
74 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
75 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
76 int ratebits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
77 uint16_t checksum;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
78
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
79 assert(get_bits_count(gb) == 0);
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
80
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
81 if (gb->size_in_bits < 28 << 3) {
7198
479fc906650f spelling cosmetics
diego
parents: 7177
diff changeset
82 av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
83 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
84 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
85
7559
fd24c8628221 mlp: Split common code from parser and decoder to be used by encoder.
ramiro
parents: 7557
diff changeset
86 checksum = ff_mlp_checksum16(gb->buffer, 26);
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
87 if (checksum != AV_RL16(gb->buffer+26)) {
7198
479fc906650f spelling cosmetics
diego
parents: 7177
diff changeset
88 av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n");
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
89 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
90 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
91
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
92 if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
93 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
94
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
95 mh->stream_type = get_bits(gb, 8);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
96
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
97 if (mh->stream_type == 0xbb) {
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
98 mh->group1_bits = mlp_quants[get_bits(gb, 4)];
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
99 mh->group2_bits = mlp_quants[get_bits(gb, 4)];
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
100
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
101 ratebits = get_bits(gb, 4);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
102 mh->group1_samplerate = mlp_samplerate(ratebits);
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
103 mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4));
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
104
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
105 skip_bits(gb, 11);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
106
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
107 mh->channels_mlp = get_bits(gb, 5);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
108 } else if (mh->stream_type == 0xba) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
109 mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere?
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
110 mh->group2_bits = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
111
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
112 ratebits = get_bits(gb, 4);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
113 mh->group1_samplerate = mlp_samplerate(ratebits);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
114 mh->group2_samplerate = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
115
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
116 skip_bits(gb, 8);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
117
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
118 mh->channels_thd_stream1 = get_bits(gb, 5);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
119
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
120 skip_bits(gb, 2);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
121
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
122 mh->channels_thd_stream2 = get_bits(gb, 13);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
123 } else
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
124 return -1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
125
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
126 mh->access_unit_size = 40 << (ratebits & 7);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
127 mh->access_unit_size_pow2 = 64 << (ratebits & 7);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
128
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
129 skip_bits_long(gb, 48);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
130
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
131 mh->is_vbr = get_bits1(gb);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
132
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
133 mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4;
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
134
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
135 mh->num_substreams = get_bits(gb, 4);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
136
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
137 skip_bits_long(gb, 4 + 11 * 8);
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
138
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
139 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
140 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
141
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
142 typedef struct MLPParseContext
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
143 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
144 ParseContext pc;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
145
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
146 int bytes_left;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
147
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
148 int in_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
149
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
150 int num_substreams;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
151 } MLPParseContext;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
152
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
153 static int mlp_parse(AVCodecParserContext *s,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
154 AVCodecContext *avctx,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
155 const uint8_t **poutbuf, int *poutbuf_size,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
156 const uint8_t *buf, int buf_size)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
157 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
158 MLPParseContext *mp = s->priv_data;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
159 int sync_present;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
160 uint8_t parity_bits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
161 int next;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
162 int i, p = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
163
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
164 *poutbuf_size = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
165 if (buf_size == 0)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
166 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
167
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
168 if (!mp->in_sync) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
169 // Not in sync - find a major sync header
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
170
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
171 for (i = 0; i < buf_size; i++) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
172 mp->pc.state = (mp->pc.state << 8) | buf[i];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
173 if ((mp->pc.state & 0xfffffffe) == 0xf8726fba) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
174 mp->in_sync = 1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
175 mp->bytes_left = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
176 break;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
177 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
178 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
179
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
180 if (!mp->in_sync) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
181 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
182 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
183 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
184
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
185 ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
186
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
187 return i - 7;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
188 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
189
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
190 if (mp->bytes_left == 0) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
191 // Find length of this packet
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
192
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
193 /* Copy overread bytes from last frame into buffer. */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
194 for(; mp->pc.overread>0; mp->pc.overread--) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
195 mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
196 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
197
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
198 if (mp->pc.index + buf_size < 2) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
199 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
200 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
201 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
202
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
203 mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
204 | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
205 mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
206 mp->bytes_left -= mp->pc.index;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
207 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
208
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
209 next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
210
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
211 if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
212 mp->bytes_left -= buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
213 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
214 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
215
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
216 mp->bytes_left = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
217
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
218 sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
219
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
220 if (!sync_present) {
7177
a82e7d9c8c34 Clarify comment about parity nibble.
ramiro
parents: 7176
diff changeset
221 /* The first nibble of a frame is a parity check of the 4-byte
a82e7d9c8c34 Clarify comment about parity nibble.
ramiro
parents: 7176
diff changeset
222 * access unit header and all the 2- or 4-byte substream headers. */
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
223 // Only check when this isn't a sync frame - syncs have a checksum.
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
224
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
225 parity_bits = 0;
7137
186eb61a9860 Make it a little easier to spot that the code is not dealing only with
ramiro
parents: 6763
diff changeset
226 for (i = -1; i < mp->num_substreams; i++) {
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
227 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
228 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
229
7137
186eb61a9860 Make it a little easier to spot that the code is not dealing only with
ramiro
parents: 6763
diff changeset
230 if (i < 0 || buf[p-2] & 0x80) {
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
231 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
232 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
233 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
234 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
235
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
236 if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
237 av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
238 goto lost_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
239 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
240 } else {
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
241 GetBitContext gb;
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
242 MLPHeaderInfo mh;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
243
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
244 init_get_bits(&gb, buf + 4, (buf_size - 4) << 3);
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
245 if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0)
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
246 goto lost_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
247
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
248 #ifdef CONFIG_AUDIO_NONSHORT
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
249 avctx->bits_per_sample = mh.group1_bits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
250 if (avctx->bits_per_sample > 16)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
251 avctx->sample_fmt = SAMPLE_FMT_S32;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
252 #endif
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
253 avctx->sample_rate = mh.group1_samplerate;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
254 avctx->frame_size = mh.access_unit_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
255
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
256 if (mh.stream_type == 0xbb) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
257 /* MLP stream */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
258 avctx->channels = mlp_channels[mh.channels_mlp];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
259 } else { /* mh.stream_type == 0xba */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
260 /* TrueHD stream */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
261 if (mh.channels_thd_stream2)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
262 avctx->channels = truehd_channels(mh.channels_thd_stream2);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
263 else
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
264 avctx->channels = truehd_channels(mh.channels_thd_stream1);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
265 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
266
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
267 if (!mh.is_vbr) /* Stream is CBR */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
268 avctx->bit_rate = mh.peak_bitrate;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
269
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
270 mp->num_substreams = mh.num_substreams;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
271 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
272
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
273 *poutbuf = buf;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
274 *poutbuf_size = buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
275
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
276 return next;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
277
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
278 lost_sync:
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
279 mp->in_sync = 0;
7154
a9ed669e8cd1 Seek the file forwards instead of backwards when sync is lost.
ramiro
parents: 7137
diff changeset
280 return 1;
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
281 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
282
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
283 AVCodecParser mlp_parser = {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
284 { CODEC_ID_MLP },
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
285 sizeof(MLPParseContext),
7559
fd24c8628221 mlp: Split common code from parser and decoder to be used by encoder.
ramiro
parents: 7557
diff changeset
286 ff_mlp_init_crc2D,
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
287 mlp_parse,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
288 NULL,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
289 };