⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 254565 in webkit


Ignore:
Timestamp:
Jan 15, 2020, 6:40:01 AM (7 years ago)
Author:
commit-queue@webkit.org
Message:

[GStreamer] Several buffering fixes
​https://bugs.webkit.org/show_bug.cgi?id=206234

Patch by Thibault Saunier <​tsaunier@igalia.com> on 2020-01-15
Reviewed by Xabier Rodriguez-Calvar.

No new tests as this is already tested.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::durationChanged): Minor typo fix
(WebCore::MediaPlayerPrivateGStreamer::fillTimerFired): Query buffering on the pipeline not the source

otherwise GstBaseSrc returns some useless values before downloadbuffer actually gives us the
info about DOWNLOAD buffering status. Also ignores response if they are not in DOWNLOAD mode as those
will end up screwing our buffering management algorithm.

(WebCore::MediaPlayerPrivateGStreamer::handleMessage):

  • Detect when DOWNLOAD is done by using the downloadbuffer GstCacheDownloadComplete element message which is what is supposed to be used for that purpose.
  • Fix the way we detect that buffering is done (mostly when using a downloadbuffer) by relying on a buffering query to check if it is still buffering.

(WebCore::MediaPlayerPrivateGStreamer::updateBufferingStatus): Ensure that we properly pause the pipeline when

restarting buffering. There were cases when not using downloadbuffer where we didn't pause the pipeline
leading to pretty bad user experience.

(WebCore::MediaPlayerPrivateGStreamer::updateStates): Buffering should happen only on non live pipelines.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r254564 r254565  
     12020-01-15  Thibault Saunier  <tsaunier@igalia.com>
     2
     3        [GStreamer] Several buffering fixes
     4        https://bugs.webkit.org/show_bug.cgi?id=206234
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        No new tests as this is already tested.
     9
     10        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     11        (WebCore::MediaPlayerPrivateGStreamer::durationChanged): Minor typo fix
     12        (WebCore::MediaPlayerPrivateGStreamer::fillTimerFired): Query buffering on the pipeline not the source
     13            otherwise GstBaseSrc returns some useless values before `downloadbuffer` actually gives us the
     14            info about DOWNLOAD buffering status. Also ignores response if they are not in DOWNLOAD mode as those
     15            will end up screwing our buffering management algorithm.
     16        (WebCore::MediaPlayerPrivateGStreamer::handleMessage):
     17            - Detect when DOWNLOAD is done by using the `downloadbuffer` `GstCacheDownloadComplete`
     18              element message which is what is supposed to be used for that purpose.
     19            - Fix the way we detect that buffering is done (mostly when using a `downloadbuffer`) by relying on a
     20              buffering query to check if it is still buffering.
     21        (WebCore::MediaPlayerPrivateGStreamer::updateBufferingStatus): Ensure that we properly pause the pipeline when
     22            restarting buffering. There were cases when not using `downloadbuffer` where we didn't pause the pipeline
     23            leading to pretty bad user experience.
     24        (WebCore::MediaPlayerPrivateGStreamer::updateStates): Buffering should happen only on **non live** pipelines.
     25
    1262020-01-15  youenn fablet  <youenn@apple.com>
    227
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r254507 r254565  
    10541054    m_cachedDuration = MediaTime::invalidTime();
    10551055
    1056     // Avoid emiting durationchanged in the case where the previous
     1056    // Avoid emitting durationChanged in the case where the previous
    10571057    // duration was 0 because that case is already handled by the
    10581058    // HTMLMediaElement.
    … …  
    14571457    GstBufferingMode mode = GST_BUFFERING_DOWNLOAD;
    14581458
    1459     if (gst_element_query(m_source.get(), query.get())) {
     1459    if (gst_element_query(pipeline(), query.get())) {
    14601460        gst_query_parse_buffering_stats(query.get(), &mode, nullptr, nullptr, nullptr);
    14611461
    … …  
    14711471    }
    14721472
    1473     updateBufferingStatus(mode, fillStatus);
     1473    if (mode != GST_BUFFERING_DOWNLOAD)
     1474        GST_INFO_OBJECT(pipeline(), "Ignoring buffering in %s", enumToString(GST_TYPE_BUFFERING_MODE, mode).data());
     1475    else
     1476        updateBufferingStatus(mode, fillStatus);
    14741477}
    14751478
    … …  
    21992202                    m_hasTaintedOrigin = webKitSrcWouldTaintOrigin(WEBKIT_WEB_SRC_CAST(m_source.get()), SecurityOrigin::create(URL(URL(), uri)));
    22002203            }
     2204        } else if (gst_structure_has_name(structure, "GstCacheDownloadComplete")) {
     2205            GST_INFO_OBJECT(pipeline(), "Stream is fully downloaded, stopping monitoring downloading progress.");
     2206            m_fillTimer.stop();
     2207            m_bufferingPercentage = 100;
     2208            updateStates();
    22012209        } else
    22022210            GST_DEBUG_OBJECT(pipeline(), "Unhandled element message: %" GST_PTR_FORMAT, structure);
    … …  
    22932301void MediaPlayerPrivateGStreamer::updateBufferingStatus(GstBufferingMode mode, double percentage)
    22942302{
     2303    bool wasBuffering = m_isBuffering;
     2304
    22952305    GST_DEBUG_OBJECT(pipeline(), "[Buffering] mode: %s, status: %f%%", enumToString(GST_TYPE_BUFFERING_MODE, mode).data(), percentage);
    22962306
    … …  
    22982308    m_isBuffering = !m_didDownloadFinish;
    22992309
     2310    if (!m_didDownloadFinish)
     2311        m_isBuffering = true;
     2312
     2313    m_bufferingPercentage = percentage;
    23002314    switch (mode) {
    23012315    case GST_BUFFERING_STREAM: {
    … …  
    23032317
    23042318        m_bufferingPercentage = percentage;
    2305         if (m_didDownloadFinish)
     2319        if (m_didDownloadFinish || (!wasBuffering && m_isBuffering))
    23062320            updateStates();
    23072321
    … …  
    23102324    case GST_BUFFERING_DOWNLOAD: {
    23112325        updateMaxTimeLoaded(percentage);
    2312 
    2313         // Media is now fully loaded. It will play even if network connection is
    2314         // cut. Buffering is done, remove the fill source from the main loop.
    2315         if (m_didDownloadFinish)
    2316             m_fillTimer.stop();
    2317 
    23182326        updateStates();
    23192327        break;
    … …  
    25782586        case GST_STATE_PLAYING:
    25792587            if (m_isBuffering) {
    2580                 if (m_bufferingPercentage == 100) {
    2581                     GST_DEBUG_OBJECT(pipeline(), "[Buffering] Complete.");
    2582                     m_isBuffering = false;
     2588                GRefPtr<GstQuery> query = adoptGRef(gst_query_new_buffering(GST_FORMAT_PERCENT));
     2589
     2590                m_isBuffering = m_bufferingPercentage == 100;
     2591                if (gst_element_query(m_pipeline.get(), query.get())) {
     2592                    gboolean isBuffering = m_isBuffering;
     2593                    gst_query_parse_buffering_percent(query.get(), &isBuffering, nullptr);
     2594                    m_isBuffering = isBuffering;
     2595                }
     2596
     2597                if (!m_isBuffering) {
     2598                    GST_INFO_OBJECT(pipeline(), "[Buffering] Complete.");
    25832599                    m_readyState = MediaPlayer::ReadyState::HaveEnoughData;
    25842600                    m_networkState = m_didDownloadFinish ? MediaPlayer::NetworkState::Idle : MediaPlayer::NetworkState::Loading;
    … …  
    26102626
    26112627            if (didBuffering && !m_isBuffering && !m_isPaused && m_playbackRate) {
    2612                 GST_DEBUG_OBJECT(pipeline(), "[Buffering] Restarting playback.");
     2628                GST_INFO_OBJECT(pipeline(), "[Buffering] Restarting playback.");
    26132629                changePipelineState(GST_STATE_PLAYING);
    26142630            }
    … …  
    26172633
    26182634            if ((m_isBuffering && !m_isLiveStream) || !m_playbackRate) {
    2619                 GST_DEBUG_OBJECT(pipeline(), "[Buffering] Pausing stream for buffering.");
     2635                GST_INFO_OBJECT(pipeline(), "[Buffering] Pausing stream for buffering.");
    26202636                changePipelineState(GST_STATE_PAUSED);
    26212637            }
Note: See TracChangeset for help on using the changeset viewer.