Log in

View Full Version : Proper interlaced encoding with x265


Blue_MiSfit
22nd November 2019, 18:56
Hello!

I've been messing around with interlaced encoding since x265 seems to support this. However, I'm getting some unexpected results.

When I encode with ffmpeg and take a 1080i59.94 ProRes 422 source in, and encode to x265 setting interlace=tff I get a file that looks as expected in mediainfo:

Video
ID : 1
Format : HEVC
Format/Info : High Efficiency Video Coding
Format profile : Format Range@L4@Main
Codec ID : hev1
Codec ID/Info : High Efficiency Video Coding
Duration : 30 s 30 ms
Bit rate : 1 129 kb/s
Width : 1 920 pixels
Height : 1 080 pixels
Display aspect ratio : 16:9
Frame rate mode : Constant
Frame rate : 29.970 (30000/1001) FPS
Color space : YUV
Chroma subsampling : 4:2:2
Bit depth : 10 bits
Scan type : Interlaced
Scan type, store method : Interleaved fields
Scan order : Top Field First
Bits/(Pixel*Frame) : 0.018
Stream size : 4.04 MiB (100%)
Writing library : x265 3.2+9-971180b100f8:[Windows][GCC 9.2.1][64 bit] 10bit
Encoding settings : cpuid=1111039 / frame-threads=3 / numa-pools=8 / wpp / no-pmode / no-pme / no-psnr / no-ssim / log-level=2 / input-csp=2 / input-res=1920x1080 / interlace=1 / total-frames=0 / level-idc=0 / high-tier=1 / uhd-bd=0 / ref=3 / no-allow-non-conformance / no-repeat-headers / annexb / no-aud / no-hrd / info / hash=0 / no-temporal-layers / open-gop / min-keyint=25 / keyint=250 / gop-lookahead=0 / bframes=4 / b-adapt=2 / b-pyramid / bframe-bias=0 / rc-lookahead=20 / lookahead-slices=6 / scenecut=40 / radl=0 / no-splice / no-intra-refresh / ctu=64 / min-cu-size=8 / no-rect / no-amp / max-tu-size=32 / tu-inter-depth=1 / tu-intra-depth=1 / limit-tu=0 / rdoq-level=0 / dynamic-rd=0.00 / no-ssim-rd / signhide / no-tskip / nr-intra=0 / nr-inter=0 / no-constrained-intra / strong-intra-smoothing / max-merge=3 / limit-refs=1 / no-limit-modes / me=1 / subme=2 / merange=57 / temporal-mvp / no-frame-dup / no-hme / weightp / no-weightb / no-analyze-src-pics / deblock=0:0 / sao / no-sao-non-deblock / rd=3 / selective-sao=4 / early-skip / rskip / no-fast-intra / no-tskip-fast / no-cu-lossless / b-intra / no-splitrd-skip / rdpenalty=0 / psy-rd=2.00 / psy-rdoq=0.00 / no-rd-refine / no-lossless / cbqpoffs=0 / crqpoffs=0 / rc=crf / crf=16.0 / qcomp=0.60 / qpstep=4 / stats-write=0 / stats-read=0 / ipratio=1.40 / pbratio=1.30 / aq-mode=2 / aq-strength=1.00 / cutree / zone-count=0 / no-strict-cbr / qg-size=32 / no-rc-grain / qpmax=69 / qpmin=0 / no-const-vbv / sar=1 / overscan=0 / videoformat=5 / range=0 / colorprim=2 / transfer=2 / colormatrix=2 / chromaloc=0 / display-window=0 / cll=0,0 / min-luma=0 / max-luma=1023 / log2-max-poc-lsb=8 / vui-timing-info / vui-hrd-info / slices=1 / no-opt-qp-pps / no-opt-ref-list-length-pps / no-multi-pass-opt-rps / scenecut-bias=0.05 / no-opt-cu-delta-qp / no-aq-motion / no-hdr / no-hdr-opt / no-dhdr10-opt / no-idr-recovery-sei / analysis-reuse-level=5 / scale-factor=0 / refine-intra=0 / refine-inter=0 / refine-mv=1 / refine-ctu-distortion=0 / no-limit-sao / ctu-info=0 / no-lowpass-dct / refine-analysis-type=0 / copy-pic=1 / max-ausize-factor=1.0 / no-dynamic-refine / no-single-sei / no-hevc-aq / no-svt / no-field / qp-adaptation-range=1.00
Language : English
Color range : Limited
Codec configuration box : hvcC

However, when I play this back in MPC-HC I get terrible results. It's full of aliasing and every other frame is a duplicate. Definitely some incorrect field handling going on there. However, when I decode into AviSynth with ffvideosource I see a typical interlaced frame and when I separate fields it looks fine and has clean 60p motion.

I did some googling and found this thread:
https://trac.mpc-hc.org/ticket/5088

Notably "So in a 1080i stream, encoded as 1088i, a field = picture would indeed have a height of 544 luma samples."

I've also been messing with a hardware HEVC encoder that supports 1080i and it seems to do the above, encode 1920x540 (or I guess 544) at 59.94fps.

What the heck is going on here? What's the "right" way to encode 1080i59.94 with HEVC?

Cary Knoop
22nd November 2019, 19:49
All I want to say that it was a missed chance to completely spec out interlaced encoding ability from H.265.

Just use H.264.

Blue_MiSfit
22nd November 2019, 23:20
In this particular case I cannot.

RanmaCanada
23rd November 2019, 00:46
I don't think there is a right way. Interlaced content is typically SD, and x265 (HEVC) was designed for HD content. Yes 1080i is part of the specs, but x265 just can't handle interlaced content worth a damn. I say this with a massive anime dvd library that is just remuxed because they looked like garbage when I tried to compress with x265 in an effort to save space, and encoding them as h.264?? heck I might as well just keep the original as space is now cheap as heck!

Boulder
23rd November 2019, 11:20
Interlaced HD is quite common with concerts etc. Never saw any HEVC encoded ones though.
Would it be possible to simply use QTGMC for high quality bobbing and encode as progressive at double-rate? That's what I always do with my interlaced sources.

Sharc
23rd November 2019, 11:52
From here
https://x265.readthedocs.io/en/default/cli.html
HEVC encodes interlaced content as fields. Fields must be provided to the encoder in the correct temporal order. The source dimensions must be field dimensions and the FPS must be in units of fields per second. The decoder must re-combine the fields in their correct orientation for display.

So x265 outputs each field as a distinct picture. Not sure if and how MPC-HC can play this correctly.

MGarret
23rd November 2019, 14:09
Well, even though interlaced hevc is rare nowadays, I know at least one satelite tv service that's using 1080i hevc for hd programs. Their stb supports such streams while software decoders on pc still don't support it as far as I know. Plus you use 4:2:2 which further complicates testing.

Blue_MiSfit
24th November 2019, 02:16
Yeah, it's looking like the way you do interlacing in HEVC is to code each field as its own picture.

So, in AviSynth speak, you take your interlaced source and do SeparateFields() and then encode the result. Then your decoder needs to reverse this process by doing something like AssumeFieldBased().Weave() prior to handing off to the rest of the pipeline which would probably deinterlace and present in 60p.

Sharc
24th November 2019, 11:33
Exactly.
For an undistorted playback it may help to add --sar 1:2 for the encoding. Depends on the player though.

sonnati
29th November 2019, 11:58
I confirm, must separate the fields. However x265 is not optimized to encode interlaced, nor the hevc so expect less efficient ration between 1080p vs 1080i compared to h264