On Wed, 13 Jun 2018, Tomas Härdin wrote:
sön 2018-06-10 klockan 12:36 +0200 skrev Marton Balint:
Also compute the correct essence_offset and essence_length for all clip wrapped
essences.
> Signed-off-by: Marton Balint <c...@passwd.hu>
---
libavformat/mxfdec.c | 108 +++++++++++++++++++++++++++------------------------
1 file changed, 57 insertions(+), 51 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 1ab34f4873..67b0028e88 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -98,6 +98,7 @@ typedef struct MXFPartition {
int pack_length;
int64_t pack_ofs; ///< absolute offset of pack in file,
including run-in
int64_t body_offset;
+ KLVPacket first_essence_klv;
} MXFPartition;
typedef struct MXFCryptoContext {
@@ -2782,47 +2783,76 @@ static int mxf_parse_handle_partition_or_eof(MXFContext
*mxf)
return mxf->parsing_backward ? mxf_seek_to_previous_partition(mxf) : 1;
}
+static int64_t round_to_kag(int64_t position, int kag_size)
+{
+ /* TODO: account for run-in? the spec isn't clear whether KAG should
account for it */
+ /* NOTE: kag_size may be any integer between 1 - 2^10 */
+ int64_t ret = (position / kag_size) * kag_size;
+ return ret == position ? ret : ret + kag_size;
This should probably just be
return ((position + kag_size - 1) / kag_size) * kag_size;
but maybe there's some fine point I'm overlooking. What happens if
kag_size is a smallish value like 16?
A check for position > INT64_MAX - kag_size might also be appropriate.
Well, this is your code as well :), I just moved it to avoid a forward
declaration.
+}
+
+static MXFWrappingScheme mxf_get_wrapping_by_body_sid(AVFormatContext *s, int
body_sid)
+{
+ for (int i = 0; i < s->nb_streams; i++) {
+ MXFTrack *track = s->streams[i]->priv_data;
+ if (track && track->body_sid == body_sid && track->wrapping !=
UnknownWrapped)
+ return track->wrapping;
+ }
+ return UnknownWrapped;
+}
+
/**
* Figures out the proper offset and length of the essence container in each
partition
*/
-static void mxf_compute_essence_containers(MXFContext *mxf)
+static void mxf_compute_essence_containers(AVFormatContext *s)
{
+ MXFContext *mxf = s->priv_data;
int x;
- /* everything is already correct */
- if (mxf->op == OPAtom)
- return;
-
for (x = 0; x < mxf->partitions_count; x++) {
MXFPartition *p = &mxf->partitions[x];
+ MXFWrappingScheme wrapping;
if (!p->body_sid)
continue; /* BodySID == 0 -> no essence */
- if (x >= mxf->partitions_count - 1)
- break; /* FooterPartition - can't compute length (and we
don't need to) */
+ /* for non clip-wrapped essences we compute essence_offset
+ * for clip wrapped essences we point essence_offset after the KL
(usually klv.offset + 20 or 25)
+ */
- /* essence container spans to the next partition */
- p->essence_length = mxf->partitions[x+1].this_partition -
p->essence_offset;
+ wrapping = (mxf->op == OPAtom) ? ClipWrapped :
mxf_get_wrapping_by_body_sid(s, p->body_sid);
- if (p->essence_length < 0) {
- /* next ThisPartition < essence_offset */
- p->essence_length = 0;
- av_log(mxf->fc, AV_LOG_ERROR,
- "partition %i: bad ThisPartition = %"PRIX64"\n",
- x+1, mxf->partitions[x+1].this_partition);
+ if (wrapping == ClipWrapped) {
+ p->essence_offset = p->first_essence_klv.next_klv -
p->first_essence_klv.length;
+ p->essence_length = p->first_essence_klv.length;
Much nicer
+ } else {
+ int64_t op1a_essence_offset =
+ p->this_partition +
+ round_to_kag(p->pack_length, p->kag_size) +
+ round_to_kag(p->header_byte_count, p->kag_size) +
+ round_to_kag(p->index_byte_count, p->kag_size);
Is this really always the case? I guess with OP1a it isn't a huge
concern since the demuxer will find the next essence packet anyway. But
still..
I'm also fairly sure this is my code originally so.. :)
I think this tends to work well, if kag_size is not guessed. However, if
it _is_ guessed, then there might be problems, and having a 0 kagsize is
valid (only means an unknown KAG). So I am inclined to simply
use p->first_essence_klv.offset unconditionally, as you suggested in
http://ffmpeg.org/pipermail/ffmpeg-devel/2018-February/225629.html
See the attached patch.
Regards,
Marton
From 6ff3c549fa78caeb8bfddfbee9961ecd59ca7c5f Mon Sep 17 00:00:00 2001
From: Marton Balint <c...@passwd.hu>
Date: Wed, 13 Jun 2018 21:46:34 +0200
Subject: [PATCH] avformat/mxfdec: simply use the first essence element for non
frame-wrapped partition essence offset
Also add the canopus essence element to the list of the recognized essence
element keys.
Signed-off-by: Marton Balint <c...@passwd.hu>
---
libavformat/mxfdec.c | 33 ++-------------------------------
1 file changed, 2 insertions(+), 31 deletions(-)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 8f43ef46b9..2ec778e280 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -719,18 +719,6 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size
mxf->op = OP1a;
}
- if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) {
- av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %"PRId32" - guessing ",
- partition->kag_size);
-
- if (mxf->op == OPSONYOpt)
- partition->kag_size = 512;
- else
- partition->kag_size = 1;
-
- av_log(mxf->fc, AV_LOG_WARNING, "%"PRId32"\n", partition->kag_size);
- }
-
return 0;
}
@@ -2800,14 +2788,6 @@ static int mxf_parse_handle_partition_or_eof(MXFContext *mxf)
return mxf->parsing_backward ? mxf_seek_to_previous_partition(mxf) : 1;
}
-static int64_t round_to_kag(int64_t position, int kag_size)
-{
- /* TODO: account for run-in? the spec isn't clear whether KAG should account for it */
- /* NOTE: kag_size may be any integer between 1 - 2^10 */
- int64_t ret = (position / kag_size) * kag_size;
- return ret == position ? ret : ret + kag_size;
-}
-
static MXFWrappingScheme mxf_get_wrapping_by_body_sid(AVFormatContext *s, int body_sid)
{
for (int i = 0; i < s->nb_streams; i++) {
@@ -2843,17 +2823,7 @@ static void mxf_compute_essence_containers(AVFormatContext *s)
p->essence_offset = p->first_essence_klv.next_klv - p->first_essence_klv.length;
p->essence_length = p->first_essence_klv.length;
} else {
- int64_t op1a_essence_offset =
- p->this_partition +
- round_to_kag(p->pack_length, p->kag_size) +
- round_to_kag(p->header_byte_count, p->kag_size) +
- round_to_kag(p->index_byte_count, p->kag_size);
-
- /* NOTE: op1a_essence_offset may be less than to klv.offset (C0023S01.mxf) */
- if (IS_KLV_KEY(p->first_essence_klv.key, mxf_system_item_key_cp) || IS_KLV_KEY(p->first_essence_klv.key, mxf_system_item_key_gc))
- p->essence_offset = p->first_essence_klv.offset;
- else
- p->essence_offset = op1a_essence_offset;
+ p->essence_offset = p->first_essence_klv.offset;
/* essence container spans to the next partition */
if (x < mxf->partitions_count - 1)
@@ -3066,6 +3036,7 @@ static int mxf_read_header(AVFormatContext *s)
av_log(s, AV_LOG_TRACE, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
+ IS_KLV_KEY(klv.key, mxf_canopus_essence_element_key) ||
IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) ||
IS_KLV_KEY(klv.key, mxf_system_item_key_cp) ||
IS_KLV_KEY(klv.key, mxf_system_item_key_gc)) {
--
2.16.4
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel