Bug 167165 - [GStreamer] Clear out m_appsinkCaps in AppendPipeline::appsinkCapsChanged() before using outPtr()
Summary: [GStreamer] Clear out m_appsinkCaps in AppendPipeline::appsinkCapsChanged() b...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Zan Dobersek
URL:
Keywords:
: 167199 (view as bug list)
Depends on:
Blocks:
 
Reported: 2017-01-18 10:42 PST by Zan Dobersek
Modified: 2017-01-22 00:30 PST (History)
5 users (show)

See Also:


Attachments
Patch (1.73 KB, patch)
2017-01-18 10:46 PST, Zan Dobersek
no flags Details | Formatted Diff | Diff
Patch (2.45 KB, patch)
2017-01-19 02:19 PST, Zan Dobersek
no flags Details | Formatted Diff | Diff
Patch (2.03 KB, patch)
2017-01-20 07:20 PST, Zan Dobersek
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews115 for mac-elcapitan (1.62 MB, application/zip)
2017-01-20 08:41 PST, Build Bot
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zan Dobersek 2017-01-18 10:42:59 PST
[GStreamer] Clear out m_appsinkCaps in AppendPipeline::appsinkCapsChanged() before using outPtr()
Comment 1 Zan Dobersek 2017-01-18 10:46:08 PST
Created attachment 299157 [details]
Patch
Comment 2 Enrique Ocaña 2017-01-18 12:00:56 PST
Comment on attachment 299157 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=299157&action=review

> Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:605
> +    m_appsinkCaps = nullptr;

I'm not sure that's the proper way to fix the bug. Have a look at how was the original code[1] before the migration to GRefPtr() and to the behaviour of gst_caps_replace()[2]. The function is thought to replace one pointer by another, automatically onreffing the old caps and reffing the new ones. Maybe the right fix would be to use raw pointers again?

[1] https://github.com/eocanha/webkit/blob/mse-backport-rebased-20160414/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerMSE.cpp#L1652
[2] https://developer.gnome.org/gstreamer/1.0/gstreamer-GstCaps.html#gst-caps-replace
Comment 3 Zan Dobersek 2017-01-19 00:41:13 PST
Comment on attachment 299157 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=299157&action=review

>> Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:605
>> +    m_appsinkCaps = nullptr;
> 
> I'm not sure that's the proper way to fix the bug. Have a look at how was the original code[1] before the migration to GRefPtr() and to the behaviour of gst_caps_replace()[2]. The function is thought to replace one pointer by another, automatically onreffing the old caps and reffing the new ones. Maybe the right fix would be to use raw pointers again?
> 
> [1] https://github.com/eocanha/webkit/blob/mse-backport-rebased-20160414/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerMSE.cpp#L1652
> [2] https://developer.gnome.org/gstreamer/1.0/gstreamer-GstCaps.html#gst-caps-replace

It's not a bug, this works around the assert in GRefPtr<>::outPtr(). IMO the assert is valid, but this specific usage of it isn't.

Using raw pointers doesn't fix anything, it disables a much more simpler control of an object.
Comment 4 Zan Dobersek 2017-01-19 00:47:00 PST
(In reply to comment #3)
> It's not a bug, this works around the assert in GRefPtr<>::outPtr(). IMO the
> assert is valid, but this specific usage of it isn't.
> 

... but this specific usage of GRefPtr<>::outPtr() isn't.*
Comment 5 Carlos Garcia Campos 2017-01-19 00:54:15 PST
Comment on attachment 299157 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=299157&action=review

>>> Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:605
>>> +    m_appsinkCaps = nullptr;
>> 
>> I'm not sure that's the proper way to fix the bug. Have a look at how was the original code[1] before the migration to GRefPtr() and to the behaviour of gst_caps_replace()[2]. The function is thought to replace one pointer by another, automatically onreffing the old caps and reffing the new ones. Maybe the right fix would be to use raw pointers again?
>> 
>> [1] https://github.com/eocanha/webkit/blob/mse-backport-rebased-20160414/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerMSE.cpp#L1652
>> [2] https://developer.gnome.org/gstreamer/1.0/gstreamer-GstCaps.html#gst-caps-replace
> 
> It's not a bug, this works around the assert in GRefPtr<>::outPtr(). IMO the assert is valid, but this specific usage of it isn't.
> 
> Using raw pointers doesn't fix anything, it disables a much more simpler control of an object.

I think this at least deserves a comment, explaining that gst_caps_replace does the unref. However, maybe we should do what we did for GUniqueOutPtr and replace the assert with a clear(). That way this is done automatically here and everywhere else and we avoid similar problems in the future.
Comment 6 Xabier Rodríguez Calvar 2017-01-19 01:02:54 PST
Comment on attachment 299157 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=299157&action=review

>>>> Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:605
>>>> +    m_appsinkCaps = nullptr;
>>> 
>>> I'm not sure that's the proper way to fix the bug. Have a look at how was the original code[1] before the migration to GRefPtr() and to the behaviour of gst_caps_replace()[2]. The function is thought to replace one pointer by another, automatically onreffing the old caps and reffing the new ones. Maybe the right fix would be to use raw pointers again?
>>> 
>>> [1] https://github.com/eocanha/webkit/blob/mse-backport-rebased-20160414/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerMSE.cpp#L1652
>>> [2] https://developer.gnome.org/gstreamer/1.0/gstreamer-GstCaps.html#gst-caps-replace
>> 
>> It's not a bug, this works around the assert in GRefPtr<>::outPtr(). IMO the assert is valid, but this specific usage of it isn't.
>> 
>> Using raw pointers doesn't fix anything, it disables a much more simpler control of an object.
> 
> I think this at least deserves a comment, explaining that gst_caps_replace does the unref. However, maybe we should do what we did for GUniqueOutPtr and replace the assert with a clear(). That way this is done automatically here and everywhere else and we avoid similar problems in the future.

I agree with Carlos here. Let's bring consistency between GRefPtr and GUniquePtr.
Comment 7 Zan Dobersek 2017-01-19 02:02:41 PST
(In reply to comment #2)
> Comment on attachment 299157 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=299157&action=review
> 
> > Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:605
> > +    m_appsinkCaps = nullptr;
> 
> I'm not sure that's the proper way to fix the bug. Have a look at how was
> the original code[1] before the migration to GRefPtr() and to the behaviour
> of gst_caps_replace()[2]. The function is thought to replace one pointer by
> another, automatically onreffing the old caps and reffing the new ones.
> Maybe the right fix would be to use raw pointers again?
> 
> [1]
> https://github.com/eocanha/webkit/blob/mse-backport-rebased-20160414/Source/
> WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerMSE.cpp#L1652
> [2]
> https://developer.gnome.org/gstreamer/1.0/gstreamer-GstCaps.html#gst-caps-
> replace

OK, let's try raw pointers again in order to keep the atomic replacement.
Comment 8 Zan Dobersek 2017-01-19 02:19:15 PST
Created attachment 299241 [details]
Patch
Comment 9 Carlos Garcia Campos 2017-01-19 05:23:25 PST
*** Bug 167199 has been marked as a duplicate of this bug. ***
Comment 10 Xabier Rodríguez Calvar 2017-01-19 06:47:02 PST
Comment on attachment 299241 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=299241&action=review

> Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:611
>          if (m_playerPrivate && previousCapsWereNull)

if (m_playerPrivate && !currentCaps)

And remove the variable declaration from above
Comment 11 Xabier Rodríguez Calvar 2017-01-19 06:59:43 PST
Comment on attachment 299241 [details]
Patch

Please write a comment on the code because it looks like we are doing things more complicated than what they are for no reason.
Comment 12 Xabier Rodríguez Calvar 2017-01-19 07:09:23 PST
Enrique, do you recall why gst_caps_replace is needed here?
Comment 13 Zan Dobersek 2017-01-19 08:31:44 PST
Comment on attachment 299241 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=299241&action=review

>> Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp:611
>>          if (m_playerPrivate && previousCapsWereNull)
> 
> if (m_playerPrivate && !currentCaps)
> 
> And remove the variable declaration from above

That's not correct -- if the gst_caps_replace() call succeeded, then currentCaps will now hold the same pointer as the caps GRefPtr<>.
Comment 14 Enrique Ocaña 2017-01-19 10:53:09 PST
(In reply to comment #12)
> Enrique, do you recall why gst_caps_replace is needed here?

At the moment (using raw pointers) it was the best way to automate the operation of unreffing the old caps and reffing the new ones.

Now that I think about it, the smart pointer behaviour already do the job of gst_caps_replace(), so we could just do something like this:

    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(m_appsink.get(), "sink"));
    GRefPtr<GstCaps> newCaps = adoptGRef(gst_pad_get_current_caps(pad.get()));
    GRefPtr<GstCaps> currentCaps = m_appsinkCaps;

    if (!newCaps)
        return;

    // This means that we're right after a new track has appeared. Otherwise, it's a caps change inside the same track.
    bool previousCapsWereNull = !m_appsinkCaps;

    m_appsinkCaps = newCaps;
    if (currentCaps != newCaps) {
        if (m_playerPrivate && previousCapsWereNull)
            m_playerPrivate->trackDetected(this, m_oldTrack, m_track);
        didReceiveInitializationSegment();
        gst_element_set_state(m_pipeline.get(), GST_STATE_PLAYING);
    }
Comment 15 Xabier Rodríguez Calvar 2017-01-20 00:38:00 PST
(In reply to comment #13)
> That's not correct -- if the gst_caps_replace() call succeeded, then
> currentCaps will now hold the same pointer as the caps GRefPtr<>.

Indeed, how could I miss that?
Comment 16 Xabier Rodríguez Calvar 2017-01-20 00:40:52 PST
(In reply to comment #14)
> Now that I think about it, the smart pointer behaviour already do the job of
> gst_caps_replace(), so we could just do something like this:

This would be my preference.
Comment 17 Zan Dobersek 2017-01-20 07:20:52 PST
Created attachment 299347 [details]
Patch
Comment 18 Build Bot 2017-01-20 08:41:48 PST
Comment on attachment 299347 [details]
Patch

Attachment 299347 [details] did not pass mac-debug-ews (mac):
Output: http://webkit-queues.webkit.org/results/2920646

New failing tests:
media/modern-media-controls/media-controller/media-controller-auto-hide-mouse-leave-after-play.html
Comment 19 Build Bot 2017-01-20 08:41:52 PST
Created attachment 299349 [details]
Archive of layout-test-results from ews115 for mac-elcapitan

The attached test failures were seen while running run-webkit-tests on the mac-debug-ews.
Bot: ews115  Port: mac-elcapitan  Platform: Mac OS X 10.11.6
Comment 20 Zan Dobersek 2017-01-22 00:30:45 PST
Comment on attachment 299347 [details]
Patch

Clearing flags on attachment: 299347

Committed r211026: <http://trac.webkit.org/changeset/211026>
Comment 21 Zan Dobersek 2017-01-22 00:30:54 PST
All reviewed patches have been landed.  Closing bug.