diff options
author | Tomas Härdin <tomas.hardin@codemill.se> | 2011-12-15 16:53:38 +0100 |
---|---|---|
committer | Tomas Härdin <tomas.hardin@codemill.se> | 2011-12-16 11:48:02 +0100 |
commit | 36c305f9db0ed9e0a4313f11683ea0de7efc496f (patch) | |
tree | ce28d5fb9c69a5cc4af50763be242d6f0221e9ea /libavformat/mxfdec.c | |
parent | b56adc784288bdbe5e34e581e8081b51a2a3eb5f (diff) | |
download | ffmpeg-36c305f9db0ed9e0a4313f11683ea0de7efc496f.tar.gz |
mxfdec: Add mxf_edit_unit_absolute_offset()
This maps an EditUnit in an index table to the corresponding absolute offset
in the file.
Diffstat (limited to 'libavformat/mxfdec.c')
-rw-r--r-- | libavformat/mxfdec.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index cb2dbf78ea..98a71459b6 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1014,6 +1014,55 @@ static int64_t mxf_essence_container_length(MXFContext *mxf, int body_sid) return ret; } +/* EditUnit -> absolute offset */ +static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, int64_t *edit_unit_out, int64_t *offset_out, int nag) +{ + int i; + int offset_temp = 0; + + for (i = 0; i < index_table->nb_segments; i++) { + MXFIndexTableSegment *s = index_table->segments[i]; + + edit_unit = FFMAX(edit_unit, s->index_start_position); /* clamp if trying to seek before start */ + + if (edit_unit < s->index_start_position + s->index_duration) { + int64_t index = edit_unit - s->index_start_position; + + if (s->edit_unit_byte_count) + offset_temp += s->edit_unit_byte_count * index; + else if (s->nb_index_entries) { + if (s->nb_index_entries == 2 * s->index_duration + 1) + index *= 2; /* Avid index */ + + if (index < 0 || index > s->nb_index_entries) { + av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" IndexEntryArray too small\n", + index_table->index_sid, s->index_start_position); + return AVERROR_INVALIDDATA; + } + + offset_temp = s->stream_offset_entries[index]; + } else { + av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" missing EditUnitByteCount and IndexEntryArray\n", + index_table->index_sid, s->index_start_position); + return AVERROR_INVALIDDATA; + } + + if (edit_unit_out) + *edit_unit_out = edit_unit; + + return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out); + } else { + /* EditUnitByteCount == 0 for VBR indexes, which is fine since they use explicit StreamOffsets */ + offset_temp += s->edit_unit_byte_count * s->index_duration; + } + } + + if (nag) + av_log(mxf->fc, AV_LOG_ERROR, "failed to map EditUnit %"PRId64" in IndexSID %i to an offset\n", edit_unit, index_table->index_sid); + + return AVERROR_INVALIDDATA; +} + static int mxf_parse_index(MXFContext *mxf, int track_id, AVStream *st, MXFIndexTableSegment **sorted_segments, int nb_sorted_segments) { int64_t accumulated_offset = 0; |