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)