Browse Source

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>
tags/n0.11
Joseph Artsimovich Michael Niedermayer 13 years ago
parent
commit
84b9b4aa18
2 changed files with 33 additions and 2 deletions
  1. +8
    -0
      libavformat/mxf.h
  2. +25
    -2
      libavformat/mxfdec.c

+ 8
- 0
libavformat/mxf.h View File

@@ -46,6 +46,14 @@ enum MXFMetadataSetType {
TypeBottom,// add metadata type before this TypeBottom,// add metadata type before this
}; };


enum MXFFrameLayout {
FullFrame = 0,
MixedFields,
OneField,
SegmentedFrame,
SeparateFields
};

typedef struct { typedef struct {
UID key; UID key;
int64_t offset; int64_t offset;


+ 25
- 2
libavformat/mxfdec.c View File

@@ -142,7 +142,8 @@ typedef struct {
AVRational sample_rate; AVRational sample_rate;
AVRational aspect_ratio; AVRational aspect_ratio;
int width; int width;
int height;
int height; /* Field height, not frame height */
int frame_layout; /* See MXFFrameLayout enum */
int channels; int channels;
int bits_per_sample; int bits_per_sample;
unsigned int component_depth; unsigned int component_depth;
@@ -832,6 +833,9 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int
case 0x3202: case 0x3202:
descriptor->height = avio_rb32(pb); descriptor->height = avio_rb32(pb);
break; break;
case 0x320C:
descriptor->frame_layout = avio_r8(pb);
break;
case 0x320E: case 0x320E:
descriptor->aspect_ratio.num = avio_rb32(pb); descriptor->aspect_ratio.num = avio_rb32(pb);
descriptor->aspect_ratio.den = 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) if (st->codec->codec_id == CODEC_ID_NONE)
st->codec->codec_id = container_ul->id; st->codec->codec_id = container_ul->id;
st->codec->width = descriptor->width; 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) { if (st->codec->codec_id == CODEC_ID_RAWVIDEO) {
st->codec->pix_fmt = descriptor->pix_fmt; st->codec->pix_fmt = descriptor->pix_fmt;
if (st->codec->pix_fmt == PIX_FMT_NONE) { if (st->codec->pix_fmt == PIX_FMT_NONE) {


Loading…
Cancel
Save