Mercurial > libavformat.hg
comparison matroska.c @ 1829:bf82ef5c32b4 libavformat
split a matroska_parse_block() function from matroska_parse_blockgroup()
author | aurel |
---|---|
date | Thu, 01 Mar 2007 23:46:14 +0000 |
parents | f1397cd39ec3 |
children | ae69f36fe685 |
comparison
equal
deleted
inserted
replaced
1828:f1397cd39ec3 | 1829:bf82ef5c32b4 |
---|---|
2374 { | 2374 { |
2375 return AV_RL32(data+8*slice+4) + 8*slices; | 2375 return AV_RL32(data+8*slice+4) + 8*slices; |
2376 } | 2376 } |
2377 | 2377 |
2378 static int | 2378 static int |
2379 matroska_parse_blockgroup (MatroskaDemuxContext *matroska, | 2379 matroska_parse_block(MatroskaDemuxContext *matroska, uint64_t cluster_time, |
2380 uint64_t cluster_time) | 2380 int is_keyframe, int *ptrack, AVPacket **ppkt) |
2381 { | 2381 { |
2382 int res = 0; | 2382 int res; |
2383 uint32_t id; | 2383 uint32_t id; |
2384 AVPacket *pkt = NULL; | 2384 int track; |
2385 int is_keyframe = PKT_FLAG_KEY, last_num_packets = matroska->num_packets; | 2385 AVPacket *pkt; |
2386 uint64_t duration = AV_NOPTS_VALUE; | |
2387 int track = -1; | |
2388 | |
2389 av_log(matroska->ctx, AV_LOG_DEBUG, "parsing blockgroup...\n"); | |
2390 | |
2391 while (res == 0) { | |
2392 if (!(id = ebml_peek_id(matroska, &matroska->level_up))) { | |
2393 res = AVERROR_IO; | |
2394 break; | |
2395 } else if (matroska->level_up) { | |
2396 matroska->level_up--; | |
2397 break; | |
2398 } | |
2399 | |
2400 switch (id) { | |
2401 /* one block inside the group. Note, block parsing is one | |
2402 * of the harder things, so this code is a bit complicated. | |
2403 * See http://www.matroska.org/ for documentation. */ | |
2404 case MATROSKA_ID_BLOCK: { | |
2405 uint8_t *data, *origdata; | 2386 uint8_t *data, *origdata; |
2406 int size; | 2387 int size; |
2407 int16_t block_time; | 2388 int16_t block_time; |
2408 uint32_t *lace_size = NULL; | 2389 uint32_t *lace_size = NULL; |
2409 int n, flags, laces = 0; | 2390 int n, flags, laces = 0; |
2410 uint64_t num; | 2391 uint64_t num; |
2411 int64_t pos= url_ftell(&matroska->ctx->pb); | 2392 int64_t pos= url_ftell(&matroska->ctx->pb); |
2412 | 2393 |
2413 if ((res = ebml_read_binary(matroska, &id, &data, &size)) < 0) | 2394 if ((res = ebml_read_binary(matroska, &id, &data, &size)) < 0) |
2414 break; | 2395 return res; |
2415 origdata = data; | 2396 origdata = data; |
2416 | 2397 |
2417 /* first byte(s): tracknum */ | 2398 /* first byte(s): tracknum */ |
2418 if ((n = matroska_ebmlnum_uint(data, size, &num)) < 0) { | 2399 if ((n = matroska_ebmlnum_uint(data, size, &num)) < 0) { |
2419 av_log(matroska->ctx, AV_LOG_ERROR, | 2400 av_log(matroska->ctx, AV_LOG_ERROR, |
2420 "EBML block data error\n"); | 2401 "EBML block data error\n"); |
2421 av_free(origdata); | 2402 av_free(origdata); |
2422 break; | 2403 return res; |
2423 } | 2404 } |
2424 data += n; | 2405 data += n; |
2425 size -= n; | 2406 size -= n; |
2426 | 2407 |
2427 /* fetch track from num */ | 2408 /* fetch track from num */ |
2428 track = matroska_find_track_by_num(matroska, num); | 2409 track = matroska_find_track_by_num(matroska, num); |
2410 if (ptrack) *ptrack = track; | |
2429 if (size <= 3 || track < 0 || track >= matroska->num_tracks) { | 2411 if (size <= 3 || track < 0 || track >= matroska->num_tracks) { |
2430 av_log(matroska->ctx, AV_LOG_INFO, | 2412 av_log(matroska->ctx, AV_LOG_INFO, |
2431 "Invalid stream %d or size %u\n", track, size); | 2413 "Invalid stream %d or size %u\n", track, size); |
2432 av_free(origdata); | 2414 av_free(origdata); |
2433 break; | 2415 return res; |
2434 } | 2416 } |
2435 if(matroska->ctx->streams[ matroska->tracks[track]->stream_index ]->discard >= AVDISCARD_ALL){ | 2417 if(matroska->ctx->streams[ matroska->tracks[track]->stream_index ]->discard >= AVDISCARD_ALL){ |
2436 av_free(origdata); | 2418 av_free(origdata); |
2437 break; | 2419 return res; |
2438 } | 2420 } |
2439 | 2421 |
2440 /* block_time (relative to cluster time) */ | 2422 /* block_time (relative to cluster time) */ |
2441 block_time = (data[0] << 8) | data[1]; | 2423 block_time = (data[0] << 8) | data[1]; |
2442 data += 2; | 2424 data += 2; |
2547 if (slice+1 == slices) | 2529 if (slice+1 == slices) |
2548 slice_size = lace_size[n] - slice_offset; | 2530 slice_size = lace_size[n] - slice_offset; |
2549 else | 2531 else |
2550 slice_size = rv_offset(data, slice+1, slices) - slice_offset; | 2532 slice_size = rv_offset(data, slice+1, slices) - slice_offset; |
2551 pkt = av_mallocz(sizeof(AVPacket)); | 2533 pkt = av_mallocz(sizeof(AVPacket)); |
2534 if (ppkt) *ppkt = pkt; | |
2552 /* XXX: prevent data copy... */ | 2535 /* XXX: prevent data copy... */ |
2553 if (av_new_packet(pkt, slice_size) < 0) { | 2536 if (av_new_packet(pkt, slice_size) < 0) { |
2554 res = AVERROR_NOMEM; | 2537 res = AVERROR_NOMEM; |
2555 n = laces-1; | 2538 n = laces-1; |
2556 break; | 2539 break; |
2571 } | 2554 } |
2572 } | 2555 } |
2573 | 2556 |
2574 av_free(lace_size); | 2557 av_free(lace_size); |
2575 av_free(origdata); | 2558 av_free(origdata); |
2559 return res; | |
2560 } | |
2561 | |
2562 static int | |
2563 matroska_parse_blockgroup (MatroskaDemuxContext *matroska, | |
2564 uint64_t cluster_time) | |
2565 { | |
2566 int res = 0; | |
2567 uint32_t id; | |
2568 AVPacket *pkt = NULL; | |
2569 int is_keyframe = PKT_FLAG_KEY, last_num_packets = matroska->num_packets; | |
2570 uint64_t duration = AV_NOPTS_VALUE; | |
2571 int track = -1; | |
2572 | |
2573 av_log(matroska->ctx, AV_LOG_DEBUG, "parsing blockgroup...\n"); | |
2574 | |
2575 while (res == 0) { | |
2576 if (!(id = ebml_peek_id(matroska, &matroska->level_up))) { | |
2577 res = AVERROR_IO; | |
2578 break; | |
2579 } else if (matroska->level_up) { | |
2580 matroska->level_up--; | |
2581 break; | |
2582 } | |
2583 | |
2584 switch (id) { | |
2585 /* one block inside the group. Note, block parsing is one | |
2586 * of the harder things, so this code is a bit complicated. | |
2587 * See http://www.matroska.org/ for documentation. */ | |
2588 case MATROSKA_ID_BLOCK: { | |
2589 res = matroska_parse_block(matroska, cluster_time, | |
2590 is_keyframe, &track, &pkt); | |
2576 break; | 2591 break; |
2577 } | 2592 } |
2578 | 2593 |
2579 case MATROSKA_ID_BLOCKDURATION: { | 2594 case MATROSKA_ID_BLOCKDURATION: { |
2580 if ((res = ebml_read_uint(matroska, &id, &duration)) < 0) | 2595 if ((res = ebml_read_uint(matroska, &id, &duration)) < 0) |