Jump to content

Why is my transcoding quality so bad?


drapacioli

Recommended Posts

drapacioli

Hi - I'm trying to figure out why the transcoding quality is absolutely terrible on the videos that need subtitle burn-in. I have transcoding quality settings set to a fast preset with a CRF value of 15. This should be nearly indistinguishable from the original quality, but I'm seeing noticeable pixelation and blocking throughout any sort of motion/fast scenes. This simply shouldn't be happening at these quality levels, and when I try the same CRF value on something like Handbrake, the quality is fine. Even setting placebo values of CRF=0 and an encoding preset of medium/slow shows noticeable pixelation. Also, what I'm seeing is the bitrate doesn't seem to increase as the CRF quality is raised. Shouldn't the bitrate be going up as the quality preset is improved?

 

Am I missing a setting or something?

 

Please see attached files and screenshots for examples of what I'm seeing, as well as the server and transcoding logs. The transcoding settings were medium preset, 0 CRF on these screenshots, and they look identical to the fast/15 setting I normally have.

embyserver.txtffmpeg-transcode-c21920dc-de03-4614-a0ab-f5cbb1bcf73c_1.txt

Screenshots:

Spoiler

Original video screenshot (Via VLC Media Player):

336540906_Screenshotfrom2020-11-2710-10-34.thumb.png.ef60ca039f52633d8b4c794af8e8a67d.png

Emby screenshot:

314040760_Screenshotfrom2020-11-2710-13-54.thumb.png.e3cb632ebabeb19d1e5ad36cc52f04c8.png

 

Transcoding quality settings:

Spoiler

Screenshot from 2020-11-27 09-57-11.png

 

Edited by drapacioli
Link to comment
Share on other sites

  • 2 weeks later...

@drapacioli 

Hi, and apologies for replying late.

We have an internal rule which ensures that a transcoded video can't have a higher bitrate than the source video.
If a source video has been encoded in a very efficient way (using lots of CPU resources, maybe doing 2-pass encoding), then it's possible that Emby's transcoding quality (at the same bitrate) is inferior to the input video quality.

The best possible result you can achieve at the moment is to choose "very slow" for the preset and "18" for CRF.

Beyond that, we need to think about what we could do to improve this.

Link to comment
Share on other sites

drapacioli

Thanks for the response. I was afraid you'd say something like that. It would be nice if we could make those choices for ourselves. If I'm on my local network, the bitrate being used honestly doesn't matter. It's the quality that is important to me, and my expectation is that a higher quality would result in a higher bitrate. 

 

I would be willing to use the diagnostics plugin, sure. 

Edited by drapacioli
Link to comment
Share on other sites

drapacioli

I did try installing the plugin but it looks like it does not work presently. Any attempts to make changes in the diagnostic page in the settings results in a blank "internal server error" popup, and the codec settings page is blank.

 

Is the plugin known to work on ubuntu 20.04?

Edited by drapacioli
Link to comment
Share on other sites

10 minutes ago, drapacioli said:

Thanks for the response. I was afraid you'd say something like that. It would be nice if we could make those choices for ourselves. If I'm on my local network, the bitrate being used honestly doesn't matter. It's the quality that is important to me, and my expectation is that a higher quality would result in a higher bitrate. 

This is surely not about making a "bad" choice for you. In most cases where transcoding is happening, it's about streaming at a reduced bitrate and for the other cases (like yours), it was just a simple decision to say that it wouldn't make much sense to transcode video to a higher bitrate as the source. 
And well - admittedly - your case is an exception where this rule doesn't fit exactly.

But what we can't do on the other side, is to use the bitrate that a user has configured in one of the client apps. That configuration is meant to indicate a maximum bitrate that can be streamed, and it's used to determine when transcoding is required to reduce the streaming bitrate. We really can't use this value as a target bitrate for transcoding (and transcode a 2 Mbps video to 80 Mbps because a user has configured 80 as the maximum bitrate).

Link to comment
Share on other sites

3 minutes ago, drapacioli said:

I did try installing the plugin but it looks like it does not work presently. Any attempts to make changes in the diagnostic page in the settings results in a blank "internal server error" popup, and the codec settings page is blank.

I'm not quite sure, but you might need the older version of the plugin for the release server..

Edited by softworkz
Link to comment
Share on other sites

drapacioli
5 minutes ago, softworkz said:

I'm not quite sure, but you might need the older version of the plugin for the release server..

Just tried the older version - same thing. Here's a copy of the error log, if it helps:

 

Spoiler

Client-Version=4.5.4.1. UserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
2020-12-10 21:22:12.328 Error Server: Error processing request
	*** Error Report ***
	Version: 4.5.3.0
	Command line: /opt/emby-server/system/EmbyServer.dll -programdata /var/lib/emby -ffdetect /opt/emby-server/bin/ffdetect -ffmpeg /opt/emby-server/bin/ffmpeg -ffprobe /opt/emby-server/bin/ffprobe -restartexitcode 3 -updatepackage emby-server-deb_{version}_amd64.deb
	Operating system: Linux version 5.4.0-56-generic (buildd@lgw01-amd64-025) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)) #62-Ubuntu SMP Mon Nov 23 19:20:19 UTC 2020
	Framework: .NET Core 3.1.7
	OS/Process: x64/x64
	Runtime: opt/emby-server/system/System.Private.CoreLib.dll
	Processor count: 8
	Data path: /var/lib/emby
	Application path: /opt/emby-server/system
	System.InvalidOperationException: System.InvalidOperationException: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
	   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream.Read(Byte[] buffer, Int32 offset, Int32 count)
	   at System.IO.Stream.CopyTo(Stream destination, Int32 bufferSize)
	   at System.IO.Stream.CopyTo(Stream destination)
	   at ServiceStack.StreamExtensions.CopyToNewMemoryStream(Stream stream) in C:\BuildAgent\work\912418dcce86a188\src\ServiceStack.Text\StreamExtensions.cs:line 507
	   at ServiceStack.Memory.NetCoreMemory.Deserialize(Stream stream, Type type, DeserializeStringSpanDelegate deserializer) in C:\BuildAgent\work\912418dcce86a188\src\ServiceStack.Text\NetCoreMemory.cs:line 148
	   at ServiceStack.Text.JsonSerializer.DeserializeFromStream(Type type, Stream stream) in C:\BuildAgent\work\912418dcce86a188\src\ServiceStack.Text\JsonSerializer.cs:line 195
	   at Emby.Common.Implementations.Serialization.JsonSerializer.DeserializeFromStream(Stream stream, Type type)
	   at Emby.Web.GenericEdit.EditableObjectBase.DeserializeFromJsonStream(Stream jsonStream, IJsonSerializer serializer)
	   at Emby.DiagnosticsPlugin.Api.DiagnosticsPluginService.Post(UpdateDiagnosticOptions request)
	   at Emby.Server.Implementations.Services.ServiceController.<>c__DisplayClass6_0.<VoidActionDelegate>b__0(Object service, Object request)
	   at Emby.Server.Implementations.Services.ServiceController.Execute(HttpListenerHost appHost, Object requestDto, IRequest req)
	   at Emby.Server.Implementations.Services.ServiceHandler.ProcessRequestAsync(HttpListenerHost appHost, IRequest httpReq, IResponse httpRes, RestPath restPath, String responseContentType, CancellationToken cancellationToken)
	   at Emby.Server.Implementations.HttpServer.HttpListenerHost.RequestHandler(IRequest httpReq, ReadOnlyMemory`1 urlString, ReadOnlyMemory`1 localPath, CancellationToken cancellationToken)
	Source: Microsoft.AspNetCore.Server.Kestrel.Core
	TargetSite: Int32 Read(Byte[], Int32, Int32)
	
2020-12-10 21:22:12.328 Info Server: http/1.1 Response 500 to 192.168.1.40. Time: 10ms. http://192.168.1.40:8096/emby/EncodingDiagnostics/DiagnosticOptions?X-Emby-Client=Emby Web&X-Emby-Device-Name=Chrome&X-Emby-Device-Id=8b24350c-3402-493f-8deb-b3497dc7b2b4&X-Emby-Client-Version=4.5.4.1

 

Edited by drapacioli
Link to comment
Share on other sites

drapacioli

Looks like the save button is working now on the diagnostic options page, but the codec parameters page is still blank. 

 

Can we work from just the diagnostics options page, or will we need a working codec parameters page too? The codec parameter page doesn't appear to be throwing any errors - it's just blank.

Edited by drapacioli
Link to comment
Share on other sites

The reason why we can't get any better results with libx264, even with the "very slow" preset, it that we're overriding a number of settings that are normally controller by the presets.

And with the Diagnostic Plugin, we can eliminate some of them.

Please go to the "Diagnostic Options" page.

There are two text fields for manipulating the ffmpeg command, I would start trying the following:

- Find: :rc_lookahead=10:me=dia:no_chroma_me

- Replace: <leave empty>

 

 

Link to comment
Share on other sites

4 minutes ago, drapacioli said:

Looks like the save button is working now on the diagnostic options page, but the codec parameters page is still blank. 

You need to go to the "Transcoding" page, choose "Advanced" and Save.

Then you'll see the codecs, but we don't need that page.

Link to comment
Share on other sites

drapacioli

OK, I've gone ahead and done the find/replace option. I do not see any change in visual quality or the bitrate reported in the stats pane while testing it. I presume no server reboot since the settings will be wiped, so I just applied them and tried an episode right away. 

Link to comment
Share on other sites

Ýou won't see any change of bitrate. The bitrate is set and will be the same as the source video. The purpose of this would be to achieve higher quality (at the cost of higher CPU of course).

A more radical approach would be to remove all custom settings: -x264opts:v:0 "subme=0:me_range=4:rc_lookahead=10:me=dia:no_chroma_me:partitions=none"

Don't forget to set the preset to "Very Slow" and CRF to 18.

Link to comment
Share on other sites

drapacioli

Oh I see. This probably won't achieve the result I was hoping for then, but let me see if the second string at least gets it closer.

 

I'll give Very Slow a try just for a quality comparison, but this is an intel U series processor. It's an 8259U so not the worst, but still a lower power chip that wouldn't be capable of transcoding in real time at that preset. I'll probably see 5-10fps at best.

 

Give me a bit to test it. 

Link to comment
Share on other sites

drapacioli

Second string is a no-go with Very Slow/18 CRF. Significant video glitching and skipping. Can't even get a decent still for comparison.

 

For the record, I was doing testing with this CPU when I first got it, and found the best I can manage for most videos was Medium preset.

Edited by drapacioli
Link to comment
Share on other sites

Just now, drapacioli said:

Second string is a no-go with Very Slow/18 CRF. Significant video glitching and skipping. Can't even get a decent still for comparison.

Probably better to go for individual settings to eliminate.

But when your CPU can't keep up, then there is probably no better result to achieve at all. A higher output bandwidth won't provide better results at the same CPU load.

You can try for yourself, just look up the bitrate, e.g. -maxrate:v:0 3643554 -bufsize:v:0 7287108

And with the find/replace feature you can change that to whatever you want to try (just make sure that bufsize is the double of the bitrate.

I think you got a lot of options to try now... 😉

 

Link to comment
Share on other sites

drapacioli
3 minutes ago, softworkz said:

You can try for yourself, just look up the bitrate, e.g. -maxrate:v:0 3643554 -bufsize:v:0 7287108

Just so I understand, that bold text goes as-is in the "text to replace" field, or do I have to format that differently?

Link to comment
Share on other sites

drapacioli

OK, so on a whim I tried just pasting that bold text into the "text to replace" field. It works...sometimes.

On the video file I was originally using for testing, I immediately saw the bitrate in the stats pane jump well above the original bitrate, and everything looked crystal clear. I could not tell a difference between it and the original source file - no blockiness or pixelation even during the fastest movement scenes.

 

However, some other files seem to be completely unaffected by this. From what I can tell, the only difference in the encodings is that the one that's working uses an H264 High profile, and the one that doesn't work uses an H264 Main profile. I threw the preset down to Very Slow again to double check and sure enough, the High profile file stalled out at 7fps, and the main one carried on at 30-50fps at a noticeably reduced quality, like it was completely ignoring the transcoding quality settings. 

 

Is this expected behavior?

Edited by drapacioli
Link to comment
Share on other sites

I took that text from your ffmpeg log. It will of course be different for other videos and for each video you'll have to look at the ffmpeg log first to check out the text to replace.
(of course we are testing things here, it's not about creating a solution...)

Link to comment
Share on other sites

drapacioli

I see, so if I want to test other video files I need to change that. 

It does seem that allowing an "unlimited" bitrate is producing the results I'd like though. With what I know about h264 encoding, I suppose that's not unexpected.

I guess my next question is - is there a settings file somewhere where I can override this behavior on a global level, until such time that the Emby team is willing or able to incorporate a true solution for users managing transcoding via local playback from their media library? Does the diagnostic plugin support wildcard operators?

Frankly, I just want to see the videos I have in the quality I have them encoded them in. I wouldn't call myself completely ignorant of the processes in place here, but if I see a setting available in the dashboard, I expect it will do exactly what it says it does, and not assume I don't know what I want and override my choices. That's why I picked Emby in the first place over, say, Plex - for the transcoding flexibility. I realize it's a niche power user use case, and I can't say I don't understand the need to protect novice users from themselves sometimes (because let's face it, many people do), but this issue does have me a little frustrated, not gonna lie.

  • Like 1
Link to comment
Share on other sites

drapacioli

I understand and appreciate anything you can do in the future. Again, if there's any further info or testing I can do, please let me know. 

 

If I may make a suggestion as sort of a compromise between two extremes - perhaps allowing users to set a transcoding max bitrate as both an absolute maximum value and a percentage of the source file's bitrate would work wonders here. I.e., a file that is at a 2.7mbps bitrate could be set to a 500% transcode bitrate as a maximum (producing a 13.5mbps output file), whereas a 20mbps source file would cap at, say a global max the user sets at 30mbps, instead of going up to 60mbps. If you could have separate options for local vs remote playback too, then all the merrier. This would allow the change without altering Emby's default behavior, and you could keep it in an advanced settings screen to help keep people from messing with it without knowing what it does. 

Once again, thank you for your time looking into this, and I hope to hear back some day. 

Edited by drapacioli
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...