annotate mlp_parser.c @ 9357:2108342734cc libavcodec

Move av_packet_*() functions from libavformat/ to libavcodec/, where the AVPacket structure now resides also. Patch by Thilo Borgmann thilo.borgmann googlemail com, see the mailinglist thread "Google Summer of Code participation" for additional discussion.
author rbultje
date Tue, 07 Apr 2009 18:31:14 +0000
parents 5b4f4d83431f
children 0dce4fe6e6f3
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 /**
8718
e9d9d946f213 Use full internal pathname in doxygen @file directives.
diego
parents: 8276
diff changeset
23 * @file libavcodec/mlp_parser.c
5954
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
8248
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
153 static av_cold int mlp_init(AVCodecParserContext *s)
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
154 {
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
155 ff_mlp_init_crc();
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
156 return 0;
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
157 }
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
158
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
159 static int mlp_parse(AVCodecParserContext *s,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
160 AVCodecContext *avctx,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
161 const uint8_t **poutbuf, int *poutbuf_size,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
162 const uint8_t *buf, int buf_size)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
163 {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
164 MLPParseContext *mp = s->priv_data;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
165 int sync_present;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
166 uint8_t parity_bits;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
167 int next;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
168 int i, p = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
169
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
170 *poutbuf_size = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
171 if (buf_size == 0)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
172 return 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
173
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
174 if (!mp->in_sync) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
175 // Not in sync - find a major sync header
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
176
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
177 for (i = 0; i < buf_size; i++) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
178 mp->pc.state = (mp->pc.state << 8) | buf[i];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
179 if ((mp->pc.state & 0xfffffffe) == 0xf8726fba) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
180 mp->in_sync = 1;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
181 mp->bytes_left = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
182 break;
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
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
186 if (!mp->in_sync) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
187 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
188 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
189 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
190
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
191 ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
192
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
193 return i - 7;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
194 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
195
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
196 if (mp->bytes_left == 0) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
197 // Find length of this packet
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
198
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
199 /* Copy overread bytes from last frame into buffer. */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
200 for(; mp->pc.overread>0; mp->pc.overread--) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
201 mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
202 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
203
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
204 if (mp->pc.index + buf_size < 2) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
205 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
206 return buf_size;
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 mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
210 | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
211 mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
212 mp->bytes_left -= mp->pc.index;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
213 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
214
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
215 next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
216
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
217 if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
218 mp->bytes_left -= buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
219 return buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
220 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
221
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
222 mp->bytes_left = 0;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
223
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
224 sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
225
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
226 if (!sync_present) {
7177
a82e7d9c8c34 Clarify comment about parity nibble.
ramiro
parents: 7176
diff changeset
227 /* 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
228 * access unit header and all the 2- or 4-byte substream headers. */
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
229 // Only check when this isn't a sync frame - syncs have a checksum.
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
230
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
231 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
232 for (i = -1; i < mp->num_substreams; i++) {
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
233 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
234 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
235
7137
186eb61a9860 Make it a little easier to spot that the code is not dealing only with
ramiro
parents: 6763
diff changeset
236 if (i < 0 || buf[p-2] & 0x80) {
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
237 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
238 parity_bits ^= buf[p++];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
239 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
240 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
241
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
242 if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
5980
3055403f0e57 cosmetics: spelling fixes
diego
parents: 5954
diff changeset
243 av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
244 goto lost_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
245 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
246 } else {
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
247 GetBitContext gb;
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
248 MLPHeaderInfo mh;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
249
7176
ae78650d4ac8 Make ff_mlp_read_major_sync() take a GetBitContext instead of buffers.
ramiro
parents: 7154
diff changeset
250 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
251 if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0)
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
252 goto lost_sync;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
253
8274
82dbfe8d2e0b mlp: Fix compilation under CONFIG_AUDIO_NONSHORT.
ramiro
parents: 8248
diff changeset
254 avctx->bits_per_raw_sample = mh.group1_bits;
82dbfe8d2e0b mlp: Fix compilation under CONFIG_AUDIO_NONSHORT.
ramiro
parents: 8248
diff changeset
255 if (avctx->bits_per_raw_sample > 16)
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
256 avctx->sample_fmt = SAMPLE_FMT_S32;
8276
9149588e5cc9 mlp: support bit-depths greater than 16 by default.
ramiro
parents: 8274
diff changeset
257 else
9149588e5cc9 mlp: support bit-depths greater than 16 by default.
ramiro
parents: 8274
diff changeset
258 avctx->sample_fmt = SAMPLE_FMT_S16;
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
259 avctx->sample_rate = mh.group1_samplerate;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
260 avctx->frame_size = mh.access_unit_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
261
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
262 if (mh.stream_type == 0xbb) {
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
263 /* MLP stream */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
264 avctx->channels = mlp_channels[mh.channels_mlp];
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
265 } else { /* mh.stream_type == 0xba */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
266 /* TrueHD stream */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
267 if (mh.channels_thd_stream2)
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
268 avctx->channels = truehd_channels(mh.channels_thd_stream2);
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
269 else
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
270 avctx->channels = truehd_channels(mh.channels_thd_stream1);
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 if (!mh.is_vbr) /* Stream is CBR */
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
274 avctx->bit_rate = mh.peak_bitrate;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
275
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
276 mp->num_substreams = mh.num_substreams;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
277 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
278
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
279 *poutbuf = buf;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
280 *poutbuf_size = buf_size;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
281
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
282 return next;
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
283
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
284 lost_sync:
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
285 mp->in_sync = 0;
7154
a9ed669e8cd1 Seek the file forwards instead of backwards when sync is lost.
ramiro
parents: 7137
diff changeset
286 return 1;
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
287 }
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
288
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
289 AVCodecParser mlp_parser = {
9190
5b4f4d83431f Split TrueHD decoder from MLP
ramiro
parents: 8718
diff changeset
290 { CODEC_ID_MLP, CODEC_ID_TRUEHD },
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
291 sizeof(MLPParseContext),
8248
45cfe1d44e86 mlp: initialize all CRC tables in a common function.
ramiro
parents: 7559
diff changeset
292 mlp_init,
5954
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
293 mlp_parse,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
294 NULL,
aafe67fa196f MLP/TrueHD parser
cehoyos
parents:
diff changeset
295 };