Shotcut passing wrong parameters for interlacing to libx264


#1

When exporting interlaced video, shotcut encodes as top field first even if the user has selected bottom field first.

From the logfile, we see:

[libx264 @ 0000000005f3d7c0] 264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x1:0x111 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=tff bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=0 keyint=149 keyint_min=14 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=21.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00

As well as not reflecting the user’s intent, passing “interlaced=tff” to libx264 is incorrect syntax. x264 has two boolean parameters, b_interlaced and b_tff which should be set as follows:
For progressive: b_interlaced=0, b_tff=don’t care
For interlaced, tff: b_interlaced=1, b_tff=1
For interlaced, bff: b_interlaced=1, b_tff=0


#2

Shotcut does not pass that to x264 directly. It uses MLT, which uses FFmpeg libavcodec, which does only use b_interlaced and b_tff as those are the only fields the x264 C API provides as can be seen here for b_tff and here for b_interlaced. It is x264 that is converting these parameters to its report output. Thus, x264 is encoding as top-field-first as instructed.
When I make a test, mediainfo reports

Scan type, store method                  : Interleaved fields
Scan order                               : Top Field First

and it Shotcut incorrectly reports it as Bottom Field First in Properties. Of course, this information should be coming from FFmpeg libavcodec. If you use Properties > menu > More Information, which invokes ffprobe, it shows for the video stream: field_order=unknown.
ffprobe -show_frames also shows for all frames:

interlaced_frame=1
top_field_first=0

hmm. I am not sure why decode is wrong and need to investigate further.


#3

I find if I request Bottom Field First encoding in the export settings, the resulting video is Top Field First (checked independently with the MediaInfo tool). So I think there is also an issue somewhere in the encode path (export settings) -> libavcodec -> libx264.


#4

I get this too. I think there is a small bug in FFmpeg and/or x264 and requires x264 param --bff to change it. When I run ffmpeg command line with a DV file input, which is bottom field first (per its standard and MediaInfo), then x264 outputs tff until I supply -x264-params bff=1:

ffmpeg -loglevel verbose -i some.dv -c:v libx264 -flags +ildct+ilme -c:a aac -y /i/testing/ffmpeg-bff.mp4

produces “Scan order: Top Field First” in MediaInfo!

ffmpeg -loglevel verbose -i some.dv -c:v libx264 -flags +ildct+ilme -x264-params bff=1 -c:a aac -y /i/testing/ffmpeg-bff.mp4

produces “Scan order: Bottom Field First” in MediaInfo.

As a result, in Shotcut, if I add x264-params=bff=1 to Export > Advanced > Other, then I get bottom field first in MediaInfo.

Also, I found a bug in MLT when testing with MPEG-2 output. Top Field First is not respected if the source is progressive. I fixed that for the next version. Also, for the next version I will change Shotcut to add bff=1 to x264-params when that is selected.