mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
bfa0b50441
commit
7ec90b168b
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user