Roku Ultra 2020, aka 4800x, direct play, colors distorted when playing back HEVC, 1080p content on 1080p screen. Applies to both 8-bit and 10-bit packaging of 8-bit content

I created 6 sample HEVC files with Handbrake, MKV, M4V and MP4 container types, AAC and AC-3 audio. The M4V and MP4 containers contain MP4 stream format, MKV files contain MKV stream format. All 6 play perfectly in Roku Media Player from a local thumbdrive. I have not analyzed the header info to see what BT info is there. With this data I believe the Roku is not completely at fault. Roku Ultra player can play HEVC/HDR content on a 1080p TV with no problems, I believe the problem lies in the stream that Plex is passing to the Roku to play.

Here are the 6 sample files I created.

All of this is really a moot point, we can discuss what we think is the problem till the end of time. Until a Plex developer reads these comments and begins to investigate, it’ll never get fixed. The only Plex person to comment was last Feb.

The ā€œPlex Employeeā€ who is most focused of any Plex Employee on Roku development read and responded to this very thread back in February of 2021.

I don’t know ljunkie’s internal role; however, ljunkie is the person who has posted about every Plex for Roku update announcement since July of 2014.

The person from Plex who is most focused on the Plex client for Roku has looked into the issue. I can’t say that anyone from Roku has looked at this issue.

Here is the other huge indicator that the issue lies with Roku and not Plex. I only have 1080p televisions which have a maximum of BT.709 color (8-bit). I have the Roku set for 1080p maximum color output. If I feed the Roku BT.709 color (8-bit) HEVC video, it should not be possible for a Roku to output more than BT.709 color, (8-bit) to a screen set for 1080p maximum resolution.

Even if somehow Plex was at fault for this issue, which they are not, the 4800x Roku should not be outputting BT.2020 color (12-bit) to a television set to only play a maximum of BT.709 color, (8-bit) let alone when feed BT.709 color (8-bit) video.

Once again, Roku needs to fix this issue. The problem is 100% in the Roku firmware.

1 Like

I agree it’s a Roku issue for multiple reasons. And that the fix probably has to come from Roku.

Plex does have a long history of working around player bugs.

Workarounds like ā€œDon’t send multichannel AAC because Roku devices downmix to Stereoā€ aren’t harmful to other devices.

But I’m not sure how Plex could work around this, without negatively impacting playback on other Roku devices.

1 Like

With Plex the Plex Server is opening and reading the MKV/MP4 file and is generating a bitstream that is passed over the network to the Plex Client which is then passing the bitstream to the Roku to properly play. Plex Server is generating the bitstream. If on a SDR TV (1080p) you can see the HDR being displayed when the content is HEVC SDR, then that is a Plex Server problem, since its generating the bitstream and header info. No matter whats in the MKV/MP4 file the Plex Server is generating the bitstream. If realtime transcoding needs to happen, like AAC → AC-3, then Plex Server is converting the AAC to AC-3 and inserting that data into the bitstream. Plex is also generating the header info, like if the video is AVC or HEVC, and whether its BT.709 or BT.2020. All that is put in the header of the bitstream that Plex Server is generating.

When Plex is playing a file in Direct Play mode it should be passing the audio and video data unmodified, but Plex Server is still generating the header info at the beginning of the bitstream from the header data it read from the MKV/MP4 file. Possibly its incorrectly stating the BT.2020 instead of BT.709.

So the fact that the bitstream Plex is feeding the Roku states BT.2020, Plex Server is responsible for generating the header info and inserting that into the bitstream. The Roku is simply trying to display the video data that its being fed to it by Plex Client.

The fact that when the Roku is playing these files natively from the Roku Media Play & video is bring displayed correctly, yet when played thru Plex the video is NOT being displayed correctly, that tells me Plex is responsible for the problem.

Its really time for a Plex Developer / Debugger / Tester to chime in. There’s nothing more I can do without guidance from a developer to help debug this issue. We can keep going round and round discussing what we ā€˜think’ is going on but until Plex employee responds its all just theory.

You are neglecting the fact that the same exact issue also occurs with Emby and Jellyfin. Why would all three be sending a BT.2020 MKV header for BT.709 video and why would this problem not occur with my 4670R Roku? If Plex is somehow sending the wrong header info when both the 4800x and the 4670R use the exact same Roku profile, why does this issue not occur with the 4670R?

Is there any evidence of that?

(Roku logs and/or Plex logs showing transcoder parameters?)

I think there’s good evidence that one Roku model makes bad assumptions when color space isn’t signaled, but I haven’t seen any indication that Plex is setting it incorrectly.

(Hrm. I wonder if there’s a conflict between container-level signaling and stream-level signaling. That’s a common issue with aspect ratio, for instance. Just a hunch. I don’t have a 4800x in front of me, but I’ll try to look at your sample files for clues.)

It seems to me that Plex is using different profiles for the 4800x versus 4670R, which is why we’re seeing problems.

A recent experiment by a person over at the Roku forum, discussing this exact issue, showed that the Roku is applying BT.2020 instead of BT.709 when it finds BT.709 in the MKV header. When the BT.709 header is stripped from an MKV, the video plays perfectly from USB.

We literally know the cause of what is happening at this point and what needs to be done to fix it, we need a firmware update from Roku to fix how it reads BT.709 MKV header with HEVC video. That’s literally it.

I do not know why granjan7 states this issue does not occur from USB played video, because it has been for other people.

It doesn’t though. The 4800x and 4670r use the exact same profile. I manually went through and looked, only one plex server profile exists for both the 4800x and 4670r.

Have you played the 6 Sample files I uploaded from a thumbdrive on your Roku with the Roku Media Player app? Do they display correctly? Now play them from Plex. Do they display correctly? This is how Im trying to debug this issue. I have not had the time to look at the headers of those 6 files yet, hopefully Sunday I can dedicate some time.

It would be helpful if you explained your experience with those six files, playing from USB v Plex. It has occurred previously in this thread that people have confused the cause of their issues with the known 8-bit HEVC, MKV issues with the 4800x. I don’t want to troubleshoot your issues to uncover that you have an unrelated cause to the issue that I have been trying to solve since December of 2020.

Did you test your test files yourself in Plex?

All six of your example videos play perfectly in plex on my 4800x, with no transcoding. All of the audio is stereo so no transcoding is required. Literally, everything played perfectly.

In Plex:
1-ac3.m4v - No Transcoding of video or audio, played perfect, HEVC 8-bit with AC3 stereo audio
1-aac.m4v - No Transcoding of video or audio, played perfect, HEVC 8-bit with AAC stereo audio
2-ac3.mkv - No Transcoding of video or audio, played perfect, HEVC 8-bit with AC3 stereo audio
2-aac.mkv - No Transcoding of video or audio, played perfect, HEVC 8-bit with AAC stereo audio
3-ac3.mp4 - No Transcoding of video or audio, played perfect, HEVC 8-bit with AC3 stereo audio
3-aac.mp4 - No Transcoding of video or audio, played perfect, HEVC 8-bit with AAC stereo audio

Meanwhile, my HEVC file I converted to HEVC/MKV using FFmpeg is majorly jacked up. 56.86 MB file on MEGA

My guess is it’s the difference in the MKV headers from FFmpeg v Handbreak. Handbrake’s header file has almost nothing in it compared to FFmpeg.

But seriously, granjan7, if you are having issues with these files in Plex, you have something else going on from what I first started this thread about. These videos played back perfectly on my 4800x.

In comparison, my test file or literally any HEVC mp4 with AAC audio, from the rarbg release group tag will experience the problem I started this thread about.

If those 6 test files are broken for you, you have something else broken other than what I described.

@Volts @ljunkie

I had a major breakthrough in solving the mystery of the 4800x and HEVC video that I believe is worth a tag.

@granjan7 had me test his handbrake encoded MKV files and they played correctly on the 4800x. That lead me to reencode my test file using Handbreak to make to see what would happen. To my shock and amazement, it played perfectly on the 4800x.

My test video is AAC mono, originally shot on an iPhone 6s. This is important as this means the plex server will not attempt to transcode any part of the newly constructed MKV files.

This file plays perfectly on the 4800x:

https://mega.nz/file/ELo1GA7Z#ymwHUOmvN3rD4qIhN3U0wLhhND759YijuDW9XxafBRE

This is where things get interesting. I used the latest FFmpeg release, FFmpeg 4.4 to make a new container for the video/audio without modifying the underlying video or audio.

i.e.,

./ffmpeg -i ā€˜OG-Handbreak-Img-8880-Hevcsdr8bit-1.mkv’ -flags +global_header -vcodec copy -acodec copy ā€˜Broken-FFmpeg-Img-8880-Hevcsdr8bit-2.mkv’

https://mega.nz/file/9ax0lJAZ#AcTbb0Xo5l9OhTYRJLoUH2T0bp1vN5EBGhQmvG4Nhv4

When I add the new MKV file with the MKV container that has just been built by FFmpeg to Plex and try to direct play it on the Roku 4800x, now I am seeing the Roku 4800x apply BT.2020 color to the video despite the fact that the OG version with the container encoded by HandBreak plays the video back as BT.709.

This explains all the issues with the plex server transcoding multichannel AAC also, as 5.1 channel AAC audio is transcoded to 5.1 AC3 and merged with the original HEVC video in a new MKV container when transcoding. Since FFmpeg is adding/missing a flag, or something else, compared to Handbreak in the newly constructed MKV container, the video is played back as BT.2020 HEVC despite being coded as BT.709 HEVC.

I have no idea if this is something that Plex can build a profile to work around or if the FFmpeg devs can add something that fixes this problem. To me, it’s underly mindblowing that a new Roku would not work better with the current FFmpeg release.

In any event, the cause of the 4800x issues has been narrowed down. Something with the 4800x does not process 8-bit, HEVC, MKV containers encoded with the latest FFmpeg properly and this is why we are seeing BT.2020 color when we should be seeing BT.709 on the displays.

1 Like

The original file (ā€˜OG-’) is definitely only signalling the color information in the stream, while the remuxed (ā€˜Broken-’) does so in both container and stream.

The values look good to me. I suspect that the Roku bug is that it’s barfing when those values are present in the MKV container, even if they’re correct.

I was going to suggest removing them and seeing if it would fall back to the stream-level data. But it looks like somebody has already tested exactly that:

Re: 265 coded MKV files color very saturated - Page 5 - Roku Community


I suppose Plex could generate MP4 instead of MKV … I don’t know if profile hacking would let you test that - easy enough to try - or if the profile enrichment would override it.

You might need to account for subtitles. MP4 definitely doesn’t want SRT. Could just remove it for testing, or try subtitleCodec="mov_text".

1 Like

Looking at the MKV header info with mkvtoolsnix it appears that Handbrake is creating a header type 4, where as ffmpeg is creating a header type 2. Thats the only thing that really stood out to me as differences in the header info. Even though Handbrake can passthru audio & subtitle content has no way to passthru video content. Searching the Handbrake forums they have, in no uncertain terms, NO desire to add that feature. Since Handbrake creates a header that works with Plex and the Roku 4400x I tried ā€˜repackaging’ my MKV file with different software to try & find 1 that creates a header that works. Many of my MKV files were generated by ffmpeg on Windows. I tried the following…
MakeMKV
MKXtoolsNIX
ffmpeg on Ubuntu

None worked correctly. Next is AVIDEMUX on Windows.

I realize that this is a band-aid until Plex and/or Roku fix their problems.

A person should be able to use mkvpropedit, as part of MKVToolNix, to edit MKV files and remove the color space from the MKV containers and in doing so, convert the MKVs to be compatible with the 4800x, assuming the resulting MKV does not have anything else that will trigger any kind of transcoding, i.e., multichannel AAC audio, ā€œ.assā€ subtitles, etc.

https://mkvtoolnix.download/doc/mkvpropedit.html

I have been super busy since I did my last research/post on this subject, but it should be possible to script out a removal of the color space info from the MKV container, for all of a person’s HEVC, MKV files, specifically. All of this without modifying the audio/video in any other way.

The strategy of removing the BT.709 header flags is known/proven to work to at least partially ā€œwork aroundā€ the issue and has been proved to work.

https://community.roku.com/t5/Channel-Issues-Questions/Severe-color-contrast-distortion-while-Plex-streaming-HEVC-EAC3-videos/m-p/710365/highlight/true#M85774

https://community.roku.com/t5/Channel-Issues-Questions/Severe-color-contrast-distortion-while-Plex-streaming-HEVC-EAC3-videos/m-p/711371/highlight/true#M86015

When I get time to get around to it, which may be a couple weeks, if no one else beats me to it, I will work on putting together a bash script to remove the color space info from HEVC, MKV header, at least partially working around the 4800x MKV issues.

1 Like

I’m just thinking out loud here. If ā€˜removing’ / ā€˜setting to zero’ the following 4 fields allows it to play on 4400x, is the resulting MKV file technically now ā€˜incorrect’, ā€˜illegal’, or ā€˜invalid’? Should ALL media players be able to play the MKV file correctly without these 4 fields worth of data? I suppose so since HandBrake does not include these values in its video header info for MKV files.

Colour Matrix Coefficients
Colour Range
Transfer Characteristics
Colour Primaries

I dont know if I want to removes these 4 fields worth of data from all of my MKV files just to find out the data is really necessary down the road.

Then it makes me wonder if HandBrake should be including these fields in its video headers?

There’s so much I dont fully understand.

1 Like

It’s a super quick change, not even a remux required.

mkvpropedit FILE.MKV --edit track:v1 --delete colour-primaries --delete colour-range --delete colour-matrix-coefficients --delete colour-transfer-characteristics --delete chroma-siting-horizontal --delete chroma-siting-vertical

They shouldn’t be 0. 0 isn’t always the default for MKV. For a few of these elements, 0 is either reserved or means Identity.

MKV specifices that missing values should be defaulted. The default for all of these items is unspecified, which isn’t always 0.

The values should either be correct, or simply removed from the file.

Not at all!

Many information elements can be stored in the container, inside the encoded stream(s) within the container, or in both places. (Why store it in both places? If it’s in the container, it can be parsed generically without needing to access or parse the stream. )

It’s up to a player/decoder which location is consulted & prioritized. The stream-level information is typically used. In this case the Roku seems to stumble when these elements are in the container, even if they’re accurate.

I think this is a pretty safe thing to do.

  • I have many MKV files with colour information in the stream only, not the container.
  • I’m not aware of any players/decoders that require it to be present in the container for playback.
  • The information remains present in the stream, so it can be rebuilt if necessary.
    • It could be probed from the stream and re-saved into the MKV.
    • Or ffmpeg could be used to remux the video again, which will recreate it.

Cool, thanks for the info. These seem to be set in the video stream header, not the container. If it seems to work I’ll run it on all of my HEVC MKV files.

What does ā€œvideo stream headerā€ mean - where are you looking? In the examples I’ve seen it’s in both container and stream.

MKVToolNix will only show container-level info.
An accessible tool for displaying where it’s stored is MediaInfo.

% mediainfo -f FILE.MKV
<snip>
Color range                              : Limited
colour_range_Source                      : Container / Stream
Color primaries                          : BT.709
colour_primaries_Source                  : Container / Stream
Transfer characteristics                 : BT.709
transfer_characteristics_Source          : Container / Stream
Matrix coefficients                      : BT.709
matrix_coefficients_Source               : Container / Stream
<snip>

Updated command; also removes chroma siting:

# Remove color info from MKV container headers
mkvpropedit FILE.MKV --edit track:v1 --delete colour-primaries --delete colour-range --delete colour-matrix-coefficients --delete colour-transfer-characteristics --delete chroma-siting-horizontal --delete chroma-siting-vertical