Originally committed as revision 18013 to svn://svn.ffmpeg.org/ffmpeg/trunk
Ronald S. Bultje authored on 2009/03/16 22:03:23... | ... |
@@ -292,6 +292,49 @@ skip: |
292 | 292 |
return 0; |
293 | 293 |
} |
294 | 294 |
|
295 |
+/** this function assumes that the demuxer has already seeked to the start |
|
296 |
+ * of the INDX chunk, and will bail out if not. */ |
|
297 |
+static int rm_read_index(AVFormatContext *s) |
|
298 |
+{ |
|
299 |
+ ByteIOContext *pb = s->pb; |
|
300 |
+ unsigned int size, n_pkts, str_id, next_off, n, pos, pts; |
|
301 |
+ AVStream *st; |
|
302 |
+ |
|
303 |
+ do { |
|
304 |
+ if (get_le32(pb) != MKTAG('I','N','D','X')) |
|
305 |
+ return -1; |
|
306 |
+ size = get_be32(pb); |
|
307 |
+ if (size < 20) |
|
308 |
+ return -1; |
|
309 |
+ url_fskip(pb, 2); |
|
310 |
+ n_pkts = get_be32(pb); |
|
311 |
+ str_id = get_be16(pb); |
|
312 |
+ next_off = get_be32(pb); |
|
313 |
+ for (n = 0; n < s->nb_streams; n++) |
|
314 |
+ if (s->streams[n]->id == str_id) { |
|
315 |
+ st = s->streams[n]; |
|
316 |
+ break; |
|
317 |
+ } |
|
318 |
+ if (n == s->nb_streams) |
|
319 |
+ goto skip; |
|
320 |
+ |
|
321 |
+ for (n = 0; n < n_pkts; n++) { |
|
322 |
+ url_fskip(pb, 2); |
|
323 |
+ pts = get_be32(pb); |
|
324 |
+ pos = get_be32(pb); |
|
325 |
+ url_fskip(pb, 4); /* packet no. */ |
|
326 |
+ |
|
327 |
+ av_add_index_entry(st, pos, pts, 0, 0, AVINDEX_KEYFRAME); |
|
328 |
+ } |
|
329 |
+ |
|
330 |
+skip: |
|
331 |
+ if (next_off && url_ftell(pb) != next_off && |
|
332 |
+ url_fseek(pb, next_off, SEEK_SET) < 0) |
|
333 |
+ return -1; |
|
334 |
+ } while (next_off); |
|
335 |
+ |
|
336 |
+ return 0; |
|
337 |
+} |
|
295 | 338 |
|
296 | 339 |
static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) |
297 | 340 |
{ |
... | ... |
@@ -314,6 +357,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) |
314 | 314 |
unsigned int tag; |
315 | 315 |
int tag_size; |
316 | 316 |
unsigned int start_time, duration; |
317 |
+ unsigned int data_off = 0, indx_off = 0; |
|
317 | 318 |
char buf[128]; |
318 | 319 |
int flags = 0; |
319 | 320 |
|
... | ... |
@@ -357,8 +401,8 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) |
357 | 357 |
get_be32(pb); /* nb packets */ |
358 | 358 |
get_be32(pb); /* duration */ |
359 | 359 |
get_be32(pb); /* preroll */ |
360 |
- get_be32(pb); /* index offset */ |
|
361 |
- get_be32(pb); /* data offset */ |
|
360 |
+ indx_off = get_be32(pb); /* index offset */ |
|
361 |
+ data_off = get_be32(pb); /* data offset */ |
|
362 | 362 |
get_be16(pb); /* nb streams */ |
363 | 363 |
flags = get_be16(pb); /* flags */ |
364 | 364 |
break; |
... | ... |
@@ -400,6 +444,14 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) |
400 | 400 |
if (!rm->nb_packets && (flags & 4)) |
401 | 401 |
rm->nb_packets = 3600 * 25; |
402 | 402 |
get_be32(pb); /* next data header */ |
403 |
+ |
|
404 |
+ if (!data_off) |
|
405 |
+ data_off = url_ftell(pb) - 18; |
|
406 |
+ if (indx_off && url_fseek(pb, indx_off, SEEK_SET) >= 0) { |
|
407 |
+ rm_read_index(s); |
|
408 |
+ url_fseek(pb, data_off + 18, SEEK_SET); |
|
409 |
+ } |
|
410 |
+ |
|
403 | 411 |
return 0; |
404 | 412 |
} |
405 | 413 |
|