Re: [FFmpeg-devel] [PATCH] avformat/mxfdec: Detect field_order based on video_line_map

2016-10-18 Thread Tobias Rapp

On 11.10.2016 10:40, Tobias Rapp wrote:

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(-)



Ping. Example files can be found at [1]. To debug the detected field 
order I used ffprobe plus the patch in [2]:


./ffprobe -show_streams -select_streams v -i $INPUT_FILE 2>/dev/null | 
grep field_order


For file "Avid-5.mxf" [3] the result is:
field_order=tt (without patch)
field_order=bb (with patch)

For file "OpenCube-3.mxf" [4] the result is:
field_order=unknown (without patch)
field_order=bb (with patch)

Regards,
Tobias

Links:
[1] http://mxf.irt.de/files/filter.php?action=query=manufacturers
[2] https://ffmpeg.org/pipermail/ffmpeg-devel/2016-October/200607.html
[3] 
http://mxf.irt.de/files/download.php?action=getFile=manufacturers=85
[4] 
http://mxf.irt.de/files/download.php?action=getFile=manufacturers=114


___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] avformat/mxfdec: Detect field_order based on video_line_map

2016-10-11 Thread Tobias Rapp
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, >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,
+