Changeset 258542 in webkit


Ignore:
Timestamp:
Mar 17, 2020 2:36:31 AM (4 years ago)
Author:
Philippe Normand
Message:

[GStreamer][MSE] Playback rate update support
https://bugs.webkit.org/show_bug.cgi?id=208454

Reviewed by Xabier Rodriguez-Calvar.

Implement playback rate update support for the MSE player. Also
includes drive-by logging cleanups.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::updatePlaybackRate):
(WebCore::MediaPlayerPrivateGStreamer::setRate):
(WebCore::MediaPlayerPrivateGStreamer::setPreservesPitch):

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:

(WebCore::MediaPlayerPrivateGStreamer::pipeline const):

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

(WebCore::MediaPlayerPrivateGStreamerMSE::seek):
(WebCore::MediaPlayerPrivateGStreamerMSE::doSeek):
(WebCore::MediaPlayerPrivateGStreamerMSE::maybeFinishSeek):
(WebCore::MediaPlayerPrivateGStreamerMSE::seekCompleted):
(WebCore::MediaPlayerPrivateGStreamerMSE::updatePlaybackRate): Deleted.
(WebCore::MediaPlayerPrivateGStreamerMSE::setRate): Deleted.

  • platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r258541 r258542  
     12020-03-17  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer][MSE] Playback rate update support
     4        https://bugs.webkit.org/show_bug.cgi?id=208454
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        Implement playback rate update support for the MSE player. Also
     9        includes drive-by logging cleanups.
     10
     11        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     12        (WebCore::MediaPlayerPrivateGStreamer::updatePlaybackRate):
     13        (WebCore::MediaPlayerPrivateGStreamer::setRate):
     14        (WebCore::MediaPlayerPrivateGStreamer::setPreservesPitch):
     15        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
     16        (WebCore::MediaPlayerPrivateGStreamer::pipeline const):
     17        * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
     18        (WebCore::MediaPlayerPrivateGStreamerMSE::seek):
     19        (WebCore::MediaPlayerPrivateGStreamerMSE::doSeek):
     20        (WebCore::MediaPlayerPrivateGStreamerMSE::maybeFinishSeek):
     21        (WebCore::MediaPlayerPrivateGStreamerMSE::seekCompleted):
     22        (WebCore::MediaPlayerPrivateGStreamerMSE::updatePlaybackRate): Deleted.
     23        (WebCore::MediaPlayerPrivateGStreamerMSE::setRate): Deleted.
     24        * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:
     25
    1262020-03-16  Simon Fraser  <simon.fraser@apple.com>
    227
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r258199 r258542  
    800800        return;
    801801
    802     GST_INFO_OBJECT(pipeline(), "Set Rate to %f", m_playbackRate);
     802    GST_INFO_OBJECT(pipeline(), "Set playback rate to %f", m_playbackRate);
    803803
    804804    // Mute the sound if the playback rate is negative or too extreme and audio pitch is not adjusted.
     
    811811        m_lastPlaybackRate = m_playbackRate;
    812812    } else {
     813        GST_ERROR_OBJECT(pipeline(), "Set rate to %f failed", m_playbackRate);
    813814        m_playbackRate = m_lastPlaybackRate;
    814         GST_ERROR("Set rate to %f failed", m_playbackRate);
    815815    }
    816816
     
    859859    float rateClamped = clampTo(rate, -20.0, 20.0);
    860860    if (rateClamped != rate)
    861         GST_WARNING("Clamping original rate (%f) to [-20, 20] (%f), higher rates cause crashes", rate, rateClamped);
    862 
     861        GST_WARNING_OBJECT(pipeline(), "Clamping original rate (%f) to [-20, 20] (%f), higher rates cause crashes", rate, rateClamped);
     862
     863    GST_DEBUG_OBJECT(pipeline(), "Setting playback rate to %f", rateClamped);
    863864    // Avoid useless playback rate update.
    864865    if (m_playbackRate == rateClamped) {
     
    906907void MediaPlayerPrivateGStreamer::setPreservesPitch(bool preservesPitch)
    907908{
     909    GST_DEBUG_OBJECT(pipeline(), "Preserving audio pitch: %s", boolForPrinting(preservesPitch));
    908910    m_shouldPreservePitch = preservesPitch;
    909911}
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r257463 r258542  
    247247    virtual void configurePlaySink() { }
    248248    virtual bool changePipelineState(GstState);
     249    virtual void updatePlaybackRate();
    249250
    250251#if USE(GSTREAMER_HOLEPUNCH)
     
    273274
    274275    void setPipeline(GstElement*);
     276    GstElement* pipeline() const { return m_pipeline.get(); }
    275277
    276278    void repaint();
     
    387389    bool isPlayerShuttingDown() const { return m_isPlayerShuttingDown.load(); }
    388390    MediaTime maxTimeLoaded() const;
    389     GstElement* pipeline() const { return m_pipeline.get(); }
    390391    void setVideoSourceOrientation(ImageOrientation);
    391392    MediaTime platformDuration() const;
     
    433434#endif
    434435    virtual bool doSeek(const MediaTime& position, float rate, GstSeekFlags seekType);
    435     virtual void updatePlaybackRate();
    436436
    437437    String engineDescription() const override { return "GStreamer"; }
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp

    r253482 r258542  
    3737#include "MediaDescription.h"
    3838#include "MediaPlayer.h"
    39 #include "NotImplemented.h"
    4039#include "PlaybackPipeline.h"
    4140#include "SourceBufferPrivateGStreamer.h"
     
    174173        return;
    175174
    176     GST_INFO("[Seek] seek attempt to %s secs", toString(time).utf8().data());
     175    GST_INFO_OBJECT(pipeline(), "[Seek] seek attempt to %s secs", toString(time).utf8().data());
    177176
    178177    // Avoid useless seeking.
     
    192191    }
    193192
    194     GST_DEBUG("Seeking from %s to %s seconds", toString(current).utf8().data(), toString(time).utf8().data());
     193    GST_DEBUG_OBJECT(pipeline(), "Seeking from %s to %s seconds", toString(current).utf8().data(), toString(time).utf8().data());
    195194
    196195    MediaTime previousSeekTime = m_seekTime;
    197196    m_seekTime = time;
    198197
    199     if (!doSeek()) {
     198    if (!doSeek(m_seekTime, m_playbackRate, static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE))) {
    200199        m_seekTime = previousSeekTime;
    201         GST_WARNING("Seeking to %s failed", toString(time).utf8().data());
     200        GST_WARNING_OBJECT(pipeline(), "Seeking to %s failed", toString(time).utf8().data());
    202201        return;
    203202    }
    204203
    205204    m_isEndReached = false;
    206     GST_DEBUG("m_isSeeking=%s, m_seekTime=%s", boolForPrinting(m_isSeeking), toString(m_seekTime).utf8().data());
     205    GST_DEBUG_OBJECT(pipeline(), "m_isSeeking=%s, m_seekTime=%s", boolForPrinting(m_isSeeking), toString(m_seekTime).utf8().data());
    207206}
    208207
     
    243242}
    244243
    245 bool MediaPlayerPrivateGStreamerMSE::doSeek(const MediaTime&, float, GstSeekFlags)
    246 {
    247     // Use doSeek() instead. If anybody is calling this version of doSeek(), something is wrong.
    248     ASSERT_NOT_REACHED();
    249     return false;
    250 }
    251 
    252 bool MediaPlayerPrivateGStreamerMSE::doSeek()
    253 {
    254     MediaTime seekTime = m_seekTime;
    255     double rate = m_player->rate();
    256     GstSeekFlags seekType = static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE);
     244bool MediaPlayerPrivateGStreamerMSE::doSeek(const MediaTime& position, float rate, GstSeekFlags seekType)
     245{
     246    // FIXME: Make a copy here because in some cases below it is modified. This
     247    // sounds like a bad idea and should be investigated further.
     248    MediaTime seekTime = position;
    257249
    258250    // Always move to seeking state to report correct 'currentTime' while pending for actual seek to complete.
     
    263255    GstStateChangeReturn getStateResult = gst_element_get_state(m_pipeline.get(), &state, &newState, 0);
    264256    if (getStateResult == GST_STATE_CHANGE_FAILURE || getStateResult == GST_STATE_CHANGE_NO_PREROLL) {
    265         GST_DEBUG("[Seek] cannot seek, current state change is %s", gst_element_state_change_return_get_name(getStateResult));
     257        GST_DEBUG_OBJECT(pipeline(), "[Seek] cannot seek, current state change is %s", gst_element_state_change_return_get_name(getStateResult));
    266258        webKitMediaSrcSetReadyForSamples(WEBKIT_MEDIA_SRC(m_source.get()), true);
    267259        m_isSeeking = false;
     
    285277            reason = "Previous seek is not finished yet";
    286278
    287         GST_DEBUG("[Seek] Delaying the seek: %s", reason.data());
     279        GST_DEBUG_OBJECT(pipeline(), "[Seek] Delaying the seek: %s", reason.data());
    288280
    289281        m_isSeekPending = true;
     
    312304            MediaTime nearest = m_mediaSource->buffered()->nearest(seekTime);
    313305            if (nearest.isValid() && nearest > seekTime && (nearest - seekTime) <= miniGap && isTimeBuffered(nearest + miniGap)) {
    314                 GST_DEBUG("[Seek] Changed the seek target time from %s to %s, a near point in the future", toString(seekTime).utf8().data(), toString(nearest).utf8().data());
     306                GST_DEBUG_OBJECT(pipeline(), "[Seek] Changed the seek target time from %s to %s, a near point in the future", toString(seekTime).utf8().data(), toString(nearest).utf8().data());
    315307                seekTime = nearest;
    316308            }
     
    320312    // Check if MSE has samples for requested time and defer actual seek if needed.
    321313    if (!isTimeBuffered(seekTime)) {
    322         GST_DEBUG("[Seek] Delaying the seek: MSE is not ready");
     314        GST_DEBUG_OBJECT(pipeline(), "[Seek] Delaying the seek: MSE is not ready");
    323315        GstStateChangeReturn setStateResult = gst_element_set_state(m_pipeline.get(), GST_STATE_PAUSED);
    324316        if (setStateResult == GST_STATE_CHANGE_FAILURE) {
    325             GST_DEBUG("[Seek] Cannot seek, failed to pause playback pipeline.");
     317            GST_DEBUG_OBJECT(pipeline(), "[Seek] Cannot seek, failed to pause playback pipeline.");
    326318            webKitMediaSrcSetReadyForSamples(WEBKIT_MEDIA_SRC(m_source.get()), true);
    327319            m_isSeeking = false;
     
    342334    }
    343335
    344     GST_DEBUG("We can seek now");
     336    GST_DEBUG_OBJECT(pipeline(), "We can seek now");
    345337
    346338    MediaTime startTime = seekTime, endTime = MediaTime::invalidTime();
     
    354346        rate = 1;
    355347
    356     GST_DEBUG("Actual seek to %s, end time:  %s, rate: %f", toString(startTime).utf8().data(), toString(endTime).utf8().data(), rate);
     348    GST_DEBUG_OBJECT(pipeline(), "Actual seek to %s, end time:  %s, rate: %f", toString(startTime).utf8().data(), toString(endTime).utf8().data(), rate);
    357349
    358350    // This will call notifySeekNeedsData() after some time to tell that the pipeline is ready for sample enqueuing.
     
    364356        m_isSeeking = false;
    365357        m_gstSeekCompleted = true;
    366         GST_DEBUG("doSeek(): gst_element_seek() failed, returning false");
     358        GST_DEBUG_OBJECT(pipeline(), "doSeek(): gst_element_seek() failed, returning false");
    367359        return false;
    368360    }
    369361
    370362    // The samples will be enqueued in notifySeekNeedsData().
    371     GST_DEBUG("doSeek(): gst_element_seek() succeeded, returning true");
     363    GST_DEBUG_OBJECT(pipeline(), "doSeek(): gst_element_seek() succeeded, returning true");
    372364    return true;
    373365}
     
    390382        GST_DEBUG("[Seek] Committing pending seek to %s", toString(m_seekTime).utf8().data());
    391383        m_isSeekPending = false;
    392         if (!doSeek()) {
     384        if (!doSeek(m_seekTime, m_playbackRate, static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE))) {
    393385            GST_WARNING("[Seek] Seeking to %s failed", toString(m_seekTime).utf8().data());
    394386            m_cachedPosition = MediaTime::invalidTime();
     
    408400}
    409401
    410 void MediaPlayerPrivateGStreamerMSE::updatePlaybackRate()
    411 {
    412     notImplemented();
    413 }
    414 
    415402bool MediaPlayerPrivateGStreamerMSE::seeking() const
    416403{
     
    468455    m_mseSeekCompleted = true;
    469456
    470     doSeek();
     457    doSeek(m_seekTime, m_playbackRate, static_cast<GstSeekFlags>(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE));
    471458
    472459    if (!seeking() && m_readyState >= MediaPlayer::ReadyState::HaveFutureData)
     
    475462    if (!seeking())
    476463        m_player->timeChanged();
    477 }
    478 
    479 void MediaPlayerPrivateGStreamerMSE::setRate(float)
    480 {
    481     notImplemented();
    482464}
    483465
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h

    r253482 r258542  
    6666    MediaTime durationMediaTime() const override;
    6767
    68     void setRate(float) override;
    6968    std::unique_ptr<PlatformTimeRanges> buffered() const override;
    7069    MediaTime maxMediaTimeSeekable() const override;
     
    9493
    9594    bool doSeek(const MediaTime&, float, GstSeekFlags) override;
    96     bool doSeek();
    9795    void maybeFinishSeek();
    98     void updatePlaybackRate() override;
     96
    9997    void asyncStateChangeDone() override;
    10098
Note: See TracChangeset for help on using the changeset viewer.