aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2018-05-17 20:49:25 +0200
committerMarton Balint <cus@passwd.hu>2018-06-24 20:42:35 +0200
commit7ec90b168b9ad5f6a2798c3df64eba65bd98910a (patch)
tree448427eb1e303d0098cb321b8c312cdbda29bb9f
parentbfa0b50441785871062b507ece63bfaf63f67dfd (diff)
downloadffmpeg-7ec90b168b9ad5f6a2798c3df64eba65bd98910a.tar.gz
avformat/mxfdec: add support for determining essence wrapping scheme
Some code is based on bmxlib-libmxf/mxf/mxf_utils.c. Signed-off-by: Marton Balint <cus@passwd.hu>
-rw-r--r--libavformat/mxf.h9
-rw-r--r--libavformat/mxfdec.c79
2 files changed, 68 insertions, 20 deletions
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index 93bc2cd075..f6e75919c5 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -65,11 +65,20 @@ typedef struct KLVPacket {
int64_t next_klv;
} KLVPacket;
+typedef enum {
+ NormalWrap = 0,
+ D10D11Wrap,
+ RawAWrap,
+ RawVWrap
+} MXFWrappingIndicatorType;
+
typedef struct MXFCodecUL {
UID uid;
unsigned matching_len;
int id;
const char *desc;
+ unsigned wrapping_indicator_pos;
+ MXFWrappingIndicatorType wrapping_indicator_type;
} MXFCodecUL;
typedef struct {
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index a5c5fb3b8a..927653b515 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -76,6 +76,12 @@ typedef enum {
OPSONYOpt, /* FATE sample, violates the spec in places */
} MXFOP;
+typedef enum {
+ UnknownWrapped = 0,
+ FrameWrapped,
+ ClipWrapped,
+} MXFWrappingScheme;
+
typedef struct MXFPartition {
int closed;
int complete;
@@ -165,6 +171,7 @@ typedef struct {
int64_t original_duration; /* st->duration in SampleRate/EditRate units */
int index_sid;
int body_sid;
+ MXFWrappingScheme wrapping;
} MXFTrack;
typedef struct MXFDescriptor {
@@ -281,11 +288,6 @@ typedef struct MXFContext {
int edit_units_per_packet; ///< how many edit units to read at a time (PCM, OPAtom)
} MXFContext;
-enum MXFWrappingScheme {
- Frame,
- Clip,
-};
-
/* NOTE: klv_offset is not set (-1) for local keys */
typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset);
@@ -1233,16 +1235,16 @@ static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMe
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
// video essence container uls
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000 },
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x10,0x60,0x01 }, 14, AV_CODEC_ID_H264 }, /* H.264 frame wrapped */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, 14, AV_CODEC_ID_DNXHD }, /* VC-3 */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x12,0x01,0x00 }, 14, AV_CODEC_ID_VC1 }, /* VC-1 frame wrapped */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x14,0x01,0x00 }, 14, AV_CODEC_ID_TIFF }, /* TIFF */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x15,0x01,0x00 }, 14, AV_CODEC_ID_DIRAC }, /* VC-2 */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MPEG-ES frame wrapped */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* Type D-10 mapping of 40Mbps 525/60-I */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO }, /* DV 625 25mbps */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO }, /* uncompressed picture */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000, NULL, 14 },
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x10,0x60,0x01 }, 14, AV_CODEC_ID_H264, NULL, 15 }, /* H.264 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, 14, AV_CODEC_ID_DNXHD, NULL, 14 }, /* VC-3 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x12,0x01,0x00 }, 14, AV_CODEC_ID_VC1, NULL, 14 }, /* VC-1 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x14,0x01,0x00 }, 14, AV_CODEC_ID_TIFF, NULL, 14 }, /* TIFF */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x15,0x01,0x00 }, 14, AV_CODEC_ID_DIRAC, NULL, 14 }, /* VC-2 */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO, NULL, 15 }, /* MPEG-ES */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO, NULL, 15, D10D11Wrap }, /* SMPTE D-10 mapping */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO, NULL, 15 }, /* DV 625 25mbps */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO, NULL, 15, RawVWrap }, /* uncompressed picture */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x01,0x01 }, 15, AV_CODEC_ID_HQ_HQA },
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x02,0x01 }, 15, AV_CODEC_ID_HQX },
{ { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14, AV_CODEC_ID_RAWVIDEO }, /* Legacy ?? Uncompressed Picture */
@@ -1273,21 +1275,55 @@ static const MXFCodecUL mxf_intra_only_picture_coded_width[] = {
static const MXFCodecUL mxf_sound_essence_container_uls[] = {
// sound essence container uls
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, AV_CODEC_ID_PCM_S16LE }, /* BWF Frame wrapped */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, AV_CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, AV_CODEC_ID_PCM_S16LE }, /* D-10 Mapping 50Mbps PAL Extended Template */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, AV_CODEC_ID_PCM_S16LE, NULL, 14, RawAWrap }, /* BWF */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, AV_CODEC_ID_MP2, NULL, 15 }, /* MPEG-ES */
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, AV_CODEC_ID_PCM_S16LE, NULL, 13 }, /* D-10 Mapping 50Mbps PAL Extended Template */
{ { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4F }, 14, AV_CODEC_ID_PCM_S16LE }, /* 0001GL00.MXF.A1.mxf_opatom.mxf */
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14, AV_CODEC_ID_AAC }, /* MPEG-2 AAC ADTS (legacy) */
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
};
static const MXFCodecUL mxf_data_essence_container_uls[] = {
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0d,0x00,0x00 }, 16, AV_CODEC_ID_NONE, "vbi_smpte_436M" },
- { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16, AV_CODEC_ID_NONE, "vbi_vanc_smpte_436M" },
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0d,0x00,0x00 }, 16, AV_CODEC_ID_NONE, "vbi_smpte_436M", 11 },
+ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16, AV_CODEC_ID_NONE, "vbi_vanc_smpte_436M", 11 },
{ { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x13,0x01,0x01 }, 16, AV_CODEC_ID_TTML },
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE },
};
+static MXFWrappingScheme mxf_get_wrapping_kind(UID *essence_container_ul)
+{
+ int val;
+ const MXFCodecUL *codec_ul;
+
+ codec_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
+ if (!codec_ul->uid[0])
+ codec_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
+ if (!codec_ul->uid[0])
+ codec_ul = mxf_get_codec_ul(mxf_data_essence_container_uls, essence_container_ul);
+ if (!codec_ul->uid[0] || !codec_ul->wrapping_indicator_pos)
+ return UnknownWrapped;
+
+ val = (*essence_container_ul)[codec_ul->wrapping_indicator_pos];
+ switch (codec_ul->wrapping_indicator_type) {
+ case RawVWrap:
+ val = val % 4;
+ break;
+ case RawAWrap:
+ if (val == 0x03 || val == 0x04)
+ val -= 0x02;
+ break;
+ case D10D11Wrap:
+ if (val == 0x02)
+ val = 0x01;
+ break;
+ }
+ if (val == 0x01)
+ return FrameWrapped;
+ if (val == 0x02)
+ return ClipWrapped;
+ return UnknownWrapped;
+}
+
static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
{
int i, j, nb_segments = 0;
@@ -2179,6 +2215,9 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
PRINT_KEY(mxf->fc, "essence codec ul", descriptor->essence_codec_ul);
PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
essence_container_ul = &descriptor->essence_container_ul;
+ source_track->wrapping = (mxf->op == OPAtom) ? ClipWrapped : mxf_get_wrapping_kind(essence_container_ul);
+ if (source_track->wrapping == UnknownWrapped)
+ av_log(mxf->fc, AV_LOG_INFO, "wrapping of stream %d is unknown\n", st->index);
/* HACK: replacing the original key with mxf_encrypted_essence_container
* is not allowed according to s429-6, try to find correct information anyway */
if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {