History

mxfdec: Compute packet offsets properly

This replaces the old essence_offset code

Tomas Härdin committed 14 years ago

Commit 5e67e3e1 parent 5fb800f1 file · +38 −23Browse files

Unified · Split

libavformat/mxfdec.c+38−23
@@ -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 */
988static 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
988static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st)1013static 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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t