annotate rl2.c @ 3754:8d267b43eaba libavformat

Move malloc() down until after all initializations, so that the resource is only allocated if initialization worked. This means that on failure, we don't have to deallocate it.
author rbultje
date Sat, 23 Aug 2008 18:46:30 +0000
parents 7a0230981402
children 1d3d17de20ba
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
1 /*
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
2 * RL2 Format Demuxer
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
3 * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
4 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
5 * This file is part of FFmpeg.
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
6 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
11 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
15 * Lesser General Public License for more details.
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
16 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
20 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
21
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
22 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
23 * RL2 file demuxer
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
24 * @file rl2.c
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
25 * @author Sascha Sommer (saschasommer@freenet.de)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
26 * For more information regarding the RL2 file format, visit:
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
27 * http://wiki.multimedia.cx/index.php?title=RL2
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
28 *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
29 * extradata:
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
30 * 2 byte le initial drawing offset within 320x200 viewport
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
31 * 4 byte le number of used colors
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
32 * 256 * 3 bytes rgb palette
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
33 * optional background_frame
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
34 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
35
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
36 #include "avformat.h"
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
37
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
38 #define EXTRADATA1_SIZE (6 + 256 * 3) ///< video base, clr, palette
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
39
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
40 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
41 #define RLV2_TAG MKBETAG('R', 'L', 'V', '2')
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
42 #define RLV3_TAG MKBETAG('R', 'L', 'V', '3')
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
43
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
44 typedef struct Rl2DemuxContext {
3365
19bd4caf27a9 consistency cosmetics: indices --> indexes
diego
parents: 3172
diff changeset
45 unsigned int index_pos[2]; ///< indexes in the sample tables
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
46 } Rl2DemuxContext;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
47
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
48
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
49 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
50 * check if the file is in rl2 format
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
51 * @param p probe buffer
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
52 * @return 0 when the probe buffer does not contain rl2 data, > 0 otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
53 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
54 static int rl2_probe(AVProbeData *p)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
55 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
56
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
57 if(AV_RB32(&p->buf[0]) != FORM_TAG)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
58 return 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
59
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
60 if(AV_RB32(&p->buf[8]) != RLV2_TAG &&
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
61 AV_RB32(&p->buf[8]) != RLV3_TAG)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
62 return 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
63
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
64 return AVPROBE_SCORE_MAX;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
65 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
66
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
67 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
68 * read rl2 header data and setup the avstreams
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
69 * @param s demuxer context
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
70 * @param ap format parameters
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
71 * @return 0 on success, AVERROR otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
72 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
73 static av_cold int rl2_read_header(AVFormatContext *s,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
74 AVFormatParameters *ap)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
75 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
76 ByteIOContext *pb = s->pb;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
77 AVStream *st;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
78 unsigned int frame_count;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
79 unsigned int audio_frame_counter = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
80 unsigned int video_frame_counter = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
81 unsigned int back_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
82 int data_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
83 unsigned short encoding_method;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
84 unsigned short sound_rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
85 unsigned short rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
86 unsigned short channels;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
87 unsigned short def_sound_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
88 unsigned int signature;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
89 unsigned int pts_den = 11025; /* video only case */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
90 unsigned int pts_num = 1103;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
91 unsigned int* chunk_offset = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
92 int* chunk_size = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
93 int* audio_size = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
94 int i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
95 int ret = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
96
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
97 url_fskip(pb,4); /* skip FORM tag */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
98 back_size = get_le32(pb); /** get size of the background frame */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
99 signature = get_be32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
100 data_size = get_be32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
101 frame_count = get_le32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
102
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
103 /* disallow back_sizes and frame_counts that may lead to overflows later */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
104 if(back_size > INT_MAX/2 || frame_count > INT_MAX / sizeof(uint32_t))
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
105 return AVERROR_INVALIDDATA;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
106
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
107 encoding_method = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
108 sound_rate = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
109 rate = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
110 channels = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
111 def_sound_size = get_le16(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
112
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
113 /** setup video stream */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
114 st = av_new_stream(s, 0);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
115 if(!st)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
116 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
117
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
118 st->codec->codec_type = CODEC_TYPE_VIDEO;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
119 st->codec->codec_id = CODEC_ID_RL2;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
120 st->codec->codec_tag = 0; /* no fourcc */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
121 st->codec->width = 320;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
122 st->codec->height = 200;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
123
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
124 /** allocate and fill extradata */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
125 st->codec->extradata_size = EXTRADATA1_SIZE;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
126
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
127 if(signature == RLV3_TAG && back_size > 0)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
128 st->codec->extradata_size += back_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
129
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
130 st->codec->extradata = av_mallocz(st->codec->extradata_size +
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
131 FF_INPUT_BUFFER_PADDING_SIZE);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
132 if(!st->codec->extradata)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
133 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
134
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
135 if(get_buffer(pb,st->codec->extradata,st->codec->extradata_size) !=
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
136 st->codec->extradata_size)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
137 return AVERROR(EIO);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
138
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
139 /** setup audio stream if present */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
140 if(sound_rate){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
141 pts_num = def_sound_size;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
142 pts_den = rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
143
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
144 st = av_new_stream(s, 0);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
145 if (!st)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
146 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
147 st->codec->codec_type = CODEC_TYPE_AUDIO;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
148 st->codec->codec_id = CODEC_ID_PCM_U8;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
149 st->codec->codec_tag = 1;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
150 st->codec->channels = channels;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
151 st->codec->bits_per_sample = 8;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
152 st->codec->sample_rate = rate;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
153 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
154 st->codec->bits_per_sample;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
155 st->codec->block_align = st->codec->channels *
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
156 st->codec->bits_per_sample / 8;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
157 av_set_pts_info(st,32,1,rate);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
158 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
159
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
160 av_set_pts_info(s->streams[0], 32, pts_num, pts_den);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
161
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
162 chunk_size = av_malloc(frame_count * sizeof(uint32_t));
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
163 audio_size = av_malloc(frame_count * sizeof(uint32_t));
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
164 chunk_offset = av_malloc(frame_count * sizeof(uint32_t));
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
165
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
166 if(!chunk_size || !audio_size || !chunk_offset){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
167 av_free(chunk_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
168 av_free(audio_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
169 av_free(chunk_offset);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
170 return AVERROR(ENOMEM);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
171 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
173 /** read offset and size tables */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
174 for(i=0; i < frame_count;i++)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
175 chunk_size[i] = get_le32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
176 for(i=0; i < frame_count;i++)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
177 chunk_offset[i] = get_le32(pb);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
178 for(i=0; i < frame_count;i++)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
179 audio_size[i] = get_le32(pb) & 0xFFFF;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
180
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
181 /** build the sample index */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
182 for(i=0;i<frame_count;i++){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
183 if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
184 ret = AVERROR_INVALIDDATA;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
185 break;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
186 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
187
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
188 if(sound_rate && audio_size[i]){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
189 av_add_index_entry(s->streams[1], chunk_offset[i],
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
190 audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
191 audio_frame_counter += audio_size[i] / channels;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
192 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
193 av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i],
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
194 video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
195 ++video_frame_counter;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
196 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
197
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
198
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
199 av_free(chunk_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
200 av_free(audio_size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
201 av_free(chunk_offset);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
202
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
203 return ret;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
204 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
205
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
206 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
207 * read a single audio or video packet
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
208 * @param s demuxer context
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
209 * @param pkt the packet to be filled
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
210 * @return 0 on success, AVERROR otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
211 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
212 static int rl2_read_packet(AVFormatContext *s,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
213 AVPacket *pkt)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
214 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
215 Rl2DemuxContext *rl2 = s->priv_data;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
216 ByteIOContext *pb = s->pb;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
217 AVIndexEntry *sample = NULL;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
218 int i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
219 int ret = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
220 int stream_id = -1;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
221 int64_t pos = INT64_MAX;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
222
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
223 /** check if there is a valid video or audio entry that can be used */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
224 for(i=0; i<s->nb_streams; i++){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
225 if(rl2->index_pos[i] < s->streams[i]->nb_index_entries
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
226 && s->streams[i]->index_entries[ rl2->index_pos[i] ].pos < pos){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
227 sample = &s->streams[i]->index_entries[ rl2->index_pos[i] ];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
228 pos= sample->pos;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
229 stream_id= i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
230 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
231 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
232
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
233 if(stream_id == -1)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
234 return AVERROR(EIO);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
235
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
236 ++rl2->index_pos[stream_id];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
237
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
238 /** position the stream (will probably be there anyway) */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
239 url_fseek(pb, sample->pos, SEEK_SET);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
240
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
241 /** fill the packet */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
242 ret = av_get_packet(pb, pkt, sample->size);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
243 if(ret != sample->size){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
244 av_free_packet(pkt);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
245 return AVERROR(EIO);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
246 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
247
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
248 pkt->stream_index = stream_id;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
249 pkt->pts = sample->timestamp;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
250
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
251 return ret;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
252 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
253
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
254 /**
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
255 * seek to a new timestamp
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
256 * @param s demuxer context
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
257 * @param stream_index index of the stream that should be seeked
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
258 * @param timestamp wanted timestamp
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
259 * @param flags direction and seeking mode
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
260 * @return 0 on success, -1 otherwise
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
261 */
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
262 static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
263 {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
264 AVStream *st = s->streams[stream_index];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
265 Rl2DemuxContext *rl2 = s->priv_data;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
266 int i;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
267 int index = av_index_search_timestamp(st, timestamp, flags);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
268 if(index < 0)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
269 return -1;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
270
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
271 rl2->index_pos[stream_index] = index;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
272 timestamp = st->index_entries[index].timestamp;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
273
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
274 for(i=0; i < s->nb_streams; i++){
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
275 AVStream *st2 = s->streams[i];
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
276 index = av_index_search_timestamp(st2,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
277 av_rescale_q(timestamp, st->time_base, st2->time_base),
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
278 flags | AVSEEK_FLAG_BACKWARD);
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
279
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
280 if(index < 0)
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
281 index = 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
282
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
283 rl2->index_pos[i] = index;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
284 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
285
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
286 return 0;
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
287 }
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
288
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
289 AVInputFormat rl2_demuxer = {
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
290 "rl2",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 3365
diff changeset
291 NULL_IF_CONFIG_SMALL("rl2 format"),
3172
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
292 sizeof(Rl2DemuxContext),
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
293 rl2_probe,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
294 rl2_read_header,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
295 rl2_read_packet,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
296 NULL,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
297 rl2_read_seek,
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
298 };
c806866fa0cc rl2 demuxer
faust3
parents:
diff changeset
299