After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 791771 - opusenc, opusdec: add option to disable phase inversion
opusenc, opusdec: add option to disable phase inversion
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
unspecified
Other Linux
: Normal enhancement
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-12-19 07:21 UTC by Hector Martin
Modified: 2018-11-03 12:02 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
opusdec: Add property to control phase inversion (4.01 KB, patch)
2018-08-01 03:12 UTC, Nicolas Dufresne (ndufresne)
committed Details | Review

Description Hector Martin 2017-12-19 07:21:01 UTC
http://opus-codec.org/docs/opus_api-1.2/group__opus__genericctls.html#ga10fa1f6eab136baf83c232afa989b6a8

When downmixing stereo streams to mono, having phase inversion enabled produces terrible audio quality (it sounds like a low bitrate MP3), since frequency bands randomly cancel out. This should be exposed in the encoder (to produce bitstreams that always sound good when downmixed to mono, regardless of what the decoder does), and in the decoder (to allow any arbitrary bitstream to sound good when downmixed to mono, regardless of what the encoder did). On the decoder, additionally, it should probably default to disabled (i.e. OPUS_SET_PHASE_INVERSION_DISABLED(1)) when the output channel count is 1.

Here's a sample of just how bad decoding opus to mono without this enabled sounds: https://mrcn.st/t/opus_decoding_test.ogg . This is 6 seconds of stereo decoding, 3 seconds of mono decoding, repeatedly. The input bitstream is the same in both cases, with phase inversion enabled, as is the case right now in gstreamer. It gets *really* bad at 0:50 or so.

See also: https://tools.ietf.org/html/rfc8251#section-10
Comment 1 Nicolas Dufresne (ndufresne) 2018-08-01 02:58:04 UTC
After some googling and testing, your report is a bit off. So if the output channels count is 1, this setting have just no effect (I just tested it). Which makes sense, since in this case the decoder is aware of this side effect and can avoid it.

The problem is when we produce let's say a stereo stream and downmix outside of the decoder. That's where you can ear the bad audio.

gst-launch-1.0 filesrc location=stereo.wav ! wavparse ! opusenc ! opusdec ! audio/x-raw,channels=2 ! audioconvert ! audio/x-raw,channels=1 ! pulsesink

Now, what the doc says is that stereo quality will be decrease, but marginally, while the stream will be down sampler friendly.
Comment 2 Nicolas Dufresne (ndufresne) 2018-08-01 03:12:51 UTC
Created attachment 373234 [details] [review]
opusdec: Add property to control phase inversion

When enabled, phase-inversion slightly increase stereo quality, but
produce a stream that when downmixed to mono will present important
audio distortion. This patch disables this feature by default and
introduce a property that let user enable it if desired.
Comment 3 Nicolas Dufresne (ndufresne) 2018-08-01 13:55:04 UTC
Attachment 373234 [details] pushed as d2aff7b - opusdec: Add property to control phase inversion
Comment 4 Hector Martin 2018-08-07 04:11:48 UTC
Thanks for the fix. Yes, I wasn't clear in my report: the problem occurs when the stream is downmixed outside the decoder itself. If libopus is downmixing the stream itself then it knows how to do the right thing. The issue is that pretty often downmixing happens later and the decoder has no idea.
Comment 5 Hector Martin 2018-08-07 04:20:13 UTC
I see the patch is for opusdec only. Can we get the same feature implemented for opusenc? That was actually my use case: I'm encoding audio with gstreamer for WebRTC distribution, and Chrome was spuriously downmixing it (due to a bad RTP descriptor, but that's another story), causing extremely bad audio quality. I want to ensure that regardless of what clients do, I don't get this effect.

In fact disabling phase inversion by default (unconditionally, not just for mono output) in the decoder may not be the best idea, since it'll reduce stereo imaging for streams that use it. I was thinking disabling it in the encoder might be a good idea, since it ensures streams sound good regardless of what the decoder does or any downmixing that occurs. But if the decoder thinks the channel count is 2 then it probably makes sense to leave it on, so that if the encoder relied on the feature it is used. Of course, if something downstream ends up downmixing the audio to mono then it'll sound bad, so I guess it depends on how likely we think that will be.
Comment 6 GStreamer system administrator 2018-11-03 12:02:25 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/409.