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.

211 lines
6.3KB

  1. /*
  2. * MLP parser
  3. * Copyright (c) 2007 Ian Caulfield
  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. * @file
  23. * MLP parser
  24. */
  25. #include <stdint.h>
  26. #include "libavutil/internal.h"
  27. #include "get_bits.h"
  28. #include "parser.h"
  29. #include "mlp_parse.h"
  30. #include "mlp.h"
  31. typedef struct MLPParseContext
  32. {
  33. ParseContext pc;
  34. int bytes_left;
  35. int in_sync;
  36. int num_substreams;
  37. } MLPParseContext;
  38. static av_cold int mlp_init(AVCodecParserContext *s)
  39. {
  40. ff_mlp_init_crc();
  41. return 0;
  42. }
  43. static int mlp_parse(AVCodecParserContext *s,
  44. AVCodecContext *avctx,
  45. const uint8_t **poutbuf, int *poutbuf_size,
  46. const uint8_t *buf, int buf_size)
  47. {
  48. MLPParseContext *mp = s->priv_data;
  49. int sync_present;
  50. uint8_t parity_bits;
  51. int next;
  52. int ret;
  53. int i, p = 0;
  54. *poutbuf_size = 0;
  55. if (buf_size == 0)
  56. return 0;
  57. if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
  58. next = buf_size;
  59. } else {
  60. if (!mp->in_sync) {
  61. // Not in sync - find a major sync header
  62. for (i = 0; i < buf_size; i++) {
  63. mp->pc.state = (mp->pc.state << 8) | buf[i];
  64. if ((mp->pc.state & 0xfffffffe) == 0xf8726fba &&
  65. // ignore if we do not have the data for the start of header
  66. mp->pc.index + i >= 7) {
  67. mp->in_sync = 1;
  68. mp->bytes_left = 0;
  69. break;
  70. }
  71. }
  72. if (!mp->in_sync) {
  73. if (ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size) != -1)
  74. av_log(avctx, AV_LOG_WARNING, "ff_combine_frame failed\n");
  75. return buf_size;
  76. }
  77. if ((ret = ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size)) < 0) {
  78. av_log(avctx, AV_LOG_WARNING, "ff_combine_frame failed\n");
  79. return ret;
  80. }
  81. return i - 7;
  82. }
  83. if (mp->bytes_left == 0) {
  84. // Find length of this packet
  85. /* Copy overread bytes from last frame into buffer. */
  86. for(; mp->pc.overread>0; mp->pc.overread--) {
  87. mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++];
  88. }
  89. if (mp->pc.index + buf_size < 2) {
  90. if (ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size) != -1)
  91. av_log(avctx, AV_LOG_WARNING, "ff_combine_frame failed\n");
  92. return buf_size;
  93. }
  94. mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
  95. | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
  96. mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
  97. if (mp->bytes_left <= 0) { // prevent infinite loop
  98. goto lost_sync;
  99. }
  100. mp->bytes_left -= mp->pc.index;
  101. }
  102. next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
  103. if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
  104. mp->bytes_left -= buf_size;
  105. return buf_size;
  106. }
  107. mp->bytes_left = 0;
  108. }
  109. sync_present = buf_size >= 8 && (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
  110. if (!sync_present) {
  111. /* The first nibble of a frame is a parity check of the 4-byte
  112. * access unit header and all the 2- or 4-byte substream headers. */
  113. // Only check when this isn't a sync frame - syncs have a checksum.
  114. parity_bits = 0;
  115. for (i = -1; i < mp->num_substreams; i++) {
  116. parity_bits ^= buf[p++];
  117. parity_bits ^= buf[p++];
  118. if (i < 0 || buf[p-2] & 0x80) {
  119. parity_bits ^= buf[p++];
  120. parity_bits ^= buf[p++];
  121. }
  122. }
  123. if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
  124. av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
  125. goto lost_sync;
  126. }
  127. } else {
  128. GetBitContext gb;
  129. MLPHeaderInfo mh;
  130. init_get_bits(&gb, buf + 4, (buf_size - 4) << 3);
  131. if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0)
  132. goto lost_sync;
  133. avctx->bits_per_raw_sample = mh.group1_bits;
  134. if (avctx->bits_per_raw_sample > 16)
  135. avctx->sample_fmt = AV_SAMPLE_FMT_S32;
  136. else
  137. avctx->sample_fmt = AV_SAMPLE_FMT_S16;
  138. avctx->sample_rate = mh.group1_samplerate;
  139. avctx->frame_size =
  140. s->duration = mh.access_unit_size;
  141. if(!avctx->channels || !avctx->channel_layout) {
  142. if (mh.stream_type == 0xbb) {
  143. /* MLP stream */
  144. avctx->channels = mh.channels_mlp;
  145. avctx->channel_layout = mh.channel_layout_mlp;
  146. } else { /* mh.stream_type == 0xba */
  147. /* TrueHD stream */
  148. if (!mh.channels_thd_stream2) {
  149. avctx->channels = mh.channels_thd_stream1;
  150. avctx->channel_layout = mh.channel_layout_thd_stream1;
  151. } else {
  152. avctx->channels = mh.channels_thd_stream2;
  153. avctx->channel_layout = mh.channel_layout_thd_stream2;
  154. }
  155. }
  156. }
  157. if (!mh.is_vbr) /* Stream is CBR */
  158. avctx->bit_rate = mh.peak_bitrate;
  159. mp->num_substreams = mh.num_substreams;
  160. }
  161. *poutbuf = buf;
  162. *poutbuf_size = buf_size;
  163. return next;
  164. lost_sync:
  165. mp->in_sync = 0;
  166. return 1;
  167. }
  168. AVCodecParser ff_mlp_parser = {
  169. .codec_ids = { AV_CODEC_ID_MLP, AV_CODEC_ID_TRUEHD },
  170. .priv_data_size = sizeof(MLPParseContext),
  171. .parser_init = mlp_init,
  172. .parser_parse = mlp_parse,
  173. .parser_close = ff_parse_close,
  174. };