Log in

View Full Version : Encoding an AppleProres DCI P3 file


FranceBB
6th September 2019, 01:31
Hi there,
as you may know I encode any kind of contents since I work in broadcast, but I got tired of encoding crappy random clips taken from all over the internet for our news channel and I decided to give a shot and try to encode some movies for the Cinema department.

Alright, so... the file I received today is the following one:

Video
ID : 1
Format : ProRes
Format version : Version 0
Format profile : 422
Codec ID : apcn
Bit rate mode : Variable
Bit rate : 116 Mb/s
Width : 2 048 pixels
Height : 858 pixels
Display aspect ratio : 2.40:1
Frame rate mode : Constant
Frame rate : 24.000 FPS
Color space : YUV
Chroma subsampling : 4:2:2
Scan type : Progressive
Bits/(Pixel*Frame) : 2.740
Title : Core Media Video
Color primaries : SMPTE RP 431-2
Transfer characteristics : BT.709
Matrix coefficients : BT.709

Audio #1
ID : 2
Format : PCM
Format settings : Little / Signed
Codec ID : in24
Bit rate mode : Constant
Bit rate : 2 304 kb/s
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 48.0 kHz
Bit depth : 24 bits
Title : Core Media Audio
Default : Yes
Alternate group : 1

Audio #2
ID : 3
Format : PCM
Format settings : Little / Signed
Codec ID : in24
Bit rate mode : Constant
Bit rate : 2 304 kb/s
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 48.0 kHz
Bit depth : 24 bits
Title : Core Media Audio
Default : Yes
Alternate group : 2

Audio #3
ID : 4
Format : PCM
Format settings : Little / Signed
Codec ID : in24
Bit rate mode : Constant
Bit rate : 2 304 kb/s
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 48.0 kHz
Bit depth : 24 bits
Title : Core Media Audio
Default : Yes
Alternate group : 3

Audio #4
ID : 5
Format : PCM
Format settings : Little / Signed
Codec ID : in24
Bit rate mode : Constant
Bit rate : 2 304 kb/s
Channel(s) : 2 channels
Channel positions : Front: L R
Sampling rate : 48.0 kHz
Bit depth : 24 bits
Title : Core Media Audio
Default : Yes
Alternate group : 4

Other
ID : 6
Type : Time code
Format : QuickTime TC
Duration : 10 s 0 ms
Time code of first frame : 09:59:16:21
Time code, striped : Yes
Title : Core Media Video
Language : English
Default : No


Apparently, the matrix has been correctly converted by someone to BT709 Linear, however, the primaries are wrong and have to be converted to BT709 linear.
I've never done this with such a file, but I think I have two ways to do this:

1) Make a custom matrix of linear transformation (LUT) in order to convert it. I've made plenty of them in the past for other kind of conversions (like PQ to BT709 and so on).

2) Use HDRTools, bring everything to a non linear space (XYZ), convert the primaries and then convert back to YUV with 16bit precision.

I decided to go for the latter.

Apparently, the DCI_P3 has the following values:

xW=0.314
yW=0.351
K°=6300 (Color temperature)
Xr=0.680
Yr=0.320
Xg=0.265
Yg=0.690
Xb=0.150
Yb=0.060

While BT709 has the following values:

xW=0.3127
yW=0.3290
Xr=0.64
Yr=0.33
Xg=0.30
Yg=0.60
Xb=0.15
Yb=0.06

In other words, they are not so terribly different.

If I got it right, I think I should go for this:

#Indexing
video=FFVideoSource("L422_1107_cut 24.mov")
ch1=FFAudioSource("L422_1107_cut 24.mov", track=1)
ch2=FFAudioSource("L422_1107_cut 24.mov", track=2)
ch3=FFAudioSource("L422_1107_cut 24.mov", track=3)
ch4=FFAudioSource("L422_1107_cut 24.mov", track=4)
audio=MergeChannels(ch1, ch2, ch3, ch4)
AudioDub(video, audio)

#Bring everything to 16bit planar
ConvertBits(16)

#Going to non linear space XYZ with 16bit precision using the DCI_P3 values
ConvertYUVtoXYZ(Color=2, Rx=0.680, Ry=0.320, Gx=0.265, Gy=0.690, Bx=0.150, By=0.060, Wx=0.314, Wy=0.351)

#Going back to YUV with 16bit precision using the BT709 values
ConvertXYZtoYUV(pColor=2, Rx=0.708, Ry=0.292, Gx=0.170, Gy=0.797, Bx=0.131, By=0.046, Wx=0.3127, Wy=0.3290)

#Adding borders to go from 2.35 LB to 1.77 16:9
AddBorders(0, 148, 0, 148)

#Downscale to FULL HD with 16bit precision
Spline64Resize(1920, 1080)

#PAL 4% Speedup to get 25p
ResampleAudio(48000)
AssumeFPS(25, 1, true)
SSRC(48000)

#Going down to 8bit with the Floyd-Steinberg error diffusion
ConvertBits(bits=8, dither=1)

#Going from 4:4:4 planar to 4:2:2 planar
Converttoyv16(matrix="Rec709", interlaced=false)

Then I'm gonna encode an XDCAM file as progressive flagged as interlaced and send it for QC, but before I do so, I wanna be 100% sure that I'm not fucking up the conversion.
Since the movie has not aired yet, I can't give you a sample.
As a matter of fact, I can't even give you a full screenshot of the main characters due to copyright restrictions, but I can give you a few screenshots about the setting and how it changed with the conversion.

Original SMPTE RP 431-2 (DCI_P3):

https://i.imgur.com/rgiLc1T.png

BT709:

https://i.imgur.com/qEKgl3t.png

Original SMPTE RP 431-2 (DCI_P3):

https://i.imgur.com/g6qB5vH.png

BT709:

https://i.imgur.com/xb3c7UP.png

Original SMPTE RP 431-2 (DCI_P3):

https://i.imgur.com/cp7rz7v.png

BT709:

https://i.imgur.com/Y8oPNOx.png


Apparently the red-ish tint is gone, however I'm not sure whether it was an "artistic choice" or if I messed up the conversion myself.

Thank you in advance,
Frank.

Alexkral
8th September 2019, 08:33
You are using Rec2020 primaries in ConvertXYZtoYUV, it makes no sense that Rec709 looks more desaturated than DCI-P3.

The problem with the reddish tint is very common with these conversions, I think it is related to the gamma rendering taking place in a larger or smaller color space as explained in Annex 3 of ITU BT.2087, but I don't know how it could be solved.

age
8th September 2019, 12:00
#Going back to YUV with 16bit precision using the BT709 values
ConvertXYZtoYUV(pColor=2, Rx=0.64, Ry=0.33, Gx=0.30, Gy=0.60, Bx=0.15, By=0.06, Wx=0.3127, Wy=0.3290)

Is the source yuv limited range or yuv full range?
What kind of transfer curve is used in ConvertYUVtoXYZ and ConvertXYZtoYUV ?

Vapoursynth equivalent

c=core.resize.Bicubic(clip=c, format=vs.RGBS, filter_param_a=0, filter_param_b=0.75, matrix_in_s="709", range_in_s="limited", range_s="full")
c=core.resize.Bicubic(clip=c, format=vs.RGBS, transfer_in_s="709", transfer_s="linear")
c=core.resize.Bicubic(clip=c, format=vs.RGBS, primaries_in_s="st431-2", primaries_s="709")
c=core.resize.Bicubic(clip=c, format=vs.RGBS, transfer_in_s="linear", transfer_s="709")
c=core.resize.Bicubic(clip=c, format=vs.YUV420P8,matrix_s="709", filter_param_a=0, filter_param_b=0.75, range_in_s="full",range_s="limited", chromaloc_in_s="center",dither_type="error_diffusion")

FranceBB
9th September 2019, 18:17
#Going back to YUV with 16bit precision using the BT709 values
ConvertXYZtoYUV(pColor=2, Rx=0.64, Ry=0.33, Gx=0.30, Gy=0.60, Bx=0.15, By=0.06, Wx=0.3127, Wy=0.3290)

Is the source yuv limited range or yuv full range?



It's not flagged, but looking at the waveform, it looks Limited TV Range 10bit 64-940 with the black higher than it should be.

https://i.imgur.com/EGsja0W.png
https://i.imgur.com/ZvYsQum.png
https://i.imgur.com/3z6Nt3R.png
https://i.imgur.com/rsvSkpM.png

Cary Knoop
9th September 2019, 18:25
Should you not linearize the gamma first before you convert colorspaces?

Typically to do a conversion you take four steps:

1. Convert the gamma to linear, so in your case you have to go from Rec709 to Linear
2. Convert the current color space to the all-purpose intermediate XYZ
3. Convert from XYZ to the target color space
4. Convert the linear gamma to the target gamma