Changeset 54878 in webkit
- Timestamp:
- Feb 17, 2010 12:37:38 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r54818 r54878 1 2010-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 1 11 2010-02-16 Xan Lopez <xlopez@igalia.com> 2 12 -
trunk/LayoutTests/ChangeLog
r54876 r54878 1 2010-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 1 20 2010-02-17 Xan Lopez <xlopez@igalia.com> 2 21 -
trunk/LayoutTests/platform/gtk/media/controls-after-reload-expected.txt
r52266 r54878 18 18 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 19 19 RenderButton {INPUT} at (0,0) size 20x20 20 RenderFlexibleBox {DIV} at (20,0) size 240x20 21 RenderSlider {INPUT} at ( 0,0) size 240x2020 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 21 RenderSlider {INPUT} at (1,0) size 238x20 22 22 RenderBlock {DIV} at (2,4) size 12x12 23 23 RenderButton {INPUT} at (260,0) size 20x20 -
trunk/LayoutTests/platform/gtk/media/controls-drag-timebar-expected.txt
r52266 r54878 5 5 EVENT(playing) 6 6 EVENT(seeked) 7 Time: 2. 27 Time: 2.1 8 8 EVENT(seeked) 9 9 Time: 2.7 -
trunk/LayoutTests/platform/gtk/media/controls-strict-expected.txt
r52266 r54878 18 18 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 19 19 RenderButton {INPUT} at (0,0) size 20x20 20 RenderFlexibleBox {DIV} at (20,0) size 240x20 21 RenderSlider {INPUT} at ( 0,0) size 240x2020 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 21 RenderSlider {INPUT} at (1,0) size 238x20 22 22 RenderBlock {DIV} at (2,4) size 12x12 23 23 RenderButton {INPUT} at (260,0) size 20x20 -
trunk/LayoutTests/platform/gtk/media/controls-styling-expected.txt
r52266 r54878 22 22 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 23 23 RenderButton {INPUT} at (0,0) size 20x20 24 RenderFlexibleBox {DIV} at (20,0) size 240x20 25 RenderSlider {INPUT} at ( 0,0) size 240x2024 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 25 RenderSlider {INPUT} at (1,0) size 238x20 26 26 RenderBlock {DIV} at (2,4) size 12x12 27 27 RenderButton {INPUT} at (260,0) size 20x20 … … 33 33 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 34 34 RenderButton {INPUT} at (0,0) size 20x20 35 RenderFlexibleBox {DIV} at (20,0) size 240x20 36 RenderSlider {INPUT} at ( 0,0) size 240x2035 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 36 RenderSlider {INPUT} at (1,0) size 238x20 37 37 RenderBlock {DIV} at (2,4) size 12x12 38 38 RenderButton {INPUT} at (260,0) size 20x20 -
trunk/LayoutTests/platform/gtk/media/video-controls-rendering-expected.txt
r52266 r54878 21 21 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 22 22 RenderButton {INPUT} at (0,0) size 20x20 23 RenderFlexibleBox {DIV} at (20,0) size 240x20 24 RenderSlider {INPUT} at ( 0,0) size 240x2023 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 24 RenderSlider {INPUT} at (1,0) size 238x20 25 25 RenderBlock {DIV} at (2,4) size 12x12 26 26 RenderButton {INPUT} at (260,0) size 20x20 … … 32 32 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 33 33 RenderButton {INPUT} at (0,0) size 20x20 34 RenderFlexibleBox {DIV} at (20,0) size 240x20 35 RenderSlider {INPUT} at ( 0,0) size 240x2034 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 35 RenderSlider {INPUT} at (1,0) size 238x20 36 36 RenderBlock {DIV} at (2,4) size 12x12 37 37 RenderButton {INPUT} at (260,0) size 20x20 … … 45 45 RenderFlexibleBox (positioned) {DIV} at (0,220) size 320x20 46 46 RenderButton {INPUT} at (0,0) size 20x20 47 RenderFlexibleBox {DIV} at (20,0) size 240x20 48 RenderSlider {INPUT} at ( 0,0) size 240x2047 RenderFlexibleBox {DIV} at (20,0) size 240x20 [border: (1px solid #FFFFFF33) none (1px solid #FFFFFF33)] 48 RenderSlider {INPUT} at (1,0) size 238x20 49 49 RenderBlock {DIV} at (2,4) size 12x12 50 50 RenderButton {INPUT} at (260,0) size 20x20 -
trunk/WebCore/ChangeLog
r54873 r54878 1 2010-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 1 48 2010-02-16 Chris Evans <cevans@chromium.org> 2 49 -
trunk/WebCore/css/mediaControlsGtk.css
r52266 r54878 42 42 audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container { 43 43 height: 20px; 44 border-left: 1px solid rgba(255, 255, 255, 0.2); 45 border-right: 1px solid rgba(255, 255, 255, 0.2); 44 46 } 45 47 -
trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
r54782 r54878 4 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 5 5 * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> 6 * Copyright (C) 2009, 2010 Igalia S.L 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 56 57 #include <wtf/gtk/GOwnPtr.h> 57 58 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. 62 typedef 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 58 74 using namespace std; 59 75 … … 77 93 MediaPlayer::NetworkState error; 78 94 MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data); 79 gint percent = 0;80 95 bool issueError = true; 81 96 bool attemptNextLocation = false; … … 127 142 break; 128 143 case GST_MESSAGE_BUFFERING: 129 gst_message_parse_buffering(message, &percent); 130 LOG_VERBOSE(Media, "Buffering %d", percent); 144 mp->processBufferingStats(message); 131 145 break; 132 146 case GST_MESSAGE_DURATION: … … 184 198 mp->muteChangedCallback(); 185 199 return FALSE; 200 } 201 202 gboolean bufferingTimeoutCallback(gpointer data) 203 { 204 MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data); 205 return mp->queryBufferingStats(); 186 206 } 187 207 … … 290 310 , m_errorOccured(false) 291 311 , m_volumeIdleId(0) 292 , m_mediaDuration(0 .0)312 , m_mediaDuration(0) 293 313 , 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(); 296 321 } 297 322 298 323 MediaPlayerPrivate::~MediaPlayerPrivate() 299 324 { 325 if (m_fillTimeoutId) { 326 g_source_remove(m_fillTimeoutId); 327 m_fillTimeoutId = 0; 328 } 329 300 330 if (m_volumeIdleId) { 301 331 g_source_remove(m_volumeIdleId); … … 350 380 } 351 381 352 createGSTPlayBin(url);382 g_object_set(m_playBin, "uri", url.utf8().data(), NULL); 353 383 pause(); 354 384 } … … 652 682 } 653 683 684 void 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 702 bool 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 654 747 float MediaPlayerPrivate::maxTimeSeekable() const 655 748 { … … 657 750 return 0.0; 658 751 659 // TODO660 752 LOG_VERBOSE(Media, "maxTimeSeekable"); 661 if (m_isStreaming)662 return numeric_limits<float>::infinity();663 753 // infinite duration means live stream 754 if (isinf(duration())) 755 return 0.0; 756 664 757 return maxTimeLoaded(); 665 758 } … … 670 763 return 0.0; 671 764 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; 676 770 } 677 771 678 772 unsigned MediaPlayerPrivate::bytesLoaded() const 679 773 { 680 notImplemented(); 681 LOG_VERBOSE(Media, "bytesLoaded"); 682 /*if (!m_playBin) 774 if (!m_playBin) 683 775 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; 690 783 } 691 784 692 785 unsigned MediaPlayerPrivate::totalBytes() const 693 786 { 694 LOG_VERBOSE(Media, "totalBytes");695 787 if (!m_source) 696 788 return 0; … … 702 794 gint64 length = 0; 703 795 gst_element_query_duration(m_source, &fmt, &length); 796 LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length); 704 797 705 798 return length; … … 752 845 m_readyState = MediaPlayer::HaveEnoughData; 753 846 m_paused = false; 847 m_startedPlaying = true; 754 848 if (!m_mediaDuration) { 755 849 float newDuration = duration(); … … 760 854 m_paused = true; 761 855 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 762 878 if (m_changingRate) { 763 879 m_player->rateChanged(); … … 770 886 } 771 887 772 m_networkState = MediaPlayer::Loaded;773 888 break; 774 889 case GST_STATE_CHANGE_ASYNC: … … 940 1055 // synchronize position and duration values. 941 1056 float now = currentTime(); 942 if (now > 0) 1057 if (now > 0) { 943 1058 m_mediaDuration = now; 1059 m_player->durationChanged(); 1060 } 1061 944 1062 gst_element_set_state(m_playBin, GST_STATE_PAUSED); 945 1063 … … 1192 1310 } 1193 1311 1194 void MediaPlayerPrivate::createGSTPlayBin(String url) 1312 void 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 1324 void MediaPlayerPrivate::createGSTPlayBin() 1195 1325 { 1196 1326 ASSERT(!m_playBin); … … 1201 1331 g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this); 1202 1332 gst_object_unref(bus); 1203 1204 g_object_set(m_playBin, "uri", url.utf8().data(), NULL);1205 1333 1206 1334 g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this); … … 1222 1350 m_fpsSink = 0; 1223 1351 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"); 1225 1353 } 1226 1354 } else -
trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
r54136 r54878 3 3 * Copyright (C) 2007 Collabora Ltd. All rights reserved. 4 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 5 * Copyright (C) 2009, 2010 Igalia S.L 5 6 * 6 7 * This library is free software; you can redistribute it and/or … … 87 88 void muteChangedCallback(); 88 89 90 void setAutobuffer(bool); 91 bool queryBufferingStats(); 92 89 93 MediaPlayer::NetworkState networkState() const; 90 94 MediaPlayer::ReadyState readyState() const; … … 129 133 void startEndPointTimerIfNeeded(); 130 134 131 void createGSTPlayBin( String url);135 void createGSTPlayBin(); 132 136 bool changePipelineState(GstState state); 137 138 void processBufferingStats(GstMessage* message); 133 139 134 140 private: … … 158 164 gfloat m_mediaDuration; 159 165 guint m_muteIdleId; 166 bool m_startedBuffering; 167 guint m_fillTimeoutId; 168 float m_maxTimeLoaded; 169 gdouble m_fillStatus; 160 170 }; 161 171 } -
trunk/WebCore/platform/gtk/RenderThemeGtk.cpp
r54503 r54878 28 28 #include "CString.h" 29 29 #include "GOwnPtr.h" 30 #include "Gradient.h" 30 31 #include "GraphicsContext.h" 31 32 #include "HTMLMediaElement.h" 32 33 #include "HTMLNames.h" 34 #include "MediaControlElements.h" 33 35 #include "NotImplemented.h" 34 36 #include "RenderBox.h" … … 687 689 bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 688 690 { 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 692 731 return false; 693 732 } -
trunk/configure.ac
r54818 r54878 212 212 SQLITE_REQUIRED_VERSION=3.0 213 213 GSTREAMER_REQUIRED_VERSION=0.10 214 GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION=0.10.2 3214 GSTREAMER_PLUGINS_BASE_REQUIRED_VERSION=0.10.25 215 215 ENCHANT_REQUIRED_VERSION=0.22 216 216 GAIL_REQUIRED_VERSION=1.8
Note: See TracChangeset
for help on using the changeset viewer.