2 * Tiertex Limited SEQ File Demuxer
3 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavformat/tiertexseq.c
24 * Tiertex Limited SEQ file demuxer
29 #define SEQ_FRAME_SIZE 6144
30 #define SEQ_FRAME_W 256
31 #define SEQ_FRAME_H 128
32 #define SEQ_NUM_FRAME_BUFFERS 30
33 #define SEQ_AUDIO_BUFFER_SIZE 882
34 #define SEQ_SAMPLE_RATE 22050
35 #define SEQ_FRAME_RATE 25
38 typedef struct TiertexSeqFrameBuffer
{
42 } TiertexSeqFrameBuffer
;
44 typedef struct SeqDemuxContext
{
45 int audio_stream_index
;
46 int video_stream_index
;
47 int current_frame_pts
;
48 int current_frame_offs
;
49 TiertexSeqFrameBuffer frame_buffers
[SEQ_NUM_FRAME_BUFFERS
];
50 int frame_buffers_count
;
51 unsigned int current_audio_data_size
;
52 unsigned int current_audio_data_offs
;
53 unsigned int current_pal_data_size
;
54 unsigned int current_pal_data_offs
;
55 unsigned int current_video_data_size
;
56 unsigned char *current_video_data_ptr
;
57 int audio_buffer_full
;
61 static int seq_probe(AVProbeData
*p
)
65 if (p
->buf_size
< 258)
68 /* there's no real header in a .seq file, the only thing they have in common */
69 /* is the first 256 bytes of the file which are always filled with 0 */
70 for (i
= 0; i
< 256; i
++)
74 if(p
->buf
[256]==0 && p
->buf
[257]==0)
77 /* only one fourth of the score since the previous check is too naive */
78 return AVPROBE_SCORE_MAX
/ 4;
81 static int seq_init_frame_buffers(SeqDemuxContext
*seq
, ByteIOContext
*pb
)
84 TiertexSeqFrameBuffer
*seq_buffer
;
86 url_fseek(pb
, 256, SEEK_SET
);
88 for (i
= 0; i
< SEQ_NUM_FRAME_BUFFERS
; i
++) {
93 seq_buffer
= &seq
->frame_buffers
[i
];
94 seq_buffer
->fill_size
= 0;
95 seq_buffer
->data_size
= sz
;
96 seq_buffer
->data
= av_malloc(sz
);
97 if (!seq_buffer
->data
)
98 return AVERROR(ENOMEM
);
101 seq
->frame_buffers_count
= i
;
105 static int seq_fill_buffer(SeqDemuxContext
*seq
, ByteIOContext
*pb
, int buffer_num
, unsigned int data_offs
, int data_size
)
107 TiertexSeqFrameBuffer
*seq_buffer
;
109 if (buffer_num
>= SEQ_NUM_FRAME_BUFFERS
)
110 return AVERROR_INVALIDDATA
;
112 seq_buffer
= &seq
->frame_buffers
[buffer_num
];
113 if (seq_buffer
->fill_size
+ data_size
> seq_buffer
->data_size
|| data_size
<= 0)
114 return AVERROR_INVALIDDATA
;
116 url_fseek(pb
, seq
->current_frame_offs
+ data_offs
, SEEK_SET
);
117 if (get_buffer(pb
, seq_buffer
->data
+ seq_buffer
->fill_size
, data_size
) != data_size
)
120 seq_buffer
->fill_size
+= data_size
;
124 static int seq_parse_frame_data(SeqDemuxContext
*seq
, ByteIOContext
*pb
)
126 unsigned int offset_table
[4], buffer_num
[4];
127 TiertexSeqFrameBuffer
*seq_buffer
;
130 seq
->current_frame_offs
+= SEQ_FRAME_SIZE
;
131 url_fseek(pb
, seq
->current_frame_offs
, SEEK_SET
);
134 seq
->current_audio_data_offs
= get_le16(pb
);
135 if (seq
->current_audio_data_offs
) {
136 seq
->current_audio_data_size
= SEQ_AUDIO_BUFFER_SIZE
* 2;
138 seq
->current_audio_data_size
= 0;
142 seq
->current_pal_data_offs
= get_le16(pb
);
143 if (seq
->current_pal_data_offs
) {
144 seq
->current_pal_data_size
= 768;
146 seq
->current_pal_data_size
= 0;
150 for (i
= 0; i
< 4; i
++)
151 buffer_num
[i
] = get_byte(pb
);
153 for (i
= 0; i
< 4; i
++)
154 offset_table
[i
] = get_le16(pb
);
156 for (i
= 0; i
< 3; i
++) {
157 if (offset_table
[i
]) {
158 for (e
= i
+ 1; e
< 3 && offset_table
[e
] == 0; e
++);
159 err
= seq_fill_buffer(seq
, pb
, buffer_num
[1 + i
],
161 offset_table
[e
] - offset_table
[i
]);
167 if (buffer_num
[0] != 255) {
168 if (buffer_num
[0] >= SEQ_NUM_FRAME_BUFFERS
)
169 return AVERROR_INVALIDDATA
;
171 seq_buffer
= &seq
->frame_buffers
[buffer_num
[0]];
172 seq
->current_video_data_size
= seq_buffer
->fill_size
;
173 seq
->current_video_data_ptr
= seq_buffer
->data
;
174 seq_buffer
->fill_size
= 0;
176 seq
->current_video_data_size
= 0;
177 seq
->current_video_data_ptr
= 0;
183 static int seq_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
186 SeqDemuxContext
*seq
= s
->priv_data
;
187 ByteIOContext
*pb
= s
->pb
;
190 /* init internal buffers */
191 rc
= seq_init_frame_buffers(seq
, pb
);
195 seq
->current_frame_offs
= 0;
197 /* preload (no audio data, just buffer operations related data) */
198 for (i
= 1; i
<= 100; i
++) {
199 rc
= seq_parse_frame_data(seq
, pb
);
204 seq
->current_frame_pts
= 0;
206 seq
->audio_buffer_full
= 0;
208 /* initialize the video decoder stream */
209 st
= av_new_stream(s
, 0);
211 return AVERROR(ENOMEM
);
213 av_set_pts_info(st
, 32, 1, SEQ_FRAME_RATE
);
214 seq
->video_stream_index
= st
->index
;
215 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
216 st
->codec
->codec_id
= CODEC_ID_TIERTEXSEQVIDEO
;
217 st
->codec
->codec_tag
= 0; /* no fourcc */
218 st
->codec
->width
= SEQ_FRAME_W
;
219 st
->codec
->height
= SEQ_FRAME_H
;
221 /* initialize the audio decoder stream */
222 st
= av_new_stream(s
, 0);
224 return AVERROR(ENOMEM
);
226 av_set_pts_info(st
, 32, 1, SEQ_SAMPLE_RATE
);
227 seq
->audio_stream_index
= st
->index
;
228 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
229 st
->codec
->codec_id
= CODEC_ID_PCM_S16BE
;
230 st
->codec
->codec_tag
= 0; /* no tag */
231 st
->codec
->channels
= 1;
232 st
->codec
->sample_rate
= SEQ_SAMPLE_RATE
;
233 st
->codec
->bits_per_coded_sample
= 16;
234 st
->codec
->bit_rate
= st
->codec
->sample_rate
* st
->codec
->bits_per_coded_sample
* st
->codec
->channels
;
235 st
->codec
->block_align
= st
->codec
->channels
* st
->codec
->bits_per_coded_sample
;
240 static int seq_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
243 SeqDemuxContext
*seq
= s
->priv_data
;
244 ByteIOContext
*pb
= s
->pb
;
246 if (!seq
->audio_buffer_full
) {
247 rc
= seq_parse_frame_data(seq
, pb
);
252 if (seq
->current_pal_data_size
+ seq
->current_video_data_size
!= 0) {
253 if (av_new_packet(pkt
, 1 + seq
->current_pal_data_size
+ seq
->current_video_data_size
))
254 return AVERROR(ENOMEM
);
257 if (seq
->current_pal_data_size
) {
259 url_fseek(pb
, seq
->current_frame_offs
+ seq
->current_pal_data_offs
, SEEK_SET
);
260 if (get_buffer(pb
, &pkt
->data
[1], seq
->current_pal_data_size
) != seq
->current_pal_data_size
)
263 if (seq
->current_video_data_size
) {
265 memcpy(&pkt
->data
[1 + seq
->current_pal_data_size
],
266 seq
->current_video_data_ptr
,
267 seq
->current_video_data_size
);
269 pkt
->stream_index
= seq
->video_stream_index
;
270 pkt
->pts
= seq
->current_frame_pts
;
272 /* sound buffer will be processed on next read_packet() call */
273 seq
->audio_buffer_full
= 1;
279 if (seq
->current_audio_data_offs
== 0) /* end of data reached */
282 url_fseek(pb
, seq
->current_frame_offs
+ seq
->current_audio_data_offs
, SEEK_SET
);
283 rc
= av_get_packet(pb
, pkt
, seq
->current_audio_data_size
);
287 pkt
->stream_index
= seq
->audio_stream_index
;
288 seq
->current_frame_pts
++;
290 seq
->audio_buffer_full
= 0;
294 static int seq_read_close(AVFormatContext
*s
)
297 SeqDemuxContext
*seq
= s
->priv_data
;
299 for (i
= 0; i
< SEQ_NUM_FRAME_BUFFERS
; i
++)
300 av_free(seq
->frame_buffers
[i
].data
);
305 AVInputFormat tiertexseq_demuxer
= {
307 NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
308 sizeof(SeqDemuxContext
),