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.

173 lines
5.0KB

  1. /*
  2. * Raw DTS-HD demuxer
  3. * Copyright (c) 2012 Paul B Mahol
  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 "libavutil/intreadwrite.h"
  22. #include "libavutil/dict.h"
  23. #include "libavcodec/dca.h"
  24. #include "avformat.h"
  25. #include "internal.h"
  26. #define AUPR_HDR 0x415550522D484452
  27. #define AUPRINFO 0x41555052494E464F
  28. #define BITSHVTB 0x4249545348565442
  29. #define BLACKOUT 0x424C41434B4F5554
  30. #define BRANCHPT 0x4252414E43485054
  31. #define BUILDVER 0x4255494C44564552
  32. #define CORESSMD 0x434F524553534D44
  33. #define DTSHDHDR 0x4454534844484452
  34. #define EXTSS_MD 0x45585453535f4d44
  35. #define FILEINFO 0x46494C45494E464F
  36. #define NAVI_TBL 0x4E4156492D54424C
  37. #define STRMDATA 0x5354524D44415441
  38. #define TIMECODE 0x54494D45434F4445
  39. typedef struct DTSHDDemuxContext {
  40. uint64_t data_end;
  41. } DTSHDDemuxContext;
  42. static int dtshd_probe(AVProbeData *p)
  43. {
  44. if (AV_RB64(p->buf) == DTSHDHDR)
  45. return AVPROBE_SCORE_MAX;
  46. return 0;
  47. }
  48. static int dtshd_read_header(AVFormatContext *s)
  49. {
  50. DTSHDDemuxContext *dtshd = s->priv_data;
  51. AVIOContext *pb = s->pb;
  52. uint64_t chunk_type, chunk_size;
  53. int64_t duration, data_start;
  54. AVStream *st;
  55. int ret;
  56. char *value;
  57. st = avformat_new_stream(s, NULL);
  58. if (!st)
  59. return AVERROR(ENOMEM);
  60. st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
  61. st->codecpar->codec_id = AV_CODEC_ID_DTS;
  62. st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
  63. for (;;) {
  64. chunk_type = avio_rb64(pb);
  65. chunk_size = avio_rb64(pb);
  66. if (avio_feof(pb))
  67. break;
  68. if (chunk_size < 4) {
  69. av_log(s, AV_LOG_ERROR, "chunk size too small\n");
  70. return AVERROR_INVALIDDATA;
  71. }
  72. if (chunk_size > ((uint64_t)1 << 61)) {
  73. av_log(s, AV_LOG_ERROR, "chunk size too big\n");
  74. return AVERROR_INVALIDDATA;
  75. }
  76. switch (chunk_type) {
  77. case STRMDATA:
  78. data_start = avio_tell(pb);
  79. dtshd->data_end = data_start + chunk_size;
  80. if (dtshd->data_end <= chunk_size)
  81. return AVERROR_INVALIDDATA;
  82. if (!pb->seekable)
  83. goto break_loop;
  84. goto skip;
  85. break;
  86. case AUPR_HDR:
  87. if (chunk_size < 21)
  88. return AVERROR_INVALIDDATA;
  89. avio_skip(pb, 3);
  90. st->codecpar->sample_rate = avio_rb24(pb);
  91. if (!st->codecpar->sample_rate)
  92. return AVERROR_INVALIDDATA;
  93. duration = avio_rb32(pb); // num_frames
  94. duration *= avio_rb16(pb); // samples_per_frames
  95. st->duration = duration;
  96. avio_skip(pb, 5);
  97. st->codecpar->channels = ff_dca_count_chs_for_mask(avio_rb16(pb));
  98. st->codecpar->initial_padding = avio_rb16(pb);
  99. avio_skip(pb, chunk_size - 21);
  100. break;
  101. case FILEINFO:
  102. if (chunk_size > INT_MAX)
  103. goto skip;
  104. value = av_malloc(chunk_size);
  105. if (!value)
  106. goto skip;
  107. avio_read(pb, value, chunk_size);
  108. value[chunk_size - 1] = 0;
  109. av_dict_set(&s->metadata, "fileinfo", value,
  110. AV_DICT_DONT_STRDUP_VAL);
  111. break;
  112. default:
  113. skip:
  114. ret = avio_skip(pb, chunk_size);
  115. if (ret < 0)
  116. return ret;
  117. };
  118. }
  119. if (!dtshd->data_end)
  120. return AVERROR_EOF;
  121. avio_seek(pb, data_start, SEEK_SET);
  122. break_loop:
  123. if (st->codecpar->sample_rate)
  124. avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
  125. return 0;
  126. }
  127. static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
  128. {
  129. DTSHDDemuxContext *dtshd = s->priv_data;
  130. int64_t size, left;
  131. int ret;
  132. left = dtshd->data_end - avio_tell(s->pb);
  133. size = FFMIN(left, 1024);
  134. if (size <= 0)
  135. return AVERROR_EOF;
  136. ret = av_get_packet(s->pb, pkt, size);
  137. if (ret < 0)
  138. return ret;
  139. pkt->stream_index = 0;
  140. return ret;
  141. }
  142. AVInputFormat ff_dtshd_demuxer = {
  143. .name = "dtshd",
  144. .long_name = NULL_IF_CONFIG_SMALL("raw DTS-HD"),
  145. .priv_data_size = sizeof(DTSHDDemuxContext),
  146. .read_probe = dtshd_probe,
  147. .read_header = dtshd_read_header,
  148. .read_packet = raw_read_packet,
  149. .flags = AVFMT_GENERIC_INDEX,
  150. .extensions = "dtshd",
  151. .raw_codec_id = AV_CODEC_ID_DTS,
  152. };