This is part of a series of patches that fix tickets 3278 and 4040 (http://trac.ffmpeg.org/ticket/3278 http://trac.ffmpeg.org/ticket/4040), plus some refactoring.

I uploaded a file called deadlock3.mxf (and corresponding deadlock3.txt) to incoming that demonstrates another issue similar to Ticket3278 (see patch 2/5).

/Tomas
From 55117f8fd8d209830db8932a1c59f0b309e3ac44 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <tomas.har...@codemill.se>
Date: Tue, 28 Oct 2014 13:33:04 +0100
Subject: [PATCH 1/5] mxfdec: Break out parts of mxf_read_header() into
 separate functions

---
 libavformat/mxfdec.c | 69 +++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 47 insertions(+), 22 deletions(-)

diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index b01dd0c..31adece 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -2031,6 +2031,51 @@ static int mxf_read_local_tags(MXFContext *mxf, 
KLVPacket *klv, MXFMetadataReadF
 }
 
 /**
+ * Matches any partition pack key, in other words:
+ * - HeaderPartition
+ * - BodyPartition
+ * - FooterPartition
+ * @return non-zero if the key is a partition pack key, zero otherwise
+ */
+static int mxf_is_partition_pack_key(UID key)
+{
+    //NOTE: this is a little lax since it doesn't constraint key[14]
+    return !memcmp(key, mxf_header_partition_pack_key, 13) &&
+            key[13] >= 2 && key[13] <= 4;
+}
+
+/**
+ * Parses a metadata KLV
+ * @return <0 on error, 0 otherwise
+ */
+static int mxf_parse_klv(MXFContext *mxf, KLVPacket klv, MXFMetadataReadFunc 
*read,
+                                     int ctx_size, enum MXFMetadataSetType 
type)
+{
+    AVFormatContext *s = mxf->fc;
+    int res;
+    if (klv.key[5] == 0x53) {
+        res = mxf_read_local_tags(mxf, &klv, read, ctx_size, type);
+    } else {
+        uint64_t next = avio_tell(s->pb) + klv.length;
+        res = read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
+
+        /* only seek forward, else this can loop for a long time */
+        if (avio_tell(s->pb) > next) {
+            av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
+                   klv.offset);
+            return AVERROR_INVALIDDATA;
+        }
+
+        avio_seek(s->pb, next, SEEK_SET);
+    }
+    if (res < 0) {
+        av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
+        return res;
+    }
+    return 0;
+}
+
+/**
  * Seeks to the previous partition, if possible
  * @return <= 0 if we should stop parsing, > 0 if we should keep going
  */
@@ -2292,8 +2337,7 @@ static int mxf_read_header(AVFormatContext *s)
             if (mxf_parse_handle_essence(mxf) <= 0)
                 break;
             continue;
-        } else if (!memcmp(klv.key, mxf_header_partition_pack_key, 13) &&
-                   klv.key[13] >= 2 && klv.key[13] <= 4 && 
mxf->current_partition) {
+        } else if (mxf_is_partition_pack_key(klv.key) && 
mxf->current_partition) {
             /* next partition pack - keep going, seek to previous partition or 
stop */
             if(mxf_parse_handle_partition_or_eof(mxf) <= 0)
                 break;
@@ -2304,27 +2348,8 @@ static int mxf_read_header(AVFormatContext *s)
 
         for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
             if (IS_KLV_KEY(klv.key, metadata->key)) {
-                int res;
-                if (klv.key[5] == 0x53) {
-                    res = mxf_read_local_tags(mxf, &klv, metadata->read, 
metadata->ctx_size, metadata->type);
-                } else {
-                    uint64_t next = avio_tell(s->pb) + klv.length;
-                    res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, 
klv.offset);
-
-                    /* only seek forward, else this can loop for a long time */
-                    if (avio_tell(s->pb) > next) {
-                        av_log(s, AV_LOG_ERROR, "read past end of KLV @ 
%#"PRIx64"\n",
-                               klv.offset);
-                        return AVERROR_INVALIDDATA;
-                    }
-
-                    avio_seek(s->pb, next, SEEK_SET);
-                }
-                if (res < 0) {
-                    av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
-                    ret = res;
+                if ((ret = mxf_parse_klv(mxf, klv, metadata->read, 
metadata->ctx_size, metadata->type)) < 0)
                     goto fail;
-                }
                 break;
             } else {
                 av_log(s, AV_LOG_VERBOSE, "Dark key " PRIxUID "\n",
-- 
1.9.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to