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.0KB

  1. /*
  2. * GXF demuxer.
  3. * Copyright (c) 2006 Reimar Doeffinger.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include "avformat.h"
  20. typedef enum {
  21. PKT_MAP = 0xbc,
  22. PKT_MEDIA = 0xbf,
  23. PKT_EOS = 0xfb,
  24. PKT_FLT = 0xfc,
  25. PKT_UMF = 0xfd
  26. } pkt_type_t;
  27. /**
  28. * \brief parses a packet header, extracting type and length
  29. * \param pb ByteIOContext to read header from
  30. * \param type detected packet type is stored here
  31. * \param length detected packet length, excluding header is stored here
  32. * \return 0 if header not found or contains invalid data, 1 otherwise
  33. */
  34. static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) {
  35. if (get_be32(pb))
  36. return 0;
  37. if (get_byte(pb) != 1)
  38. return 0;
  39. *type = get_byte(pb);
  40. *length = get_be32(pb);
  41. if ((*length >> 24) || *length < 16)
  42. return 0;
  43. *length -= 16;
  44. if (get_be32(pb))
  45. return 0;
  46. if (get_byte(pb) != 0xe1)
  47. return 0;
  48. if (get_byte(pb) != 0xe2)
  49. return 0;
  50. return 1;
  51. }
  52. /**
  53. * \brief check if file starts with a PKT_MAP header
  54. */
  55. static int gxf_probe(AVProbeData *p) {
  56. static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet
  57. static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2};
  58. if (p->buf_size < 16)
  59. return 0;
  60. if (!memcmp(p->buf, startcode, sizeof(startcode)) &&
  61. !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))
  62. return AVPROBE_SCORE_MAX;
  63. return 0;
  64. }
  65. /**
  66. * \brief gets the stream index for the track with the specified id, creates new
  67. * stream if not found
  68. * \param stream id of stream to find / add
  69. * \param format stream format identifier
  70. */
  71. static int get_sindex(AVFormatContext *s, int id, int format) {
  72. int i;
  73. AVStream *st = NULL;
  74. for (i = 0; i < s->nb_streams; i++) {
  75. if (s->streams[i]->id == id)
  76. return i;
  77. }
  78. st = av_new_stream(s, id);
  79. switch (format) {
  80. case 3:
  81. case 4:
  82. st->codec->codec_type = CODEC_TYPE_VIDEO;
  83. st->codec->codec_id = CODEC_ID_MJPEG;
  84. st->codec->codec_tag = MKTAG('M', 'J', 'P', 'G');
  85. break;
  86. case 13:
  87. case 15:
  88. st->codec->codec_type = CODEC_TYPE_VIDEO;
  89. st->codec->codec_id = CODEC_ID_DVVIDEO;
  90. st->codec->codec_tag = MKTAG('d', 'v', 'c', ' ');
  91. break;
  92. case 14:
  93. case 16:
  94. st->codec->codec_type = CODEC_TYPE_VIDEO;
  95. st->codec->codec_id = CODEC_ID_DVVIDEO;
  96. st->codec->codec_tag = MKTAG('d', 'v', 'c', 'p');
  97. break;
  98. case 11:
  99. case 12:
  100. case 20:
  101. st->codec->codec_type = CODEC_TYPE_VIDEO;
  102. st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
  103. st->codec->codec_tag = MKTAG('M', 'P', 'G', '2');
  104. break;
  105. case 22:
  106. case 23:
  107. st->codec->codec_type = CODEC_TYPE_VIDEO;
  108. st->codec->codec_id = CODEC_ID_MPEG1VIDEO;
  109. st->codec->codec_tag = MKTAG('M', 'P', 'G', '1');
  110. break;
  111. case 9:
  112. st->codec->codec_type = CODEC_TYPE_AUDIO;
  113. st->codec->codec_id = CODEC_ID_PCM_S24LE;
  114. st->codec->codec_tag = 0x1;
  115. st->codec->channels = 1;
  116. st->codec->sample_rate = 48000;
  117. st->codec->bit_rate = 3 * 1 * 48000 * 8;
  118. st->codec->block_align = 3 * 1;
  119. st->codec->bits_per_sample = 24;
  120. break;
  121. case 10:
  122. st->codec->codec_type = CODEC_TYPE_AUDIO;
  123. st->codec->codec_id = CODEC_ID_PCM_S16LE;
  124. st->codec->codec_tag = 0x1;
  125. st->codec->channels = 1;
  126. st->codec->sample_rate = 48000;
  127. st->codec->bit_rate = 2 * 1 * 48000 * 8;
  128. st->codec->block_align = 2 * 1;
  129. st->codec->bits_per_sample = 16;
  130. break;
  131. case 17:
  132. st->codec->codec_type = CODEC_TYPE_AUDIO;
  133. st->codec->codec_id = CODEC_ID_AC3;
  134. st->codec->codec_tag = 0x2000;
  135. st->codec->channels = 2;
  136. st->codec->sample_rate = 48000;
  137. break;
  138. default:
  139. st->codec->codec_type = CODEC_TYPE_UNKNOWN;
  140. st->codec->codec_id = CODEC_ID_NONE;
  141. break;
  142. }
  143. return s->nb_streams - 1;
  144. }
  145. static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) {
  146. ByteIOContext *pb = &s->pb;
  147. pkt_type_t pkt_type;
  148. int map_len;
  149. int len;
  150. if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) {
  151. av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n");
  152. return 0;
  153. }
  154. map_len -= 2;
  155. if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) {
  156. av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n");
  157. return 0;
  158. }
  159. map_len -= 2;
  160. len = get_be16(pb); // length of material data section
  161. if (len > map_len) {
  162. av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n");
  163. return 0;
  164. }
  165. map_len -= len;
  166. url_fskip(pb, len);
  167. map_len -= 2;
  168. len = get_be16(pb); // length of track description
  169. if (len > map_len) {
  170. av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n");
  171. return 0;
  172. }
  173. map_len -= len;
  174. while (len > 0) {
  175. int track_type, track_id, track_len;
  176. len -= 4;
  177. track_type = get_byte(pb);
  178. track_id = get_byte(pb);
  179. track_len = get_be16(pb);
  180. len -= track_len;
  181. url_fskip(pb, track_len);
  182. if (!(track_type & 0x80)) {
  183. av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type);
  184. continue;
  185. }
  186. track_type &= 0x7f;
  187. if ((track_id & 0xc0) != 0xc0) {
  188. av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id);
  189. continue;
  190. }
  191. track_id &= 0x3f;
  192. get_sindex(s, track_id, track_type);
  193. }
  194. if (len < 0)
  195. av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n");
  196. if (map_len)
  197. url_fskip(pb, map_len);
  198. return 0;
  199. }
  200. static int gxf_packet(AVFormatContext *s, AVPacket *pkt) {
  201. ByteIOContext *pb = &s->pb;
  202. pkt_type_t pkt_type;
  203. int pkt_len;
  204. while (!url_feof(pb)) {
  205. int track_type, track_id, ret;
  206. if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
  207. if (!url_feof(pb))
  208. av_log(s, AV_LOG_ERROR, "GXF: sync lost\n");
  209. return -1;
  210. }
  211. if (pkt_type != PKT_MEDIA) {
  212. url_fskip(pb, pkt_len);
  213. continue;
  214. }
  215. if (pkt_len < 16) {
  216. av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n");
  217. continue;
  218. }
  219. pkt_len -= 16;
  220. track_type = get_byte(pb);
  221. track_id = get_byte(pb);
  222. get_be32(pb); // field number
  223. get_be32(pb); // field information
  224. get_be32(pb); // "timeline" field number
  225. get_byte(pb); // flags
  226. get_byte(pb); // reserved
  227. // NOTE: there is also data length information in the
  228. // field information, it might be better to take this int account
  229. // as well.
  230. ret = av_get_packet(pb, pkt, pkt_len);
  231. pkt->stream_index = get_sindex(s, track_id, track_type);
  232. return ret;
  233. }
  234. return AVERROR_IO;
  235. }
  236. AVInputFormat gxf_demuxer = {
  237. "gxf",
  238. "GXF format",
  239. 0,
  240. gxf_probe,
  241. gxf_header,
  242. gxf_packet,
  243. NULL,
  244. NULL,
  245. };