FFmpeg
pcm-bluray.c
Go to the documentation of this file.
1 /*
2  * LPCM codecs for PCM format found in Blu-ray PCM streams
3  * Copyright (c) 2009, 2013 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 codec for Blu-ray PCM audio tracks
25  */
26 
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "internal.h"
31 
32 /*
33  * Channel Mapping according to
34  * Blu-ray Disc Read-Only Format Version 1
35  * Part 3: Audio Visual Basic Specifications
36  * mono M1 X
37  * stereo L R
38  * 3/0 L R C X
39  * 2/1 L R S X
40  * 3/1 L R C S
41  * 2/2 L R LS RS
42  * 3/2 L R C LS RS X
43  * 3/2+lfe L R C LS RS lfe
44  * 3/4 L R C LS Rls Rrs RS X
45  * 3/4+lfe L R C LS Rls Rrs RS lfe
46  */
47 
48 /**
49  * Parse the header of a LPCM frame read from a Blu-ray MPEG-TS stream
50  * @param avctx the codec context
51  * @param header pointer to the first four bytes of the data packet
52  */
54  const uint8_t *header)
55 {
56  static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 };
57  static const uint32_t channel_layouts[16] = {
61  AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0
62  };
63  static const uint8_t channels[16] = {
64  0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0
65  };
66  uint8_t channel_layout = header[2] >> 4;
67 
68  if (avctx->debug & FF_DEBUG_PICT_INFO)
69  ff_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n",
70  header[0], header[1], header[2], header[3]);
71 
72  /* get the sample depth and derive the sample format from it */
73  avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6];
74  if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) {
75  av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample);
76  return AVERROR_INVALIDDATA;
77  }
78  avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16
80  if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
82 
83  /* get the sample rate. Not all values are used. */
84  switch (header[2] & 0x0f) {
85  case 1:
86  avctx->sample_rate = 48000;
87  break;
88  case 4:
89  avctx->sample_rate = 96000;
90  break;
91  case 5:
92  avctx->sample_rate = 192000;
93  break;
94  default:
95  avctx->sample_rate = 0;
96  av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n",
97  header[2] & 0x0f);
98  return AVERROR_INVALIDDATA;
99  }
100 
101  /*
102  * get the channel number (and mapping). Not all values are used.
103  * It must be noted that the number of channels in the MPEG stream can
104  * differ from the actual meaningful number, e.g. mono audio still has two
105  * channels, one being empty.
106  */
107  avctx->channel_layout = channel_layouts[channel_layout];
108  avctx->channels = channels[channel_layout];
109  if (!avctx->channels) {
110  av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n",
111  channel_layout);
112  return AVERROR_INVALIDDATA;
113  }
114 
115  avctx->bit_rate = FFALIGN(avctx->channels, 2) * avctx->sample_rate *
116  avctx->bits_per_coded_sample;
117 
118  if (avctx->debug & FF_DEBUG_PICT_INFO)
119  ff_dlog(avctx,
120  "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %"PRId64" bit/s\n",
121  avctx->channels, avctx->bits_per_coded_sample,
122  avctx->sample_rate, avctx->bit_rate);
123  return 0;
124 }
125 
126 static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
127  int *got_frame_ptr, AVPacket *avpkt)
128 {
129  AVFrame *frame = data;
130  const uint8_t *src = avpkt->data;
131  int buf_size = avpkt->size;
132  GetByteContext gb;
133  int num_source_channels, channel, retval;
134  int sample_size, samples;
135  int16_t *dst16;
136  int32_t *dst32;
137 
138  if (buf_size < 4) {
139  av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
140  return AVERROR_INVALIDDATA;
141  }
142 
143  if ((retval = pcm_bluray_parse_header(avctx, src)))
144  return retval;
145  src += 4;
146  buf_size -= 4;
147 
148  bytestream2_init(&gb, src, buf_size);
149 
150  /* There's always an even number of channels in the source */
151  num_source_channels = FFALIGN(avctx->channels, 2);
152  sample_size = (num_source_channels *
153  (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
154  samples = buf_size / sample_size;
155 
156  /* get output buffer */
157  frame->nb_samples = samples;
158  if ((retval = ff_get_buffer(avctx, frame, 0)) < 0)
159  return retval;
160  dst16 = (int16_t *)frame->data[0];
161  dst32 = (int32_t *)frame->data[0];
162 
163  if (samples) {
164  switch (avctx->channel_layout) {
165  /* cases with same number of source and coded channels */
166  case AV_CH_LAYOUT_STEREO:
168  case AV_CH_LAYOUT_2_2:
169  samples *= num_source_channels;
170  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
171 #if HAVE_BIGENDIAN
172  bytestream2_get_buffer(&gb, dst16, buf_size);
173 #else
174  do {
175  *dst16++ = bytestream2_get_be16u(&gb);
176  } while (--samples);
177 #endif
178  } else {
179  do {
180  *dst32++ = bytestream2_get_be24u(&gb) << 8;
181  } while (--samples);
182  }
183  break;
184  /* cases where number of source channels = coded channels + 1 */
185  case AV_CH_LAYOUT_MONO:
187  case AV_CH_LAYOUT_2_1:
189  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
190  do {
191 #if HAVE_BIGENDIAN
192  bytestream2_get_buffer(&gb, dst16, avctx->channels * 2);
193  dst16 += avctx->channels;
194 #else
195  channel = avctx->channels;
196  do {
197  *dst16++ = bytestream2_get_be16u(&gb);
198  } while (--channel);
199 #endif
200  bytestream2_skip(&gb, 2);
201  } while (--samples);
202  } else {
203  do {
204  channel = avctx->channels;
205  do {
206  *dst32++ = bytestream2_get_be24u(&gb) << 8;
207  } while (--channel);
208  bytestream2_skip(&gb, 3);
209  } while (--samples);
210  }
211  break;
212  /* remapping: L, R, C, LBack, RBack, LF */
214  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
215  do {
216  dst16[0] = bytestream2_get_be16u(&gb);
217  dst16[1] = bytestream2_get_be16u(&gb);
218  dst16[2] = bytestream2_get_be16u(&gb);
219  dst16[4] = bytestream2_get_be16u(&gb);
220  dst16[5] = bytestream2_get_be16u(&gb);
221  dst16[3] = bytestream2_get_be16u(&gb);
222  dst16 += 6;
223  } while (--samples);
224  } else {
225  do {
226  dst32[0] = bytestream2_get_be24u(&gb) << 8;
227  dst32[1] = bytestream2_get_be24u(&gb) << 8;
228  dst32[2] = bytestream2_get_be24u(&gb) << 8;
229  dst32[4] = bytestream2_get_be24u(&gb) << 8;
230  dst32[5] = bytestream2_get_be24u(&gb) << 8;
231  dst32[3] = bytestream2_get_be24u(&gb) << 8;
232  dst32 += 6;
233  } while (--samples);
234  }
235  break;
236  /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */
238  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
239  do {
240  dst16[0] = bytestream2_get_be16u(&gb);
241  dst16[1] = bytestream2_get_be16u(&gb);
242  dst16[2] = bytestream2_get_be16u(&gb);
243  dst16[5] = bytestream2_get_be16u(&gb);
244  dst16[3] = bytestream2_get_be16u(&gb);
245  dst16[4] = bytestream2_get_be16u(&gb);
246  dst16[6] = bytestream2_get_be16u(&gb);
247  dst16 += 7;
248  bytestream2_skip(&gb, 2);
249  } while (--samples);
250  } else {
251  do {
252  dst32[0] = bytestream2_get_be24u(&gb) << 8;
253  dst32[1] = bytestream2_get_be24u(&gb) << 8;
254  dst32[2] = bytestream2_get_be24u(&gb) << 8;
255  dst32[5] = bytestream2_get_be24u(&gb) << 8;
256  dst32[3] = bytestream2_get_be24u(&gb) << 8;
257  dst32[4] = bytestream2_get_be24u(&gb) << 8;
258  dst32[6] = bytestream2_get_be24u(&gb) << 8;
259  dst32 += 7;
260  bytestream2_skip(&gb, 3);
261  } while (--samples);
262  }
263  break;
264  /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */
266  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
267  do {
268  dst16[0] = bytestream2_get_be16u(&gb);
269  dst16[1] = bytestream2_get_be16u(&gb);
270  dst16[2] = bytestream2_get_be16u(&gb);
271  dst16[6] = bytestream2_get_be16u(&gb);
272  dst16[4] = bytestream2_get_be16u(&gb);
273  dst16[5] = bytestream2_get_be16u(&gb);
274  dst16[7] = bytestream2_get_be16u(&gb);
275  dst16[3] = bytestream2_get_be16u(&gb);
276  dst16 += 8;
277  } while (--samples);
278  } else {
279  do {
280  dst32[0] = bytestream2_get_be24u(&gb) << 8;
281  dst32[1] = bytestream2_get_be24u(&gb) << 8;
282  dst32[2] = bytestream2_get_be24u(&gb) << 8;
283  dst32[6] = bytestream2_get_be24u(&gb) << 8;
284  dst32[4] = bytestream2_get_be24u(&gb) << 8;
285  dst32[5] = bytestream2_get_be24u(&gb) << 8;
286  dst32[7] = bytestream2_get_be24u(&gb) << 8;
287  dst32[3] = bytestream2_get_be24u(&gb) << 8;
288  dst32 += 8;
289  } while (--samples);
290  }
291  break;
292  }
293  }
294 
295  *got_frame_ptr = 1;
296 
297  retval = bytestream2_tell(&gb);
298  if (avctx->debug & FF_DEBUG_BITSTREAM)
299  ff_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
300  retval, buf_size);
301  return retval + 4;
302 }
303 
305  .name = "pcm_bluray",
306  .long_name = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
307  .type = AVMEDIA_TYPE_AUDIO,
309  .decode = pcm_bluray_decode_frame,
311  .sample_fmts = (const enum AVSampleFormat[]){
313  },
314 };
AV_CH_LAYOUT_7POINT0
#define AV_CH_LAYOUT_7POINT0
Definition: channel_layout.h:110
AVCodec
AVCodec.
Definition: codec.h:202
AV_CODEC_ID_PCM_BLURAY
@ AV_CODEC_ID_PCM_BLURAY
Definition: codec_id.h:338
AVCodecContext::channel_layout
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:1043
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:992
GetByteContext
Definition: bytestream.h:33
AV_CH_LAYOUT_MONO
#define AV_CH_LAYOUT_MONO
Definition: channel_layout.h:90
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
data
const char data[16]
Definition: mxf.c:143
FF_DEBUG_PICT_INFO
#define FF_DEBUG_PICT_INFO
Definition: avcodec.h:1303
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:91
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1425
channels
channels
Definition: aptx.h:33
AV_CH_LAYOUT_2_1
#define AV_CH_LAYOUT_2_1
Definition: channel_layout.h:93
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:433
src
#define src
Definition: vp8dsp.c:255
AV_CH_LAYOUT_5POINT1
#define AV_CH_LAYOUT_5POINT1
Definition: channel_layout.h:101
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
AV_CODEC_CAP_CHANNEL_CONF
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition: codec.h:109
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:29
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1652
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1000
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
pcm_bluray_decode_frame
static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: pcm-bluray.c:126
header
static const uint8_t header[24]
Definition: sdr2.c:67
AVCodecContext::channels
int channels
number of audio channels
Definition: avcodec.h:993
AV_CH_LAYOUT_5POINT0
#define AV_CH_LAYOUT_5POINT0
Definition: channel_layout.h:100
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1418
ff_pcm_bluray_decoder
const AVCodec ff_pcm_bluray_decoder
Definition: pcm-bluray.c:304
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AV_CH_LAYOUT_7POINT1
#define AV_CH_LAYOUT_7POINT1
Definition: channel_layout.h:112
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
pcm_bluray_parse_header
static int pcm_bluray_parse_header(AVCodecContext *avctx, const uint8_t *header)
Parse the header of a LPCM frame read from a Blu-ray MPEG-TS stream.
Definition: pcm-bluray.c:53
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
avcodec.h
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:94
AVCodecContext
main external API structure.
Definition: avcodec.h:383
channel_layout.h
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AVCodecContext::debug
int debug
debug
Definition: avcodec.h:1302
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:350
channel_layouts
static const uint16_t channel_layouts[7]
Definition: dca_lbr.c:114
AV_CH_LAYOUT_4POINT0
#define AV_CH_LAYOUT_4POINT0
Definition: channel_layout.h:96
int32_t
int32_t
Definition: audioconvert.c:56
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
FF_DEBUG_BITSTREAM
#define FF_DEBUG_BITSTREAM
Definition: avcodec.h:1305
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:62
AV_CH_LAYOUT_2_2
#define AV_CH_LAYOUT_2_2
Definition: channel_layout.h:98
channel
channel
Definition: ebur128.h:39