Skip to content

Commit 821a5f4

Browse files
authored
DNxHD updates with MXF (#35)
* DNxHD updates with MXF This also has examples of mxf outputs for AVID. Signed-off-by: [email protected] <[email protected]> (cherry picked from commit c2d54f2) * Adding frame rate, thanks to Mark Reid for pointing me to this - https://github.com/markreidvfx/pyaaf2/blob/23b61437452e8f18fc445d5a8c8b605972fa2349/src/aaf2/video.py#L12 Signed-off-by: [email protected] <[email protected]> * Adding a reference to pyaaf2 library, which could be useful for someworkflows. Also updated the DNxHD table with frame-rates. Thanks to Mark Reid for pointing these out. Signed-off-by: [email protected] <[email protected]> --------- Signed-off-by: [email protected] <[email protected]> Co-authored-by: [email protected] <[email protected]>
1 parent 62a2172 commit 821a5f4

File tree

3 files changed

+414
-6
lines changed

3 files changed

+414
-6
lines changed

EncodeDNXHD.md

Lines changed: 190 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,195 @@
11
---
22
layout: default
3-
nav_order: 4.3
3+
nav_order: 4.6
44
title: DNxHD Encoding
5-
parent: Encoding
5+
parent: Codec Comparisons
66
---
77

8+
9+
# DNxHD/DNxHR
10+
11+
Avid [DNxHD](https://en.wikipedia.org/wiki/Avid_DNxHD) ("Digital Nonlinear Extensible High Definition") is a lossy post-production codec that is intended for use for editing as well as a presentation format.
12+
13+
There are a number of pre-defined resolutions, frame-rates and bit-rates that are supported, see [AVID Resolutions](https://en.wikipedia.org/wiki/List_of_Avid_DNxHD_resolutions) for a list. However, we are going to focus on the DNxHR version of the codec, since it allows quite a bit more flexibility for larger image sizes than HD, more flexible frame rates and bit-rates of up to 3730Mbit/s (See [DNxHR-Codec-Bandwidth-Specifications](https://avid.secure.force.com/pkb/articles/en_US/White_Paper/DNxHR-Codec-Bandwidth-Specifications) ).
14+
15+
16+
Supported pixel formats: yuv422p yuv422p10le yuv444p10le gbrp10le
17+
18+
Example encoding:
19+
20+
<!---
21+
name: test_dnxhd_mov
22+
sources:
23+
- sourceimages/chip-chart-1080-16bit-noicc.png.yml
24+
comparisontest:
25+
- testtype: idiff
26+
compare_image: ../sourceimages/chip-chart-1080-16bit-noicc-yuv422p10le.png
27+
- testtype: assertresults
28+
tests:
29+
- assert: less
30+
value: max_error
31+
less: 0.00195
32+
-->
33+
```
34+
ffmpeg -r 24 -start_number 1 -i inputfile.%04d.png -frames:v 200 -c:v dnxhd \
35+
-pix_fmt yuv422p10le -profile:v dnxhr_hqx -sws_flags spline+accurate_rnd+full_chroma_int \
36+
-vf "scale=in_range=full:in_color_matrix=bt709:out_range=tv:out_color_matrix=bt709" \
37+
-color_range 1 -colorspace 1 -color_primaries 1 -color_trc 2 -y outputfile.mov
38+
```
39+
40+
41+
## ffmpeg DNxHR Profiles
42+
43+
| Profile name | Profile description | Profile # | Pix Fmt | Bit Depth | Compression Ratio |
44+
|:----------|:-----------|:-----------|:-----------|:-----------|:-----------|
45+
| dnxhr_lb | Low Bandwidth | 1 | YUV 4:2:2 | 8 | 22:1 |
46+
| dnxhr_sq | Standard Quality | 2 | YUV 4:2:2 | 8 | 7:1 |
47+
| dnxhr_hq | High Quality | 3 | YUV 4:2:2 | 8 | 4.5:1 |
48+
| dnxhr_hqx | High Quality | 4 | YUV 4:2:2 | 12 (*) | 5.5: 1 |
49+
| dnxhr_444 | DNxHR 4:4:4 | 5 | YUV 4:4:4 or RGB | 12 (*) | 4.5:1 |
50+
51+
There really are not any significant flags to be used, changing bit-rate has no effect.
52+
53+
(*) The 12-bit depth is what the codec can support, but does not appear to be supported by ffmpeg, since the encoding only allows 10-bit image data to be encoded.
54+
55+
## ffmpeg RGB support
56+
57+
<!---
58+
name: test_prores444_rgb
59+
sources:
60+
- sourceimages/chip-chart-1080-16bit-noicc.png.yml
61+
comparisontest:
62+
- testtype: idiff
63+
- testtype: assertresults
64+
tests:
65+
- assert: less
66+
value: max_error
67+
less: 0.00195
68+
-->
69+
```
70+
ffmpeg -y -r 24 -i inputfile.%04d.png -vframes 100 \
71+
-c:v dnxhd -profile:v dnxhr_444 \
72+
-vf "scale=in_color_matrix=bt709:out_color_matrix=bt709" \
73+
-color_primaries bt709 -color_range tv -color_trc bt709 -colorspace rgb \
74+
-pix_fmt gbrp10le outputfile.mov
75+
```
76+
77+
## AVID friendly MXF
78+
79+
AVID prefer deliveries in MXF using the Avid Op-Atom format. Generating the Op-Atom format used to be a separate application, but its now integrated into ffmpeg.
80+
81+
<!---
82+
name: test_prores444_mxf
83+
sources:
84+
- sourceimages/chip-chart-1080-16bit-noicc.png.yml
85+
comparisontest:
86+
- testtype: idiff
87+
- testtype: assertresults
88+
tests:
89+
- assert: less
90+
value: max_error
91+
less: 0.00195
92+
-->
93+
```
94+
ffmpeg -y -r 24 -i inputfile.%04d.png -vframes 100 \
95+
-c:v dnxhd -profile:v dnxhr_444 \
96+
-metadata project="MY PROJECT" \
97+
-metadata material_package_name="MY CLIP" \
98+
-b:v 36M -f mxf_opatom outputfile.mxf
99+
```
100+
101+
See [https://johnwarburton.net/blog/?p=50731](https://johnwarburton.net/blog/?p=50731)
102+
103+
## AAF Creation
104+
105+
If you are tightly integrating your pipeline into an AVID workflow, you should checkout [pyaaf2](https://github.com/markreidvfx/pyaaf2). [OTIO To Multi AAF Transcode example](https://github.com/markreidvfx/otio_to_multi_aaf_alab_example) is an example of using OTIO and pyaaf2 to create a AAF file from an OTIO file.
106+
107+
Ideally with AAF files, you would be importing MXF files (like the example above) to minimize the import time to the AVID (so it doesnt require any media transcoding).
108+
109+
## DNxHD Profiles
110+
111+
For example below is an example of DNxHD at 175Mbps at yuv422p10 at resolution 1920x1080.
112+
113+
<!---
114+
name: test_prores422_profile
115+
sources:
116+
- sourceimages/chip-chart-1080-16bit-noicc.png.yml
117+
comparisontest:
118+
- testtype: idiff
119+
compare_image: ../sourceimages/chip-chart-1080-16bit-noicc-yuv422p10le.png
120+
- testtype: assertresults
121+
tests:
122+
- assert: less
123+
value: max_error
124+
less: 0.00195
125+
-->
126+
```
127+
ffmpeg -y -r 24 -i inputfile.%04d.png -vframes 100 \
128+
-c:v dnxhd -b:v 175M \
129+
-vf "scale=in_color_matrix=bt709:out_color_matrix=bt709" \
130+
-color_primaries bt709 -color_range tv -color_trc bt709 -colorspace rgb \
131+
-pix_fmt yuv422p10 outputfile.mov
132+
```
133+
134+
Other combinations of resolution, bitrate and format are:
135+
136+
| Resolution | Bit Rate | Pix Format | Frame Rates |
137+
|:----------|-----------:|:-----------|:-----------|
138+
| 1920x1080p| 175M | yuv422p10 | 23.98, 24 |
139+
| 1920x1080p| 185M | yuv422p10 | 25 |
140+
| 1920x1080p| 365M | yuv422p10 | 50 |
141+
| 1920x1080p| 440M | yuv422p10 | 59.94, 60 |
142+
| 1920x1080p| 115M | yuv422p | 23.97, 24 |
143+
| 1920x1080p| 120M | yuv422p | 25 |
144+
| 1920x1080p| 145M | yuv422p | 29.97, 50 |
145+
| 1920x1080p| 240M | yuv422p | 50 |
146+
| 1920x1080p| 290M | yuv422p | 59.94, 60 |
147+
| 1920x1080p| 175M | yuv422p | 23.97, 24 |
148+
| 1920x1080p| 185M | yuv422p | 25 |
149+
| 1920x1080p| 220M | yuv422p | 29.97 |
150+
| 1920x1080p| 365M | yuv422p | 50 |
151+
| 1920x1080p| 440M | yuv422p | 59.94, 60 |
152+
| 1920x1080i| 185M | yuv422p10 | 25 |
153+
| 1920x1080i| 220M | yuv422p10 | 29.97 |
154+
| 1920x1080i| 120M | yuv422p | 25 |
155+
| 1920x1080i| 145M | yuv422p | 29.97 |
156+
| 1920x1080i| 185M | yuv422p | 25 |
157+
| 1920x1080i| 220M | yuv422p | 29.97 |
158+
| 1440x1080i| 120M | yuv422p | 25 |
159+
| 1440x1080i| 145M | yuv422p | 29.97 |
160+
| 1280x720p| 90M | yuv422p10 | 23.97, 24, 25 |
161+
| 1280x720p| 180M | yuv422p10 | 50, 59.94, 60 |
162+
| 1280x720p| 220M | yuv422p10 | 59.94, 60 |
163+
| 1280x720p| 90M | yuv422p | 23.97, 24, 25 |
164+
| 1280x720p| 110M | yuv422p | 29.97 |
165+
| 1280x720p| 180M | yuv422p | 50 |
166+
| 1280x720p| 220M | yuv422p | 59.94, 60 |
167+
| 1280x720p| 60M | yuv422p | 23.97, 24, 25 |
168+
| 1280x720p| 75M | yuv422p | 29.97 |
169+
| 1280x720p| 120M | yuv422p | 50 |
170+
| 1280x720p| 145M | yuv422p | 59.94, 60 |
171+
| 1920x1080p| 36M | yuv422p | 23.97, 24, 25 |
172+
| 1920x1080p| 45M | yuv422p | 29.97 |
173+
| 1920x1080p| 75M | yuv422p | 50 |
174+
| 1920x1080p| 90M | yuv422p | 59.94, 60 |
175+
| 1920x1080p| 350M | yuv444p10, gbrp10 | 23.97, 24 |
176+
| 1920x1080p| 390M | yuv444p10, gbrp10 | 25 |
177+
| 1920x1080p| 440M | yuv444p10, gbrp10 | 29.97 |
178+
| 1920x1080p| 730M | yuv444p10, gbrp10 | 50 |
179+
| 1920x1080p| 880M | yuv444p10, gbrp10 | 59.94, 60 |
180+
| 960x720p| 42M | yuv422p |
181+
| 960x720p| 60M | yuv422p |
182+
| 960x720p| 75M | yuv422p |
183+
| 960x720p| 115M | yuv422p |
184+
| 1440x1080p| 63M | yuv422p |
185+
| 1440x1080p| 84M | yuv422p |
186+
| 1440x1080p| 100M | yuv422p |
187+
| 1440x1080p| 110M | yuv422p |
188+
| 1440x1080i| 80M | yuv422p |
189+
| 1440x1080i| 90M | yuv422p |
190+
| 1440x1080i| 100M | yuv422p |
191+
| 1440x1080i| 110M | yuv422p |
192+
193+
## TODO
194+
195+
* The output sizes dont vary with different profiles, which seems wildly wrong.

enctests/test_configs/dnxhd_color_tests.yml

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
---
3-
test_dnxhd_color:
3+
test_dnxhd_444:
44
app: ffmpeg
55
comparisontest:
66
- testtype: idiff
@@ -14,15 +14,12 @@ test_dnxhd_color:
1414
-y "{outfile}"
1515
name: test_dnxhd_color
1616
sources:
17-
- ../sourceimages/chip-chart-1080-noicc.png.yml
1817
- ../sourceimages/chip-chart-1080-16bit-noicc.png.yml
19-
- ../sourceimages/smptehdbars_16.png.yml
2018
suffix: .mov
2119
wedges:
2220
dnxhd-yuv444p10le: &basednxhd
2321
-c:v: dnxhd
2422
-profile:v: dnxhr_444
25-
-b:v: 3M
2623
-vf: '"scale=in_color_matrix=bt709:out_color_matrix=bt709"'
2724
-color_primaries: bt709
2825
-color_range: tv
@@ -36,6 +33,10 @@ test_dnxhd_color:
3633

3734
#-profile:v: main444-10
3835

36+
dnxhd-yuv444p10le-440m:
37+
<< : *basednxhd
38+
-b:v: 440m
39+
3940
dnxhd-gbrp10:
4041
<< : *basednxhd
4142
#-vf: '"scale=in_range=full:in_color_matrix=bt709:out_range=full:out_color_matrix=bt709"'
@@ -57,9 +58,109 @@ test_dnxhd_color:
5758
#-colorspace: rgb
5859
#-pix_fmt: gbrp10le
5960

61+
test_dnxhd_422:
62+
app: ffmpeg
63+
comparisontest:
64+
- testtype: idiff
65+
compare_image: ../sourceimages/chip-chart-1080-16bit-noicc-yuv422p10le.png
66+
- testtype: assertresults
67+
tests:
68+
- assert: less
69+
value: max_error
70+
less: 0.00195
71+
description: dnxhd color tests of different pix-fmts
72+
encoding_template: ffmpeg -y {input_args} -i "{source}" {encoding_args}
73+
-y "{outfile}"
74+
name: test_dnxhd_color
75+
sources:
76+
- ../sourceimages/chip-chart-1080-16bit-noicc.png.yml
77+
suffix: .mov
78+
wedges:
79+
dnxhqx: &basednxhqx
80+
-c:v: dnxhd
81+
-profile:v: dnxhr_hqx
82+
-b:v: 440m
83+
-vf: '"scale=in_color_matrix=bt709:out_color_matrix=bt709"'
84+
-color_primaries: bt709
85+
-color_range: tv
86+
-color_trc: bt709
87+
-colorspace: bt709
88+
-pix_fmt: yuv422p10le
89+
#-preset: 3
90+
#-tag:v: hvc1
91+
92+
93+
#-profile:v: main444-10
94+
95+
p10_440M:
96+
<< : *basednxhqx
97+
-profile:v: dnxhd
98+
-pix_fmt: yuv422p10
99+
-b:v: 440M
100+
101+
p10_365M:
102+
<< : *basednxhqx
103+
-profile:v: dnxhd
104+
-pix_fmt: yuv422p10
105+
-b:v: 365M
106+
107+
p10_185M:
108+
<< : *basednxhqx
109+
-profile:v: dnxhd
110+
-pix_fmt: yuv422p10
111+
-b:v: 185M
112+
113+
p10_175M:
114+
<< : *basednxhqx
115+
-profile:v: dnxhd
116+
-pix_fmt: yuv422p10
117+
-b:v: 175M
118+
119+
440M:
120+
<< : *basednxhqx
121+
-profile:v: dnxhr_hq
122+
-pix_fmt: yuv422p
123+
-b:v: 440M
124+
125+
185M:
126+
<< : *basednxhqx
127+
-profile:v: dnxhr_hq
128+
-pix_fmt: yuv422p
129+
-b:v: 185M
130+
131+
115M:
132+
<< : *basednxhqx
133+
-profile:v: dnxhr_hq
134+
-pix_fmt: yuv422p
135+
-b:v: 115M
60136

61137
---
62138
reports:
139+
graphs:
140+
- args:
141+
color: name
142+
height: 400
143+
barmode: group
144+
x: media
145+
y: max_error
146+
name: max_error.png
147+
type: bar
148+
- args:
149+
color: name
150+
height: 400
151+
x: media
152+
barmode: group
153+
y: encode_time
154+
name: encode_time.png
155+
type: bar
156+
- args:
157+
color: name
158+
height: 400
159+
x: media
160+
barmode: group
161+
y: filesize
162+
name: filesize.png
163+
type: bar
63164
description: This is testing DNxHR color encoding.
64165
directory: dnxhd-color-encode
65166
name: dnxhd-color-tests

0 commit comments

Comments
 (0)