Libav 0.7.1
|
00001 /* 00002 * RL2 Format Demuxer 00003 * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de) 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 00036 #include "libavutil/intreadwrite.h" 00037 #include "avformat.h" 00038 00039 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette 00040 00041 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M') 00042 #define RLV2_TAG MKBETAG('R', 'L', 'V', '2') 00043 #define RLV3_TAG MKBETAG('R', 'L', 'V', '3') 00044 00045 typedef struct Rl2DemuxContext { 00046 unsigned int index_pos[2]; 00047 } Rl2DemuxContext; 00048 00049 00055 static int rl2_probe(AVProbeData *p) 00056 { 00057 00058 if(AV_RB32(&p->buf[0]) != FORM_TAG) 00059 return 0; 00060 00061 if(AV_RB32(&p->buf[8]) != RLV2_TAG && 00062 AV_RB32(&p->buf[8]) != RLV3_TAG) 00063 return 0; 00064 00065 return AVPROBE_SCORE_MAX; 00066 } 00067 00074 static av_cold int rl2_read_header(AVFormatContext *s, 00075 AVFormatParameters *ap) 00076 { 00077 AVIOContext *pb = s->pb; 00078 AVStream *st; 00079 unsigned int frame_count; 00080 unsigned int audio_frame_counter = 0; 00081 unsigned int video_frame_counter = 0; 00082 unsigned int back_size; 00083 unsigned short sound_rate; 00084 unsigned short rate; 00085 unsigned short channels; 00086 unsigned short def_sound_size; 00087 unsigned int signature; 00088 unsigned int pts_den = 11025; /* video only case */ 00089 unsigned int pts_num = 1103; 00090 unsigned int* chunk_offset = NULL; 00091 int* chunk_size = NULL; 00092 int* audio_size = NULL; 00093 int i; 00094 int ret = 0; 00095 00096 avio_skip(pb,4); /* skip FORM tag */ 00097 back_size = avio_rl32(pb); 00098 signature = avio_rb32(pb); 00099 avio_skip(pb, 4); /* data size */ 00100 frame_count = avio_rl32(pb); 00101 00102 /* disallow back_sizes and frame_counts that may lead to overflows later */ 00103 if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t)) 00104 return AVERROR_INVALIDDATA; 00105 00106 avio_skip(pb, 2); /* encoding mentod */ 00107 sound_rate = avio_rl16(pb); 00108 rate = avio_rl16(pb); 00109 channels = avio_rl16(pb); 00110 def_sound_size = avio_rl16(pb); 00111 00113 st = av_new_stream(s, 0); 00114 if(!st) 00115 return AVERROR(ENOMEM); 00116 00117 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00118 st->codec->codec_id = CODEC_ID_RL2; 00119 st->codec->codec_tag = 0; /* no fourcc */ 00120 st->codec->width = 320; 00121 st->codec->height = 200; 00122 00124 st->codec->extradata_size = EXTRADATA1_SIZE; 00125 00126 if(signature == RLV3_TAG && back_size > 0) 00127 st->codec->extradata_size += back_size; 00128 00129 st->codec->extradata = av_mallocz(st->codec->extradata_size + 00130 FF_INPUT_BUFFER_PADDING_SIZE); 00131 if(!st->codec->extradata) 00132 return AVERROR(ENOMEM); 00133 00134 if(avio_read(pb,st->codec->extradata,st->codec->extradata_size) != 00135 st->codec->extradata_size) 00136 return AVERROR(EIO); 00137 00139 if(sound_rate){ 00140 pts_num = def_sound_size; 00141 pts_den = rate; 00142 00143 st = av_new_stream(s, 0); 00144 if (!st) 00145 return AVERROR(ENOMEM); 00146 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00147 st->codec->codec_id = CODEC_ID_PCM_U8; 00148 st->codec->codec_tag = 1; 00149 st->codec->channels = channels; 00150 st->codec->bits_per_coded_sample = 8; 00151 st->codec->sample_rate = rate; 00152 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 00153 st->codec->bits_per_coded_sample; 00154 st->codec->block_align = st->codec->channels * 00155 st->codec->bits_per_coded_sample / 8; 00156 av_set_pts_info(st,32,1,rate); 00157 } 00158 00159 av_set_pts_info(s->streams[0], 32, pts_num, pts_den); 00160 00161 chunk_size = av_malloc(frame_count * sizeof(uint32_t)); 00162 audio_size = av_malloc(frame_count * sizeof(uint32_t)); 00163 chunk_offset = av_malloc(frame_count * sizeof(uint32_t)); 00164 00165 if(!chunk_size || !audio_size || !chunk_offset){ 00166 av_free(chunk_size); 00167 av_free(audio_size); 00168 av_free(chunk_offset); 00169 return AVERROR(ENOMEM); 00170 } 00171 00173 for(i=0; i < frame_count;i++) 00174 chunk_size[i] = avio_rl32(pb); 00175 for(i=0; i < frame_count;i++) 00176 chunk_offset[i] = avio_rl32(pb); 00177 for(i=0; i < frame_count;i++) 00178 audio_size[i] = avio_rl32(pb) & 0xFFFF; 00179 00181 for(i=0;i<frame_count;i++){ 00182 if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){ 00183 ret = AVERROR_INVALIDDATA; 00184 break; 00185 } 00186 00187 if(sound_rate && audio_size[i]){ 00188 av_add_index_entry(s->streams[1], chunk_offset[i], 00189 audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME); 00190 audio_frame_counter += audio_size[i] / channels; 00191 } 00192 av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i], 00193 video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME); 00194 ++video_frame_counter; 00195 } 00196 00197 00198 av_free(chunk_size); 00199 av_free(audio_size); 00200 av_free(chunk_offset); 00201 00202 return ret; 00203 } 00204 00211 static int rl2_read_packet(AVFormatContext *s, 00212 AVPacket *pkt) 00213 { 00214 Rl2DemuxContext *rl2 = s->priv_data; 00215 AVIOContext *pb = s->pb; 00216 AVIndexEntry *sample = NULL; 00217 int i; 00218 int ret = 0; 00219 int stream_id = -1; 00220 int64_t pos = INT64_MAX; 00221 00223 for(i=0; i<s->nb_streams; i++){ 00224 if(rl2->index_pos[i] < s->streams[i]->nb_index_entries 00225 && s->streams[i]->index_entries[ rl2->index_pos[i] ].pos < pos){ 00226 sample = &s->streams[i]->index_entries[ rl2->index_pos[i] ]; 00227 pos= sample->pos; 00228 stream_id= i; 00229 } 00230 } 00231 00232 if(stream_id == -1) 00233 return AVERROR(EIO); 00234 00235 ++rl2->index_pos[stream_id]; 00236 00238 avio_seek(pb, sample->pos, SEEK_SET); 00239 00241 ret = av_get_packet(pb, pkt, sample->size); 00242 if(ret != sample->size){ 00243 av_free_packet(pkt); 00244 return AVERROR(EIO); 00245 } 00246 00247 pkt->stream_index = stream_id; 00248 pkt->pts = sample->timestamp; 00249 00250 return ret; 00251 } 00252 00261 static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 00262 { 00263 AVStream *st = s->streams[stream_index]; 00264 Rl2DemuxContext *rl2 = s->priv_data; 00265 int i; 00266 int index = av_index_search_timestamp(st, timestamp, flags); 00267 if(index < 0) 00268 return -1; 00269 00270 rl2->index_pos[stream_index] = index; 00271 timestamp = st->index_entries[index].timestamp; 00272 00273 for(i=0; i < s->nb_streams; i++){ 00274 AVStream *st2 = s->streams[i]; 00275 index = av_index_search_timestamp(st2, 00276 av_rescale_q(timestamp, st->time_base, st2->time_base), 00277 flags | AVSEEK_FLAG_BACKWARD); 00278 00279 if(index < 0) 00280 index = 0; 00281 00282 rl2->index_pos[i] = index; 00283 } 00284 00285 return 0; 00286 } 00287 00288 AVInputFormat ff_rl2_demuxer = { 00289 "rl2", 00290 NULL_IF_CONFIG_SMALL("RL2 format"), 00291 sizeof(Rl2DemuxContext), 00292 rl2_probe, 00293 rl2_read_header, 00294 rl2_read_packet, 00295 NULL, 00296 rl2_read_seek, 00297 }; 00298