FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
libdcadec.c
Go to the documentation of this file.
1 /*
2  * libdcadec decoder wrapper
3  * Copyright (C) 2015 Hendrik Leppkes
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 #include <libdcadec/dca_context.h>
23 
25 #include "libavutil/common.h"
26 #include "libavutil/opt.h"
27 
28 #include "avcodec.h"
29 #include "dca.h"
30 #include "dca_syncwords.h"
31 #include "internal.h"
32 
33 typedef struct DCADecContext {
34  struct dcadec_context *ctx;
39 
40 static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
41  int *got_frame_ptr, AVPacket *avpkt)
42 {
43  DCADecContext *s = avctx->priv_data;
44  AVFrame *frame = data;
45  av_unused struct dcadec_exss_info *exss;
46  int ret, i, k;
47  int **samples, nsamples, channel_mask, sample_rate, bits_per_sample, profile;
48  uint32_t mrk;
49  uint8_t *input = avpkt->data;
50  int input_size = avpkt->size;
51 
52  /* convert bytestream syntax to RAW BE format if required */
53  if (input_size < 8) {
54  av_log(avctx, AV_LOG_ERROR, "Input size too small\n");
55  return AVERROR_INVALIDDATA;
56  }
57  mrk = AV_RB32(input);
58  if (mrk != DCA_SYNCWORD_CORE_BE && mrk != DCA_SYNCWORD_SUBSTREAM) {
60  if (!s->buffer)
61  return AVERROR(ENOMEM);
62 
63  for (i = 0, ret = AVERROR_INVALIDDATA; i < input_size - 3 && ret < 0; i++)
64  ret = avpriv_dca_convert_bitstream(input + i, input_size - i, s->buffer, s->buffer_size);
65 
66  if (ret < 0)
67  return ret;
68 
69  input = s->buffer;
70  input_size = ret;
71  }
72 
73  if ((ret = dcadec_context_parse(s->ctx, input, input_size)) < 0) {
74  av_log(avctx, AV_LOG_ERROR, "dcadec_context_parse() failed: %d (%s)\n", -ret, dcadec_strerror(ret));
75  return AVERROR_EXTERNAL;
76  }
77  if ((ret = dcadec_context_filter(s->ctx, &samples, &nsamples, &channel_mask,
78  &sample_rate, &bits_per_sample, &profile)) < 0) {
79  av_log(avctx, AV_LOG_ERROR, "dcadec_context_filter() failed: %d (%s)\n", -ret, dcadec_strerror(ret));
80  return AVERROR_EXTERNAL;
81  }
82 
83  avctx->channels = av_get_channel_layout_nb_channels(channel_mask);
84  avctx->channel_layout = channel_mask;
85  avctx->sample_rate = sample_rate;
86 
87  if (bits_per_sample == 16)
89  else if (bits_per_sample > 16 && bits_per_sample <= 24)
91  else {
92  av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits per sample: %d\n",
93  bits_per_sample);
94  return AVERROR(ENOSYS);
95  }
96 
97  avctx->bits_per_raw_sample = bits_per_sample;
98 
99  switch (profile) {
100  case DCADEC_PROFILE_DS:
101  avctx->profile = FF_PROFILE_DTS;
102  break;
103  case DCADEC_PROFILE_DS_96_24:
104  avctx->profile = FF_PROFILE_DTS_96_24;
105  break;
106  case DCADEC_PROFILE_DS_ES:
107  avctx->profile = FF_PROFILE_DTS_ES;
108  break;
109  case DCADEC_PROFILE_HD_HRA:
111  break;
112  case DCADEC_PROFILE_HD_MA:
113  avctx->profile = FF_PROFILE_DTS_HD_MA;
114  break;
115  case DCADEC_PROFILE_EXPRESS:
117  break;
118  case DCADEC_PROFILE_UNKNOWN:
119  default:
120  avctx->profile = FF_PROFILE_UNKNOWN;
121  break;
122  }
123 
124  /* bitrate is only meaningful if there are no HD extensions, as they distort the bitrate */
125  if (profile == DCADEC_PROFILE_DS || profile == DCADEC_PROFILE_DS_96_24 || profile == DCADEC_PROFILE_DS_ES) {
126  struct dcadec_core_info *info = dcadec_context_get_core_info(s->ctx);
127  avctx->bit_rate = info->bit_rate;
128  dcadec_context_free_core_info(info);
129  } else
130  avctx->bit_rate = 0;
131 
132 #if HAVE_STRUCT_DCADEC_EXSS_INFO_MATRIX_ENCODING
133  if (exss = dcadec_context_get_exss_info(s->ctx)) {
134  enum AVMatrixEncoding matrix_encoding = AV_MATRIX_ENCODING_NONE;
135 
136  if (!s->downmix_warned) {
137  uint64_t layout = avctx->request_channel_layout;
138 
139  if (((layout == AV_CH_LAYOUT_STEREO_DOWNMIX || layout == AV_CH_LAYOUT_STEREO) && !exss->embedded_stereo) ||
140  ( layout == AV_CH_LAYOUT_5POINT1 && !exss->embedded_6ch))
141  av_log(avctx, AV_LOG_WARNING, "%s downmix was requested but no custom coefficients are available, "
142  "this may result in clipping\n",
143  layout == AV_CH_LAYOUT_5POINT1 ? "5.1" : "Stereo");
144  s->downmix_warned = 1;
145  }
146 
147  switch(exss->matrix_encoding) {
148  case DCADEC_MATRIX_ENCODING_SURROUND:
149  matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
150  break;
151  case DCADEC_MATRIX_ENCODING_HEADPHONE:
152  matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
153  break;
154  }
155  dcadec_context_free_exss_info(exss);
156 
157  if (matrix_encoding != AV_MATRIX_ENCODING_NONE &&
158  (ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0)
159  return ret;
160  }
161 #endif
162 
163  frame->nb_samples = nsamples;
164  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
165  return ret;
166 
167  for (i = 0; i < avctx->channels; i++) {
168  if (frame->format == AV_SAMPLE_FMT_S16P) {
169  int16_t *plane = (int16_t *)frame->extended_data[i];
170  for (k = 0; k < nsamples; k++)
171  plane[k] = samples[i][k];
172  } else {
173  int32_t *plane = (int32_t *)frame->extended_data[i];
174  int shift = 32 - bits_per_sample;
175  for (k = 0; k < nsamples; k++)
176  plane[k] = samples[i][k] << shift;
177  }
178  }
179 
180  *got_frame_ptr = 1;
181 
182  return avpkt->size;
183 }
184 
186 {
187  DCADecContext *s = avctx->priv_data;
188  dcadec_context_clear(s->ctx);
189 }
190 
192 {
193  DCADecContext *s = avctx->priv_data;
194 
195  dcadec_context_destroy(s->ctx);
196  s->ctx = NULL;
197 
198  av_freep(&s->buffer);
199 
200  return 0;
201 }
202 
204 {
205  DCADecContext *s = avctx->priv_data;
206  int flags = 0;
207 
208  /* Affects only lossy DTS profiles. DTS-HD MA is always bitexact */
209  if (avctx->flags & AV_CODEC_FLAG_BITEXACT)
210  flags |= DCADEC_FLAG_CORE_BIT_EXACT;
211 
213  switch (avctx->request_channel_layout) {
214  case AV_CH_LAYOUT_STEREO:
216  /* libdcadec ignores the 2ch flag if used alone when no custom downmix coefficients
217  are available, silently outputting a 5.1 downmix if possible instead.
218  Using both the 2ch and 6ch flags together forces a 2ch downmix using default
219  coefficients in such cases. This matches the behavior of the 6ch flag when used
220  alone, where a 5.1 downmix is generated if possible, regardless of custom
221  coefficients being available or not. */
222  flags |= DCADEC_FLAG_KEEP_DMIX_2CH | DCADEC_FLAG_KEEP_DMIX_6CH;
223  break;
225  flags |= DCADEC_FLAG_KEEP_DMIX_6CH;
226  break;
227  default:
228  av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
229  break;
230  }
231  }
232 
233  s->ctx = dcadec_context_create(flags);
234  if (!s->ctx)
235  return AVERROR(ENOMEM);
236 
238  avctx->bits_per_raw_sample = 24;
239 
240  return 0;
241 }
242 
243 static const AVProfile profiles[] = {
244  { FF_PROFILE_DTS, "DTS" },
245  { FF_PROFILE_DTS_ES, "DTS-ES" },
246  { FF_PROFILE_DTS_96_24, "DTS 96/24" },
247  { FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" },
248  { FF_PROFILE_DTS_HD_MA, "DTS-HD MA" },
249  { FF_PROFILE_DTS_EXPRESS, "DTS Express" },
250  { FF_PROFILE_UNKNOWN },
251 };
252 
254  .name = "libdcadec",
255  .long_name = NULL_IF_CONFIG_SMALL("dcadec DCA decoder"),
256  .type = AVMEDIA_TYPE_AUDIO,
257  .id = AV_CODEC_ID_DTS,
258  .priv_data_size = sizeof(DCADecContext),
259  .init = dcadec_init,
261  .close = dcadec_close,
262  .flush = dcadec_flush,
266  .profiles = NULL_IF_CONFIG_SMALL(profiles),
267 };
int plane
Definition: avisynth_c.h:291
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
struct dcadec_context * ctx
Definition: libdcadec.c:34
static int shift(int a, int b)
Definition: sonic.c:82
This structure describes decoded (raw) audio or video data.
Definition: frame.h:171
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
static void flush(AVCodecContext *avctx)
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static av_cold void dcadec_flush(AVCodecContext *avctx)
Definition: libdcadec.c:185
int size
Definition: avcodec.h:1424
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition: avcodec.h:916
#define AV_CH_LAYOUT_STEREO
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:3003
int profile
profile
Definition: avcodec.h:3115
AVCodec.
Definition: avcodec.h:3472
#define FF_PROFILE_DTS_EXPRESS
Definition: avcodec.h:3135
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
#define FF_PROFILE_DTS_ES
Definition: avcodec.h:3131
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:2270
uint8_t
#define av_cold
Definition: attributes.h:74
AVOptions.
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:3116
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:87
int buffer_size
Definition: libdcadec.c:36
#define FF_PROFILE_DTS_96_24
Definition: avcodec.h:3132
static AVFrame * frame
uint8_t * data
Definition: avcodec.h:1423
#define av_log(a,...)
#define AV_CH_LAYOUT_5POINT1
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
Definition: mem.c:480
int profile
Definition: mxfenc.c:1806
#define AVERROR(e)
Definition: error.h:43
#define FF_PROFILE_DTS
Definition: avcodec.h:3130
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1597
const char * name
Name of the codec implementation.
Definition: avcodec.h:3479
Libavcodec external API header.
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:2323
#define FF_PROFILE_DTS_HD_HRA
Definition: avcodec.h:3133
int bit_rate
the average bitrate
Definition: avcodec.h:1567
audio channel layout utility functions
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition: avcodec.h:788
signed 32 bits, planar
Definition: samplefmt.h:69
int32_t
int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, int max_size)
Convert bitstream to one representation based on sync marker.
Definition: dca.c:39
static int dcadec_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: libdcadec.c:40
int ff_side_data_update_matrix_encoding(AVFrame *frame, enum AVMatrixEncoding matrix_encoding)
Add or update AV_FRAME_DATA_MATRIXENCODING side data.
Definition: utils.c:246
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:232
static av_cold int dcadec_init(AVCodecContext *avctx)
Definition: libdcadec.c:203
sample_rate
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:59
int sample_rate
samples per second
Definition: avcodec.h:2262
#define AV_CH_LAYOUT_NATIVE
Channel mask value used for AVCodecContext.request_channel_layout to indicate that the user requests ...
main external API structure.
Definition: avcodec.h:1502
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:1040
static const AVProfile profiles[]
Definition: libdcadec.c:243
static av_cold int dcadec_close(AVCodecContext *avctx)
Definition: libdcadec.c:191
static int flags
Definition: cpu.c:47
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
Definition: ccaption_dec.c:523
int downmix_warned
Definition: libdcadec.c:37
common internal api header.
common internal and external API header
AVProfile.
Definition: avcodec.h:3460
uint8_t * buffer
Definition: libdcadec.c:35
#define FF_PROFILE_DTS_HD_MA
Definition: avcodec.h:3134
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:636
void * priv_data
Definition: avcodec.h:1544
int channels
number of audio channels
Definition: avcodec.h:2263
uint64_t layout
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
#define av_freep(p)
signed 16 bits, planar
Definition: samplefmt.h:68
AVMatrixEncoding
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:215
uint64_t request_channel_layout
Request decoder to use this channel layout if it can (0 for default)
Definition: avcodec.h:2330
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
This structure stores compressed data.
Definition: avcodec.h:1400
AVCodec ff_libdcadec_decoder
Definition: libdcadec.c:253
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:225
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:857
for(j=16;j >0;--j)
#define av_unused
Definition: attributes.h:118