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 #include "profiles.h"
33 
34 typedef struct DCADecContext {
35  const AVClass *class;
36  struct dcadec_context *ctx;
40  int core_only;
42 
43 static void my_log_cb(int level, const char *file, int line,
44  const char *message, void *cbarg)
45 {
46  int av_level;
47 
48  switch (level) {
49  case DCADEC_LOG_ERROR:
50  av_level = AV_LOG_ERROR;
51  break;
52  case DCADEC_LOG_WARNING:
53  av_level = AV_LOG_WARNING;
54  break;
55  case DCADEC_LOG_INFO:
56  av_level = AV_LOG_INFO;
57  break;
58  case DCADEC_LOG_VERBOSE:
59  av_level = AV_LOG_VERBOSE;
60  break;
61  case DCADEC_LOG_DEBUG:
62  default:
63  av_level = AV_LOG_DEBUG;
64  break;
65  }
66 
67  av_log(cbarg, av_level, "%s\n", message);
68 }
69 
70 static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
71  int *got_frame_ptr, AVPacket *avpkt)
72 {
73  DCADecContext *s = avctx->priv_data;
74  AVFrame *frame = data;
75  struct dcadec_exss_info *exss;
76  int ret, i, k;
77  int **samples, nsamples, channel_mask, sample_rate, bits_per_sample, profile;
78  uint32_t mrk;
79  uint8_t *input = avpkt->data;
80  int input_size = avpkt->size;
81 
82  /* convert bytestream syntax to RAW BE format if required */
83  if (input_size < 8) {
84  av_log(avctx, AV_LOG_ERROR, "Input size too small\n");
85  return AVERROR_INVALIDDATA;
86  }
87  mrk = AV_RB32(input);
88  if (mrk != DCA_SYNCWORD_CORE_BE && mrk != DCA_SYNCWORD_SUBSTREAM) {
90  if (!s->buffer)
91  return AVERROR(ENOMEM);
92 
93  for (i = 0, ret = AVERROR_INVALIDDATA; i < input_size - 3 && ret < 0; i++)
94  ret = avpriv_dca_convert_bitstream(input + i, input_size - i, s->buffer, s->buffer_size);
95 
96  if (ret < 0)
97  return ret;
98 
99  input = s->buffer;
100  input_size = ret;
101  }
102 
103  if ((ret = dcadec_context_parse(s->ctx, input, input_size)) < 0) {
104  av_log(avctx, AV_LOG_ERROR, "dcadec_context_parse() failed: %d (%s)\n", -ret, dcadec_strerror(ret));
105  return AVERROR_EXTERNAL;
106  }
107  if ((ret = dcadec_context_filter(s->ctx, &samples, &nsamples, &channel_mask,
108  &sample_rate, &bits_per_sample, &profile)) < 0) {
109  av_log(avctx, AV_LOG_ERROR, "dcadec_context_filter() failed: %d (%s)\n", -ret, dcadec_strerror(ret));
110  return AVERROR_EXTERNAL;
111  }
112 
113  avctx->channels = av_get_channel_layout_nb_channels(channel_mask);
114  avctx->channel_layout = channel_mask;
115  avctx->sample_rate = sample_rate;
116 
117  if (bits_per_sample == 16)
119  else if (bits_per_sample > 16 && bits_per_sample <= 24)
121  else {
122  av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits per sample: %d\n",
123  bits_per_sample);
124  return AVERROR(ENOSYS);
125  }
126 
127  avctx->bits_per_raw_sample = bits_per_sample;
128 
129  switch (profile) {
130  case DCADEC_PROFILE_DS:
131  avctx->profile = FF_PROFILE_DTS;
132  break;
133  case DCADEC_PROFILE_DS_96_24:
134  avctx->profile = FF_PROFILE_DTS_96_24;
135  break;
136  case DCADEC_PROFILE_DS_ES:
137  avctx->profile = FF_PROFILE_DTS_ES;
138  break;
139  case DCADEC_PROFILE_HD_HRA:
141  break;
142  case DCADEC_PROFILE_HD_MA:
143  avctx->profile = FF_PROFILE_DTS_HD_MA;
144  break;
145  case DCADEC_PROFILE_EXPRESS:
147  break;
148  case DCADEC_PROFILE_UNKNOWN:
149  default:
150  avctx->profile = FF_PROFILE_UNKNOWN;
151  break;
152  }
153 
154  /* bitrate is only meaningful if there are no HD extensions, as they distort the bitrate */
155  if (profile == DCADEC_PROFILE_DS || profile == DCADEC_PROFILE_DS_96_24 || profile == DCADEC_PROFILE_DS_ES) {
156  struct dcadec_core_info *info = dcadec_context_get_core_info(s->ctx);
157  avctx->bit_rate = info->bit_rate;
158  dcadec_context_free_core_info(info);
159  } else
160  avctx->bit_rate = 0;
161 
162  if (exss = dcadec_context_get_exss_info(s->ctx)) {
163  enum AVMatrixEncoding matrix_encoding = AV_MATRIX_ENCODING_NONE;
164 
165  switch(exss->matrix_encoding) {
166  case DCADEC_MATRIX_ENCODING_SURROUND:
167  matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
168  break;
169  case DCADEC_MATRIX_ENCODING_HEADPHONE:
170  matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
171  break;
172  }
173  dcadec_context_free_exss_info(exss);
174 
175  if (matrix_encoding != AV_MATRIX_ENCODING_NONE &&
176  (ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0)
177  return ret;
178  }
179 
180  frame->nb_samples = nsamples;
181  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
182  return ret;
183 
184  for (i = 0; i < avctx->channels; i++) {
185  if (frame->format == AV_SAMPLE_FMT_S16P) {
186  int16_t *plane = (int16_t *)frame->extended_data[i];
187  for (k = 0; k < nsamples; k++)
188  plane[k] = samples[i][k];
189  } else {
190  int32_t *plane = (int32_t *)frame->extended_data[i];
191  int shift = 32 - bits_per_sample;
192  for (k = 0; k < nsamples; k++)
193  plane[k] = samples[i][k] << shift;
194  }
195  }
196 
197  *got_frame_ptr = 1;
198 
199  return avpkt->size;
200 }
201 
203 {
204  DCADecContext *s = avctx->priv_data;
205  dcadec_context_clear(s->ctx);
206 }
207 
209 {
210  DCADecContext *s = avctx->priv_data;
211 
212  dcadec_context_destroy(s->ctx);
213  s->ctx = NULL;
214 
215  av_freep(&s->buffer);
216 
217  return 0;
218 }
219 
221 {
222  DCADecContext *s = avctx->priv_data;
223  int flags = 0;
224 
225  /* Affects only lossy DTS profiles. DTS-HD MA is always bitexact */
226  if (avctx->flags & AV_CODEC_FLAG_BITEXACT)
227  flags |= DCADEC_FLAG_CORE_BIT_EXACT;
228 
229  if (avctx->err_recognition & AV_EF_EXPLODE)
230  flags |= DCADEC_FLAG_STRICT;
231 
232  if (avctx->request_channel_layout) {
233  switch (avctx->request_channel_layout) {
234  case AV_CH_LAYOUT_STEREO:
236  flags |= DCADEC_FLAG_KEEP_DMIX_2CH;
237  break;
239  flags |= DCADEC_FLAG_KEEP_DMIX_6CH;
240  break;
241  case AV_CH_LAYOUT_NATIVE:
242  flags |= DCADEC_FLAG_NATIVE_LAYOUT;
243  break;
244  default:
245  av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
246  break;
247  }
248  }
249 
250  if (s->core_only)
251  flags |= DCADEC_FLAG_CORE_ONLY;
252 
253  switch (s->lfe_filter) {
254 #if DCADEC_API_VERSION >= DCADEC_VERSION_CODE(0, 1, 0)
255  case 1:
256  flags |= DCADEC_FLAG_CORE_LFE_IIR;
257  break;
258 #endif
259  case 2:
260  flags |= DCADEC_FLAG_CORE_LFE_FIR;
261  break;
262  }
263 
264  s->ctx = dcadec_context_create(flags);
265  if (!s->ctx)
266  return AVERROR(ENOMEM);
267 
268  dcadec_context_set_log_cb(s->ctx, my_log_cb, avctx);
269 
271  avctx->bits_per_raw_sample = 24;
272 
273  return 0;
274 }
275 
276 #define OFFSET(x) offsetof(DCADecContext, x)
277 #define PARAM AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
278 
279 static const AVOption dcadec_options[] = {
280  { "lfe_filter", "Lossy LFE channel interpolation filter", OFFSET(lfe_filter), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, PARAM, "lfe_filter" },
281  { "default", "Library default", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, PARAM, "lfe_filter" },
282  { "iir", "IIR filter", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, PARAM, "lfe_filter" },
283  { "fir", "FIR filter", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, PARAM, "lfe_filter" },
284  { "core_only", "Decode core only without extensions", OFFSET(core_only), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, PARAM },
285  { NULL }
286 };
287 
288 static const AVClass dcadec_class = {
289  .class_name = "libdcadec decoder",
290  .item_name = av_default_item_name,
291  .option = dcadec_options,
292  .version = LIBAVUTIL_VERSION_INT,
293  .category = AV_CLASS_CATEGORY_DECODER,
294 };
295 
297  .name = "libdcadec",
298  .long_name = NULL_IF_CONFIG_SMALL("dcadec DCA decoder"),
299  .type = AVMEDIA_TYPE_AUDIO,
300  .id = AV_CODEC_ID_DTS,
301  .priv_data_size = sizeof(DCADecContext),
302  .init = dcadec_init,
304  .close = dcadec_close,
305  .flush = dcadec_flush,
309  .priv_class = &dcadec_class,
311 };
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:36
static int shift(int a, int b)
Definition: sonic.c:82
This structure describes decoded (raw) audio or video data.
Definition: frame.h:181
AVOption.
Definition: opt.h:245
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
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1597
#define LIBAVUTIL_VERSION_INT
Definition: version.h:70
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define FF_PROFILE_DTS_HD_HRA
Definition: avcodec.h:3046
static av_cold void dcadec_flush(AVCodecContext *avctx)
Definition: libdcadec.c:202
int size
Definition: avcodec.h:1468
static const AVClass dcadec_class
Definition: libdcadec.c:288
#define FF_PROFILE_DTS_EXPRESS
Definition: avcodec.h:3048
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition: avcodec.h:915
#define AV_CH_LAYOUT_STEREO
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:2924
int profile
profile
Definition: avcodec.h:3028
AVCodec.
Definition: avcodec.h:3392
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:2295
uint8_t
#define av_cold
Definition: attributes.h:82
AVOptions.
int lfe_filter
Definition: libdcadec.c:39
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:38
static AVFrame * frame
uint8_t * data
Definition: avcodec.h:1467
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define av_log(a,...)
#define DCA_SYNCWORD_CORE_BE
Definition: dca_syncwords.h:22
#define AV_CH_LAYOUT_5POINT1
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define OFFSET(x)
Definition: libdcadec.c:276
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
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
#define FF_PROFILE_DTS_ES
Definition: avcodec.h:3044
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1627
Definition: graph2dot.c:48
const char * name
Name of the codec implementation.
Definition: avcodec.h:3399
uint64_t channel_layout
Audio channel layout.
Definition: avcodec.h:2338
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:787
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:2811
signed 32 bits, planar
Definition: samplefmt.h:69
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:3029
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
#define FF_PROFILE_DTS
Definition: avcodec.h:3043
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:2822
static int dcadec_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: libdcadec.c:70
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:239
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:242
#define FF_PROFILE_DTS_96_24
Definition: avcodec.h:3045
static av_cold int dcadec_init(AVCodecContext *avctx)
Definition: libdcadec.c:220
sample_rate
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
Libavcodec external API header.
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:59
int sample_rate
samples per second
Definition: avcodec.h:2287
static void my_log_cb(int level, const char *file, int line, const char *message, void *cbarg)
Definition: libdcadec.c:43
#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:1532
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:894
Describe the class of an AVClass context structure.
Definition: log.h:67
#define PARAM
Definition: libdcadec.c:277
static av_cold int dcadec_close(AVCodecContext *avctx)
Definition: libdcadec.c:208
mfxU16 profile
Definition: qsvenc.c:42
static int flags
Definition: cpu.c:47
const AVProfile ff_dca_profiles[]
Definition: profiles.c:40
uint8_t level
Definition: svq3.c:150
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
Definition: ccaption_dec.c:572
common internal api header.
common internal and external API header
uint8_t * buffer
Definition: libdcadec.c:37
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:635
void * priv_data
Definition: avcodec.h:1574
int channels
number of audio channels
Definition: avcodec.h:2288
#define DCA_SYNCWORD_SUBSTREAM
Definition: dca_syncwords.h:32
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
#define av_freep(p)
signed 16 bits, planar
Definition: samplefmt.h:68
AVMatrixEncoding
#define FF_PROFILE_DTS_HD_MA
Definition: avcodec.h:3047
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:225
uint64_t request_channel_layout
Request decoder to use this channel layout if it can (0 for default)
Definition: avcodec.h:2345
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
This structure stores compressed data.
Definition: avcodec.h:1444
AVCodec ff_libdcadec_decoder
Definition: libdcadec.c:296
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:235
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:856
for(j=16;j >0;--j)
static const AVOption dcadec_options[]
Definition: libdcadec.c:279