2 * Tiertex Limited SEQ File Demuxer
3 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
5 * This file is part of Libav.
7 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * Tiertex Limited SEQ file demuxer
27 #include "libavutil/channel_layout.h"
31 #define SEQ_FRAME_SIZE 6144
32 #define SEQ_FRAME_W 256
33 #define SEQ_FRAME_H 128
34 #define SEQ_NUM_FRAME_BUFFERS 30
35 #define SEQ_AUDIO_BUFFER_SIZE 882
36 #define SEQ_SAMPLE_RATE 22050
37 #define SEQ_FRAME_RATE 25
40 typedef struct TiertexSeqFrameBuffer
{
44 } TiertexSeqFrameBuffer
;
46 typedef struct SeqDemuxContext
{
47 int audio_stream_index
;
48 int video_stream_index
;
49 int current_frame_pts
;
50 int current_frame_offs
;
51 TiertexSeqFrameBuffer frame_buffers
[SEQ_NUM_FRAME_BUFFERS
];
52 int frame_buffers_count
;
53 unsigned int current_audio_data_size
;
54 unsigned int current_audio_data_offs
;
55 unsigned int current_pal_data_size
;
56 unsigned int current_pal_data_offs
;
57 unsigned int current_video_data_size
;
58 unsigned char *current_video_data_ptr
;
59 int audio_buffer_full
;
63 static int seq_probe(AVProbeData
*p
)
67 if (p
->buf_size
< 258)
70 /* there's no real header in a .seq file, the only thing they have in common */
71 /* is the first 256 bytes of the file which are always filled with 0 */
72 for (i
= 0; i
< 256; i
++)
76 if(p
->buf
[256]==0 && p
->buf
[257]==0)
79 /* only one fourth of the score since the previous check is too naive */
80 return AVPROBE_SCORE_MAX
/ 4;
83 static int seq_init_frame_buffers(SeqDemuxContext
*seq
, AVIOContext
*pb
)
86 TiertexSeqFrameBuffer
*seq_buffer
;
88 avio_seek(pb
, 256, SEEK_SET
);
90 for (i
= 0; i
< SEQ_NUM_FRAME_BUFFERS
; i
++) {
95 seq_buffer
= &seq
->frame_buffers
[i
];
96 seq_buffer
->fill_size
= 0;
97 seq_buffer
->data_size
= sz
;
98 seq_buffer
->data
= av_malloc(sz
);
99 if (!seq_buffer
->data
)
100 return AVERROR(ENOMEM
);
103 seq
->frame_buffers_count
= i
;
107 static int seq_fill_buffer(SeqDemuxContext
*seq
, AVIOContext
*pb
, int buffer_num
, unsigned int data_offs
, int data_size
)
109 TiertexSeqFrameBuffer
*seq_buffer
;
111 if (buffer_num
>= SEQ_NUM_FRAME_BUFFERS
)
112 return AVERROR_INVALIDDATA
;
114 seq_buffer
= &seq
->frame_buffers
[buffer_num
];
115 if (seq_buffer
->fill_size
+ data_size
> seq_buffer
->data_size
|| data_size
<= 0)
116 return AVERROR_INVALIDDATA
;
118 avio_seek(pb
, seq
->current_frame_offs
+ data_offs
, SEEK_SET
);
119 if (avio_read(pb
, seq_buffer
->data
+ seq_buffer
->fill_size
, data_size
) != data_size
)
122 seq_buffer
->fill_size
+= data_size
;
126 static int seq_parse_frame_data(SeqDemuxContext
*seq
, AVIOContext
*pb
)
128 unsigned int offset_table
[4], buffer_num
[4];
129 TiertexSeqFrameBuffer
*seq_buffer
;
132 seq
->current_frame_offs
+= SEQ_FRAME_SIZE
;
133 avio_seek(pb
, seq
->current_frame_offs
, SEEK_SET
);
136 seq
->current_audio_data_offs
= avio_rl16(pb
);
137 if (seq
->current_audio_data_offs
) {
138 seq
->current_audio_data_size
= SEQ_AUDIO_BUFFER_SIZE
* 2;
140 seq
->current_audio_data_size
= 0;
144 seq
->current_pal_data_offs
= avio_rl16(pb
);
145 if (seq
->current_pal_data_offs
) {
146 seq
->current_pal_data_size
= 768;
148 seq
->current_pal_data_size
= 0;
152 for (i
= 0; i
< 4; i
++)
153 buffer_num
[i
] = avio_r8(pb
);
155 for (i
= 0; i
< 4; i
++)
156 offset_table
[i
] = avio_rl16(pb
);
158 for (i
= 0; i
< 3; i
++) {
159 if (offset_table
[i
]) {
160 for (e
= i
+ 1; e
< 3 && offset_table
[e
] == 0; e
++);
161 err
= seq_fill_buffer(seq
, pb
, buffer_num
[1 + i
],
163 offset_table
[e
] - offset_table
[i
]);
169 if (buffer_num
[0] != 255) {
170 if (buffer_num
[0] >= SEQ_NUM_FRAME_BUFFERS
)
171 return AVERROR_INVALIDDATA
;
173 seq_buffer
= &seq
->frame_buffers
[buffer_num
[0]];
174 seq
->current_video_data_size
= seq_buffer
->fill_size
;
175 seq
->current_video_data_ptr
= seq_buffer
->data
;
176 seq_buffer
->fill_size
= 0;
178 seq
->current_video_data_size
= 0;
179 seq
->current_video_data_ptr
= 0;
185 static int seq_read_header(AVFormatContext
*s
)
188 SeqDemuxContext
*seq
= s
->priv_data
;
189 AVIOContext
*pb
= s
->pb
;
192 /* init internal buffers */
193 rc
= seq_init_frame_buffers(seq
, pb
);
197 seq
->current_frame_offs
= 0;
199 /* preload (no audio data, just buffer operations related data) */
200 for (i
= 1; i
<= 100; i
++) {
201 rc
= seq_parse_frame_data(seq
, pb
);
206 seq
->current_frame_pts
= 0;
208 seq
->audio_buffer_full
= 0;
210 /* initialize the video decoder stream */
211 st
= avformat_new_stream(s
, NULL
);
213 return AVERROR(ENOMEM
);
215 avpriv_set_pts_info(st
, 32, 1, SEQ_FRAME_RATE
);
216 seq
->video_stream_index
= st
->index
;
217 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
218 st
->codec
->codec_id
= AV_CODEC_ID_TIERTEXSEQVIDEO
;
219 st
->codec
->codec_tag
= 0; /* no fourcc */
220 st
->codec
->width
= SEQ_FRAME_W
;
221 st
->codec
->height
= SEQ_FRAME_H
;
223 /* initialize the audio decoder stream */
224 st
= avformat_new_stream(s
, NULL
);
226 return AVERROR(ENOMEM
);
229 avpriv_set_pts_info(st
, 32, 1, SEQ_SAMPLE_RATE
);
230 seq
->audio_stream_index
= st
->index
;
231 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
232 st
->codec
->codec_id
= AV_CODEC_ID_PCM_S16BE
;
233 st
->codec
->codec_tag
= 0; /* no tag */
234 st
->codec
->channels
= 1;
235 st
->codec
->channel_layout
= AV_CH_LAYOUT_MONO
;
236 st
->codec
->sample_rate
= SEQ_SAMPLE_RATE
;
237 st
->codec
->bits_per_coded_sample
= 16;
238 st
->codec
->bit_rate
= st
->codec
->sample_rate
* st
->codec
->bits_per_coded_sample
* st
->codec
->channels
;
239 st
->codec
->block_align
= st
->codec
->channels
* st
->codec
->bits_per_coded_sample
/ 8;
244 static int seq_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
247 SeqDemuxContext
*seq
= s
->priv_data
;
248 AVIOContext
*pb
= s
->pb
;
250 if (!seq
->audio_buffer_full
) {
251 rc
= seq_parse_frame_data(seq
, pb
);
256 if (seq
->current_pal_data_size
+ seq
->current_video_data_size
!= 0) {
257 if (av_new_packet(pkt
, 1 + seq
->current_pal_data_size
+ seq
->current_video_data_size
))
258 return AVERROR(ENOMEM
);
261 if (seq
->current_pal_data_size
) {
263 avio_seek(pb
, seq
->current_frame_offs
+ seq
->current_pal_data_offs
, SEEK_SET
);
264 if (avio_read(pb
, &pkt
->data
[1], seq
->current_pal_data_size
) != seq
->current_pal_data_size
)
267 if (seq
->current_video_data_size
) {
269 memcpy(&pkt
->data
[1 + seq
->current_pal_data_size
],
270 seq
->current_video_data_ptr
,
271 seq
->current_video_data_size
);
273 pkt
->stream_index
= seq
->video_stream_index
;
274 pkt
->pts
= seq
->current_frame_pts
;
276 /* sound buffer will be processed on next read_packet() call */
277 seq
->audio_buffer_full
= 1;
283 if (seq
->current_audio_data_offs
== 0) /* end of data reached */
286 avio_seek(pb
, seq
->current_frame_offs
+ seq
->current_audio_data_offs
, SEEK_SET
);
287 rc
= av_get_packet(pb
, pkt
, seq
->current_audio_data_size
);
291 pkt
->stream_index
= seq
->audio_stream_index
;
292 seq
->current_frame_pts
++;
294 seq
->audio_buffer_full
= 0;
298 static int seq_read_close(AVFormatContext
*s
)
301 SeqDemuxContext
*seq
= s
->priv_data
;
303 for (i
= 0; i
< SEQ_NUM_FRAME_BUFFERS
; i
++)
304 av_free(seq
->frame_buffers
[i
].data
);
309 AVInputFormat ff_tiertexseq_demuxer
= {
310 .name
= "tiertexseq",
311 .long_name
= NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ"),
312 .priv_data_size
= sizeof(SeqDemuxContext
),
313 .read_probe
= seq_probe
,
314 .read_header
= seq_read_header
,
315 .read_packet
= seq_read_packet
,
316 .read_close
= seq_read_close
,