tiertexseq.c
Go to the documentation of this file.
1 /*
2  * Tiertex Limited SEQ File Demuxer
3  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
4  *
5  * This file is part of Libav.
6  *
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.
11  *
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.
16  *
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
20  */
21 
27 #include "avformat.h"
28 #include "internal.h"
29 
30 #define SEQ_FRAME_SIZE 6144
31 #define SEQ_FRAME_W 256
32 #define SEQ_FRAME_H 128
33 #define SEQ_NUM_FRAME_BUFFERS 30
34 #define SEQ_AUDIO_BUFFER_SIZE 882
35 #define SEQ_SAMPLE_RATE 22050
36 #define SEQ_FRAME_RATE 25
37 
38 
39 typedef struct TiertexSeqFrameBuffer {
40  int fill_size;
41  int data_size;
42  unsigned char *data;
44 
45 typedef struct SeqDemuxContext {
54  unsigned int current_pal_data_size;
55  unsigned int current_pal_data_offs;
57  unsigned char *current_video_data_ptr;
60 
61 
62 static int seq_probe(AVProbeData *p)
63 {
64  int i;
65 
66  if (p->buf_size < 258)
67  return 0;
68 
69  /* there's no real header in a .seq file, the only thing they have in common */
70  /* is the first 256 bytes of the file which are always filled with 0 */
71  for (i = 0; i < 256; i++)
72  if (p->buf[i])
73  return 0;
74 
75  if(p->buf[256]==0 && p->buf[257]==0)
76  return 0;
77 
78  /* only one fourth of the score since the previous check is too naive */
79  return AVPROBE_SCORE_MAX / 4;
80 }
81 
83 {
84  int i, sz;
85  TiertexSeqFrameBuffer *seq_buffer;
86 
87  avio_seek(pb, 256, SEEK_SET);
88 
89  for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++) {
90  sz = avio_rl16(pb);
91  if (sz == 0)
92  break;
93  else {
94  seq_buffer = &seq->frame_buffers[i];
95  seq_buffer->fill_size = 0;
96  seq_buffer->data_size = sz;
97  seq_buffer->data = av_malloc(sz);
98  if (!seq_buffer->data)
99  return AVERROR(ENOMEM);
100  }
101  }
102  seq->frame_buffers_count = i;
103  return 0;
104 }
105 
106 static int seq_fill_buffer(SeqDemuxContext *seq, AVIOContext *pb, int buffer_num, unsigned int data_offs, int data_size)
107 {
108  TiertexSeqFrameBuffer *seq_buffer;
109 
110  if (buffer_num >= SEQ_NUM_FRAME_BUFFERS)
111  return AVERROR_INVALIDDATA;
112 
113  seq_buffer = &seq->frame_buffers[buffer_num];
114  if (seq_buffer->fill_size + data_size > seq_buffer->data_size || data_size <= 0)
115  return AVERROR_INVALIDDATA;
116 
117  avio_seek(pb, seq->current_frame_offs + data_offs, SEEK_SET);
118  if (avio_read(pb, seq_buffer->data + seq_buffer->fill_size, data_size) != data_size)
119  return AVERROR(EIO);
120 
121  seq_buffer->fill_size += data_size;
122  return 0;
123 }
124 
126 {
127  unsigned int offset_table[4], buffer_num[4];
128  TiertexSeqFrameBuffer *seq_buffer;
129  int i, e, err;
130 
132  avio_seek(pb, seq->current_frame_offs, SEEK_SET);
133 
134  /* sound data */
136  if (seq->current_audio_data_offs) {
138  } else {
139  seq->current_audio_data_size = 0;
140  }
141 
142  /* palette data */
143  seq->current_pal_data_offs = avio_rl16(pb);
144  if (seq->current_pal_data_offs) {
145  seq->current_pal_data_size = 768;
146  } else {
147  seq->current_pal_data_size = 0;
148  }
149 
150  /* video data */
151  for (i = 0; i < 4; i++)
152  buffer_num[i] = avio_r8(pb);
153 
154  for (i = 0; i < 4; i++)
155  offset_table[i] = avio_rl16(pb);
156 
157  for (i = 0; i < 3; i++) {
158  if (offset_table[i]) {
159  for (e = i + 1; e < 3 && offset_table[e] == 0; e++);
160  err = seq_fill_buffer(seq, pb, buffer_num[1 + i],
161  offset_table[i],
162  offset_table[e] - offset_table[i]);
163  if (err)
164  return err;
165  }
166  }
167 
168  if (buffer_num[0] != 255) {
169  if (buffer_num[0] >= SEQ_NUM_FRAME_BUFFERS)
170  return AVERROR_INVALIDDATA;
171 
172  seq_buffer = &seq->frame_buffers[buffer_num[0]];
173  seq->current_video_data_size = seq_buffer->fill_size;
174  seq->current_video_data_ptr = seq_buffer->data;
175  seq_buffer->fill_size = 0;
176  } else {
177  seq->current_video_data_size = 0;
178  seq->current_video_data_ptr = 0;
179  }
180 
181  return 0;
182 }
183 
185 {
186  int i, rc;
187  SeqDemuxContext *seq = s->priv_data;
188  AVIOContext *pb = s->pb;
189  AVStream *st;
190 
191  /* init internal buffers */
192  rc = seq_init_frame_buffers(seq, pb);
193  if (rc)
194  return rc;
195 
196  seq->current_frame_offs = 0;
197 
198  /* preload (no audio data, just buffer operations related data) */
199  for (i = 1; i <= 100; i++) {
200  rc = seq_parse_frame_data(seq, pb);
201  if (rc)
202  return rc;
203  }
204 
205  seq->current_frame_pts = 0;
206 
207  seq->audio_buffer_full = 0;
208 
209  /* initialize the video decoder stream */
210  st = avformat_new_stream(s, NULL);
211  if (!st)
212  return AVERROR(ENOMEM);
213 
215  seq->video_stream_index = st->index;
218  st->codec->codec_tag = 0; /* no fourcc */
219  st->codec->width = SEQ_FRAME_W;
220  st->codec->height = SEQ_FRAME_H;
221 
222  /* initialize the audio decoder stream */
223  st = avformat_new_stream(s, NULL);
224  if (!st)
225  return AVERROR(ENOMEM);
226 
228  seq->audio_stream_index = st->index;
231  st->codec->codec_tag = 0; /* no tag */
232  st->codec->channels = 1;
234  st->codec->bits_per_coded_sample = 16;
237 
238  return 0;
239 }
240 
242 {
243  int rc;
244  SeqDemuxContext *seq = s->priv_data;
245  AVIOContext *pb = s->pb;
246 
247  if (!seq->audio_buffer_full) {
248  rc = seq_parse_frame_data(seq, pb);
249  if (rc)
250  return rc;
251 
252  /* video packet */
253  if (seq->current_pal_data_size + seq->current_video_data_size != 0) {
255  return AVERROR(ENOMEM);
256 
257  pkt->data[0] = 0;
258  if (seq->current_pal_data_size) {
259  pkt->data[0] |= 1;
260  avio_seek(pb, seq->current_frame_offs + seq->current_pal_data_offs, SEEK_SET);
261  if (avio_read(pb, &pkt->data[1], seq->current_pal_data_size) != seq->current_pal_data_size)
262  return AVERROR(EIO);
263  }
264  if (seq->current_video_data_size) {
265  pkt->data[0] |= 2;
266  memcpy(&pkt->data[1 + seq->current_pal_data_size],
269  }
270  pkt->stream_index = seq->video_stream_index;
271  pkt->pts = seq->current_frame_pts;
272 
273  /* sound buffer will be processed on next read_packet() call */
274  seq->audio_buffer_full = 1;
275  return 0;
276  }
277  }
278 
279  /* audio packet */
280  if (seq->current_audio_data_offs == 0) /* end of data reached */
281  return AVERROR(EIO);
282 
283  avio_seek(pb, seq->current_frame_offs + seq->current_audio_data_offs, SEEK_SET);
284  rc = av_get_packet(pb, pkt, seq->current_audio_data_size);
285  if (rc < 0)
286  return rc;
287 
288  pkt->stream_index = seq->audio_stream_index;
289  seq->current_frame_pts++;
290 
291  seq->audio_buffer_full = 0;
292  return 0;
293 }
294 
296 {
297  int i;
298  SeqDemuxContext *seq = s->priv_data;
299 
300  for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++)
301  av_free(seq->frame_buffers[i].data);
302 
303  return 0;
304 }
305 
307  .name = "tiertexseq",
308  .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
309  .priv_data_size = sizeof(SeqDemuxContext),
314 };
unsigned int current_audio_data_size
Definition: tiertexseq.c:52
Bytestream IO Context.
Definition: avio.h:68
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
static int seq_probe(AVProbeData *p)
Definition: tiertexseq.c:62
AVInputFormat ff_tiertexseq_demuxer
Definition: tiertexseq.c:306
int audio_buffer_full
Definition: tiertexseq.c:58
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the pts for a given stream.
Definition: utils.c:3828
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:60
int index
stream index in AVFormatContext
Definition: avformat.h:621
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:211
#define SEQ_AUDIO_BUFFER_SIZE
Definition: tiertexseq.c:34
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
Definition: avcodec.h:1751
unsigned int current_audio_data_offs
Definition: tiertexseq.c:53
Format I/O context.
Definition: avformat.h:863
int video_stream_index
Definition: tiertexseq.c:47
#define SEQ_FRAME_W
Definition: tiertexseq.c:31
static int read_header(FFV1Context *f)
Definition: ffv1.c:1513
uint8_t * data
Definition: avcodec.h:908
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:140
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:269
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1974
unsigned int current_pal_data_size
Definition: tiertexseq.c:54
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:652
static int seq_parse_frame_data(SeqDemuxContext *seq, AVIOContext *pb)
Definition: tiertexseq.c:125
#define SEQ_NUM_FRAME_BUFFERS
Definition: tiertexseq.c:33
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:137
static int seq_fill_buffer(SeqDemuxContext *seq, AVIOContext *pb, int buffer_num, unsigned int data_offs, int data_size)
Definition: tiertexseq.c:106
int current_frame_offs
Definition: tiertexseq.c:49
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:191
AVStream * avformat_new_stream(AVFormatContext *s, AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:2776
struct SeqDemuxContext SeqDemuxContext
struct TiertexSeqFrameBuffer TiertexSeqFrameBuffer
static int seq_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: tiertexseq.c:241
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:632
AVCodecContext * codec
codec context
Definition: avformat.h:623
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:342
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:341
int current_frame_pts
Definition: tiertexseq.c:48
int frame_buffers_count
Definition: tiertexseq.c:51
int bit_rate
the average bitrate
Definition: avcodec.h:1340
unsigned int current_pal_data_offs
Definition: tiertexseq.c:55
int width
picture width / height.
Definition: avcodec.h:1408
unsigned char * current_video_data_ptr
Definition: tiertexseq.c:57
static int read_probe(AVProbeData *p)
Definition: img2.c:185
static const int offset_table[6]
Definition: vc1dec.c:3304
TiertexSeqFrameBuffer frame_buffers[SEQ_NUM_FRAME_BUFFERS]
Definition: tiertexseq.c:50
#define SEQ_FRAME_RATE
Definition: tiertexseq.c:36
Stream structure.
Definition: avformat.h:620
NULL
Definition: eval.c:50
enum AVMediaType codec_type
Definition: avcodec.h:1574
int sample_rate
samples per second
Definition: avcodec.h:1456
AVIOContext * pb
Definition: avformat.h:896
static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap)
Definition: tiertexseq.c:184
static int seq_read_close(AVFormatContext *s)
Definition: tiertexseq.c:295
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:1590
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:109
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:64
unsigned int current_video_data_size
Definition: tiertexseq.c:56
int audio_stream_index
Definition: tiertexseq.c:46
This structure contains the data a format has to probe a file.
Definition: avformat.h:339
#define AVPROBE_SCORE_MAX
maximum score, half of that is used for file-extension-based detection
Definition: avformat.h:345
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:722
Main libavformat public API header.
unsigned char * data
Definition: tiertexseq.c:42
#define SEQ_SAMPLE_RATE
Definition: tiertexseq.c:35
int channels
number of audio channels
Definition: avcodec.h:1457
void * priv_data
Format private data.
Definition: avformat.h:883
#define SEQ_FRAME_SIZE
Definition: tiertexseq.c:30
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:460
int stream_index
Definition: avcodec.h:910
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:901
static int seq_init_frame_buffers(SeqDemuxContext *seq, AVIOContext *pb)
Definition: tiertexseq.c:82
#define SEQ_FRAME_H
Definition: tiertexseq.c:32
enum CodecID codec_id
Definition: avcodec.h:1575