ffmpeg / libavcodec / pcm-mpeg.c @ d36beb3f
History | View | Annotate | Download (11.5 KB)
1 |
/*
|
---|---|
2 |
* LPCM codecs for PCM formats found in MPEG streams
|
3 |
* Copyright (c) 2009 Christian Schmidt
|
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 |
/**
|
23 |
* @file
|
24 |
* PCM codecs for encodings found in MPEG streams (DVD/Blu-ray)
|
25 |
*/
|
26 |
|
27 |
#include "libavcore/audioconvert.h" |
28 |
#include "avcodec.h" |
29 |
#include "bytestream.h" |
30 |
|
31 |
/*
|
32 |
* Channel Mapping according to
|
33 |
* Blu-ray Disc Read-Only Format Version 1
|
34 |
* Part 3: Audio Visual Basic Specifications
|
35 |
* mono M1 X
|
36 |
* stereo L R
|
37 |
* 3/0 L R C X
|
38 |
* 2/1 L R S X
|
39 |
* 3/1 L R C S
|
40 |
* 2/2 L R LS RS
|
41 |
* 3/2 L R C LS RS X
|
42 |
* 3/2+lfe L R C LS RS lfe
|
43 |
* 3/4 L R C LS Rls Rrs RS X
|
44 |
* 3/4+lfe L R C LS Rls Rrs RS lfe
|
45 |
*/
|
46 |
|
47 |
/**
|
48 |
* Parse the header of a LPCM frame read from a MPEG-TS stream
|
49 |
* @param avctx the codec context
|
50 |
* @param header pointer to the first four bytes of the data packet
|
51 |
*/
|
52 |
static int pcm_bluray_parse_header(AVCodecContext *avctx, |
53 |
const uint8_t *header)
|
54 |
{ |
55 |
static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; |
56 |
static const uint32_t channel_layouts[16] = { |
57 |
0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, |
58 |
AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0, |
59 |
AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0, AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0 |
60 |
}; |
61 |
static const uint8_t channels[16] = { |
62 |
0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0 |
63 |
}; |
64 |
uint8_t channel_layout = header[2] >> 4; |
65 |
|
66 |
if (avctx->debug & FF_DEBUG_PICT_INFO)
|
67 |
dprintf(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n",
|
68 |
header[0], header[1], header[2], header[3]); |
69 |
|
70 |
/* get the sample depth and derive the sample format from it */
|
71 |
avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; |
72 |
if (!avctx->bits_per_coded_sample) {
|
73 |
av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (0)\n");
|
74 |
return -1; |
75 |
} |
76 |
avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 :
|
77 |
AV_SAMPLE_FMT_S32; |
78 |
|
79 |
/* get the sample rate. Not all values are known or exist. */
|
80 |
switch (header[2] & 0x0f) { |
81 |
case 1: |
82 |
avctx->sample_rate = 48000;
|
83 |
break;
|
84 |
case 4: |
85 |
avctx->sample_rate = 96000;
|
86 |
break;
|
87 |
case 5: |
88 |
avctx->sample_rate = 192000;
|
89 |
break;
|
90 |
default:
|
91 |
avctx->sample_rate = 0;
|
92 |
av_log(avctx, AV_LOG_ERROR, "unsupported sample rate (%d)\n",
|
93 |
header[2] & 0x0f); |
94 |
return -1; |
95 |
} |
96 |
|
97 |
/*
|
98 |
* get the channel number (and mapping). Not all values are known or exist.
|
99 |
* It must be noted that the number of channels in the MPEG stream can
|
100 |
* differ from the actual meaningful number, e.g. mono audio still has two
|
101 |
* channels, one being empty.
|
102 |
*/
|
103 |
avctx->channel_layout = channel_layouts[channel_layout]; |
104 |
avctx->channels = channels[channel_layout]; |
105 |
if (!avctx->channels) {
|
106 |
av_log(avctx, AV_LOG_ERROR, "unsupported channel configuration (%d)\n",
|
107 |
channel_layout); |
108 |
return -1; |
109 |
} |
110 |
|
111 |
avctx->bit_rate = avctx->channels * avctx->sample_rate * |
112 |
avctx->bits_per_coded_sample; |
113 |
|
114 |
if (avctx->debug & FF_DEBUG_PICT_INFO)
|
115 |
dprintf(avctx, |
116 |
"pcm_bluray_parse_header: %d channels, %d bits per sample, %d kHz, %d kbit\n",
|
117 |
avctx->channels, avctx->bits_per_coded_sample, |
118 |
avctx->sample_rate, avctx->bit_rate); |
119 |
return 0; |
120 |
} |
121 |
|
122 |
static int pcm_bluray_decode_frame(AVCodecContext *avctx, |
123 |
void *data,
|
124 |
int *data_size,
|
125 |
AVPacket *avpkt) |
126 |
{ |
127 |
const uint8_t *src = avpkt->data;
|
128 |
int buf_size = avpkt->size;
|
129 |
int num_source_channels, channel, retval;
|
130 |
int sample_size, samples, output_size;
|
131 |
int16_t *dst16 = data; |
132 |
int32_t *dst32 = data; |
133 |
|
134 |
if (buf_size < 4) { |
135 |
av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
|
136 |
return -1; |
137 |
} |
138 |
|
139 |
if (pcm_bluray_parse_header(avctx, src))
|
140 |
return -1; |
141 |
src += 4;
|
142 |
buf_size -= 4;
|
143 |
|
144 |
/* There's always an even number of channels in the source */
|
145 |
num_source_channels = FFALIGN(avctx->channels, 2);
|
146 |
sample_size = (num_source_channels * avctx->bits_per_coded_sample) >> 3;
|
147 |
samples = buf_size / sample_size; |
148 |
|
149 |
output_size = samples * avctx->channels * |
150 |
(avctx->sample_fmt == AV_SAMPLE_FMT_S32 ? 4 : 2); |
151 |
if (output_size > *data_size) {
|
152 |
av_log(avctx, AV_LOG_ERROR, |
153 |
"Insufficient output buffer space (%d bytes, needed %d bytes)\n",
|
154 |
*data_size, output_size); |
155 |
return -1; |
156 |
} |
157 |
*data_size = output_size; |
158 |
|
159 |
if (samples) {
|
160 |
switch (avctx->channel_layout) {
|
161 |
/* cases with same number of source and coded channels */
|
162 |
case AV_CH_LAYOUT_STEREO:
|
163 |
case AV_CH_LAYOUT_4POINT0:
|
164 |
case AV_CH_LAYOUT_2_2:
|
165 |
samples *= num_source_channels; |
166 |
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
|
167 |
#if HAVE_BIGENDIAN
|
168 |
memcpy(dst16, src, output_size); |
169 |
#else
|
170 |
do {
|
171 |
*dst16++ = bytestream_get_be16(&src); |
172 |
} while (--samples);
|
173 |
#endif
|
174 |
} else {
|
175 |
do {
|
176 |
*dst32++ = bytestream_get_be24(&src) << 8;
|
177 |
} while (--samples);
|
178 |
} |
179 |
break;
|
180 |
/* cases where number of source channels = coded channels + 1 */
|
181 |
case AV_CH_LAYOUT_MONO:
|
182 |
case AV_CH_LAYOUT_SURROUND:
|
183 |
case AV_CH_LAYOUT_2_1:
|
184 |
case AV_CH_LAYOUT_5POINT0:
|
185 |
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
|
186 |
do {
|
187 |
#if HAVE_BIGENDIAN
|
188 |
memcpy(dst16, src, avctx->channels * 2);
|
189 |
dst16 += avctx->channels; |
190 |
src += sample_size; |
191 |
#else
|
192 |
channel = avctx->channels; |
193 |
do {
|
194 |
*dst16++ = bytestream_get_be16(&src); |
195 |
} while (--channel);
|
196 |
src += 2;
|
197 |
#endif
|
198 |
} while (--samples);
|
199 |
} else {
|
200 |
do {
|
201 |
channel = avctx->channels; |
202 |
do {
|
203 |
*dst32++ = bytestream_get_be24(&src) << 8;
|
204 |
} while (--channel);
|
205 |
src += 3;
|
206 |
} while (--samples);
|
207 |
} |
208 |
break;
|
209 |
/* remapping: L, R, C, LBack, RBack, LF */
|
210 |
case AV_CH_LAYOUT_5POINT1:
|
211 |
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
|
212 |
do {
|
213 |
dst16[0] = bytestream_get_be16(&src);
|
214 |
dst16[1] = bytestream_get_be16(&src);
|
215 |
dst16[2] = bytestream_get_be16(&src);
|
216 |
dst16[4] = bytestream_get_be16(&src);
|
217 |
dst16[5] = bytestream_get_be16(&src);
|
218 |
dst16[3] = bytestream_get_be16(&src);
|
219 |
dst16 += 6;
|
220 |
} while (--samples);
|
221 |
} else {
|
222 |
do {
|
223 |
dst32[0] = bytestream_get_be24(&src) << 8; |
224 |
dst32[1] = bytestream_get_be24(&src) << 8; |
225 |
dst32[2] = bytestream_get_be24(&src) << 8; |
226 |
dst32[4] = bytestream_get_be24(&src) << 8; |
227 |
dst32[5] = bytestream_get_be24(&src) << 8; |
228 |
dst32[3] = bytestream_get_be24(&src) << 8; |
229 |
dst32 += 6;
|
230 |
} while (--samples);
|
231 |
} |
232 |
break;
|
233 |
/* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */
|
234 |
case AV_CH_LAYOUT_7POINT0:
|
235 |
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
|
236 |
do {
|
237 |
dst16[0] = bytestream_get_be16(&src);
|
238 |
dst16[1] = bytestream_get_be16(&src);
|
239 |
dst16[2] = bytestream_get_be16(&src);
|
240 |
dst16[5] = bytestream_get_be16(&src);
|
241 |
dst16[3] = bytestream_get_be16(&src);
|
242 |
dst16[4] = bytestream_get_be16(&src);
|
243 |
dst16[6] = bytestream_get_be16(&src);
|
244 |
dst16 += 7;
|
245 |
src += 2;
|
246 |
} while (--samples);
|
247 |
} else {
|
248 |
do {
|
249 |
dst32[0] = bytestream_get_be24(&src) << 8; |
250 |
dst32[1] = bytestream_get_be24(&src) << 8; |
251 |
dst32[2] = bytestream_get_be24(&src) << 8; |
252 |
dst32[5] = bytestream_get_be24(&src) << 8; |
253 |
dst32[3] = bytestream_get_be24(&src) << 8; |
254 |
dst32[4] = bytestream_get_be24(&src) << 8; |
255 |
dst32[6] = bytestream_get_be24(&src) << 8; |
256 |
dst32 += 7;
|
257 |
src += 3;
|
258 |
} while (--samples);
|
259 |
} |
260 |
break;
|
261 |
/* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */
|
262 |
case AV_CH_LAYOUT_7POINT1:
|
263 |
if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
|
264 |
do {
|
265 |
dst16[0] = bytestream_get_be16(&src);
|
266 |
dst16[1] = bytestream_get_be16(&src);
|
267 |
dst16[2] = bytestream_get_be16(&src);
|
268 |
dst16[6] = bytestream_get_be16(&src);
|
269 |
dst16[4] = bytestream_get_be16(&src);
|
270 |
dst16[5] = bytestream_get_be16(&src);
|
271 |
dst16[7] = bytestream_get_be16(&src);
|
272 |
dst16[3] = bytestream_get_be16(&src);
|
273 |
dst16 += 8;
|
274 |
} while (--samples);
|
275 |
} else {
|
276 |
do {
|
277 |
dst32[0] = bytestream_get_be24(&src) << 8; |
278 |
dst32[1] = bytestream_get_be24(&src) << 8; |
279 |
dst32[2] = bytestream_get_be24(&src) << 8; |
280 |
dst32[6] = bytestream_get_be24(&src) << 8; |
281 |
dst32[4] = bytestream_get_be24(&src) << 8; |
282 |
dst32[5] = bytestream_get_be24(&src) << 8; |
283 |
dst32[7] = bytestream_get_be24(&src) << 8; |
284 |
dst32[3] = bytestream_get_be24(&src) << 8; |
285 |
dst32 += 8;
|
286 |
} while (--samples);
|
287 |
} |
288 |
break;
|
289 |
} |
290 |
} |
291 |
|
292 |
retval = src - avpkt->data; |
293 |
if (avctx->debug & FF_DEBUG_BITSTREAM)
|
294 |
dprintf(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
|
295 |
retval, *data_size); |
296 |
return retval;
|
297 |
} |
298 |
|
299 |
AVCodec ff_pcm_bluray_decoder = { |
300 |
"pcm_bluray",
|
301 |
AVMEDIA_TYPE_AUDIO, |
302 |
CODEC_ID_PCM_BLURAY, |
303 |
0,
|
304 |
NULL,
|
305 |
NULL,
|
306 |
NULL,
|
307 |
pcm_bluray_decode_frame, |
308 |
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, |
309 |
AV_SAMPLE_FMT_NONE}, |
310 |
.long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
|
311 |
}; |