Libav
|
00001 /* 00002 * RL2 Format Demuxer 00003 * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de) 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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 ByteIOContext *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 int data_size; 00084 unsigned short encoding_method; 00085 unsigned short sound_rate; 00086 unsigned short rate; 00087 unsigned short channels; 00088 unsigned short def_sound_size; 00089 unsigned int signature; 00090 unsigned int pts_den = 11025; /* video only case */ 00091 unsigned int pts_num = 1103; 00092 unsigned int* chunk_offset = NULL; 00093 int* chunk_size = NULL; 00094 int* audio_size = NULL; 00095 int i; 00096 int ret = 0; 00097 00098 url_fskip(pb,4); /* skip FORM tag */ 00099 back_size = get_le32(pb); 00100 signature = get_be32(pb); 00101 data_size = get_be32(pb); 00102 frame_count = get_le32(pb); 00103 00104 /* disallow back_sizes and frame_counts that may lead to overflows later */ 00105 if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t)) 00106 return AVERROR_INVALIDDATA; 00107 00108 encoding_method = get_le16(pb); 00109 sound_rate = get_le16(pb); 00110 rate = get_le16(pb); 00111 channels = get_le16(pb); 00112 def_sound_size = get_le16(pb); 00113 00115 st = av_new_stream(s, 0); 00116 if(!st) 00117 return AVERROR(ENOMEM); 00118 00119 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00120 st->codec->codec_id = CODEC_ID_RL2; 00121 st->codec->codec_tag = 0; /* no fourcc */ 00122 st->codec->width = 320; 00123 st->codec->height = 200; 00124 00126 st->codec->extradata_size = EXTRADATA1_SIZE; 00127 00128 if(signature == RLV3_TAG && back_size > 0) 00129 st->codec->extradata_size += back_size; 00130 00131 st->codec->extradata = av_mallocz(st->codec->extradata_size + 00132 FF_INPUT_BUFFER_PADDING_SIZE); 00133 if(!st->codec->extradata) 00134 return AVERROR(ENOMEM); 00135 00136 if(get_buffer(pb,st->codec->extradata,st->codec->extradata_size) != 00137 st->codec->extradata_size) 00138 return AVERROR(EIO); 00139 00141 if(sound_rate){ 00142 pts_num = def_sound_size; 00143 pts_den = rate; 00144 00145 st = av_new_stream(s, 0); 00146 if (!st) 00147 return AVERROR(ENOMEM); 00148 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00149 st->codec->codec_id = CODEC_ID_PCM_U8; 00150 st->codec->codec_tag = 1; 00151 st->codec->channels = channels; 00152 st->codec->bits_per_coded_sample = 8; 00153 st->codec->sample_rate = rate; 00154 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 00155 st->codec->bits_per_coded_sample; 00156 st->codec->block_align = st->codec->channels * 00157 st->codec->bits_per_coded_sample / 8; 00158 av_set_pts_info(st,32,1,rate); 00159 } 00160 00161 av_set_pts_info(s->streams[0], 32, pts_num, pts_den); 00162 00163 chunk_size = av_malloc(frame_count * sizeof(uint32_t)); 00164 audio_size = av_malloc(frame_count * sizeof(uint32_t)); 00165 chunk_offset = av_malloc(frame_count * sizeof(uint32_t)); 00166 00167 if(!chunk_size || !audio_size || !chunk_offset){ 00168 av_free(chunk_size); 00169 av_free(audio_size); 00170 av_free(chunk_offset); 00171 return AVERROR(ENOMEM); 00172 } 00173 00175 for(i=0; i < frame_count;i++) 00176 chunk_size[i] = get_le32(pb); 00177 for(i=0; i < frame_count;i++) 00178 chunk_offset[i] = get_le32(pb); 00179 for(i=0; i < frame_count;i++) 00180 audio_size[i] = get_le32(pb) & 0xFFFF; 00181 00183 for(i=0;i<frame_count;i++){ 00184 if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){ 00185 ret = AVERROR_INVALIDDATA; 00186 break; 00187 } 00188 00189 if(sound_rate && audio_size[i]){ 00190 av_add_index_entry(s->streams[1], chunk_offset[i], 00191 audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME); 00192 audio_frame_counter += audio_size[i] / channels; 00193 } 00194 av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i], 00195 video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME); 00196 ++video_frame_counter; 00197 } 00198 00199 00200 av_free(chunk_size); 00201 av_free(audio_size); 00202 av_free(chunk_offset); 00203 00204 return ret; 00205 } 00206 00213 static int rl2_read_packet(AVFormatContext *s, 00214 AVPacket *pkt) 00215 { 00216 Rl2DemuxContext *rl2 = s->priv_data; 00217 ByteIOContext *pb = s->pb; 00218 AVIndexEntry *sample = NULL; 00219 int i; 00220 int ret = 0; 00221 int stream_id = -1; 00222 int64_t pos = INT64_MAX; 00223 00225 for(i=0; i<s->nb_streams; i++){ 00226 if(rl2->index_pos[i] < s->streams[i]->nb_index_entries 00227 && s->streams[i]->index_entries[ rl2->index_pos[i] ].pos < pos){ 00228 sample = &s->streams[i]->index_entries[ rl2->index_pos[i] ]; 00229 pos= sample->pos; 00230 stream_id= i; 00231 } 00232 } 00233 00234 if(stream_id == -1) 00235 return AVERROR(EIO); 00236 00237 ++rl2->index_pos[stream_id]; 00238 00240 url_fseek(pb, sample->pos, SEEK_SET); 00241 00243 ret = av_get_packet(pb, pkt, sample->size); 00244 if(ret != sample->size){ 00245 av_free_packet(pkt); 00246 return AVERROR(EIO); 00247 } 00248 00249 pkt->stream_index = stream_id; 00250 pkt->pts = sample->timestamp; 00251 00252 return ret; 00253 } 00254 00263 static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 00264 { 00265 AVStream *st = s->streams[stream_index]; 00266 Rl2DemuxContext *rl2 = s->priv_data; 00267 int i; 00268 int index = av_index_search_timestamp(st, timestamp, flags); 00269 if(index < 0) 00270 return -1; 00271 00272 rl2->index_pos[stream_index] = index; 00273 timestamp = st->index_entries[index].timestamp; 00274 00275 for(i=0; i < s->nb_streams; i++){ 00276 AVStream *st2 = s->streams[i]; 00277 index = av_index_search_timestamp(st2, 00278 av_rescale_q(timestamp, st->time_base, st2->time_base), 00279 flags | AVSEEK_FLAG_BACKWARD); 00280 00281 if(index < 0) 00282 index = 0; 00283 00284 rl2->index_pos[i] = index; 00285 } 00286 00287 return 0; 00288 } 00289 00290 AVInputFormat rl2_demuxer = { 00291 "rl2", 00292 NULL_IF_CONFIG_SMALL("RL2 format"), 00293 sizeof(Rl2DemuxContext), 00294 rl2_probe, 00295 rl2_read_header, 00296 rl2_read_packet, 00297 NULL, 00298 rl2_read_seek, 00299 }; 00300