Log in

View Full Version : x265 HEVC Encoder


Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 [176] 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

jpsdr
8th November 2022, 19:28
For those interested, made a new build of my x265_mod version.
-------------------------------------------------------------------------
Will wait the results of "classic" vs "histogram" to see if i change my encoding scripts, as i'm only doing 10 bits video / main10 encodes.

tormento
8th November 2022, 19:40
It's 8-bit video, so using Main. Is it practical using main 10?
HW decoders rarely can process 8 bit HEVC.

Moreover, 10 bit encoding has (since the infamous Hi10P days) proven to increase compression with additional benefits regarding banding and no disadvantages (at least HEVC files).

nevcairiel
8th November 2022, 19:58
HW decoders rarely can process 8 bit HEVC.


Wut?
Any HW decoder that can support HEVC at all will support 8-bit, and most of them also 10-bit.

benwaggoner
8th November 2022, 21:42
HW decoders rarely can process 8 bit HEVC.
You mean can rarely process 8-bit HEVC without also supporting 10-bit HEVC, right?

Moreover, 10 bit encoding has (since the infamous Hi10P days) proven to increase compression with additional benefits regarding banding and no disadvantages (at least HEVC files).
The benefit of 10-bit encoding for 8-bit sources is less with HEVC than with H.264, as 8-bit internal precision was improved. But it can still give a few percentage improvement and can reduce banding artifacts.

tormento
9th November 2022, 09:52
You mean can rarely process 8-bit HEVC without also supporting 10-bit HEVC, right?.
So picky you are. :p

mister_no
9th November 2022, 11:37
For those interested, made a new build of my x265_mod version.
-------------------------------------------------------------------------
Will wait the results of "classic" vs "histogram" to see if i change my encoding scripts, as i'm only doing 10 bits video / main10 encodes.

Can you please make a build without the extanded progress bar? My GUI doesn't show progress with the extanded progress bar.

jpsdr
9th November 2022, 14:20
Euh... Sorry but no, don't have time to try (don't even know if i would be able to) to build specific for X, Y, Z, etc...

jpsdr
9th November 2022, 19:28
About "histogram" vs "classic", what about hrd-pq ? If Boulder's video is 8 bit, i assume it sdr, so the "issue" is maybe main10 / 10 bits sdr video...
Has someone made tests to see if "histogram" behaves better than "classic" with main10 / 10 bits video in hdr-pq ?

Boulder
10th November 2022, 06:27
About "histogram" vs "classic", what about hrd-pq ? If Boulder's video is 8 bit, i assume it sdr, so the "issue" is maybe main10 / 10 bits sdr video...
Has someone made tests to see if "histogram" behaves better than "classic" with main10 / 10 bits video in hdr-pq ?

It looks like the histogram mode works quite well with PQ sources. I tested a 3000-frame part from Harry Potter and the Philosopher's Stone, and classic produced 10 scene changes while the histogram mode found 24, which should be very close to the real value. There are some difficult parts with slo-mo in the clip which confuses the tool I use for creating a QP file.

So the issue is probably seen with SDR sources encoded with the Main10 profile.

jpsdr
10th November 2022, 19:16
Ok, thanks for the feedback. In that case, i'll change my encode scripts to use histogram mode.

benwaggoner
10th November 2022, 22:03
Wow, that's big news if the new histogram mode is good enough to be the default.

Anyone test --mctf or the new segment based rate control?

vpupkind
11th November 2022, 16:57
Wow, that's big news if the new histogram mode is good enough to be the default.

Anyone test --mctf or the new segment based rate control?

SBRC is a bit of a misnomer right now. It does some aq-related stuff, hopefully some actual rate control stuff will follow.

ShortKatz
12th November 2022, 22:07
Wow, that's big news if the new histogram mode is good enough to be the default.

Anyone test --mctf or the new segment based rate control?

Tested --mctf just once. It increased my encoding time 7-fold. So I did not do any further tests.

LeXXuz
13th November 2022, 10:17
Ok, thanks for the feedback. In that case, i'll change my encode scripts to use histogram mode.

Could you possibly add 8-bit support to your version? I'd like to do some comparisons with aq5-mode between 8 and 10bit output.

jpsdr
13th November 2022, 13:19
.... There is not...? I ran cmake to create a VS projet and checked all possible options, i thought all the supports were enabled.
Setting --profile main, -D 8 (and all others related stuff saying that video is 8 bits) on the command line is not working ?

If not, for now, unfortunately i don't know what to do for... :(

quietvoid
13th November 2022, 15:36
If you enabled HIGH_BIT_DEPTH when configuring the build, it only builds 10 bit.
12 bit if you do MAIN12 too.

There's a multilib script to get a statically linked executable with all bit depths.
I can't really help for Windows/VS though.

LeXXuz
13th November 2022, 15:56
.... There is not...? I ran cmake to create a VS projet and checked all possible options, i thought all the supports were enabled.
Setting --profile main, -D 8 (and all others related stuff saying that video is 8 bits) on the command line is not working ?


No there isn't. x265 exits with this error if forced to work in 8-bit:
x265 [FLAW]: main profile not supported, internal bit depth 10.

jpsdr
13th November 2022, 16:29
Ah.... Don't know how to do it for now, don't realy have time for now, sorry. Try to see if i can figure out something when there will be the need for a new build.
Otherwise, anyone can also make a build from my repo.

quietvoid
13th November 2022, 16:52
I just noticed that the new histogram scene cut commit removed the logging of consecutive B frames %, seemingly for no reason.
If anyone had a use for it, here's a diff: https://github.com/quietvoid/x265/commit/43e460330af001365c8508d430a35be4377e390e

Should probably be renamed from m_histogram now but I just copied the old code back.

Boulder
13th November 2022, 16:53
Here's a very crude tool written in Python to get those average figures out of the csv log file written with csv-log-level 2 set. It expects that SSIM or PSNR is not enabled as those change the column structure. Only tested with two csv files I had on my HDD ;)

Usage: "python logtool.py filename.csv". It will then write a .log file to the path where the csv file is and output the same information in the command prompt window.

import pandas as pd
import os
import sys

filename = os.path.abspath(sys.argv[1])

log_content = pd.read_csv(filename, sep=",", decimal=".", header=0)
log_content = log_content.iloc[:-4,11:-9]
log_content.columns = log_content.columns.str.replace('.1', '', regex=True)
log_content.columns = log_content.columns.str.replace('66', ' 16x16', regex=True)
log_content.columns = log_content.columns.str.replace('326', ' 32x16', regex=True)
log_content.columns = log_content.columns.str.replace('6x32', ' 16x32', regex=True)
log_content.columns = log_content.columns.str.replace('6x8', ' 16x8', regex=True)
log_content.columns = log_content.columns.str.replace('86', ' 8x16', regex=True)
log_content.columns = log_content.columns.str.replace('AMP6', 'AMP 16', regex=True)
log_content = log_content.replace('%', '', regex=True).astype(float)
average = log_content.describe().loc['mean'].to_string()

print (average)
with open(filename+str('.log'), mode='w') as outputfile:
outputfile.write(str(average))
outputfile.close()

_kermit
14th November 2022, 15:02
piping to x265 with powershell

sorry if that is too off-topic...

this works just fine in a command prompt:

ffmpeg.exe -i FILE -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | x265.exe - --y4m .....etc.

Now I wanted to use Powershell for that and the piping isn't working, the x265 process doesn't even start, while ffpmpeg is running:

It seems that using the pipe character isn't working here.
Does anyone have an idea?

excellentswordfight
14th November 2022, 15:28
piping to x265 with powershell

sorry if that is too off-topic...

this works just fine in a command prompt:

ffmpeg.exe -i FILE -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | x265.exe - --y4m .....etc.

Now I wanted to use Powershell for that and the piping isn't working, the x265 process doesn't even start, while ffpmpeg is running:

It seems that using the pipe character isn't working here.
Does anyone have an idea?
There is nothing "wrong" with the pipe command, but piping does not work in the same way in powershell as in cmd so you cannot pipe raw data in the same way.

There are some workaround and more info here https://stackoverflow.com/questions/50456424/using-ffmpeg-and-ffplay-piped-together-in-powershell

_kermit
14th November 2022, 15:45
There is nothing "wrong" with the pipe command, but piping does not work in the same way in powershell as in cmd so you cannot pipe raw data in the same way.

There are some workaround and more info here https://stackoverflow.com/questions/50456424/using-ffmpeg-and-ffplay-piped-together-in-powershell

thanks for confirming, thought this might be the issue.
Looks rather messy doing it that way and the only reason I wanted to use PS was to retrieve values from the MKV and use them in the script.
Probably too much of a hassle now.

In case anyone is interested (pretty basic, with debug code...).
params: file, CRF, presetname

$file = $args[0]
$crf = $args[1]
$preset = $args[2]

$temp = $(&D:\temp\Mediainfo\MediaInfo.exe "--Inform=Video;%MaxCLL%" $file).tostring().split(" ")
$MaxCLL= $temp[0].trim()

$temp = $(&D:\temp\Mediainfo\MediaInfo.exe "--Inform=Video;%MaxFALL%" $file).tostring().split(" ")
$MaxFALL = $temp[0].trim()

$temp = $(&D:\temp\Mediainfo\MediaInfo.exe "--Inform=Video;%MasteringDisplay_Luminance%" $file).tostring().split(" ")
if ($temp) {
$LumMin = [int]([decimal]$temp[1].trim() * 10000)
$LumMax = [int]$temp[4].trim() * 10000}
else
{$LumMin = 0 ; $LumMax = 0}

$x265Params = "- --y4m --output-depth 10 --preset $preset --crf $crf --colorprim bt2020 --transfer smpte2084 --colormatrix bt2020nc --master-display ""G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L($LumMax,$LumMin)"" --vbv-bufsize 160000 --vbv-maxrate 160000 -o ""$file." + "$crf" + "_" + $preset + """ --rdoq-level 2 --cu-lossless --max-merge 3 --rc-lookahead 25 --lookahead-slices 4 --ref 4 --range limited --max-cll ""$maxCLL,$maxFALL"" --hdr --hdr-opt --repeat-headers --aud --deblock -3:-3 --no-strong-intra-smoothing --aq-mode 1 --rskip-edge-threshold 3 --psy-rd 4 --psy-rdoq 15 --ctu 32 --rskip 2 --deblock -3:-3"

"crf: $crf"
"preset: $preset"
"maxcll: $maxcll"
"maxfall: $maxfall"
"low: $LumMin"
"high: $LumMax"
"x265Params: $x265Params"

&D:\temp\ffmpeg-4.4-full_build\bin\ffmpeg.exe -i ""$file"" -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | d:\temp\x265\x265.exe $x265Paramsffmpeg.exe -i %1 -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | d:\temp\x265\x265.exe $x265Params

quietvoid
15th November 2022, 16:02
From a quick comparison of a full length encode in PQ/HDR, --hist-scenecut seems pretty good now.

Out of 628 expected shots..
Default: 180 false positives, 214 missed (or not exact frame), 414 frame perfect. 66% correct.
--hist-scenecut: 12 false positives, 121 missed (or not exact frame), 507 frame perfect. 81% correct.

YMMV.

stax76
15th November 2022, 17:51
@_kermit

This powershell code works:


$env:ffmpeg = 'D:\ffmpeg.exe'
$env:x265 = 'D:\x265.exe'
$env:avs = 'D:\test.avs'
$env:output = 'D:\test.hevc'

$env:ffmpeg_args = '-f yuv4mpegpipe -strict -1 -loglevel fatal -hide_banner'

$env:x265_args = '--crf 18 --output-depth 10 --y4m'

cmd /s /c --% ""%ffmpeg%" -i "%avs%" %ffmpeg_args% - | "%x265%" %x265_args% --output "%output%" -"


In short:

cmd /s /c --% "<cmd style command>"

benwaggoner
15th November 2022, 22:18
From a quick comparison of a full length encode in PQ/HDR, --hist-scenecut seems pretty good now.

Out of 628 expected shots..
Default: 180 false positives, 214 missed (or not exact frame), 414 frame perfect. 66% correct.
--hist-scenecut: 12 false positives, 121 missed (or not exact frame), 507 frame perfect. 81% correct.

YMMV.

Intriguing results, thanks! The drop in false positives could help compression efficiency quite a bit.

quietvoid
16th November 2022, 01:38
It seems there's a chance the current upstream x265 segfaults with --hist-scenecut, at the end of an encode.


#0 0x0000555555641be9 in x265::Lookahead::detectHistBasedSceneChange (this=this@entry=0x555555be6a70,
frames=frames@entry=0x7fff8521b870, p0=p0@entry=7, p1=p1@entry=8, p2=p2@entry=9)
at x265/source/encoder/slicetype.cpp:2848
2848 absIntDiffFuturePast = (uint8_t)X265_ABS((int16_t)futureFrame->averageIntensityPerSegment[segmentInFrameWidthIndex][segmentInFrameHeightIndex][0] - (int16_t)previousFrame->averageIntensityPerSegment[segmentInFrameWidthIndex][segmentInFrameHeightIndex][0]);


Seems futureFrame is a null pointer.

(gdb) p futureFrame
$1 = (x265::Lowres *) 0x0
(gdb) p previousFrame
$2 = (x265::Lowres *) 0x7ffef110f6c8

Should probably be reported.

_kermit
16th November 2022, 01:45
@_kermit

This powershell code works:


$env:ffmpeg = 'D:\ffmpeg.exe'
$env:x265 = 'D:\x265.exe'
$env:avs = 'D:\test.avs'
$env:output = 'D:\test.hevc'

$env:ffmpeg_args = '-f yuv4mpegpipe -strict -1 -loglevel fatal -hide_banner'

$env:x265_args = '--crf 18 --output-depth 10 --y4m'

cmd /s /c --% ""%ffmpeg%" -i "%avs%" %ffmpeg_args% - | "%x265%" %x265_args% --output "%output%" -"


In short:

cmd /s /c --% "<cmd style command>"

I had the same idea and it works now, thanks!

Boulder
16th November 2022, 06:02
It seems there's a chance the current upstream x265 segfaults with --hist-scenecut, at the end of an encode.



Seems futureFrame is a null pointer.



Should probably be reported.

I've now had one full movie encode crash twice and judging by the ETA time left in the console window, it could be the exact same frame so maybe it's this bug causing it.

Ashok Kumar Mishra
17th November 2022, 13:23
I've now had one full movie encode crash twice and judging by the ETA time left in the console window, it could be the exact same frame so maybe it's this bug causing it.

I observed the issue and sent the commit to be pushed.

jpsdr
17th November 2022, 21:13
Odd... (and lucky...?) I'm using also --hist-scenecut but didn't observe the issue. Made some very quick test with very small file and now a multi-pass encode is running since a few days, the 1rst pass went fine, second is running for now. I just hope i'll not have the issue just at the end of the encode after several days... :(
In the meantime, I hope the commit will be avaible in the official release.

=================================================

@LeXXuz
Don't know if you'll be able to use it, but i realized that the x86 version in my current releases is a 8 bits version. When you choose Win32 target, the HIGH_BIT_DEPTH option is not avaible in the Cmake config options... Don't know why, but with CMake/VisualStudio, if you build a x86 version of x265, you can do only 8bits. I'll try to build a 8bits x64 version when the commit will be made public.

benwaggoner
17th November 2022, 21:59
@LeXXuz
Don't know if you'll be able to use it, but i realized that the x86 version in my current releases is a 8 bits version. When you choose Win32 target, the HIGH_BIT_DEPTH option is not avaible in the Cmake config options... Don't know why, but with CMake/VisualStudio, if you build a x86 version of x265, you can do only 8bits. I'll try to build a 8bits x64 version when the commit will be made public.
I have some dim recollection of 10-bit not being implemented for 10-bit as the extra memory requirements being even less feasible within the 4 GB process limit.

jpsdr
17th November 2022, 22:30
Ok. I had a suspicion of something like that.

vpupkind
18th November 2022, 01:03
From a quick comparison of a full length encode in PQ/HDR, --hist-scenecut seems pretty good now.

Out of 628 expected shots..
Default: 180 false positives, 214 missed (or not exact frame), 414 frame perfect. 66% correct.
--hist-scenecut: 12 false positives, 121 missed (or not exact frame), 507 frame perfect. 81% correct.

YMMV.

How did you determine the 628 expected shots?

quietvoid
18th November 2022, 01:43
How did you determine the 628 expected shots?

Extracted from Dolby Vision RPU, since the shot starts are flagged with "scene_refresh_flag".

qyot27
18th November 2022, 02:37
I have some dim recollection of 10-bit not being implemented for 10-bit as the extra memory requirements being even less feasible within the 4 GB process limit.
More or less that reasoning from what I recall, but it is possible to build 10-bit and 12-bit x265 (and of course, 8-10-12 multilib) for IA32 targets. You just have to disable ASM when building for 10 or 12 bit (thus, not really worth it to do it, but it is still possible).

benwaggoner
18th November 2022, 03:11
More or less that reasoning from what I recall, but it is possible to build 10-bit and 12-bit x265 (and of course, 8-10-12 multilib) for IA32 targets. You just have to disable ASM when building for 10 or 12 bit (thus, not really worth it to do it, but it is still possible).
Yeah. Running a 32-bit Windows is so limiting these days I'm always startled to realize anyone is still doing it. So many apps aren't available at all, and the ones that do exist are almost always slower than their 64-bit equivalent. And running 32-bit on 32-bit limits apps to only 2 GB, 3 GB if Large Address Aware (LAA). A 64-bit OS allows a 32-bit app to have 4 GB in LAA, and so is still preferable.

I've not had any 32-bit Windows system in my household for over a decade now. And that's been a couple of dozen by this point, what with all the kids I have.

Boulder
18th November 2022, 06:19
I've tried using --hist-scenecut on a PQ B/W movie (Mr. Smith Goes to Washington from 1939) and in this case it fails badly. Lots of missed scene changes even if they are rather sharp ones. I didn't compare against the classic mode yet.

LeXXuz
18th November 2022, 12:08
@LeXXuz
Don't know if you'll be able to use it, but i realized that the x86 version in my current releases is a 8 bits version.

Thank you but my entire workflow is in 64bit.

vpupkind
18th November 2022, 19:08
Extracted from Dolby Vision RPU, since the shot starts are flagged with "scene_refresh_flag".
Can you recommend any tool for this? Also, how do you know this is the ground truth? Is it coming from an EDL, or a DolbyVision tool?

quietvoid
18th November 2022, 19:28
Can you recommend any tool for this? Also, how do you know this is the ground truth? Is it coming from an EDL, or a DolbyVision tool?

You can just use dovi_tool if you have a binary RPU.
The flag is pretty reliable in the RPU, as long as the RPU source is authored properly.
So the shots are probably coming from the XML metadata.

This can be easily verified by looking at the video at the shot boundaries indicated.
The only exception is for user generated content and "long play mode" metadata, which doesn't have shots.

For dovi_tool, there's this simple workflow to obtain the shot frame numbers: https://forum.makemkv.com/forum/viewtopic.php?p=123221&sid=039dcffa96a306f14f96cd47121a1f60#p123221

First, convert the RPU to json:

dovi_tool export -i RPU.bin -o RPU.json

Second, use jq (https://stedolan.github.io/jq/) to get a list of frames that have the scene_refresh_flag set:

jq "to_entries | .[] | select(.value.vdr_dm_data.scene_refresh_flag == 1) | .key" RPU.json > RPU-scene-frames.txt

The result with be a file with one (zero-based) frame number per line. Then I'll pick a few throughout the file, look at those frames in the video, and verify that each one is indeed the start of a new shot.

Boulder
19th November 2022, 10:20
Here's a test clip for hist-scenecut with B/W PQ sources, where it fails miserably.
https://drive.google.com/file/d/19FyX-yJGPqultNHbfaFDQpR-xL5Bjilu/view?usp=share_link

Hist-scenecut was able to find only one scene change, the classic mode got 9 and not all in the correct place. The correct amount is 17 if I didn't miss any.

jpsdr
19th November 2022, 12:22
I observed the issue and sent the commit to be pushed.

Where can i find it ?
I searched on https://bitbucket.org/multicoreware/x265_git/src/master/ but didn't find anything.

rwill
19th November 2022, 16:22
Here's a test clip for hist-scenecut with B/W PQ sources, where it fails miserably.
https://drive.google.com/file/d/19FyX-yJGPqultNHbfaFDQpR-xL5Bjilu/view?usp=share_link

Hist-scenecut was able to find only one scene change, the classic mode got 9 and not all in the correct place. The correct amount is 17 if I didn't miss any.

I decoded the MKV stream and there are 1441 frames. There is total 0 scenecuts in the video clip.

This can easily be confirmed visually because there is almost no change in color throughout the stream.

Boulder
19th November 2022, 16:28
Using DGSource to decode and loading in VDub, these should be the scene cut frames.

45
263
375
405
492
647
668
728
772
866
898
1111
1202
1253
1285
1324
1403

jpsdr
20th November 2022, 09:55
How do you make a pull request for x265 ? Or can someone make the following PR fix :
In encoder.cpp line 4288, apply the video preset BEFORE testing bHDR10Opt just in line 4274 !!!!!!!!

ShortKatz
20th November 2022, 13:16
A pull request for x265 is quite a bit tricky and in my experiences is also mostly ignored. But you need to send it to the mailing list x265-devel@videolan.org with a specific formatting. For details see
https://bitbucket.org/multicoreware/x265_git/wiki/Contribute

jpsdr
20th November 2022, 15:22
Tricky...
I think i'll for now just do it on my personnal mod branch... If any current dev read this, he can do the PR.

jpsdr
20th November 2022, 20:44
--multi-pass-opt-rps broken !!!
I have a small clip which can reproduce the issue, this option produces a broken, unplayable h265 stream.
I can give :
- The clip
- The encode script
- The broken encode result
I can put all these data on my FTP server, so any dev can PM me to have the server information to retrieve all of these.

FranceBB
20th November 2022, 22:54
Hi Jean Philippe, I'll be back at work after Thanksgiving.
I already have access to your FTP.
We'll prepare a formal email together when I'm back (Sky is a member of the multicoreware partner program) ;)