Statistics
| Branch: | Revision:

ffmpeg / libavcodec / pcm-mpeg.c @ dfd2a005

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
        av_dlog(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
        av_dlog(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
        av_dlog(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
};