You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
8.2KB

  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. #include <libdcadec/dca_context.h>
  22. #include "libavutil/channel_layout.h"
  23. #include "libavutil/common.h"
  24. #include "libavutil/opt.h"
  25. #include "avcodec.h"
  26. #include "dca.h"
  27. #include "dca_syncwords.h"
  28. #include "internal.h"
  29. typedef struct DCADecContext {
  30. struct dcadec_context *ctx;
  31. uint8_t *buffer;
  32. int buffer_size;
  33. } DCADecContext;
  34. static int dcadec_decode_frame(AVCodecContext *avctx, void *data,
  35. int *got_frame_ptr, AVPacket *avpkt)
  36. {
  37. DCADecContext *s = avctx->priv_data;
  38. AVFrame *frame = data;
  39. struct dcadec_exss_info *exss;
  40. int ret, i, k;
  41. int **samples, nsamples, channel_mask, sample_rate, bits_per_sample, profile;
  42. uint32_t mrk;
  43. uint8_t *input = avpkt->data;
  44. int input_size = avpkt->size;
  45. /* convert bytestream syntax to RAW BE format if required */
  46. if (input_size < 8) {
  47. av_log(avctx, AV_LOG_ERROR, "Input size too small\n");
  48. return AVERROR_INVALIDDATA;
  49. }
  50. mrk = AV_RB32(input);
  51. if (mrk != DCA_SYNCWORD_CORE_BE && mrk != DCA_SYNCWORD_SUBSTREAM) {
  52. s->buffer = av_fast_realloc(s->buffer, &s->buffer_size, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
  53. if (!s->buffer)
  54. return AVERROR(ENOMEM);
  55. for (i = 0, ret = AVERROR_INVALIDDATA; i < input_size - 3 && ret < 0; i++)
  56. ret = avpriv_dca_convert_bitstream(input + i, input_size - i, s->buffer, s->buffer_size);
  57. if (ret < 0)
  58. return ret;
  59. input = s->buffer;
  60. input_size = ret;
  61. }
  62. if ((ret = dcadec_context_parse(s->ctx, input, input_size)) < 0) {
  63. av_log(avctx, AV_LOG_ERROR, "dcadec_context_parse() failed: %d (%s)\n", -ret, dcadec_strerror(ret));
  64. return AVERROR_EXTERNAL;
  65. }
  66. if ((ret = dcadec_context_filter(s->ctx, &samples, &nsamples, &channel_mask,
  67. &sample_rate, &bits_per_sample, &profile)) < 0) {
  68. av_log(avctx, AV_LOG_ERROR, "dcadec_context_filter() failed: %d (%s)\n", -ret, dcadec_strerror(ret));
  69. return AVERROR_EXTERNAL;
  70. } else if (ret > 0) {
  71. av_log(avctx, AV_LOG_WARNING, "dcadec_context_filter() warning: %d (%s)\n", ret, dcadec_strerror(ret));
  72. }
  73. avctx->channels = av_get_channel_layout_nb_channels(channel_mask);
  74. avctx->channel_layout = channel_mask;
  75. avctx->sample_rate = sample_rate;
  76. if (bits_per_sample == 16)
  77. avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
  78. else if (bits_per_sample > 16 && bits_per_sample <= 24)
  79. avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
  80. else {
  81. av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits per sample: %d\n",
  82. bits_per_sample);
  83. return AVERROR(ENOSYS);
  84. }
  85. avctx->bits_per_raw_sample = bits_per_sample;
  86. switch (profile) {
  87. case DCADEC_PROFILE_DS:
  88. avctx->profile = FF_PROFILE_DTS;
  89. break;
  90. case DCADEC_PROFILE_DS_96_24:
  91. avctx->profile = FF_PROFILE_DTS_96_24;
  92. break;
  93. case DCADEC_PROFILE_DS_ES:
  94. avctx->profile = FF_PROFILE_DTS_ES;
  95. break;
  96. case DCADEC_PROFILE_HD_HRA:
  97. avctx->profile = FF_PROFILE_DTS_HD_HRA;
  98. break;
  99. case DCADEC_PROFILE_HD_MA:
  100. avctx->profile = FF_PROFILE_DTS_HD_MA;
  101. break;
  102. case DCADEC_PROFILE_EXPRESS:
  103. avctx->profile = FF_PROFILE_DTS_EXPRESS;
  104. break;
  105. case DCADEC_PROFILE_UNKNOWN:
  106. default:
  107. avctx->profile = FF_PROFILE_UNKNOWN;
  108. break;
  109. }
  110. /* bitrate is only meaningful if there are no HD extensions, as they distort the bitrate */
  111. if (profile == DCADEC_PROFILE_DS || profile == DCADEC_PROFILE_DS_96_24 || profile == DCADEC_PROFILE_DS_ES) {
  112. struct dcadec_core_info *info = dcadec_context_get_core_info(s->ctx);
  113. avctx->bit_rate = info->bit_rate;
  114. dcadec_context_free_core_info(info);
  115. } else
  116. avctx->bit_rate = 0;
  117. if (exss = dcadec_context_get_exss_info(s->ctx)) {
  118. enum AVMatrixEncoding matrix_encoding = AV_MATRIX_ENCODING_NONE;
  119. switch(exss->matrix_encoding) {
  120. case DCADEC_MATRIX_ENCODING_SURROUND:
  121. matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
  122. break;
  123. case DCADEC_MATRIX_ENCODING_HEADPHONE:
  124. matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
  125. break;
  126. }
  127. dcadec_context_free_exss_info(exss);
  128. if (matrix_encoding != AV_MATRIX_ENCODING_NONE &&
  129. (ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0)
  130. return ret;
  131. }
  132. frame->nb_samples = nsamples;
  133. if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
  134. return ret;
  135. for (i = 0; i < avctx->channels; i++) {
  136. if (frame->format == AV_SAMPLE_FMT_S16P) {
  137. int16_t *plane = (int16_t *)frame->extended_data[i];
  138. for (k = 0; k < nsamples; k++)
  139. plane[k] = samples[i][k];
  140. } else {
  141. int32_t *plane = (int32_t *)frame->extended_data[i];
  142. int shift = 32 - bits_per_sample;
  143. for (k = 0; k < nsamples; k++)
  144. plane[k] = samples[i][k] << shift;
  145. }
  146. }
  147. *got_frame_ptr = 1;
  148. return avpkt->size;
  149. }
  150. static av_cold void dcadec_flush(AVCodecContext *avctx)
  151. {
  152. DCADecContext *s = avctx->priv_data;
  153. dcadec_context_clear(s->ctx);
  154. }
  155. static av_cold int dcadec_close(AVCodecContext *avctx)
  156. {
  157. DCADecContext *s = avctx->priv_data;
  158. dcadec_context_destroy(s->ctx);
  159. s->ctx = NULL;
  160. av_freep(&s->buffer);
  161. return 0;
  162. }
  163. static av_cold int dcadec_init(AVCodecContext *avctx)
  164. {
  165. DCADecContext *s = avctx->priv_data;
  166. int flags = 0;
  167. /* Affects only lossy DTS profiles. DTS-HD MA is always bitexact */
  168. if (avctx->flags & AV_CODEC_FLAG_BITEXACT)
  169. flags |= DCADEC_FLAG_CORE_BIT_EXACT;
  170. if (avctx->request_channel_layout) {
  171. switch (avctx->request_channel_layout) {
  172. case AV_CH_LAYOUT_STEREO:
  173. case AV_CH_LAYOUT_STEREO_DOWNMIX:
  174. flags |= DCADEC_FLAG_KEEP_DMIX_2CH;
  175. break;
  176. case AV_CH_LAYOUT_5POINT1:
  177. flags |= DCADEC_FLAG_KEEP_DMIX_6CH;
  178. break;
  179. case AV_CH_LAYOUT_NATIVE:
  180. flags |= DCADEC_FLAG_NATIVE_LAYOUT;
  181. break;
  182. default:
  183. av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
  184. break;
  185. }
  186. }
  187. s->ctx = dcadec_context_create(flags);
  188. if (!s->ctx)
  189. return AVERROR(ENOMEM);
  190. avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
  191. avctx->bits_per_raw_sample = 24;
  192. return 0;
  193. }
  194. static const AVProfile profiles[] = {
  195. { FF_PROFILE_DTS, "DTS" },
  196. { FF_PROFILE_DTS_ES, "DTS-ES" },
  197. { FF_PROFILE_DTS_96_24, "DTS 96/24" },
  198. { FF_PROFILE_DTS_HD_HRA, "DTS-HD HRA" },
  199. { FF_PROFILE_DTS_HD_MA, "DTS-HD MA" },
  200. { FF_PROFILE_DTS_EXPRESS, "DTS Express" },
  201. { FF_PROFILE_UNKNOWN },
  202. };
  203. AVCodec ff_libdcadec_decoder = {
  204. .name = "libdcadec",
  205. .long_name = NULL_IF_CONFIG_SMALL("dcadec DCA decoder"),
  206. .type = AVMEDIA_TYPE_AUDIO,
  207. .id = AV_CODEC_ID_DTS,
  208. .priv_data_size = sizeof(DCADecContext),
  209. .init = dcadec_init,
  210. .decode = dcadec_decode_frame,
  211. .close = dcadec_close,
  212. .flush = dcadec_flush,
  213. .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
  214. .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_S16P,
  215. AV_SAMPLE_FMT_NONE },
  216. .profiles = NULL_IF_CONFIG_SMALL(profiles),
  217. };