FFmpeg
pcm-blurayenc.c
Go to the documentation of this file.
1 /*
2  * LPCM codecs for PCM formats found in Blu-ray m2ts streams
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
22 #include "avcodec.h"
23 #include "bytestream.h"
24 #include "codec_internal.h"
25 #include "encode.h"
26 
27 typedef struct BlurayPCMEncContext {
28  uint16_t header; // Header added to every frame
30 
32 {
34  uint8_t ch_layout;
35  int quant, freq, frame_size;
36 
37  switch (avctx->sample_fmt) {
38  case AV_SAMPLE_FMT_S16:
39  avctx->bits_per_coded_sample = 16;
40  frame_size = 240;
41  quant = 1;
42  break;
43  case AV_SAMPLE_FMT_S32:
44  frame_size = 360;
45  avctx->bits_per_coded_sample = 24;
46  quant = 3;
47  break;
48  default:
49  return AVERROR_BUG;
50  }
51 
52  switch (avctx->sample_rate) {
53  case 48000:
54  freq = 1;
55  break;
56  case 96000:
57  freq = 4;
58  break;
59  case 192000:
60  freq = 5;
61  break;
62  default:
63  return AVERROR_BUG;
64  }
65 
66  switch (av_channel_layout_subset(&avctx->ch_layout, ~(uint64_t)0)) {
67  case AV_CH_LAYOUT_MONO:
68  ch_layout = 1;
69  break;
71  ch_layout = 3;
72  break;
74  ch_layout = 4;
75  break;
76  case AV_CH_LAYOUT_2_1:
77  ch_layout = 5;
78  break;
80  ch_layout = 6;
81  break;
82  case AV_CH_LAYOUT_2_2:
83  ch_layout = 7;
84  break;
86  ch_layout = 8;
87  break;
89  ch_layout = 9;
90  break;
92  ch_layout = 10;
93  break;
95  ch_layout = 11;
96  break;
97  default:
98  return AVERROR_BUG;
99  }
100 
101  s->header = (((ch_layout << 4) | freq) << 8) | (quant << 6);
102  avctx->frame_size = frame_size;
103 
104  return 0;
105 }
106 
108  const AVFrame *frame, int *got_packet_ptr)
109 {
110  BlurayPCMEncContext *s = avctx->priv_data;
111  int sample_size, samples, channel, num_dest_channels;
112  const int16_t *src16;
113  const int32_t *src32;
114  unsigned pkt_size;
115  PutByteContext pb;
116  int ret;
117 
118  num_dest_channels = FFALIGN(avctx->ch_layout.nb_channels, 2);
119  sample_size = (num_dest_channels *
120  (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
122 
123  pkt_size = sample_size * samples + 4;
124 
125  if ((ret = ff_get_encode_buffer(avctx, avpkt, pkt_size, 0)) < 0)
126  return ret;
127 
128  AV_WB16(avpkt->data, pkt_size - 4);
129  AV_WB16(avpkt->data + 2, s->header);
130 
131  src16 = (const int16_t *)frame->data[0];
132  src32 = (const int32_t *)frame->data[0];
133 
134  bytestream2_init_writer(&pb, avpkt->data + 4, avpkt->size - 4);
135 
136  switch (avctx->ch_layout.u.mask) {
137  /* cases with same number of source and coded channels */
138  case AV_CH_LAYOUT_STEREO:
140  case AV_CH_LAYOUT_2_2:
141  samples *= num_dest_channels;
142  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
143 #if HAVE_BIGENDIAN
144  bytestream2_put_bufferu(&pb, frame->data[0], samples * 2);
145 #else
146  do {
147  bytestream2_put_be16u(&pb, *src16++);
148  } while (--samples);
149 #endif
150  } else {
151  do {
152  bytestream2_put_be24u(&pb, (*src32++) >> 8);
153  } while (--samples);
154  }
155  break;
156  /* cases where number of source channels = coded channels + 1 */
157  case AV_CH_LAYOUT_MONO:
159  case AV_CH_LAYOUT_2_1:
161  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
162  do {
163 #if HAVE_BIGENDIAN
164  bytestream2_put_bufferu(&pb, (const uint8_t *)src16, avctx->ch_layout.nb_channels * 2);
165  src16 += avctx->ch_layout.nb_channels;
166 #else
167  channel = avctx->ch_layout.nb_channels;
168  do {
169  bytestream2_put_be16u(&pb, *src16++);
170  } while (--channel);
171 #endif
172  bytestream2_put_ne16(&pb, 0);
173  } while (--samples);
174  } else {
175  do {
176  channel = avctx->ch_layout.nb_channels;
177  do {
178  bytestream2_put_be24u(&pb, (*src32++) >> 8);
179  } while (--channel);
180  bytestream2_put_ne24(&pb, 0);
181  } while (--samples);
182  }
183  break;
184  /* remapping: L, R, C, LBack, RBack, LF */
186  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
187  do {
188  bytestream2_put_be16u(&pb, src16[0]);
189  bytestream2_put_be16u(&pb, src16[1]);
190  bytestream2_put_be16u(&pb, src16[2]);
191  bytestream2_put_be16u(&pb, src16[4]);
192  bytestream2_put_be16u(&pb, src16[5]);
193  bytestream2_put_be16u(&pb, src16[3]);
194  src16 += 6;
195  } while (--samples);
196  } else {
197  do {
198  bytestream2_put_be24u(&pb, src32[0] >> 8);
199  bytestream2_put_be24u(&pb, src32[1] >> 8);
200  bytestream2_put_be24u(&pb, src32[2] >> 8);
201  bytestream2_put_be24u(&pb, src32[4] >> 8);
202  bytestream2_put_be24u(&pb, src32[5] >> 8);
203  bytestream2_put_be24u(&pb, src32[3] >> 8);
204  src32 += 6;
205  } while (--samples);
206  }
207  break;
208  /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */
210  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
211  do {
212  bytestream2_put_be16u(&pb, src16[0]);
213  bytestream2_put_be16u(&pb, src16[1]);
214  bytestream2_put_be16u(&pb, src16[2]);
215  bytestream2_put_be16u(&pb, src16[5]);
216  bytestream2_put_be16u(&pb, src16[3]);
217  bytestream2_put_be16u(&pb, src16[4]);
218  bytestream2_put_be16u(&pb, src16[6]);
219  src16 += 7;
220  bytestream2_put_ne16(&pb, 0);
221  } while (--samples);
222  } else {
223  do {
224  bytestream2_put_be24u(&pb, src32[0] >> 8);
225  bytestream2_put_be24u(&pb, src32[1] >> 8);
226  bytestream2_put_be24u(&pb, src32[2] >> 8);
227  bytestream2_put_be24u(&pb, src32[5] >> 8);
228  bytestream2_put_be24u(&pb, src32[3] >> 8);
229  bytestream2_put_be24u(&pb, src32[4] >> 8);
230  bytestream2_put_be24u(&pb, src32[6] >> 8);
231  src32 += 7;
232  bytestream2_put_ne24(&pb, 0);
233  } while (--samples);
234  }
235  break;
236  /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */
238  if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
239  do {
240  bytestream2_put_be16u(&pb, src16[0]);
241  bytestream2_put_be16u(&pb, src16[1]);
242  bytestream2_put_be16u(&pb, src16[2]);
243  bytestream2_put_be16u(&pb, src16[6]);
244  bytestream2_put_be16u(&pb, src16[4]);
245  bytestream2_put_be16u(&pb, src16[5]);
246  bytestream2_put_be16u(&pb, src16[7]);
247  bytestream2_put_be16u(&pb, src16[3]);
248  src16 += 8;
249  } while (--samples);
250  } else {
251  do {
252  bytestream2_put_be24u(&pb, src32[0]);
253  bytestream2_put_be24u(&pb, src32[1]);
254  bytestream2_put_be24u(&pb, src32[2]);
255  bytestream2_put_be24u(&pb, src32[6]);
256  bytestream2_put_be24u(&pb, src32[4]);
257  bytestream2_put_be24u(&pb, src32[5]);
258  bytestream2_put_be24u(&pb, src32[7]);
259  bytestream2_put_be24u(&pb, src32[3]);
260  src32 += 8;
261  } while (--samples);
262  }
263  break;
264  default:
265  return AVERROR_BUG;
266  }
267 
268  *got_packet_ptr = 1;
269 
270  return 0;
271 }
272 
274  .p.name = "pcm_bluray",
275  CODEC_LONG_NAME("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
276  .p.type = AVMEDIA_TYPE_AUDIO,
277  .p.id = AV_CODEC_ID_PCM_BLURAY,
278  .priv_data_size = sizeof(BlurayPCMEncContext),
281  .p.supported_samplerates = (const int[]) { 48000, 96000, 192000, 0 },
282  .p.ch_layouts = (const AVChannelLayout[]) {
293  { 0 } },
294  .p.sample_fmts = (const enum AVSampleFormat[]) {
297 };
AV_CH_LAYOUT_7POINT0
#define AV_CH_LAYOUT_7POINT0
Definition: channel_layout.h:225
AVCodecContext::frame_size
int frame_size
Number of samples per channel in an audio frame.
Definition: avcodec.h:1077
AV_CODEC_ID_PCM_BLURAY
@ AV_CODEC_ID_PCM_BLURAY
Definition: codec_id.h:352
AVChannelLayout::u
union AVChannelLayout::@352 u
Details about which channels are present in this layout.
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:379
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1050
AV_CH_LAYOUT_MONO
#define AV_CH_LAYOUT_MONO
Definition: channel_layout.h:204
AV_CHANNEL_LAYOUT_2_2
#define AV_CHANNEL_LAYOUT_2_2
Definition: channel_layout.h:386
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
pcm_bluray_encode_frame
static int pcm_bluray_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: pcm-blurayenc.c:107
AVPacket::data
uint8_t * data
Definition: packet.h:522
encode.h
BlurayPCMEncContext::header
uint16_t header
Definition: pcm-blurayenc.c:28
FFCodec
Definition: codec_internal.h:127
AVChannelLayout::mask
uint64_t mask
This member must be used for AV_CHANNEL_ORDER_NATIVE, and may be used for AV_CHANNEL_ORDER_AMBISONIC ...
Definition: channel_layout.h:335
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:365
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1065
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:296
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:205
AV_CHANNEL_LAYOUT_SURROUND
#define AV_CHANNEL_LAYOUT_SURROUND
Definition: channel_layout.h:382
quant
static const uint8_t quant[64]
Definition: vmixdec.c:71
av_cold
#define av_cold
Definition: attributes.h:90
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
AV_CHANNEL_LAYOUT_4POINT0
#define AV_CHANNEL_LAYOUT_4POINT0
Definition: channel_layout.h:384
bytestream2_put_ne24
#define bytestream2_put_ne24
Definition: bytestream.h:128
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:401
s
#define s(width, name)
Definition: cbs_vp9.c:198
BlurayPCMEncContext
Definition: pcm-blurayenc.c:27
frame_size
int frame_size
Definition: mxfenc.c:2422
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition: codec.h:159
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
frame
static AVFrame * frame
Definition: demux_decode.c:54
AV_CH_LAYOUT_2_1
#define AV_CH_LAYOUT_2_1
Definition: channel_layout.h:207
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:403
AV_CH_LAYOUT_5POINT1
#define AV_CH_LAYOUT_5POINT1
Definition: channel_layout.h:215
pcm_bluray_encode_init
static av_cold int pcm_bluray_encode_init(AVCodecContext *avctx)
Definition: pcm-blurayenc.c:31
PutByteContext
Definition: bytestream.h:37
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:365
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:523
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
codec_internal.h
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1057
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
ff_pcm_bluray_encoder
const FFCodec ff_pcm_bluray_encoder
Definition: pcm-blurayenc.c:273
AV_CH_LAYOUT_5POINT0
#define AV_CH_LAYOUT_5POINT0
Definition: channel_layout.h:214
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1567
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:424
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
AV_CH_LAYOUT_7POINT1
#define AV_CH_LAYOUT_7POINT1
Definition: channel_layout.h:227
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
avcodec.h
bytestream2_put_ne16
#define bytestream2_put_ne16
Definition: bytestream.h:127
ret
ret
Definition: filter_design.txt:187
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:208
AV_CHANNEL_LAYOUT_7POINT0
#define AV_CHANNEL_LAYOUT_7POINT0
Definition: channel_layout.h:399
AV_CHANNEL_LAYOUT_2_1
#define AV_CHANNEL_LAYOUT_2_1
Definition: channel_layout.h:381
AVCodecContext
main external API structure.
Definition: avcodec.h:445
channel_layout.h
av_channel_layout_subset
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
Definition: channel_layout.c:856
ff_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:105
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:378
bytestream2_put_bufferu
static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:301
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:499
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AV_CH_LAYOUT_4POINT0
#define AV_CH_LAYOUT_4POINT0
Definition: channel_layout.h:210
int32_t
int32_t
Definition: audioconvert.c:56
bytestream.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AV_CHANNEL_LAYOUT_5POINT0
#define AV_CHANNEL_LAYOUT_5POINT0
Definition: channel_layout.h:388
AV_CHANNEL_LAYOUT_5POINT1
#define AV_CHANNEL_LAYOUT_5POINT1
Definition: channel_layout.h:389
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:59
AV_CH_LAYOUT_2_2
#define AV_CH_LAYOUT_2_2
Definition: channel_layout.h:212
channel
channel
Definition: ebur128.h:39