This replaces the old essence_offset code
Unified · Split
| @@ -190,9 +190,6 @@ typedef struct { · 189 unmodified lines | |||
| 190 | uint8_t *local_tags; | 190 | uint8_t *local_tags; |
| 191 | int local_tags_count; | 191 | int local_tags_count; |
| 192 | uint64_t footer_partition; | 192 | uint64_t footer_partition; |
| 193 | int64_t essence_offset; | ||
| 194 | int first_essence_kl_length; | ||
| 195 | int64_t first_essence_length; | ||
| 196 | KLVPacket current_klv_data; | 193 | KLVPacket current_klv_data; |
| 197 | int current_klv_index; | 194 | int current_klv_index; |
| 198 | int run_in; | 195 | int run_in; |
| @@ -985,9 +982,36 @@ static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segment · 786 unmodified lines | |||
| 985 | return 0; | 982 | return 0; |
| 986 | } | 983 | } |
| 987 | 984 | ||
| 985 | /** | ||
| 986 | * Computes the absolute file offset of the given essence container offset | ||
| 987 | */ | ||
| 988 | static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out) | ||
| 989 | { | ||
| 990 | int x; | ||
| 991 | int64_t offset_in = offset; /* for logging */ | ||
| 992 | |||
| 993 | for (x = 0; x < mxf->partitions_count; x++) { | ||
| 994 | MXFPartition *p = &mxf->partitions[x]; | ||
| 995 | |||
| 996 | if (p->body_sid != body_sid) | ||
| 997 | continue; | ||
| 998 | |||
| 999 | if (offset < p->essence_length || !p->essence_length) { | ||
| 1000 | *offset_out = p->essence_offset + offset; | ||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | offset -= p->essence_length; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | av_log(mxf->fc, AV_LOG_ERROR, "failed to find absolute offset of %lx in BodySID %i - partial file?\n", | ||
| 1008 | offset_in, body_sid); | ||
| 1009 | |||
| 1010 | return AVERROR_INVALIDDATA; | ||
| 1011 | } | ||
| 1012 | |||
| 988 | static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) | 1013 | static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) |
| 989 | { | 1014 | { |
| 990 | int64_t accumulated_offset = 0; | ||
| 991 | int j, k, ret, nb_sorted_segments; | 1015 | int j, k, ret, nb_sorted_segments; |
| 992 | MXFIndexTableSegment **sorted_segments; | 1016 | MXFIndexTableSegment **sorted_segments; |
| 993 | int n_delta = track_id - 1; /* TrackID = 1-based stream index */ | 1017 | int n_delta = track_id - 1; /* TrackID = 1-based stream index */ |
| @@ -1005,10 +1029,6 @@ static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) · 11 unmodified lines | |||
| 1005 | int64_t segment_size; | 1029 | int64_t segment_size; |
| 1006 | MXFIndexTableSegment *tableseg = sorted_segments[j]; | 1030 | MXFIndexTableSegment *tableseg = sorted_segments[j]; |
| 1007 | 1031 | ||
| 1008 | /* reset accumulated_offset on BodySID change */ | ||
| 1009 | if (j > 0 && tableseg->body_sid != sorted_segments[j-1]->body_sid) | ||
| 1010 | accumulated_offset = 0; | ||
| 1011 | |||
| 1012 | if (n_delta >= tableseg->nb_delta_entries && st->index != 0) | 1032 | if (n_delta >= tableseg->nb_delta_entries && st->index != 0) |
| 1013 | continue; | 1033 | continue; |
| 1014 | duration = tableseg->index_duration > 0 ? tableseg->index_duration : | 1034 | duration = tableseg->index_duration > 0 ? tableseg->index_duration : |
| @@ -1054,7 +1074,7 @@ static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) · 39 unmodified lines | |||
| 1054 | size = 0; | 1074 | size = 0; |
| 1055 | flags = !(tableseg->flag_entries[k] & 0x30) ? AVINDEX_KEYFRAME : 0; | 1075 | flags = !(tableseg->flag_entries[k] & 0x30) ? AVINDEX_KEYFRAME : 0; |
| 1056 | } else { | 1076 | } else { |
| 1057 | pos = (int64_t)k * tableseg->edit_unit_byte_count + accumulated_offset; | 1077 | pos = (int64_t)(tableseg->index_start_position + k) * tableseg->edit_unit_byte_count; |
| 1058 | if (n_delta < tableseg->nb_delta_entries - 1) | 1078 | if (n_delta < tableseg->nb_delta_entries - 1) |
| 1059 | size = tableseg->element_delta[n_delta+1] - tableseg->element_delta[n_delta]; | 1079 | size = tableseg->element_delta[n_delta+1] - tableseg->element_delta[n_delta]; |
| 1060 | else { | 1080 | else { |
| @@ -1071,10 +1091,10 @@ static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) · 10 unmodified lines | |||
| 1071 | flags = AVINDEX_KEYFRAME; | 1091 | flags = AVINDEX_KEYFRAME; |
| 1072 | } | 1092 | } |
| 1073 | 1093 | ||
| 1074 | if (k > 0 && pos < mxf->first_essence_length && accumulated_offset == 0) | 1094 | if (mxf_absolute_bodysid_offset(mxf, tableseg->body_sid, pos, &pos) < 0) { |
| 1075 | pos += mxf->first_essence_kl_length; | 1095 | /* probably partial file - no point going further for this stream */ |
| 1076 | 1096 | break; | |
| 1077 | pos += mxf->essence_offset; | 1097 | } |
| 1078 | 1098 | ||
| 1079 | av_dlog(mxf->fc, "Stream %d IndexEntry %d TrackID %d Offset %"PRIx64" Timestamp %"PRId64"\n", | 1099 | av_dlog(mxf->fc, "Stream %d IndexEntry %d TrackID %d Offset %"PRIx64" Timestamp %"PRId64"\n", |
| 1080 | st->index, st->nb_index_entries, track_id, pos, sample_duration * st->nb_index_entries); | 1100 | st->index, st->nb_index_entries, track_id, pos, sample_duration * st->nb_index_entries); |
| @@ -1082,7 +1102,6 @@ static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st) · 1 unmodified line | |||
| 1082 | if ((ret = av_add_index_entry(st, pos, sample_duration * st->nb_index_entries, size, 0, flags)) < 0) | 1102 | if ((ret = av_add_index_entry(st, pos, sample_duration * st->nb_index_entries, size, 0, flags)) < 0) |
| 1083 | return ret; | 1103 | return ret; |
| 1084 | } | 1104 | } |
| 1085 | accumulated_offset += segment_size; | ||
| 1086 | } | 1105 | } |
| 1087 | 1106 | ||
| 1088 | av_free(sorted_segments); | 1107 | av_free(sorted_segments); |
| @@ -1474,6 +1493,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) · 385 unmodified lines | |||
| 1474 | { | 1493 | { |
| 1475 | MXFContext *mxf = s->priv_data; | 1494 | MXFContext *mxf = s->priv_data; |
| 1476 | KLVPacket klv; | 1495 | KLVPacket klv; |
| 1496 | int64_t essence_offset = 0; | ||
| 1477 | 1497 | ||
| 1478 | mxf->last_forward_tell = INT64_MAX; | 1498 | mxf->last_forward_tell = INT64_MAX; |
| 1479 | 1499 | ||
| @@ -1525,13 +1545,8 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) · 45 unmodified lines | |||
| 1525 | } | 1545 | } |
| 1526 | } | 1546 | } |
| 1527 | 1547 | ||
| 1528 | if (!mxf->essence_offset) | 1548 | if (!essence_offset) |
| 1529 | mxf->essence_offset = klv.offset; | 1549 | essence_offset = klv.offset; |
| 1530 | |||
| 1531 | if (!mxf->first_essence_kl_length && IS_KLV_KEY(klv.key, mxf_essence_element_key)) { | ||
| 1532 | mxf->first_essence_kl_length = avio_tell(s->pb) - klv.offset; | ||
| 1533 | mxf->first_essence_length = klv.length; | ||
| 1534 | } | ||
| 1535 | 1550 | ||
| 1536 | /* seek to footer, previous partition or stop */ | 1551 | /* seek to footer, previous partition or stop */ |
| 1537 | if (mxf_parse_handle_essence(mxf) <= 0) | 1552 | if (mxf_parse_handle_essence(mxf) <= 0) |
| @@ -1565,11 +1580,11 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) · 27 unmodified lines | |||
| 1565 | avio_skip(s->pb, klv.length); | 1580 | avio_skip(s->pb, klv.length); |
| 1566 | } | 1581 | } |
| 1567 | /* FIXME avoid seek */ | 1582 | /* FIXME avoid seek */ |
| 1568 | if (!mxf->essence_offset) { | 1583 | if (!essence_offset) { |
| 1569 | av_log(s, AV_LOG_ERROR, "no essence\n"); | 1584 | av_log(s, AV_LOG_ERROR, "no essence\n"); |
| 1570 | return AVERROR_INVALIDDATA; | 1585 | return AVERROR_INVALIDDATA; |
| 1571 | } | 1586 | } |
| 1572 | avio_seek(s->pb, mxf->essence_offset, SEEK_SET); | 1587 | avio_seek(s->pb, essence_offset, SEEK_SET); |
| 1573 | 1588 | ||
| 1574 | mxf_compute_essence_containers(mxf); | 1589 | mxf_compute_essence_containers(mxf); |
| 1575 | 1590 | ||