00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avformat.h"
00028
00029 #define SEQ_FRAME_SIZE 6144
00030 #define SEQ_FRAME_W 256
00031 #define SEQ_FRAME_H 128
00032 #define SEQ_NUM_FRAME_BUFFERS 30
00033 #define SEQ_AUDIO_BUFFER_SIZE 882
00034 #define SEQ_SAMPLE_RATE 22050
00035 #define SEQ_FRAME_RATE 25
00036
00037
00038 typedef struct TiertexSeqFrameBuffer {
00039 int fill_size;
00040 int data_size;
00041 unsigned char *data;
00042 } TiertexSeqFrameBuffer;
00043
00044 typedef struct SeqDemuxContext {
00045 int audio_stream_index;
00046 int video_stream_index;
00047 int current_frame_pts;
00048 int current_frame_offs;
00049 TiertexSeqFrameBuffer frame_buffers[SEQ_NUM_FRAME_BUFFERS];
00050 int frame_buffers_count;
00051 unsigned int current_audio_data_size;
00052 unsigned int current_audio_data_offs;
00053 unsigned int current_pal_data_size;
00054 unsigned int current_pal_data_offs;
00055 unsigned int current_video_data_size;
00056 unsigned char *current_video_data_ptr;
00057 int audio_buffer_full;
00058 } SeqDemuxContext;
00059
00060
00061 static int seq_probe(AVProbeData *p)
00062 {
00063 int i;
00064
00065 if (p->buf_size < 258)
00066 return 0;
00067
00068
00069
00070 for (i = 0; i < 256; i++)
00071 if (p->buf[i])
00072 return 0;
00073
00074 if(p->buf[256]==0 && p->buf[257]==0)
00075 return 0;
00076
00077
00078 return AVPROBE_SCORE_MAX / 4;
00079 }
00080
00081 static int seq_init_frame_buffers(SeqDemuxContext *seq, AVIOContext *pb)
00082 {
00083 int i, sz;
00084 TiertexSeqFrameBuffer *seq_buffer;
00085
00086 avio_seek(pb, 256, SEEK_SET);
00087
00088 for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++) {
00089 sz = avio_rl16(pb);
00090 if (sz == 0)
00091 break;
00092 else {
00093 seq_buffer = &seq->frame_buffers[i];
00094 seq_buffer->fill_size = 0;
00095 seq_buffer->data_size = sz;
00096 seq_buffer->data = av_malloc(sz);
00097 if (!seq_buffer->data)
00098 return AVERROR(ENOMEM);
00099 }
00100 }
00101 seq->frame_buffers_count = i;
00102 return 0;
00103 }
00104
00105 static int seq_fill_buffer(SeqDemuxContext *seq, AVIOContext *pb, int buffer_num, unsigned int data_offs, int data_size)
00106 {
00107 TiertexSeqFrameBuffer *seq_buffer;
00108
00109 if (buffer_num >= SEQ_NUM_FRAME_BUFFERS)
00110 return AVERROR_INVALIDDATA;
00111
00112 seq_buffer = &seq->frame_buffers[buffer_num];
00113 if (seq_buffer->fill_size + data_size > seq_buffer->data_size || data_size <= 0)
00114 return AVERROR_INVALIDDATA;
00115
00116 avio_seek(pb, seq->current_frame_offs + data_offs, SEEK_SET);
00117 if (avio_read(pb, seq_buffer->data + seq_buffer->fill_size, data_size) != data_size)
00118 return AVERROR(EIO);
00119
00120 seq_buffer->fill_size += data_size;
00121 return 0;
00122 }
00123
00124 static int seq_parse_frame_data(SeqDemuxContext *seq, AVIOContext *pb)
00125 {
00126 unsigned int offset_table[4], buffer_num[4];
00127 TiertexSeqFrameBuffer *seq_buffer;
00128 int i, e, err;
00129
00130 seq->current_frame_offs += SEQ_FRAME_SIZE;
00131 avio_seek(pb, seq->current_frame_offs, SEEK_SET);
00132
00133
00134 seq->current_audio_data_offs = avio_rl16(pb);
00135 if (seq->current_audio_data_offs) {
00136 seq->current_audio_data_size = SEQ_AUDIO_BUFFER_SIZE * 2;
00137 } else {
00138 seq->current_audio_data_size = 0;
00139 }
00140
00141
00142 seq->current_pal_data_offs = avio_rl16(pb);
00143 if (seq->current_pal_data_offs) {
00144 seq->current_pal_data_size = 768;
00145 } else {
00146 seq->current_pal_data_size = 0;
00147 }
00148
00149
00150 for (i = 0; i < 4; i++)
00151 buffer_num[i] = avio_r8(pb);
00152
00153 for (i = 0; i < 4; i++)
00154 offset_table[i] = avio_rl16(pb);
00155
00156 for (i = 0; i < 3; i++) {
00157 if (offset_table[i]) {
00158 for (e = i + 1; e < 3 && offset_table[e] == 0; e++);
00159 err = seq_fill_buffer(seq, pb, buffer_num[1 + i],
00160 offset_table[i],
00161 offset_table[e] - offset_table[i]);
00162 if (err)
00163 return err;
00164 }
00165 }
00166
00167 if (buffer_num[0] != 255) {
00168 if (buffer_num[0] >= SEQ_NUM_FRAME_BUFFERS)
00169 return AVERROR_INVALIDDATA;
00170
00171 seq_buffer = &seq->frame_buffers[buffer_num[0]];
00172 seq->current_video_data_size = seq_buffer->fill_size;
00173 seq->current_video_data_ptr = seq_buffer->data;
00174 seq_buffer->fill_size = 0;
00175 } else {
00176 seq->current_video_data_size = 0;
00177 seq->current_video_data_ptr = 0;
00178 }
00179
00180 return 0;
00181 }
00182
00183 static int seq_read_header(AVFormatContext *s, AVFormatParameters *ap)
00184 {
00185 int i, rc;
00186 SeqDemuxContext *seq = s->priv_data;
00187 AVIOContext *pb = s->pb;
00188 AVStream *st;
00189
00190
00191 rc = seq_init_frame_buffers(seq, pb);
00192 if (rc)
00193 return rc;
00194
00195 seq->current_frame_offs = 0;
00196
00197
00198 for (i = 1; i <= 100; i++) {
00199 rc = seq_parse_frame_data(seq, pb);
00200 if (rc)
00201 return rc;
00202 }
00203
00204 seq->current_frame_pts = 0;
00205
00206 seq->audio_buffer_full = 0;
00207
00208
00209 st = av_new_stream(s, 0);
00210 if (!st)
00211 return AVERROR(ENOMEM);
00212
00213 av_set_pts_info(st, 32, 1, SEQ_FRAME_RATE);
00214 seq->video_stream_index = st->index;
00215 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00216 st->codec->codec_id = CODEC_ID_TIERTEXSEQVIDEO;
00217 st->codec->codec_tag = 0;
00218 st->codec->width = SEQ_FRAME_W;
00219 st->codec->height = SEQ_FRAME_H;
00220
00221
00222 st = av_new_stream(s, 0);
00223 if (!st)
00224 return AVERROR(ENOMEM);
00225
00226 av_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE);
00227 seq->audio_stream_index = st->index;
00228 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00229 st->codec->codec_id = CODEC_ID_PCM_S16BE;
00230 st->codec->codec_tag = 0;
00231 st->codec->channels = 1;
00232 st->codec->sample_rate = SEQ_SAMPLE_RATE;
00233 st->codec->bits_per_coded_sample = 16;
00234 st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels;
00235 st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
00236
00237 return 0;
00238 }
00239
00240 static int seq_read_packet(AVFormatContext *s, AVPacket *pkt)
00241 {
00242 int rc;
00243 SeqDemuxContext *seq = s->priv_data;
00244 AVIOContext *pb = s->pb;
00245
00246 if (!seq->audio_buffer_full) {
00247 rc = seq_parse_frame_data(seq, pb);
00248 if (rc)
00249 return rc;
00250
00251
00252 if (seq->current_pal_data_size + seq->current_video_data_size != 0) {
00253 if (av_new_packet(pkt, 1 + seq->current_pal_data_size + seq->current_video_data_size))
00254 return AVERROR(ENOMEM);
00255
00256 pkt->data[0] = 0;
00257 if (seq->current_pal_data_size) {
00258 pkt->data[0] |= 1;
00259 avio_seek(pb, seq->current_frame_offs + seq->current_pal_data_offs, SEEK_SET);
00260 if (avio_read(pb, &pkt->data[1], seq->current_pal_data_size) != seq->current_pal_data_size)
00261 return AVERROR(EIO);
00262 }
00263 if (seq->current_video_data_size) {
00264 pkt->data[0] |= 2;
00265 memcpy(&pkt->data[1 + seq->current_pal_data_size],
00266 seq->current_video_data_ptr,
00267 seq->current_video_data_size);
00268 }
00269 pkt->stream_index = seq->video_stream_index;
00270 pkt->pts = seq->current_frame_pts;
00271
00272
00273 seq->audio_buffer_full = 1;
00274 return 0;
00275 }
00276 }
00277
00278
00279 if (seq->current_audio_data_offs == 0)
00280 return AVERROR(EIO);
00281
00282 avio_seek(pb, seq->current_frame_offs + seq->current_audio_data_offs, SEEK_SET);
00283 rc = av_get_packet(pb, pkt, seq->current_audio_data_size);
00284 if (rc < 0)
00285 return rc;
00286
00287 pkt->stream_index = seq->audio_stream_index;
00288 seq->current_frame_pts++;
00289
00290 seq->audio_buffer_full = 0;
00291 return 0;
00292 }
00293
00294 static int seq_read_close(AVFormatContext *s)
00295 {
00296 int i;
00297 SeqDemuxContext *seq = s->priv_data;
00298
00299 for (i = 0; i < SEQ_NUM_FRAME_BUFFERS; i++)
00300 av_free(seq->frame_buffers[i].data);
00301
00302 return 0;
00303 }
00304
00305 AVInputFormat ff_tiertexseq_demuxer = {
00306 "tiertexseq",
00307 NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ format"),
00308 sizeof(SeqDemuxContext),
00309 seq_probe,
00310 seq_read_header,
00311 seq_read_packet,
00312 seq_read_close,
00313 };