| 519 | } |
| 520 | |
| 521 | static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t max_pos) |
| 522 | { |
| 523 | FLVContext *flv = s->priv_data; |
| 524 | unsigned int timeslen = 0, fileposlen = 0, i; |
| 525 | char str_val[256]; |
| 526 | int64_t *times = NULL; |
| 527 | int64_t *filepositions = NULL; |
| 528 | int ret = AVERROR(ENOSYS); |
| 529 | int64_t initial_pos = avio_tell(ioc); |
| 530 | |
| 531 | if (flv->keyframe_count > 0) { |
| 532 | av_log(s, AV_LOG_DEBUG, "keyframes have been parsed\n"); |
| 533 | return 0; |
| 534 | } |
| 535 | av_assert0(!flv->keyframe_times); |
| 536 | av_assert0(!flv->keyframe_filepositions); |
| 537 | |
| 538 | if (s->flags & AVFMT_FLAG_IGNIDX) |
| 539 | return 0; |
| 540 | |
| 541 | while (avio_tell(ioc) < max_pos - 2 && |
| 542 | amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { |
| 543 | int64_t **current_array; |
| 544 | unsigned int arraylen; |
| 545 | int factor; |
| 546 | |
| 547 | // Expect array object in context |
| 548 | if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY) |
| 549 | break; |
| 550 | |
| 551 | arraylen = avio_rb32(ioc); |
| 552 | if (arraylen>>28) |
| 553 | break; |
| 554 | |
| 555 | if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) { |
| 556 | current_array = × |
| 557 | timeslen = arraylen; |
| 558 | factor = 1000; |
| 559 | } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && |
| 560 | !filepositions) { |
| 561 | current_array = &filepositions; |
| 562 | fileposlen = arraylen; |
| 563 | factor = 1; |
| 564 | } else |
| 565 | // unexpected metatag inside keyframes, will not use such |
| 566 | // metadata for indexing |
| 567 | break; |
| 568 | |
| 569 | if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) { |
| 570 | ret = AVERROR(ENOMEM); |
| 571 | goto finish; |
| 572 | } |
| 573 | |
| 574 | for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) { |
| 575 | double d; |
| 576 | if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER) |
| 577 | goto invalid; |
| 578 | d = av_int2double(avio_rb64(ioc)) * factor; |
no test coverage detected