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