From 84b9b4aa187c5a2aacbbd45c910e5b53eeaa1adf Mon Sep 17 00:00:00 2001 From: Joseph Artsimovich Date: Tue, 7 Feb 2012 10:48:43 +0000 Subject: [PATCH] Fix frame height vs field height confusion in MXF decoding. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Tomas Härdin Reveiwed-by: Baptiste Coudurier Signed-off-by: Michael Niedermayer --- libavformat/mxf.h | 8 ++++++++ libavformat/mxfdec.c | 27 +++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libavformat/mxf.h b/libavformat/mxf.h index bbbdb1fcba..c55b50f224 100644 --- a/libavformat/mxf.h +++ b/libavformat/mxf.h @@ -46,6 +46,14 @@ enum MXFMetadataSetType { TypeBottom,// add metadata type before this }; +enum MXFFrameLayout { + FullFrame = 0, + MixedFields, + OneField, + SegmentedFrame, + SeparateFields +}; + typedef struct { UID key; int64_t offset; diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 1189f3d2db..3d99ea7624 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -142,7 +142,8 @@ typedef struct { AVRational sample_rate; AVRational aspect_ratio; int width; - int height; + int height; /* Field height, not frame height */ + int frame_layout; /* See MXFFrameLayout enum */ int channels; int bits_per_sample; unsigned int component_depth; @@ -832,6 +833,9 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int case 0x3202: descriptor->height = avio_rb32(pb); break; + case 0x320C: + descriptor->frame_layout = avio_r8(pb); + break; case 0x320E: descriptor->aspect_ratio.num = avio_rb32(pb); descriptor->aspect_ratio.den = avio_rb32(pb); @@ -1493,7 +1497,26 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = container_ul->id; st->codec->width = descriptor->width; - st->codec->height = descriptor->height; + st->codec->height = descriptor->height; /* Field height, not frame height */ + switch (descriptor->frame_layout) { + case SegmentedFrame: + /* This one is a weird layout I don't fully understand. */ + av_log(mxf->fc, AV_LOG_INFO, "SegmentedFrame layout isn't currently supported\n"); + break; + case FullFrame: + break; + case OneField: + /* Every other line is stored and needs to be duplicated. */ + av_log(mxf->fc, AV_LOG_INFO, "OneField frame layout isn't currently supported\n"); + break; /* The correct thing to do here is fall through, but by breaking we might be + able to decode some streams at half the vertical resolution, rather than not al all. + It's also for compatibility with the old behavior. */ + case SeparateFields: + case MixedFields: + st->codec->height *= 2; /* Turn field height into frame height. */ + default: + av_log(mxf->fc, AV_LOG_INFO, "Unknown frame layout type: %d\n", descriptor->frame_layout); + } if (st->codec->codec_id == CODEC_ID_RAWVIDEO) { st->codec->pix_fmt = descriptor->pix_fmt; if (st->codec->pix_fmt == PIX_FMT_NONE) {