Mercurial > libavformat.hg
annotate c93.c @ 2136:b53a19eed95d libavformat
remove duplicate PAT scaning code and actual PAT scan
also disabling the nonsense 3yr old rawts change (it would after the
above chage totally break the demuxer if its left enabled)
author | michael |
---|---|
date | Mon, 04 Jun 2007 14:44:52 +0000 |
parents | 1a3c9056982a |
children | 06083249909c |
rev | line source |
---|---|
1987 | 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 | |
23 #include "avformat.h" | |
24 #include "voc.h" | |
25 | |
26 typedef struct { | |
27 uint16_t index; | |
28 uint8_t length; | |
29 uint8_t frames; | |
30 } C93BlockRecord; | |
31 | |
32 typedef struct { | |
33 voc_dec_context_t voc; | |
34 | |
35 C93BlockRecord block_records[512]; | |
36 int current_block; | |
37 | |
38 uint32_t frame_offsets[32]; | |
39 int current_frame; | |
40 int next_pkt_is_audio; | |
41 | |
42 AVStream *audio; | |
43 } C93DemuxContext; | |
44 | |
2000
ce51095f383b
also remove c93_ prefix for static function in the c93 demuxer
michael
parents:
1987
diff
changeset
|
45 static int probe(AVProbeData *p) |
1987 | 46 { |
47 if (p->buf[0] == 0x01 && p->buf[1] == 0x00 && | |
48 p->buf[4] == 0x01 + p->buf[2] && | |
49 p->buf[8] == p->buf[4] + p->buf[6] && | |
50 p->buf[12] == p->buf[8] + p->buf[10]) | |
51 return AVPROBE_SCORE_MAX; | |
52 | |
53 return 0; | |
54 } | |
55 | |
2000
ce51095f383b
also remove c93_ prefix for static function in the c93 demuxer
michael
parents:
1987
diff
changeset
|
56 static int read_header(AVFormatContext *s, |
1987 | 57 AVFormatParameters *ap) |
58 { | |
59 AVStream *video; | |
60 ByteIOContext *pb = &s->pb; | |
61 C93DemuxContext *c93 = s->priv_data; | |
62 int i; | |
63 int framecount = 0; | |
64 | |
65 for (i = 0; i < 512; i++) { | |
66 c93->block_records[i].index = get_le16(pb); | |
67 c93->block_records[i].length = get_byte(pb); | |
68 c93->block_records[i].frames = get_byte(pb); | |
69 if (c93->block_records[i].frames > 32) { | |
70 av_log(s, AV_LOG_ERROR, "too many frames in block\n"); | |
71 return AVERROR_INVALIDDATA; | |
72 } | |
73 framecount += c93->block_records[i].frames; | |
74 } | |
75 | |
76 /* Audio streams are added if audio packets are found */ | |
77 s->ctx_flags |= AVFMTCTX_NOHEADER; | |
78 | |
79 video = av_new_stream(s, 0); | |
80 if (!video) | |
81 return AVERROR_NOMEM; | |
82 | |
83 video->codec->codec_type = CODEC_TYPE_VIDEO; | |
84 video->codec->codec_id = CODEC_ID_C93; | |
85 video->codec->width = 320; | |
86 video->codec->height = 192; | |
87 /* 4:3 320x200 with 8 empty lines */ | |
88 video->codec->sample_aspect_ratio = (AVRational) { 5, 6 }; | |
89 video->time_base = (AVRational) { 2, 25 }; | |
90 video->nb_frames = framecount; | |
91 video->duration = framecount; | |
92 video->start_time = 0; | |
93 | |
94 c93->current_block = 0; | |
95 c93->current_frame = 0; | |
96 c93->next_pkt_is_audio = 0; | |
97 return 0; | |
98 } | |
99 | |
100 #define C93_HAS_PALETTE 0x01 | |
101 #define C93_FIRST_FRAME 0x02 | |
102 | |
2000
ce51095f383b
also remove c93_ prefix for static function in the c93 demuxer
michael
parents:
1987
diff
changeset
|
103 static int read_packet(AVFormatContext *s, AVPacket *pkt) |
1987 | 104 { |
105 ByteIOContext *pb = &s->pb; | |
106 C93DemuxContext *c93 = s->priv_data; | |
107 C93BlockRecord *br = &c93->block_records[c93->current_block]; | |
108 int datasize; | |
109 int ret, i; | |
110 | |
111 if (c93->next_pkt_is_audio) { | |
112 c93->current_frame++; | |
113 c93->next_pkt_is_audio = 0; | |
114 datasize = get_le16(pb); | |
115 if (datasize > 42) { | |
116 if (!c93->audio) { | |
117 c93->audio = av_new_stream(s, 1); | |
118 if (!c93->audio) | |
119 return AVERROR_NOMEM; | |
120 c93->audio->codec->codec_type = CODEC_TYPE_AUDIO; | |
121 } | |
122 url_fskip(pb, 26); /* VOC header */ | |
123 ret = voc_get_packet(s, pkt, c93->audio, datasize - 26); | |
124 if (ret > 0) { | |
125 pkt->stream_index = 1; | |
126 pkt->flags |= PKT_FLAG_KEY; | |
127 return ret; | |
128 } | |
129 } | |
130 } | |
131 if (c93->current_frame >= br->frames) { | |
132 if (c93->current_block >= 511 || !br[1].length) | |
133 return AVERROR_IO; | |
134 br++; | |
135 c93->current_block++; | |
136 c93->current_frame = 0; | |
137 } | |
138 | |
139 if (c93->current_frame == 0) { | |
140 url_fseek(pb, br->index * 2048, SEEK_SET); | |
141 for (i = 0; i < 32; i++) { | |
142 c93->frame_offsets[i] = get_le32(pb); | |
143 } | |
144 } | |
145 | |
146 url_fseek(pb,br->index * 2048 + | |
147 c93->frame_offsets[c93->current_frame], SEEK_SET); | |
148 datasize = get_le16(pb); /* video frame size */ | |
149 | |
150 ret = av_new_packet(pkt, datasize + 768 + 1); | |
151 if (ret < 0) | |
152 return ret; | |
153 pkt->data[0] = 0; | |
154 pkt->size = datasize + 1; | |
155 | |
156 ret = get_buffer(pb, pkt->data + 1, datasize); | |
157 if (ret < datasize) { | |
158 ret = AVERROR_IO; | |
159 goto fail; | |
160 } | |
161 | |
162 datasize = get_le16(pb); /* palette size */ | |
163 if (datasize) { | |
164 if (datasize != 768) { | |
165 av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize); | |
166 ret = AVERROR_INVALIDDATA; | |
167 goto fail; | |
168 } | |
169 pkt->data[0] |= C93_HAS_PALETTE; | |
170 ret = get_buffer(pb, pkt->data + pkt->size, datasize); | |
171 if (ret < datasize) { | |
172 ret = AVERROR_IO; | |
173 goto fail; | |
174 } | |
175 pkt->size += 768; | |
176 } | |
177 pkt->stream_index = 0; | |
178 c93->next_pkt_is_audio = 1; | |
179 | |
180 /* only the first frame is guaranteed to not reference previous frames */ | |
181 if (c93->current_block == 0 && c93->current_frame == 0) { | |
182 pkt->flags |= PKT_FLAG_KEY; | |
183 pkt->data[0] |= C93_FIRST_FRAME; | |
184 } | |
185 return 0; | |
186 | |
187 fail: | |
188 av_free_packet(pkt); | |
189 return ret; | |
190 } | |
191 | |
192 AVInputFormat c93_demuxer = { | |
193 "c93", | |
194 "Interplay C93", | |
195 sizeof(C93DemuxContext), | |
2000
ce51095f383b
also remove c93_ prefix for static function in the c93 demuxer
michael
parents:
1987
diff
changeset
|
196 probe, |
ce51095f383b
also remove c93_ prefix for static function in the c93 demuxer
michael
parents:
1987
diff
changeset
|
197 read_header, |
ce51095f383b
also remove c93_ prefix for static function in the c93 demuxer
michael
parents:
1987
diff
changeset
|
198 read_packet, |
1987 | 199 }; |