Changeset 54878 in webkit


Ignore:
Timestamp:
Feb 17, 2010 12:37:38 AM (14 years ago)
Author:
Philippe Normand
Message:

2010-02-15 Philippe Normand <pnormand@igalia.com>

Reviewed by Gustavo Noronha Silva.

[GStreamer] Should handle BUFFERING messages
https://bugs.webkit.org/show_bug.cgi?id=30004

  • configure.ac: Bump gstreamer -core/-plugins-base requirements to 0.10.25 which is the minimum required version for on-disk buffering.

2010-01-07 Philippe Normand <pnormand@igalia.com>

Reviewed by Gustavo Noronha Silva.

[GStreamer] Should handle BUFFERING messages
https://bugs.webkit.org/show_bug.cgi?id=30004

Draw the buffering status in the media controls. The timebar is
now 2 pixels shorter so dragging it at same absolute position than
before produces a seek at a new position in the media, this
explains the rebaselining of the controls-drag-timebar test.

  • platform/gtk/media/controls-after-reload-expected.txt:
  • platform/gtk/media/controls-drag-timebar-expected.txt:
  • platform/gtk/media/controls-strict-expected.txt:
  • platform/gtk/media/controls-styling-expected.txt:
  • platform/gtk/media/video-controls-rendering-expected.txt: Re-baselined due to 1px left/right border added in controls timeline.

2010-01-07 Philippe Normand <pnormand@igalia.com>

Reviewed by Gustavo Noronha Silva.

[GStreamer] Should handle BUFFERING messages
https://bugs.webkit.org/show_bug.cgi?id=30004

Initial support for on-disk buffering of videos. This works only
for Quicktime and flv though.

  • css/mediaControlsGtk.css:
  • platform/gtk/RenderThemeGtk.cpp: (WebCore::RenderThemeGtk::paintMediaSliderTrack): Draw the buffering status in the media controls.
  • platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: (WebCore::mediaPlayerPrivateMessageCallback): Defer buffering messages handling to processBufferingStats(). (WebCore::bufferingTimeoutCallback): Closure called periodically during the on-disk buffering process. (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): New instance variables and create playbin2 here instead of doing it in load(). (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): New instance variables. (WebCore::MediaPlayerPrivate::load): Simply set uri on playbin2 instead of creating the pipeline and setting uri all together. (WebCore::MediaPlayerPrivate::processBufferingStats): Start a new timeout source if the player is starting on-disk buffering. (WebCore::MediaPlayerPrivate::queryBufferingStats): Method called 200ms during on-disk buffering to update the maxTimeLoaded and few other private variables. (WebCore::MediaPlayerPrivate::maxTimeSeekable): (WebCore::MediaPlayerPrivate::maxTimeLoaded): (WebCore::MediaPlayerPrivate::bytesLoaded): Fixed implementations regarding buffering. (WebCore::MediaPlayerPrivate::totalBytes): Improved logging. (WebCore::MediaPlayerPrivate::updateStates): Start playback if it was internally paused at beginning of on-disk buffering and set ready/network states depending on the state of the on-disk buffering process. (WebCore::MediaPlayerPrivate::didEnd): Emit durationChanged. (WebCore::MediaPlayerPrivate::setAutobuffer): Edit playbin2 flags property depending on autoBuffer value. (WebCore::MediaPlayerPrivate::createGSTPlayBin): Don't set uri there, it is now done in load().
  • platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: New methods and instance variables.
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r54818 r54878  
     12010-02-15  Philippe Normand  <pnormand@igalia.com>
     2
     3        Reviewed by Gustavo Noronha Silva.
     4
     5        [GStreamer] Should handle BUFFERING messages
     6        https://bugs.webkit.org/show_bug.cgi?id=30004
     7
     8        * configure.ac: Bump gstreamer -core/-plugins-base requirements to
     9        0.10.25 which is the minimum required version for on-disk buffering.
     10
    1112010-02-16  Xan Lopez  <xlopez@igalia.com>
    212
  • trunk/LayoutTests/ChangeLog

    r54876 r54878  
     12010-01-07  Philippe Normand  <pnormand@igalia.com>
     2
     3        Reviewed by Gustavo Noronha Silva.
     4
     5        [GStreamer] Should handle BUFFERING messages
     6        https://bugs.webkit.org/show_bug.cgi?id=30004
     7
     8        Draw the buffering status in the media controls. The timebar is
     9        now 2 pixels shorter so dragging it at same absolute position than
     10        before produces a seek at a new position in the media, this
     11        explains the rebaselining of the controls-drag-timebar test.
     12
     13        * platform/gtk/media/controls-after-reload-expected.txt:
     14        * platform/gtk/media/controls-drag-timebar-expected.txt:
     15        * platform/gtk/media/controls-strict-expected.txt:
     16        * platform/gtk/media/controls-styling-expected.txt:
     17        * platform/gtk/media/video-controls-rendering-expected.txt:
     18        Re-baselined due to 1px left/right border added in controls timeline.
     19
    1202010-02-17  Xan Lopez  <xlopez@igalia.com>
    221
  • trunk/LayoutTests/platform/gtk/media/controls-after-reload-expected.txt

    r52266 r54878  
    1818  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    1919    RenderButton {INPUT} at (0,0) size 20x20
    20     RenderFlexibleBox {DIV} at (20,0) size 240x20
    21       RenderSlider {INPUT} at (0,0) size 240x20
     20    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     21      RenderSlider {INPUT} at (1,0) size 238x20
    2222        RenderBlock {DIV} at (2,4) size 12x12
    2323    RenderButton {INPUT} at (260,0) size 20x20
  • trunk/LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt

    r52266 r54878  
    55EVENT(playing)
    66EVENT(seeked)
    7 Time: 2.2
     7Time: 2.1
    88EVENT(seeked)
    99Time: 2.7
  • trunk/LayoutTests/platform/gtk/media/controls-strict-expected.txt

    r52266 r54878  
    1818  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    1919    RenderButton {INPUT} at (0,0) size 20x20
    20     RenderFlexibleBox {DIV} at (20,0) size 240x20
    21       RenderSlider {INPUT} at (0,0) size 240x20
     20    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     21      RenderSlider {INPUT} at (1,0) size 238x20
    2222        RenderBlock {DIV} at (2,4) size 12x12
    2323    RenderButton {INPUT} at (260,0) size 20x20
  • trunk/LayoutTests/platform/gtk/media/controls-styling-expected.txt

    r52266 r54878  
    2222  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    2323    RenderButton {INPUT} at (0,0) size 20x20
    24     RenderFlexibleBox {DIV} at (20,0) size 240x20
    25       RenderSlider {INPUT} at (0,0) size 240x20
     24    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     25      RenderSlider {INPUT} at (1,0) size 238x20
    2626        RenderBlock {DIV} at (2,4) size 12x12
    2727    RenderButton {INPUT} at (260,0) size 20x20
     
    3333  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    3434    RenderButton {INPUT} at (0,0) size 20x20
    35     RenderFlexibleBox {DIV} at (20,0) size 240x20
    36       RenderSlider {INPUT} at (0,0) size 240x20
     35    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     36      RenderSlider {INPUT} at (1,0) size 238x20
    3737        RenderBlock {DIV} at (2,4) size 12x12
    3838    RenderButton {INPUT} at (260,0) size 20x20
  • trunk/LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt

    r52266 r54878  
    2121  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    2222    RenderButton {INPUT} at (0,0) size 20x20
    23     RenderFlexibleBox {DIV} at (20,0) size 240x20
    24       RenderSlider {INPUT} at (0,0) size 240x20
     23    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     24      RenderSlider {INPUT} at (1,0) size 238x20
    2525        RenderBlock {DIV} at (2,4) size 12x12
    2626    RenderButton {INPUT} at (260,0) size 20x20
     
    3232  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    3333    RenderButton {INPUT} at (0,0) size 20x20
    34     RenderFlexibleBox {DIV} at (20,0) size 240x20
    35       RenderSlider {INPUT} at (0,0) size 240x20
     34    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     35      RenderSlider {INPUT} at (1,0) size 238x20
    3636        RenderBlock {DIV} at (2,4) size 12x12
    3737    RenderButton {INPUT} at (260,0) size 20x20
     
    4545  RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20
    4646    RenderButton {INPUT} at (0,0) size 20x20
    47     RenderFlexibleBox {DIV} at (20,0) size 240x20
    48       RenderSlider {INPUT} at (0,0) size 240x20
     47    RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)]
     48      RenderSlider {INPUT} at (1,0) size 238x20
    4949        RenderBlock {DIV} at (2,4) size 12x12
    5050    RenderButton {INPUT} at (260,0) size 20x20
  • trunk/WebCore/ChangeLog

    r54873 r54878  
     12010-01-07  Philippe Normand  <pnormand@igalia.com>
     2
     3        Reviewed by Gustavo Noronha Silva.
     4
     5        [GStreamer] Should handle BUFFERING messages
     6        https://bugs.webkit.org/show_bug.cgi?id=30004
     7
     8        Initial support for on-disk buffering of videos. This works only
     9        for Quicktime and flv though.
     10
     11        * css/mediaControlsGtk.css:
     12        * platform/gtk/RenderThemeGtk.cpp:
     13        (WebCore::RenderThemeGtk::paintMediaSliderTrack): Draw the
     14        buffering status in the media controls.
     15        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
     16        (WebCore::mediaPlayerPrivateMessageCallback): Defer buffering
     17        messages handling to processBufferingStats().
     18        (WebCore::bufferingTimeoutCallback): Closure called periodically
     19        during the on-disk buffering process.
     20        (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): New instance
     21        variables and create playbin2 here instead of doing it in load().
     22        (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): New instance
     23        variables.
     24        (WebCore::MediaPlayerPrivate::load): Simply set uri on playbin2
     25        instead of creating the pipeline and setting uri all together.
     26        (WebCore::MediaPlayerPrivate::processBufferingStats): Start a new
     27        timeout source if the player is starting on-disk buffering.
     28        (WebCore::MediaPlayerPrivate::queryBufferingStats): Method called
     29        200ms during on-disk buffering to update the maxTimeLoaded and few
     30        other private variables.
     31        (WebCore::MediaPlayerPrivate::maxTimeSeekable):
     32        (WebCore::MediaPlayerPrivate::maxTimeLoaded):
     33        (WebCore::MediaPlayerPrivate::bytesLoaded): Fixed implementations
     34        regarding buffering.
     35        (WebCore::MediaPlayerPrivate::totalBytes): Improved logging.
     36        (WebCore::MediaPlayerPrivate::updateStates): Start playback if it
     37        was internally paused at beginning of on-disk buffering and set
     38        ready/network states depending on the state of the on-disk
     39        buffering process.
     40        (WebCore::MediaPlayerPrivate::didEnd): Emit durationChanged.
     41        (WebCore::MediaPlayerPrivate::setAutobuffer): Edit playbin2 flags
     42        property depending on autoBuffer value.
     43        (WebCore::MediaPlayerPrivate::createGSTPlayBin): Don't set uri
     44        there, it is now done in load().
     45        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: New methods
     46        and instance variables.
     47
    1482010-02-16  Chris Evans  <cevans@chromium.org>
    249
  • trunk/WebCore/css/mediaControlsGtk.css

    r52266 r54878  
    4242audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container {
    4343    height: 20px;
     44    border-left: 1px solid rgba(255, 255, 255, 0.2);
     45    border-right: 1px solid rgba(255, 255, 255, 0.2);
    4446}
    4547
  • trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp

    r54782 r54878  
    44 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
    55 * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
     6 * Copyright (C) 2009, 2010 Igalia S.L
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    5657#include <wtf/gtk/GOwnPtr.h>
    5758
     59// GstPlayFlags flags from playbin2. It is the policy of GStreamer to
     60// not publicly expose element-specific enums. That's why this
     61// GstPlayFlags enum has been copied here.
     62typedef enum {
     63    GST_PLAY_FLAG_VIDEO         = 0x00000001,
     64    GST_PLAY_FLAG_AUDIO         = 0x00000002,
     65    GST_PLAY_FLAG_TEXT          = 0x00000004,
     66    GST_PLAY_FLAG_VIS           = 0x00000008,
     67    GST_PLAY_FLAG_SOFT_VOLUME   = 0x00000010,
     68    GST_PLAY_FLAG_NATIVE_AUDIO  = 0x00000020,
     69    GST_PLAY_FLAG_NATIVE_VIDEO  = 0x00000040,
     70    GST_PLAY_FLAG_DOWNLOAD      = 0x00000080,
     71    GST_PLAY_FLAG_BUFFERING     = 0x000000100
     72} GstPlayFlags;
     73
    5874using namespace std;
    5975
     
    7793    MediaPlayer::NetworkState error;
    7894    MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
    79     gint percent = 0;
    8095    bool issueError = true;
    8196    bool attemptNextLocation = false;
     
    127142        break;
    128143    case GST_MESSAGE_BUFFERING:
    129         gst_message_parse_buffering(message, &percent);
    130         LOG_VERBOSE(Media, "Buffering %d", percent);
     144        mp->processBufferingStats(message);
    131145        break;
    132146    case GST_MESSAGE_DURATION:
     
    184198    mp->muteChangedCallback();
    185199    return FALSE;
     200}
     201
     202gboolean bufferingTimeoutCallback(gpointer data)
     203{
     204    MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
     205    return mp->queryBufferingStats();
    186206}
    187207
     
    290310    , m_errorOccured(false)
    291311    , m_volumeIdleId(0)
    292     , m_mediaDuration(0.0)
     312    , m_mediaDuration(0)
    293313    , m_muteIdleId(0)
    294 {
    295     doGstInit();
     314    , m_startedBuffering(false)
     315    , m_fillTimeoutId(0)
     316    , m_maxTimeLoaded(0)
     317    , m_fillStatus(0)
     318{
     319    if (doGstInit())
     320        createGSTPlayBin();
    296321}
    297322
    298323MediaPlayerPrivate::~MediaPlayerPrivate()
    299324{
     325    if (m_fillTimeoutId) {
     326        g_source_remove(m_fillTimeoutId);
     327        m_fillTimeoutId = 0;
     328    }
     329
    300330    if (m_volumeIdleId) {
    301331        g_source_remove(m_volumeIdleId);
     
    350380    }
    351381
    352     createGSTPlayBin(url);
     382    g_object_set(m_playBin, "uri", url.utf8().data(), NULL);
    353383    pause();
    354384}
     
    652682}
    653683
     684void MediaPlayerPrivate::processBufferingStats(GstMessage* message)
     685{
     686    GstBufferingMode mode;
     687
     688    gst_message_parse_buffering_stats(message, &mode, 0, 0, 0);
     689    if (mode != GST_BUFFERING_DOWNLOAD)
     690        return;
     691
     692    if (!m_startedBuffering) {
     693        m_startedBuffering = true;
     694
     695        if (m_fillTimeoutId > 0)
     696            g_source_remove(m_fillTimeoutId);
     697
     698        m_fillTimeoutId = g_timeout_add(200, (GSourceFunc) bufferingTimeoutCallback, this);
     699    }
     700}
     701
     702bool MediaPlayerPrivate::queryBufferingStats()
     703{
     704    GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT);
     705
     706    if (!gst_element_query(m_playBin, query)) {
     707        gst_query_unref(query);
     708        return TRUE;
     709    }
     710
     711    gint64 start, stop;
     712
     713    gst_query_parse_buffering_range(query, 0, &start, &stop, 0);
     714    gst_query_unref(query);
     715
     716    if (stop != -1)
     717        m_fillStatus = 100.0 * stop / GST_FORMAT_PERCENT_MAX;
     718    else
     719        m_fillStatus = 100.0;
     720
     721    LOG_VERBOSE(Media, "Download buffer filled up to %f%%", m_fillStatus);
     722
     723    if (!m_mediaDuration)
     724        durationChanged();
     725
     726    // Update maxTimeLoaded only if the media duration is
     727    // available. Otherwise we can't compute it.
     728    if (m_mediaDuration) {
     729        m_maxTimeLoaded = static_cast<float>((m_fillStatus * m_mediaDuration) / 100.0);
     730        LOG_VERBOSE(Media, "Updated maxTimeLoaded: %f", m_maxTimeLoaded);
     731    }
     732
     733    if (m_fillStatus != 100.0) {
     734        updateStates();
     735        return TRUE;
     736    }
     737
     738    // Media is now fully loaded. It will play even if network
     739    // connection is cut. Buffering is done, remove the fill source
     740    // from the main loop.
     741    m_fillTimeoutId = 0;
     742    m_startedBuffering = false;
     743    updateStates();
     744    return FALSE;
     745}
     746
    654747float MediaPlayerPrivate::maxTimeSeekable() const
    655748{
     
    657750        return 0.0;
    658751
    659     // TODO
    660752    LOG_VERBOSE(Media, "maxTimeSeekable");
    661     if (m_isStreaming)
    662         return numeric_limits<float>::infinity();
    663753    // infinite duration means live stream
     754    if (isinf(duration()))
     755        return 0.0;
     756
    664757    return maxTimeLoaded();
    665758}
     
    670763        return 0.0;
    671764
    672     // TODO
    673     LOG_VERBOSE(Media, "maxTimeLoaded");
    674     notImplemented();
    675     return duration();
     765    float loaded = m_maxTimeLoaded;
     766    if (!loaded && !m_fillTimeoutId)
     767        loaded = duration();
     768    LOG_VERBOSE(Media, "maxTimeLoaded: %f", loaded);
     769    return loaded;
    676770}
    677771
    678772unsigned MediaPlayerPrivate::bytesLoaded() const
    679773{
    680     notImplemented();
    681     LOG_VERBOSE(Media, "bytesLoaded");
    682     /*if (!m_playBin)
     774    if (!m_playBin)
    683775        return 0;
    684     float dur = duration();
    685     float maxTime = maxTimeLoaded();
    686     if (!dur)
    687         return 0;*/
    688 
    689     return 1; // totalBytes() * maxTime / dur;
     776
     777    if (!m_mediaDuration)
     778        return 0;
     779
     780    unsigned loaded = totalBytes() * maxTimeLoaded() / m_mediaDuration;
     781    LOG_VERBOSE(Media, "bytesLoaded: %d", loaded);
     782    return loaded;
    690783}
    691784
    692785unsigned MediaPlayerPrivate::totalBytes() const
    693786{
    694     LOG_VERBOSE(Media, "totalBytes");
    695787    if (!m_source)
    696788        return 0;
     
    702794    gint64 length = 0;
    703795    gst_element_query_duration(m_source, &fmt, &length);
     796    LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length);
    704797
    705798    return length;
     
    752845            m_readyState = MediaPlayer::HaveEnoughData;
    753846            m_paused = false;
     847            m_startedPlaying = true;
    754848            if (!m_mediaDuration) {
    755849                float newDuration = duration();
     
    760854            m_paused = true;
    761855
     856        // Is on-disk buffering in progress?
     857        if (m_fillTimeoutId) {
     858            m_networkState = MediaPlayer::Loading;
     859            // Buffering has just started, we should now have enough
     860            // data to restart playback if it was internally paused by
     861            // GStreamer.
     862            if (m_paused && !m_startedPlaying)
     863                gst_element_set_state(m_playBin, GST_STATE_PLAYING);
     864        }
     865
     866        if (maxTimeLoaded() == duration()) {
     867            m_networkState = MediaPlayer::Loaded;
     868            if (state == GST_STATE_READY)
     869                m_readyState = MediaPlayer::HaveNothing;
     870            else if (state == GST_STATE_PAUSED)
     871                m_readyState = MediaPlayer::HaveEnoughData;
     872        } else
     873            if (state == GST_STATE_READY)
     874                m_readyState = MediaPlayer::HaveNothing;
     875            else if (m_paused)
     876                m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
     877
    762878        if (m_changingRate) {
    763879            m_player->rateChanged();
     
    770886        }
    771887
    772         m_networkState = MediaPlayer::Loaded;
    773888        break;
    774889    case GST_STATE_CHANGE_ASYNC:
     
    9401055    // synchronize position and duration values.
    9411056    float now = currentTime();
    942     if (now > 0)
     1057    if (now > 0) {
    9431058        m_mediaDuration = now;
     1059        m_player->durationChanged();
     1060    }
     1061
    9441062    gst_element_set_state(m_playBin, GST_STATE_PAUSED);
    9451063
     
    11921310}
    11931311
    1194 void MediaPlayerPrivate::createGSTPlayBin(String url)
     1312void MediaPlayerPrivate::setAutobuffer(bool autoBuffer)
     1313{
     1314    ASSERT(m_playBin);
     1315
     1316    GstPlayFlags flags;
     1317    g_object_get(m_playBin, "flags", &flags, NULL);
     1318    if (autoBuffer)
     1319        g_object_set(m_playBin, "flags", flags | GST_PLAY_FLAG_DOWNLOAD, NULL);
     1320    else
     1321        g_object_set(m_playBin, "flags", flags & ~GST_PLAY_FLAG_DOWNLOAD, NULL);
     1322}
     1323
     1324void MediaPlayerPrivate::createGSTPlayBin()
    11951325{
    11961326    ASSERT(!m_playBin);
     
    12011331    g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this);
    12021332    gst_object_unref(bus);
    1203 
    1204     g_object_set(m_playBin, "uri", url.utf8().data(), NULL);
    12051333
    12061334    g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this);
     
    12221350            m_fpsSink = 0;
    12231351            g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
    1224             LOG(Media, "Can't display FPS statistics, you need gst-plugins-bad >= 0.10.18");
     1352            LOG_VERBOSE(Media, "Can't display FPS statistics, you need gst-plugins-bad >= 0.10.18");
    12251353        }
    12261354    } else
  • trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h

    r54136 r54878  
    33 * Copyright (C) 2007 Collabora Ltd. All rights reserved.
    44 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
     5 * Copyright (C) 2009, 2010 Igalia S.L
    56 *
    67 * This library is free software; you can redistribute it and/or
     
    8788            void muteChangedCallback();
    8889
     90            void setAutobuffer(bool);
     91            bool queryBufferingStats();
     92
    8993            MediaPlayer::NetworkState networkState() const;
    9094            MediaPlayer::ReadyState readyState() const;
     
    129133            void startEndPointTimerIfNeeded();
    130134
    131             void createGSTPlayBin(String url);
     135            void createGSTPlayBin();
    132136            bool changePipelineState(GstState state);
     137
     138            void processBufferingStats(GstMessage* message);
    133139
    134140        private:
     
    158164            gfloat m_mediaDuration;
    159165            guint m_muteIdleId;
     166            bool m_startedBuffering;
     167            guint m_fillTimeoutId;
     168            float m_maxTimeLoaded;
     169            gdouble m_fillStatus;
    160170    };
    161171}
  • trunk/WebCore/platform/gtk/RenderThemeGtk.cpp

    r54503 r54878  
    2828#include "CString.h"
    2929#include "GOwnPtr.h"
     30#include "Gradient.h"
    3031#include "GraphicsContext.h"
    3132#include "HTMLMediaElement.h"
    3233#include "HTMLNames.h"
     34#include "MediaControlElements.h"
    3335#include "NotImplemented.h"
    3436#include "RenderBox.h"
     
    687689bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
    688690{
    689     paintInfo.context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace);
    690     paintInfo.context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
    691                                                   r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace);
     691    GraphicsContext* context = paintInfo.context;
     692
     693    context->fillRect(FloatRect(r), m_panelColor, DeviceColorSpace);
     694    context->fillRect(FloatRect(IntRect(r.x(), r.y() + (r.height() - m_mediaSliderHeight) / 2,
     695                                        r.width(), m_mediaSliderHeight)), m_sliderColor, DeviceColorSpace);
     696
     697    RenderStyle* style = o->style();
     698    HTMLMediaElement* mediaElement = toParentMediaElement(o);
     699
     700    if (!mediaElement)
     701        return false;
     702
     703    // Draw the buffered ranges. This code is highly inspired from
     704    // Chrome.
     705    // FIXME: Draw multiple ranges if there are multiple buffered
     706    // ranges. The current implementation of the player is always
     707    // buffering a single range anyway.
     708    IntRect bufferedRect = r;
     709    bufferedRect.inflate(-style->borderLeftWidth());
     710    bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded()));
     711
     712    // Don't bother drawing an empty area.
     713    if (bufferedRect.isEmpty())
     714        return false;
     715
     716    IntPoint sliderTopLeft = bufferedRect.location();
     717    IntPoint sliderTopRight = sliderTopLeft;
     718    sliderTopRight.move(0, bufferedRect.height());
     719
     720    RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
     721    Color startColor = m_panelColor;
     722    gradient->addColorStop(0.0, startColor);
     723    gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));
     724
     725    context->save();
     726    context->setStrokeStyle(NoStroke);
     727    context->setFillGradient(gradient);
     728    context->fillRect(bufferedRect);
     729    context->restore();
     730
    692731    return false;
    693732}
  • trunk/configure.ac

    r54818 r54878  
    212212SQLITE_REQUIRED_VERSION=3.0
    213213GSTREAMER_REQUIRED_VERSION=0.10
    214 GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION=0.10.23
     214GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION=0.10.25
    215215ENCHANT_REQUIRED_VERSION=0.22
    216216GAIL_REQUIRED_VERSION=1.8
Note: See TracChangeset for help on using the changeset viewer.