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.

203 lines
5.5KB

  1. /*
  2. * Interplay C93 demuxer
  3. * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
  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,
  20. * MA 02110-1301 USA
  21. */
  22. #include "avformat.h"
  23. #include "voc.h"
  24. typedef struct {
  25. uint16_t index;
  26. uint8_t length;
  27. uint8_t frames;
  28. } C93BlockRecord;
  29. typedef struct {
  30. voc_dec_context_t voc;
  31. C93BlockRecord block_records[512];
  32. int current_block;
  33. uint32_t frame_offsets[32];
  34. int current_frame;
  35. int next_pkt_is_audio;
  36. AVStream *audio;
  37. } C93DemuxContext;
  38. static int c93_probe(AVProbeData *p)
  39. {
  40. if (p->buf_size < 13)
  41. return 0;
  42. if (p->buf[0] == 0x01 && p->buf[1] == 0x00 &&
  43. p->buf[4] == 0x01 + p->buf[2] &&
  44. p->buf[8] == p->buf[4] + p->buf[6] &&
  45. p->buf[12] == p->buf[8] + p->buf[10])
  46. return AVPROBE_SCORE_MAX;
  47. return 0;
  48. }
  49. static int c93_read_header(AVFormatContext *s,
  50. AVFormatParameters *ap)
  51. {
  52. AVStream *video;
  53. ByteIOContext *pb = &s->pb;
  54. C93DemuxContext *c93 = s->priv_data;
  55. int i;
  56. int framecount = 0;
  57. for (i = 0; i < 512; i++) {
  58. c93->block_records[i].index = get_le16(pb);
  59. c93->block_records[i].length = get_byte(pb);
  60. c93->block_records[i].frames = get_byte(pb);
  61. if (c93->block_records[i].frames > 32) {
  62. av_log(s, AV_LOG_ERROR, "too many frames in block\n");
  63. return AVERROR_INVALIDDATA;
  64. }
  65. framecount += c93->block_records[i].frames;
  66. }
  67. /* Audio streams are added if audio packets are found */
  68. s->ctx_flags |= AVFMTCTX_NOHEADER;
  69. video = av_new_stream(s, 0);
  70. if (!video)
  71. return AVERROR_NOMEM;
  72. video->codec->codec_type = CODEC_TYPE_VIDEO;
  73. video->codec->codec_id = CODEC_ID_C93;
  74. video->codec->width = 320;
  75. video->codec->height = 192;
  76. /* 4:3 320x200 with 8 empty lines */
  77. video->codec->sample_aspect_ratio = (AVRational) { 5, 6 };
  78. video->time_base = (AVRational) { 2, 25 };
  79. video->nb_frames = framecount;
  80. video->duration = framecount;
  81. video->start_time = 0;
  82. c93->current_block = 0;
  83. c93->current_frame = 0;
  84. c93->next_pkt_is_audio = 0;
  85. return 0;
  86. }
  87. #define C93_HAS_PALETTE 0x01
  88. #define C93_FIRST_FRAME 0x02
  89. static int c93_read_packet(AVFormatContext *s, AVPacket *pkt)
  90. {
  91. ByteIOContext *pb = &s->pb;
  92. C93DemuxContext *c93 = s->priv_data;
  93. C93BlockRecord *br = &c93->block_records[c93->current_block];
  94. int datasize;
  95. int ret, i;
  96. if (c93->next_pkt_is_audio) {
  97. c93->current_frame++;
  98. c93->next_pkt_is_audio = 0;
  99. datasize = get_le16(pb);
  100. if (datasize > 42) {
  101. if (!c93->audio) {
  102. c93->audio = av_new_stream(s, 1);
  103. if (!c93->audio)
  104. return AVERROR_NOMEM;
  105. c93->audio->codec->codec_type = CODEC_TYPE_AUDIO;
  106. }
  107. url_fskip(pb, 26); /* VOC header */
  108. ret = voc_get_packet(s, pkt, c93->audio, datasize - 26);
  109. if (ret > 0) {
  110. pkt->stream_index = 1;
  111. pkt->flags |= PKT_FLAG_KEY;
  112. return ret;
  113. }
  114. }
  115. }
  116. if (c93->current_frame >= br->frames) {
  117. if (c93->current_block >= 511 || !br[1].length)
  118. return AVERROR_IO;
  119. br++;
  120. c93->current_block++;
  121. c93->current_frame = 0;
  122. }
  123. if (c93->current_frame == 0) {
  124. url_fseek(pb, br->index * 2048, SEEK_SET);
  125. for (i = 0; i < 32; i++) {
  126. c93->frame_offsets[i] = get_le32(pb);
  127. }
  128. }
  129. url_fseek(pb,br->index * 2048 +
  130. c93->frame_offsets[c93->current_frame], SEEK_SET);
  131. datasize = get_le16(pb); /* video frame size */
  132. ret = av_new_packet(pkt, datasize + 768 + 1);
  133. if (ret < 0)
  134. return ret;
  135. pkt->data[0] = 0;
  136. pkt->size = datasize + 1;
  137. ret = get_buffer(pb, pkt->data + 1, datasize);
  138. if (ret < datasize) {
  139. ret = AVERROR_IO;
  140. goto fail;
  141. }
  142. datasize = get_le16(pb); /* palette size */
  143. if (datasize) {
  144. if (datasize != 768) {
  145. av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize);
  146. ret = AVERROR_INVALIDDATA;
  147. goto fail;
  148. }
  149. pkt->data[0] |= C93_HAS_PALETTE;
  150. ret = get_buffer(pb, pkt->data + pkt->size, datasize);
  151. if (ret < datasize) {
  152. ret = AVERROR_IO;
  153. goto fail;
  154. }
  155. pkt->size += 768;
  156. }
  157. pkt->stream_index = 0;
  158. c93->next_pkt_is_audio = 1;
  159. /* only the first frame is guaranteed to not reference previous frames */
  160. if (c93->current_block == 0 && c93->current_frame == 0) {
  161. pkt->flags |= PKT_FLAG_KEY;
  162. pkt->data[0] |= C93_FIRST_FRAME;
  163. }
  164. return 0;
  165. fail:
  166. av_free_packet(pkt);
  167. return ret;
  168. }
  169. AVInputFormat c93_demuxer = {
  170. "c93",
  171. "Interplay C93",
  172. sizeof(C93DemuxContext),
  173. c93_probe,
  174. c93_read_header,
  175. c93_read_packet,
  176. };