Libav 0.7.1
|
00001 /* 00002 * Tiertex Limited SEQ File Demuxer 00003 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* there's no real header in a .seq file, the only thing they have in common */ 00069 /* is the first 256 bytes of the file which are always filled with 0 */ 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 /* only one fourth of the score since the previous check is too naive */ 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 /* sound data */ 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 /* palette data */ 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 /* video data */ 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 /* init internal buffers */ 00191 rc = seq_init_frame_buffers(seq, pb); 00192 if (rc) 00193 return rc; 00194 00195 seq->current_frame_offs = 0; 00196 00197 /* preload (no audio data, just buffer operations related data) */ 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 /* initialize the video decoder stream */ 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; /* no fourcc */ 00218 st->codec->width = SEQ_FRAME_W; 00219 st->codec->height = SEQ_FRAME_H; 00220 00221 /* initialize the audio decoder stream */ 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; /* no tag */ 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 /* video packet */ 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 /* sound buffer will be processed on next read_packet() call */ 00273 seq->audio_buffer_full = 1; 00274 return 0; 00275 } 00276 } 00277 00278 /* audio packet */ 00279 if (seq->current_audio_data_offs == 0) /* end of data reached */ 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 };