aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Artsimovich <joseph@mirriad.com>2012-02-07 10:48:43 +0000
committerMichael Niedermayer <michaelni@gmx.at>2012-03-11 17:39:52 +0100
commit84b9b4aa187c5a2aacbbd45c910e5b53eeaa1adf (patch)
tree67b6fd74aedb874e7ee0f8fbfeaaea93bfa9ab6a
parent4ed0d182e249138f40c9f63bce772d5251d9703b (diff)
downloadffmpeg-84b9b4aa187c5a2aacbbd45c910e5b53eeaa1adf.tar.gz
Fix frame height vs field height confusion in MXF decoding.
Reviewed-by: Tomas Härdin <tomas.hardin@codemill.se> Reveiwed-by: Baptiste Coudurier <baptiste.coudurier@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/mxf.h8
-rw-r--r--libavformat/mxfdec.c27
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) {