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.

218 lines
6.4KB

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