Changeset 55733 in webkit


Ignore:
Timestamp:
Mar 9, 2010 10:43:51 AM (14 years ago)
Author:
kov@webkit.org
Message:

2010-03-09 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>

Reviewed by Dirk Schulze.

[GStreamer] Buffering logic is not correct, and does not work very well
https://bugs.webkit.org/show_bug.cgi?id=35706

Fix buffering to match GStreamer expectancies regarding the
pipeline state, so that videos which really need buffering to play
correctly also work, while maintaining the convenience of
on-disk-buffering. This required a bit of shuffling of state
change handling.

No behaviour change expected.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): (WebCore::MediaPlayerPrivate::processBufferingStats): (WebCore::MediaPlayerPrivate::fillTimerFired): (WebCore::MediaPlayerPrivate::updateStates):
  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r55732 r55733  
     12010-03-09  Gustavo Noronha Silva  <gustavo.noronha@collabora.co.uk>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        [GStreamer] Buffering logic is not correct, and does not work very well
     6        https://bugs.webkit.org/show_bug.cgi?id=35706
     7
     8        Fix buffering to match GStreamer expectancies regarding the
     9        pipeline state, so that videos which really need buffering to play
     10        correctly also work, while maintaining the convenience of
     11        on-disk-buffering. This required a bit of shuffling of state
     12        change handling.
     13
     14        No behaviour change expected.
     15
     16        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     17        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
     18        (WebCore::MediaPlayerPrivate::processBufferingStats):
     19        (WebCore::MediaPlayerPrivate::fillTimerFired):
     20        (WebCore::MediaPlayerPrivate::updateStates):
     21        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
     22
    1232010-03-09  Gustavo Noronha Silva  <gustavo.noronha@collabora.co.uk>
    224
  • trunk/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r55732 r55733  
    277277    , m_networkState(MediaPlayer::Empty)
    278278    , m_readyState(MediaPlayer::HaveNothing)
    279     , m_startedPlaying(false)
    280279    , m_isStreaming(false)
    281280    , m_size(IntSize())
     
    286285    , m_paused(true)
    287286    , m_seeking(false)
     287    , m_buffering(false)
    288288    , m_playbackRate(1)
    289289    , m_errorOccured(false)
     
    292292    , m_fillTimer(this, &MediaPlayerPrivate::fillTimerFired)
    293293    , m_maxTimeLoaded(0)
     294    , m_bufferingPercentage(0)
    294295{
    295296    if (doGstInit())
     
    647648void MediaPlayerPrivate::processBufferingStats(GstMessage* message)
    648649{
     650    // This is the immediate buffering that needs to happen so we have
     651    // enough to play right now.
     652    m_buffering = true;
     653    const GstStructure *structure = gst_message_get_structure(message);
     654    gst_structure_get_int(structure, "buffer-percent", &m_bufferingPercentage);
     655
     656    LOG_VERBOSE(Media, "[Buffering] Buffering: %d%%.", m_bufferingPercentage);
     657
    649658    GstBufferingMode mode;
    650 
    651659    gst_message_parse_buffering_stats(message, &mode, 0, 0, 0);
    652     if (mode != GST_BUFFERING_DOWNLOAD)
    653         return;
    654 
     660    if (mode != GST_BUFFERING_DOWNLOAD) {
     661        updateStates();
     662        return;
     663    }
     664
     665    // This is on-disk buffering, that allows us to download much more
     666    // than needed for right now.
    655667    if (!m_startedBuffering) {
     668        LOG_VERBOSE(Media, "[Buffering] Starting on-disk buffering.");
     669
    656670        m_startedBuffering = true;
    657671
     
    681695        fillStatus = 100.0 * stop / GST_FORMAT_PERCENT_MAX;
    682696
    683     LOG_VERBOSE(Media, "Download buffer filled up to %f%%", fillStatus);
     697    LOG_VERBOSE(Media, "[Buffering] Download buffer filled up to %f%%", fillStatus);
    684698
    685699    if (!m_mediaDuration)
     
    690704    if (m_mediaDuration) {
    691705        m_maxTimeLoaded = static_cast<float>((fillStatus * m_mediaDuration) / 100.0);
    692         LOG_VERBOSE(Media, "Updated maxTimeLoaded: %f", m_maxTimeLoaded);
     706        LOG_VERBOSE(Media, "[Buffering] Updated maxTimeLoaded: %f", m_maxTimeLoaded);
    693707    }
    694708
     
    771785void MediaPlayerPrivate::updateStates()
    772786{
    773     // There is no (known) way to get such level of information about
    774     // the state of GStreamer, therefore, when in PAUSED state,
    775     // we are sure we can display the first frame and go to play
    776 
    777787    if (!m_playBin)
    778788        return;
     
    798808        m_resetPipeline = state <= GST_STATE_READY;
    799809
    800         if (state == GST_STATE_READY)
     810        // Try to figure out ready and network states.
     811        if (state == GST_STATE_READY) {
    801812            m_readyState = MediaPlayer::HaveNothing;
    802         else if (state == GST_STATE_PAUSED)
     813            m_networkState = MediaPlayer::Empty;
     814        } else if (maxTimeLoaded() == duration()) {
     815            m_networkState = MediaPlayer::Loaded;
    803816            m_readyState = MediaPlayer::HaveEnoughData;
    804 
    805         if (state == GST_STATE_PLAYING) {
     817        } else {
     818            m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
     819            m_networkState = MediaPlayer::Loading;
     820        }
     821
     822        if (m_buffering && state != GST_STATE_READY) {
     823            m_readyState = MediaPlayer::HaveCurrentData;
     824            m_networkState = MediaPlayer::Loading;
     825        }
     826
     827        // Now let's try to get the states in more detail using
     828        // information from GStreamer, while we sync states where
     829        // needed.
     830        if (state == GST_STATE_PAUSED) {
     831            if (m_buffering && m_bufferingPercentage == 100) {
     832                m_buffering = false;
     833                m_bufferingPercentage = 0;
     834                m_readyState = MediaPlayer::HaveEnoughData;
     835
     836                LOG_VERBOSE(Media, "[Buffering] Complete.");
     837
     838                if (!m_paused) {
     839                    LOG_VERBOSE(Media, "[Buffering] Restarting playback.");
     840                    gst_element_set_state(m_playBin, GST_STATE_PLAYING);
     841                }
     842            } else if (!m_buffering)
     843                m_paused = true;
     844        } else if (state == GST_STATE_PLAYING) {
    806845            m_readyState = MediaPlayer::HaveEnoughData;
    807846            m_paused = false;
    808             m_startedPlaying = true;
     847
    809848            if (!m_mediaDuration) {
    810849                float newDuration = duration();
     
    812851                    m_mediaDuration = newDuration;
    813852            }
     853
     854            if (m_buffering) {
     855                m_readyState = MediaPlayer::HaveNothing;
     856                m_networkState = MediaPlayer::Loading;
     857
     858                LOG_VERBOSE(Media, "[Buffering] Pausing stream for buffering.");
     859
     860                gst_element_set_state(m_playBin, GST_STATE_PAUSED);
     861            }
    814862        } else
    815863            m_paused = true;
    816864
    817865        // Is on-disk buffering in progress?
    818         if (m_fillTimer.isActive()) {
     866        if (m_fillTimer.isActive())
    819867            m_networkState = MediaPlayer::Loading;
    820             // Buffering has just started, we should now have enough
    821             // data to restart playback if it was internally paused by
    822             // GStreamer.
    823             if (m_paused && !m_startedPlaying)
    824                 gst_element_set_state(m_playBin, GST_STATE_PLAYING);
    825         }
    826 
    827         if (maxTimeLoaded() == duration()) {
    828             m_networkState = MediaPlayer::Loaded;
    829             if (state == GST_STATE_READY)
    830                 m_readyState = MediaPlayer::HaveNothing;
    831             else if (state == GST_STATE_PAUSED)
    832                 m_readyState = MediaPlayer::HaveEnoughData;
    833         } else
    834             if (state == GST_STATE_READY)
    835                 m_readyState = MediaPlayer::HaveNothing;
    836             else if (m_paused)
    837                 m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
    838868
    839869        if (m_changingRate) {
     
    883913            // Live pipelines go in PAUSED without prerolling.
    884914            m_isStreaming = true;
    885         } else if (state == GST_STATE_PLAYING) {
    886             m_startedPlaying = true;
     915        } else if (state == GST_STATE_PLAYING)
    887916            m_paused = false;
    888         }
    889 
    890         if (m_paused && !m_startedPlaying)
    891             gst_element_set_state(m_playBin, GST_STATE_PLAYING);
    892917
    893918        if (m_seeking) {
    894919            shouldUpdateAfterSeek = true;
    895920            m_seeking = false;
    896             if (m_paused)
     921            if (!m_paused)
    897922                gst_element_set_state(m_playBin, GST_STATE_PLAYING);
    898         }
     923        } else if (!m_paused)
     924            gst_element_set_state(m_playBin, GST_STATE_PLAYING);
    899925
    900926        m_networkState = MediaPlayer::Loading;
  • trunk/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r55717 r55733  
    150150            MediaPlayer::NetworkState m_networkState;
    151151            MediaPlayer::ReadyState m_readyState;
    152             bool m_startedPlaying;
    153152            mutable bool m_isStreaming;
    154153            IntSize m_size;
     
    159158            bool m_paused;
    160159            bool m_seeking;
     160            bool m_buffering;
    161161            float m_playbackRate;
    162162            bool m_errorOccured;
     
    165165            Timer<MediaPlayerPrivate> m_fillTimer;
    166166            float m_maxTimeLoaded;
     167            int m_bufferingPercentage;
    167168    };
    168169}
Note: See TracChangeset for help on using the changeset viewer.