[FFmpeg-devel] [PATCH 5/7] mxfdec: set pixel format for cdci picture formats

Philip de Nier philipn at rd.bbc.co.uk
Tue Feb 28 15:16:39 CET 2012


The properties of the CDCI Descriptor are insufficient to specify
the pixel format for uncompressed picture data. SMPTE 377-1 and
RP224v10 have defined a set of picture coding labels to indicate what
formatting was used.

This patch uses 2 labels to detect UYVY422 or YUYV422 pixel formats.

It defaults to UYVY422 for 8-bit 4:2:2 pictures to support files
that were created before the coding labels were introduced ~2008

The codec pix_fmt default was changed from 0 (PIX_FMT_YUV420P) to
-1 (PIX_FMT_NONE)
---
 libavformat/mxf.c    |    6 ++++++
 libavformat/mxf.h    |    1 +
 libavformat/mxfdec.c |   30 +++++++++++++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index c40197e..a02701a 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -56,6 +56,12 @@ const MXFCodecUL ff_mxf_codec_uls[] = {
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       CODEC_ID_NONE },
 };
 
+const MXFCodecUL ff_mxf_pixel_format_uls[] = {
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x01 }, 16, PIX_FMT_UYVY422 },
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x02 }, 16, PIX_FMT_YUYV422 },
+    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,    PIX_FMT_NONE },
+};
+
 static const struct {
     enum PixelFormat pix_fmt;
     const char data[16];
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index 4f5d4c0..bbbdb1f 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -60,6 +60,7 @@ typedef struct {
 
 extern const MXFCodecUL ff_mxf_data_definition_uls[];
 extern const MXFCodecUL ff_mxf_codec_uls[];
+extern const MXFCodecUL ff_mxf_pixel_format_uls[];
 
 int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum PixelFormat *pix_fmt);
 
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 13d2638..3af970d 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -134,6 +134,9 @@ typedef struct {
     int height;
     int channels;
     int bits_per_sample;
+    unsigned int component_depth;
+    unsigned int horiz_subsampling;
+    unsigned int vert_subsampling;
     UID *sub_descriptors_refs;
     int sub_descriptors_count;
     int linked_track_id;
@@ -769,6 +772,7 @@ static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
 static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
 {
     MXFDescriptor *descriptor = arg;
+    descriptor->pix_fmt = PIX_FMT_NONE;
     switch(tag) {
     case 0x3F01:
         descriptor->sub_descriptors_count = avio_rb32(pb);
@@ -799,6 +803,15 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
         descriptor->aspect_ratio.num = avio_rb32(pb);
         descriptor->aspect_ratio.den = avio_rb32(pb);
         break;
+    case 0x3301:
+        descriptor->component_depth = avio_rb32(pb);
+        break;
+    case 0x3302:
+        descriptor->horiz_subsampling = avio_rb32(pb);
+        break;
+    case 0x3308:
+        descriptor->vert_subsampling = avio_rb32(pb);
+        break;
     case 0x3D03:
         descriptor->sample_rate.num = avio_rb32(pb);
         descriptor->sample_rate.den = avio_rb32(pb);
@@ -1261,6 +1274,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
         UID *essence_container_ul = NULL;
         const MXFCodecUL *codec_ul = NULL;
         const MXFCodecUL *container_ul = NULL;
+        const MXFCodecUL *pix_fmt_ul = NULL;
         AVStream *st;
 
         if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
@@ -1394,8 +1408,22 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
                 st->codec->codec_id = container_ul->id;
             st->codec->width = descriptor->width;
             st->codec->height = descriptor->height;
-            if (st->codec->codec_id == CODEC_ID_RAWVIDEO)
+            if (st->codec->codec_id == CODEC_ID_RAWVIDEO) {
                 st->codec->pix_fmt = descriptor->pix_fmt;
+                if (st->codec->pix_fmt == PIX_FMT_NONE) {
+                    pix_fmt_ul = mxf_get_codec_ul(ff_mxf_pixel_format_uls, &descriptor->essence_codec_ul);
+                    st->codec->pix_fmt = pix_fmt_ul->id;
+                    if (st->codec->pix_fmt == PIX_FMT_NONE) {
+                        /* support files created before RP224v10 by defaulting to UYVY422
+                           if subsampling is 4:2:2 and component depth is 8-bit */
+                        if (descriptor->horiz_subsampling == 2 &&
+                            descriptor->vert_subsampling == 1 &&
+                            descriptor->component_depth == 8) {
+                            st->codec->pix_fmt = PIX_FMT_UYVY422;
+                        }
+                    }
+                }
+            }
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
         } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
-- 
1.7.3.4



More information about the ffmpeg-devel mailing list