c93.c 5.7 KB

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