Bug 213213

Summary: [GTK] Cannot play H.264-encoded YouTube videos
Product: WebKit Reporter: Michael Catanzaro <mcatanzaro>
Component: MediaAssignee: Nobody <webkit-unassigned>
Status: RESOLVED CONFIGURATION CHANGED    
Severity: Normal CC: bugs-noreply, mcatanzaro, pnormand
Priority: P2    
Version: WebKit Nightly Build   
Hardware: PC   
OS: Linux   
Attachments:
Description Flags
Debug log none

Description Michael Catanzaro 2020-06-15 14:22:08 PDT
Last week, we attempted to debug why https://www.youtube.com/watch?v=N_RWY04aT1k does not work in Epiphany Tech Preview. (Note: works fine in Fedora's Epiphany, which also uses OpenH264.) Eventually we tracked it down to a qtmux bug, https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/622. That bug is now resolved in Tech Preview, but the video still does not play, so something else is wrong. I'm attaching a full debug log, but the important part is:

0:00:01.519887227    64 0x563825245b50 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:462:gst_element_factory_make: no such element factory "qtdemux"!

(WebKitWebProcess:64): GLib-GObject-WARNING **: 16:16:41.279: invalid (NULL) pointer instance

(WebKitWebProcess:64): GLib-GObject-CRITICAL **: 16:16:41.279: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:64): GLib-GObject-WARNING **: 16:16:41.279: invalid (NULL) pointer instance

(WebKitWebProcess:64): GLib-GObject-CRITICAL **: 16:16:41.279: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:64): GLib-GObject-WARNING **: 16:16:41.279: invalid (NULL) pointer instance

(WebKitWebProcess:64): GLib-GObject-CRITICAL **: 16:16:41.279: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:64): GStreamer-CRITICAL **: 16:16:41.279: gst_element_link_pads_full: assertion 'GST_IS_ELEMENT (dest)' failed

Note this seems to be a problem in qtdemux, whereas the first bug was a problem in qtmux.

(Also note that we shouldn't have criticals even if the GStreamer installation is missing a plugin.)
Comment 1 Michael Catanzaro 2020-06-15 14:22:36 PDT
Created attachment 401937 [details]
Debug log
Comment 2 Michael Catanzaro 2020-06-15 14:25:23 PDT
Also, proof that the first bug is fixed. Last week, this command was printing uninitialized memory, but now it succeeds:

$ gst-inspect-1.0 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstisomp4.so 
Plugin Details:
  Name                     isomp4
  Description              ISO base media file format support (mp4, 3gpp, qt, mj2)
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstisomp4.so
  Version                  1.16.2
  License                  LGPL
  Source module            gst-plugins-good
  Binary package           GStreamer Good Plug-ins source release
  Origin URL               freedesktop-sdk

  qtdemux: QuickTime demuxer
  rtpxqtdepay: RTP packet depayloader
  qtmux: QuickTime Muxer
  mp4mux: MP4 Muxer
  ismlmux: ISML Muxer
  3gppmux: 3GPP Muxer
  mj2mux: MJ2 Muxer
  qtmoovrecover: QT Moov Recover

  8 features:
  +-- 8 elements
Comment 3 Philippe Normand 2020-06-16 00:54:59 PDT
The qtdemux warning doesn't make sense. Maybe remove your gst registry file?

Anyway, here I get a different error:

0:00:02.472689785   591 0x55ea0cc42aa0 WARN            videodecoder gstvideodecoder.c:2523:gst_video_decoder_change_state:<openh264dec0> error: Failed to start decoder
0:00:02.472724515   591 0x55ea0cc42aa0 WARN               decodebin gstdecodebin2.c:2523:connect_pad:<decodebin1> Couldn't set openh264dec0 to PAUSED
0:00:02.472881250   591 0x55ea0cc42aa0 WARN            uridecodebin gsturidecodebin.c:920:unknown_type_cb:<uridecodebin0> warning: No decoder available for type 'video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, level=(string)3, profile=(string)main, width=(int)640, height=(int)360, pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)30000/1001, interlace-mode=(string)progressive, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true'.
0:00:02.472907546   591 0x55ea0cc42aa0 WARN               decodebin gstdecodebin2.c:4678:gst_decode_bin_expose:<decodebin1> error: no suitable plugins found:
Couldn't set openh264dec0 to PAUSED:
Could not initialize supporting library.
Could not initialize supporting library.
../gst-libs/gst/video/gstvideodecoder.c(2523): gst_video_decoder_change_state (): /GstPlayBin:media-player-0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin1/GstOpenh264Dec:openh264dec0:
Failed to start decoder


H264 playback is broken again in your runtime.
Comment 4 Michael Catanzaro 2020-06-16 07:18:54 PDT
(In reply to Philippe Normand from comment #3)
> H264 playback is broken again in your runtime.

Seems so, my penguin test video is indeed broken again. This worked just a week or two ago, so it must have broken very recently. I'll need to bisect the runtime, I guess.
Comment 5 Michael Catanzaro 2020-06-16 12:37:50 PDT
(In reply to Michael Catanzaro from comment #4)
> Seems so, my penguin test video is indeed broken again. This worked just a
> week or two ago, so it must have broken very recently. I'll need to bisect
> the runtime, I guess.

I tried "flatpak bisecting" this, but it's working again now... I didn't keep track of my exact starting revision, so it's *possible* something changed, but more likely it's just generally unreliable and I got unlucky. Anyway, it's working again now. The test is https://www.reddit.com/r/StLouis/comments/fvnqpb/gotta_love_our_zoo/ and I'm virtually certain that is testing H.264, because that video did not work during the long period where our OpenH264 was broken.

Anyway, attempting to play either the YouTube video or the penguin video results in:

$ flatpak run org.gnome.Epiphany.Devel

(WebKitWebProcess:932): GLib-GObject-WARNING **: 14:22:23.217: invalid (NULL) pointer instance

(WebKitWebProcess:932): GLib-GObject-CRITICAL **: 14:22:23.217: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:932): GLib-GObject-WARNING **: 14:22:23.217: invalid (NULL) pointer instance

(WebKitWebProcess:932): GLib-GObject-CRITICAL **: 14:22:23.217: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:932): GLib-GObject-WARNING **: 14:22:23.217: invalid (NULL) pointer instance

(WebKitWebProcess:932): GLib-GObject-CRITICAL **: 14:22:23.217: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:932): GStreamer-CRITICAL **: 14:22:23.217: gst_element_link_pads_full: assertion 'GST_IS_ELEMENT (dest)' failed

(WebKitWebProcess:932): GLib-GObject-WARNING **: 14:22:24.543: invalid (NULL) pointer instance

(WebKitWebProcess:932): GLib-GObject-CRITICAL **: 14:22:24.543: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:932): GLib-GObject-WARNING **: 14:22:24.543: invalid (NULL) pointer instance

(WebKitWebProcess:932): GLib-GObject-CRITICAL **: 14:22:24.543: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:932): GLib-GObject-WARNING **: 14:22:24.543: invalid (NULL) pointer instance

(WebKitWebProcess:932): GLib-GObject-CRITICAL **: 14:22:24.543: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

(WebKitWebProcess:932): GStreamer-CRITICAL **: 14:22:24.543: gst_element_link_pads_full: assertion 'GST_IS_ELEMENT (dest)' failed

WebKit criticals are WebKit bugs, even though they might be exposed by a runtime bug. Here's a backtrace to the first warning, taken with the YouTube video:

#0  0x00007fbf38afa692 in g_logv
    (log_domain=0x7fbf38c103a7 "GLib-GObject", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=<optimized out>) at ../glib/gmessages.c:1377
        domain = 0x0
        data = 0x0
        depth = 0
        log_func = 0x7fbf38afa360 <g_log_default_handler>
        domain_fatal_mask = <optimized out>
        masquerade_fatal = <optimized out>
        test_level = <optimized out>
        was_fatal = <optimized out>
        was_recursion = <optimized out>
        msg = 0x55a71a3efac0 "invalid (NULL) pointer instance"
        msg_alloc = 0x55a71a3efac0 "invalid (NULL) pointer instance"
        i = 4
#1  0x00007fbf38afa903 in g_log
    (log_domain=log_domain@entry=0x7fbf38c103a7 "GLib-GObject", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=<optimized out>) at ../glib/gmessages.c:1415
        args = {{gp_offset = 24, fp_offset = 48, overflow_arg_area = 0x7ffe2229ec00, reg_save_area = 0x7ffe2229eb40}}
#2  0x00007fbf38c0625a in g_type_check_instance (type_instance=type_instance@entry=0x0) at ../gobject/gtype.c:4146
#3  0x00007fbf38bfb93f in g_signal_connect_data
    (instance=0x0, detailed_signal=detailed_signal@entry=0x7fbf3b9f9bb9 "pad-added", c_handler=c_handler@entry=0x7fbf3b902d40 <_FUN(GstElement*, GstPad*, WebCore::AppendPipeline*)>, data=data@entry=0x7fbd41834ee0, destroy_data=destroy_data@entry=0x0, connect_flags=connect_flags@entry=(unknown: 0)) at ../gobject/gsignal.c:2570
        _g_boolean_var_ = <optimized out>
        signal_id = <optimized out>
        handler_seq_no = 0
        detail = 0
        itype = <optimized out>
        swapped = <optimized out>
        after = <optimized out>
        __func__ = "g_signal_connect_data"
#4  0x00007fbf3b9013af in WebCore::AppendPipeline::AppendPipeline(WTF::Ref<WebCore::MediaSourceClientGStreamerMSE, WTF::DumbPtrTraits<WebCore::MediaSourceClientGStreamerMSE> >, WTF::Ref<WebCore::SourceBufferPrivateGStreamer, WTF::DumbPtrTraits<WebCore::SourceBufferPrivateGStreamer> >, WebCore::MediaPlayerPrivateGStreamerMSE&)
    (this=0x7fbd41834ee0, mediaSourceClient=..., sourceBufferPrivate=..., playerPrivate=...)
    at DerivedSources/ForwardingHeaders/wtf/glib/GRefPtr.h:105
        type = 
            @0x7ffe2229ece0: {static MaxLength = 2147483647, m_impl = {static isRefPtr = <optimized out>, m_ptr = 0x7fbd41257340}}
        appendPipelineCount = 2
        pipelineName = 
            {static MaxLength = 2147483647, m_impl = {static isRefPtr = <optimized out>, m_ptr = 0x7fbd412adb70}}
        appsrcPad = {m_ptr = 0x55a71a3e8610 [GstPad]}
        appsinkPad = {m_ptr = 0x55a71a3e8860 [GstPad]}
        appendPipelineCount = 2
#5  0x00007fbf3b74c35f in WebCore::MediaSourceClientGStreamerMSE::addSourceBuffer(WTF::RefPtr<WebCore::SourceBufferPrivateGStreamer, WTF::DumbPtrTraits<WebCore::SourceBufferPrivateGStreamer> >, WebCore::ContentType const&)
    (this=0x7fbd40e462d0, sourceBufferPrivate=...) at DerivedSources/ForwardingHeaders/wtf/ThreadSafeRefCounted.h:43
        appendPipeline = {static isRefPtr = <optimized out>, m_ptr = 0x7fbe0823b0e0}
        __FUNCTION__ = "addSourceBuffer"
#6  0x00007fbf3b74d64d in WebCore::MediaSourceGStreamer::addSourceBuffer(WebCore::ContentType const&, WTF::RefPtr<WebC--Type <RET> for more, q to quit, c to continue without paging--c
ore::SourceBufferPrivate, WTF::DumbPtrTraits<WebCore::SourceBufferPrivate> >&) (this=0x7fbda4054478, contentType=..., sourceBufferPrivate=...) at DerivedSources/ForwardingHeaders/wtf/RefCounted.h:49
        __func__ = "addSourceBuffer"
        sourceBufferPrivateGStreamer = {static isRefPtr = <optimized out>, m_ptr = 0x7fbd40eb0c60}
#7  0x00007fbf3a627eeb in WebCore::MediaSource::createSourceBufferPrivate(WebCore::ContentType const&) (this=this@entry=0x7fbf315c7610, type=...) at DerivedSources/ForwardingHeaders/wtf/DumbPtrTraits.h:43
        sourceBufferPrivate = {static isRefPtr = <optimized out>, m_ptr = 0x7fbd40eb0c60}
#8  0x00007fbf3a62b24b in WebCore::MediaSource::addSourceBuffer(WTF::String const&) (this=this@entry=0x7fbf315c7610, type=...) at ../Source/WebCore/Modules/mediasource/MediaSource.cpp:690
        __func__ = "addSourceBuffer"
        contentType = {m_type = {static MaxLength = 2147483647, m_impl = {static isRefPtr = <optimized out>, m_ptr = 0x7fbe08249b80}}}
        sourceBufferPrivate = {m_value = {<std::experimental::fundamentals_v3::__expected_detail::base<WTF::Ref<WebCore::SourceBufferPrivate, WTF::DumbPtrTraits<WebCore::SourceBufferPrivate> >, WebCore::Exception>> = {s = {dummy = 0 '\000', val = {static isRef = <optimized out>, m_ptr = 0x0}, err = {m_code = WebCore::IndexSizeError, m_message = {static MaxLength = 2147483647, m_impl = {static isRefPtr = <optimized out>, m_ptr = 0x0}}}}, has = 104}, <No data fields>}}
        buffer = {static isRef = <optimized out>, m_ptr = 0x7fbf37ea61f7 <JSC::LLInt::setUpCall(JSC::CallFrame*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*)+87>}
        shouldGenerateTimestamps = <optimized out>
#9  0x00007fbf3a226e7a in WebCore::jsMediaSourcePrototypeFunctionAddSourceBufferBody (throwScope=..., castedThis=0x7fbde4481a88, callFrame=<optimized out>, lexicalGlobalObject=0x7fbec40e1068) at DerivedSources/WebCore/JSMediaSource.cpp:491
       <I've removed this frame since it's huge and I'm pasting the backtrace inline>
#10 0x00007fbf3a226e7a in WebCore::IDLOperation<WebCore::JSMediaSource>::call<WebCore::jsMediaSourcePrototypeFunctionAddSourceBufferBody> (operationName=0x7fbf3b9dc464 "addSourceBuffer", callFrame=..., lexicalGlobalObject=...) at ../Source/WebCore/bindings/js/JSDOMOperation.h:53
        throwScope = {<JSC::ExceptionScope> = {m_vm = @0x7fbec4200000}, <No data fields>}
        thisObject = 0x7fbde4481a88
#11 0x00007fbf3a226e7a in WebCore::jsMediaSourcePrototypeFunctionAddSourceBuffer(JSC::JSGlobalObject*, JSC::CallFrame*) (lexicalGlobalObject=0x7fbec40e1068, callFrame=<optimized out>) at DerivedSources/WebCore/JSMediaSource.cpp:497
#12 0x00007fbee3fff178 in  ()
#13 0x00007ffe2229f040 in  ()
#14 0x00007fbf375716bd in llint_op_call () at /usr/lib/debug/source/sdk/WebKitGTK.bst/Source/JavaScriptCore/llint/LowLevelInterpreter.asm:1045
#15 0x0000000000000000 in  ()

(In reply to Philippe Normand from comment #3)
> The qtdemux warning doesn't make sense. Maybe remove your gst registry file?

I don't know how to do this, and couldn't easily find instructions.
Comment 6 Michael Catanzaro 2020-06-17 07:07:00 PDT
It seems alatiera is hitting the same issue that you are. He has reported https://gitlab.gnome.org/GNOME/gnome-build-meta/-/issues/284.

(In reply to Philippe Normand from comment #3)
> The qtdemux warning doesn't make sense. Maybe remove your gst registry file?

alatiera pointed me to ~/.var/cache/org.gnome.Epiphany.Devel/gstreamer-1.0. Deleted the registry. Now the videos work. Closing.
Comment 7 Michael Catanzaro 2020-06-17 07:13:01 PDT
(In reply to Michael Catanzaro from comment #6)
> alatiera pointed me to ~/.var/cache/org.gnome.Epiphany.Devel/gstreamer-1.0.
> Deleted the registry. Now the videos work. Closing.

reddit.com videos, including my penguin test, play about 200x more reliably now. Maybe they were using something that was not H.264, and sucking.
Comment 8 Michael Catanzaro 2020-06-17 11:01:09 PDT
Phil, is it possible you have a broken OpenH264 extension installed from flathub?

From https://gitlab.gnome.org/GNOME/gnome-build-meta/-/issues/284:

"""
So looks like the issue is that I had openh264//2.0 from flathub, which was what repo flatpak has default picked upon flatpak update. Seems like the flathub extension is known to be broken till the MR above is fixed. Manually installing from gnome-nightly fixed the issue.
"""

It's unfortunate that flatpak allows picking the extension from flathub rather than gnome-nightly. :/
Comment 9 Philippe Normand 2020-06-18 09:56:59 PDT
Yes I have openh264 2.0 from flathub