mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-28 18:32:22 +00:00
avformat/mxfdec: Read Mastering Display Colour Volume from MXF
Described in Annex B SMPTE ST 2067-21:2020 Signed-off-by: Harry Mallon <harry.mallon@codex.online>
This commit is contained in:
parent
7c66d24460
commit
90e2a4d61b
@ -22,6 +22,17 @@
|
||||
#include "libavutil/common.h"
|
||||
#include "mxf.h"
|
||||
|
||||
const uint8_t ff_mxf_mastering_display_prefix[13] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01 };
|
||||
|
||||
/* be careful to update references to this array if reordering */
|
||||
/* local tags are dynamic and must not clash with others in mxfenc.c */
|
||||
const MXFLocalTagPair ff_mxf_mastering_display_local_tags[4] = {
|
||||
{ 0x8301, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x01,0x00,0x00 }}, /* Mastering Display Primaries */
|
||||
{ 0x8302, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x02,0x00,0x00 }}, /* Mastering Display White Point Chromaticity */
|
||||
{ 0x8303, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x03,0x00,0x00 }}, /* Mastering Display Maximum Luminance */
|
||||
{ 0x8304, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x04,0x00,0x00 }} /* Mastering Display Minimum Luminance */
|
||||
};
|
||||
|
||||
/**
|
||||
* SMPTE RP224 http://www.smpte-ra.org/mdd/index.html
|
||||
*/
|
||||
|
@ -78,6 +78,17 @@ typedef enum {
|
||||
RawVWrap
|
||||
} MXFWrappingIndicatorType;
|
||||
|
||||
typedef struct MXFLocalTagPair {
|
||||
int local_tag;
|
||||
UID uid;
|
||||
} MXFLocalTagPair;
|
||||
|
||||
extern const uint8_t ff_mxf_mastering_display_prefix[13];
|
||||
extern const MXFLocalTagPair ff_mxf_mastering_display_local_tags[4];
|
||||
|
||||
#define FF_MXF_MASTERING_CHROMA_DEN 50000
|
||||
#define FF_MXF_MASTERING_LUMA_DEN 10000
|
||||
|
||||
typedef struct MXFCodecUL {
|
||||
UID uid;
|
||||
unsigned matching_len;
|
||||
|
@ -28,6 +28,7 @@
|
||||
* SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
|
||||
* SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container
|
||||
* SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container
|
||||
* SMPTE 2067-21 Interoperable Master Format — Application #2E
|
||||
*
|
||||
* Principle
|
||||
* Search for Track numbers which will identify essence element KLV packets.
|
||||
@ -47,6 +48,7 @@
|
||||
|
||||
#include "libavutil/aes.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/mastering_display_metadata.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavcodec/bytestream.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
@ -213,6 +215,7 @@ typedef struct MXFDescriptor {
|
||||
UID color_primaries_ul;
|
||||
UID color_trc_ul;
|
||||
UID color_space_ul;
|
||||
AVMasteringDisplayMetadata *mastering;
|
||||
} MXFDescriptor;
|
||||
|
||||
typedef struct MXFIndexTableSegment {
|
||||
@ -337,6 +340,7 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
|
||||
switch ((*ctx)->type) {
|
||||
case Descriptor:
|
||||
av_freep(&((MXFDescriptor *)*ctx)->extradata);
|
||||
av_freep(&((MXFDescriptor *)*ctx)->mastering);
|
||||
break;
|
||||
case MultipleDescriptor:
|
||||
av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs);
|
||||
@ -1272,6 +1276,42 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
|
||||
rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K)
|
||||
descriptor->pix_fmt = AV_PIX_FMT_XYZ12;
|
||||
}
|
||||
if (IS_KLV_KEY(uid, ff_mxf_mastering_display_prefix)) {
|
||||
if (!descriptor->mastering) {
|
||||
descriptor->mastering = av_mastering_display_metadata_alloc();
|
||||
if (!descriptor->mastering)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[0].uid)) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
/* Order: large x, large y, other (i.e. RGB) */
|
||||
descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
|
||||
descriptor->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
|
||||
}
|
||||
/* Check we have seen mxf_mastering_display_white_point_chromaticity */
|
||||
if (descriptor->mastering->white_point[0].den != 0)
|
||||
descriptor->mastering->has_primaries = 1;
|
||||
}
|
||||
if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[1].uid)) {
|
||||
descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
|
||||
descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
|
||||
/* Check we have seen mxf_mastering_display_primaries */
|
||||
if (descriptor->mastering->display_primaries[0][0].den != 0)
|
||||
descriptor->mastering->has_primaries = 1;
|
||||
}
|
||||
if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[2].uid)) {
|
||||
descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
|
||||
/* Check we have seen mxf_mastering_display_minimum_luminance */
|
||||
if (descriptor->mastering->min_luminance.den != 0)
|
||||
descriptor->mastering->has_luminance = 1;
|
||||
}
|
||||
if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[3].uid)) {
|
||||
descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
|
||||
/* Check we have seen mxf_mastering_display_maximum_luminance */
|
||||
if (descriptor->mastering->max_luminance.den != 0)
|
||||
descriptor->mastering->has_luminance = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -2532,6 +2572,14 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
|
||||
st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id;
|
||||
st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id;
|
||||
st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id;
|
||||
if (descriptor->mastering) {
|
||||
ret = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
|
||||
(uint8_t *)descriptor->mastering,
|
||||
sizeof(*descriptor->mastering));
|
||||
if (ret < 0)
|
||||
goto fail_and_free;
|
||||
descriptor->mastering = NULL;
|
||||
}
|
||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
|
||||
/* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */
|
||||
|
@ -65,11 +65,6 @@ extern AVOutputFormat ff_mxf_opatom_muxer;
|
||||
#define EDIT_UNITS_PER_BODY 250
|
||||
#define KAG_SIZE 512
|
||||
|
||||
typedef struct MXFLocalTagPair {
|
||||
int local_tag;
|
||||
UID uid;
|
||||
} MXFLocalTagPair;
|
||||
|
||||
typedef struct MXFIndexEntry {
|
||||
uint64_t offset;
|
||||
unsigned slice_offset; ///< offset of audio slice
|
||||
|
Loading…
Reference in New Issue
Block a user