c93.c 5.5 KB

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