From: Tomas Härdin <[email protected]>

This maps an EditUnit in an index table to the corresponding absolute offset
in the file.
---
 libavformat/mxfdec.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index d602818..b35f02d 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -1039,6 +1039,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;
-- 
1.7.8

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to