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.

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