Changeset 243199 in webkit


Ignore:
Timestamp:
Mar 20, 2019 6:11:08 AM (5 years ago)
Author:
aboya@igalia.com
Message:

[MSE][GStreamer] Fix handling of resolution changes in AppendPipeline
https://bugs.webkit.org/show_bug.cgi?id=195855

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

MediaSample instances produced by the AppendPipeline were not
accounting for resolution changes. The causes of this are twofold:

1) m_presentationSize is set by connectDemuxerSrcPadToAppsink() (by
calling parseDemuxerSrcPadCaps()), but not by appsinkCapsChanged().

2) appsinkCapsChanged() was being called in the main thread as an
asynchronous task. In consequence, even if m_presentationSize is set
there, many samples with the new resolution would still be wrapped in
a MediaSampleGStreamer using the old resolution by the main thread
running consumeAppsinkAvailableSamples() before appsinkCapsChanged()
is dispatched.

This patch fixes these problems by updating m_presentationSize in
appsinkCapsChanged() and making the streaming thread block until the
main thread has dispatched appsinkCapsChanged(). This way the handling
of caps changes is serialized with the handling of frames.

Test: media/media-source/media-source-samples-resolution-change.html

  • platform/graphics/gstreamer/mse/AppendPipeline.cpp:

(WebCore::AppendPipeline::AppendPipeline):
(WebCore::AppendPipeline::appsinkCapsChanged):

LayoutTests:

  • media/media-source/content/test-green-6s-320x240.mp4: Added.
  • media/media-source/content/test-red-3s-480x360.mp4: Added.
  • media/media-source/media-source-samples-resolution-change-expected.txt: Added.
  • media/media-source/media-source-samples-resolution-change.html: Added.
Location:
trunk
Files:
4 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r243198 r243199  
     12019-03-20  Alicia Boya García  <aboya@igalia.com>
     2
     3        [MSE][GStreamer] Fix handling of resolution changes in AppendPipeline
     4        https://bugs.webkit.org/show_bug.cgi?id=195855
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        * media/media-source/content/test-green-6s-320x240.mp4: Added.
     9        * media/media-source/content/test-red-3s-480x360.mp4: Added.
     10        * media/media-source/media-source-samples-resolution-change-expected.txt: Added.
     11        * media/media-source/media-source-samples-resolution-change.html: Added.
     12
    1132019-03-20  Joanmarie Diggs  <jdiggs@igalia.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r243198 r243199  
     12019-03-20  Alicia Boya García  <aboya@igalia.com>
     2
     3        [MSE][GStreamer] Fix handling of resolution changes in AppendPipeline
     4        https://bugs.webkit.org/show_bug.cgi?id=195855
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        MediaSample instances produced by the AppendPipeline were not
     9        accounting for resolution changes. The causes of this are twofold:
     10
     11        1) m_presentationSize is set by connectDemuxerSrcPadToAppsink() (by
     12        calling parseDemuxerSrcPadCaps()), but not by appsinkCapsChanged().
     13
     14        2) appsinkCapsChanged() was being called in the main thread as an
     15        asynchronous task. In consequence, even if m_presentationSize is set
     16        there, many samples with the new resolution would still be wrapped in
     17        a MediaSampleGStreamer using the old resolution by the main thread
     18        running consumeAppsinkAvailableSamples() before appsinkCapsChanged()
     19        is dispatched.
     20
     21        This patch fixes these problems by updating m_presentationSize in
     22        appsinkCapsChanged() and making the streaming thread block until the
     23        main thread has dispatched appsinkCapsChanged(). This way the handling
     24        of caps changes is serialized with the handling of frames.
     25
     26        Test: media/media-source/media-source-samples-resolution-change.html
     27
     28        * platform/graphics/gstreamer/mse/AppendPipeline.cpp:
     29        (WebCore::AppendPipeline::AppendPipeline):
     30        (WebCore::AppendPipeline::appsinkCapsChanged):
     31
    1322019-03-20  Joanmarie Diggs  <jdiggs@igalia.com>
    233
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp

    r242034 r243199  
    173173        }
    174174
    175         appendPipeline->m_taskQueue.enqueueTask([appendPipeline]() {
     175        // The streaming thread has just received a new caps and is about to let samples using the
     176        // new caps flow. Let's block it until the main thread has consumed the samples with the old
     177        // caps and has processed the caps change.
     178        appendPipeline->m_taskQueue.enqueueTaskAndWait<AbortableTaskQueue::Void>([appendPipeline]() {
    176179            appendPipeline->appsinkCapsChanged();
     180            return AbortableTaskQueue::Void();
    177181        });
    178182    }), this);
     
    408412    ASSERT(isMainThread());
    409413
     414    // Consume any pending samples with the previous caps.
     415    consumeAppsinkAvailableSamples();
     416
    410417    GRefPtr<GstPad> pad = adoptGRef(gst_element_get_static_pad(m_appsink.get(), "sink"));
    411418    GRefPtr<GstCaps> caps = adoptGRef(gst_pad_get_current_caps(pad.get()));
     
    413420    if (!caps)
    414421        return;
     422
     423    if (doCapsHaveType(caps.get(), GST_VIDEO_CAPS_TYPE_PREFIX)) {
     424        Optional<FloatSize> size = getVideoResolutionFromCaps(caps.get());
     425        if (size.hasValue())
     426            m_presentationSize = size.value();
     427    }
    415428
    416429    // This means that we're right after a new track has appeared. Otherwise, it's a caps change inside the same track.
Note: See TracChangeset for help on using the changeset viewer.