From patchwork Tue Oct 11 08:40:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Rapp X-Patchwork-Id: 952 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.66 with SMTP id o63csp221438vsd; Tue, 11 Oct 2016 01:40:58 -0700 (PDT) X-Received: by 10.194.6.36 with SMTP id x4mr3364450wjx.175.1476175258868; Tue, 11 Oct 2016 01:40:58 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id cv8si3547251wjc.92.2016.10.11.01.40.58; Tue, 11 Oct 2016 01:40:58 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 44DAA68993E; Tue, 11 Oct 2016 11:40:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from p1002.netstorage.at (p1002.netstorage.at [89.207.146.186]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A58D268971F for ; Tue, 11 Oct 2016 11:40:50 +0300 (EEST) Received: from mailix (noaport.de [46.237.252.213]) by p1002.netstorage.at (Postfix) with ESMTPA id E654881AC2 for ; Tue, 11 Oct 2016 10:40:49 +0200 (CEST) Received: from frogstar-a.kuhnle.local (frogstar-a.kuhnle.local [192.168.0.26]) by mailix with ESMTPA ; Tue, 11 Oct 2016 10:40:49 +0200 From: Tobias Rapp To: ffmpeg-devel@ffmpeg.org Date: Tue, 11 Oct 2016 10:40:49 +0200 Message-Id: <1476175249-605-1-git-send-email-t.rapp@noa-archive.com> X-Mailer: git-send-email 1.9.1 X-PPP-Message-ID: <20161011084050.3092.5883@p1002.netstorage.at> X-PPP-Vhost: noa-archive.com Subject: [FFmpeg-devel] [PATCH] avformat/mxfdec: Detect field_order based on video_line_map X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Read video_line_map from MXF generic picture essence descriptor and use it to derive the coded field order. Use field_dominance to derive the display field order from coded field order. If field_dominance is not available the default value "1" is used as defined in SMPTE S377-1. Fixes field_order detection for a bunch of DV/DVCPRO files. The heuristic for deriving coded field order from video_line_map is inspired by MediaInfo. Signed-off-by: Tobias Rapp --- libavformat/mxfdec.c | 75 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 15 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 1939761..8332362 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -173,8 +173,10 @@ typedef struct MXFDescriptor { int width; int height; /* Field height, not frame height */ int frame_layout; /* See MXFFrameLayout enum */ -#define MXF_TFF 1 -#define MXF_BFF 2 + int video_line_map[2]; +#define MXF_FIELD_DOMINANCE_DEFAULT 0 +#define MXF_FIELD_DOMINANCE_FF 1 /* coded first, displayed first */ +#define MXF_FIELD_DOMINANCE_FL 2 /* coded first, displayed last */ int field_dominance; int channels; int bits_per_sample; @@ -968,6 +970,8 @@ 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; + int entry_count, entry_size; + switch(tag) { case 0x3F01: return mxf_read_strong_ref_array(pb, &descriptor->sub_descriptors_refs, @@ -996,6 +1000,21 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int case 0x320C: descriptor->frame_layout = avio_r8(pb); break; + case 0x320D: + entry_count = avio_rb32(pb); + entry_size = avio_rb32(pb); + if (entry_size == 4) { + if (entry_count > 0) + descriptor->video_line_map[0] = avio_rb32(pb); + else + descriptor->video_line_map[0] = 0; + if (entry_count > 1) + descriptor->video_line_map[1] = avio_rb32(pb); + else + descriptor->video_line_map[1] = 0; + } else + av_log(NULL, AV_LOG_WARNING, "VideoLineMap element size %d currently not supported\n", entry_size); + break; case 0x320E: descriptor->aspect_ratio.num = avio_rb32(pb); descriptor->aspect_ratio.den = avio_rb32(pb); @@ -2044,19 +2063,45 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) case SegmentedFrame: st->codecpar->field_order = AV_FIELD_PROGRESSIVE; case SeparateFields: - switch (descriptor->field_dominance) { - case MXF_TFF: - st->codecpar->field_order = AV_FIELD_TT; - break; - case MXF_BFF: - st->codecpar->field_order = AV_FIELD_BB; - break; - default: - avpriv_request_sample(mxf->fc, - "Field dominance %d support", - descriptor->field_dominance); - case 0: // we already have many samples with field_dominance == unknown - break; + av_log(mxf->fc, AV_LOG_DEBUG, "video_line_map: (%d, %d), field_dominance: %d\n", + descriptor->video_line_map[0], descriptor->video_line_map[1], + descriptor->field_dominance); + if ((descriptor->video_line_map[0] > 0) && (descriptor->video_line_map[1] > 0)) { + /* Detect coded field order from VideoLineMap: + * (even, even) => bottom field coded first + * (even, odd) => top field coded first + * (odd, even) => top field coded first + * (odd, odd) => bottom field coded first + */ + if ((descriptor->video_line_map[0] + descriptor->video_line_map[1]) % 2) { + switch (descriptor->field_dominance) { + case MXF_FIELD_DOMINANCE_DEFAULT: + case MXF_FIELD_DOMINANCE_FF: + st->codecpar->field_order = AV_FIELD_TT; + break; + case MXF_FIELD_DOMINANCE_FL: + st->codecpar->field_order = AV_FIELD_TB; + break; + default: + avpriv_request_sample(mxf->fc, + "Field dominance %d support", + descriptor->field_dominance); + } + } else { + switch (descriptor->field_dominance) { + case MXF_FIELD_DOMINANCE_DEFAULT: + case MXF_FIELD_DOMINANCE_FF: + st->codecpar->field_order = AV_FIELD_BB; + break; + case MXF_FIELD_DOMINANCE_FL: + st->codecpar->field_order = AV_FIELD_BT; + break; + default: + avpriv_request_sample(mxf->fc, + "Field dominance %d support", + descriptor->field_dominance); + } + } } /* Turn field height into frame height. */ st->codecpar->height *= 2;