Changeset 47710 in webkit
- Timestamp:
- Aug 24, 2009, 7:30:38 AM (17 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/gtk/Skipped (modified) (2 diffs)
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp (modified) (29 diffs)
-
WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h (modified) (2 diffs)
-
WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r47709 r47710 1 2009-08-24 Zan Dobersek <zandobersek@gmail.com> 2 3 Reviewed by Gustavo Noronha. 4 5 [GTK] Integrate GStreamer video with the graphics backend 6 https://bugs.webkit.org/show_bug.cgi?id=16356 7 8 Enable media tests that now pass. 9 10 * platform/gtk/Skipped: 11 1 12 2009-08-24 Andras Becsi <becsi.andras@stud.u-szeged.hu> 2 13 -
trunk/LayoutTests/platform/gtk/Skipped
r47691 r47710 3932 3932 # Tests in media/ directory 3933 3933 # Tests failing 3934 media/audio-constructor-src.html3935 media/audio-mpeg-supported.html3936 media/broken-video.html3937 media/event-attributes.html3938 media/media-startTime.html3939 media/progress-event-total.html3940 media/progress-event.html3941 media/remove-from-document.html3942 media/video-append-source.html3943 media/video-autoplay.html3944 media/video-buffered.html3945 3934 media/video-can-play-type.html 3946 3935 media/video-click-dblckick-standalone.html 3947 3936 media/video-controls-transformed.html 3948 3937 media/video-controls-zoomed.html 3949 media/video-controls.html3950 media/video-currentTime-set.html3951 media/video-currentTime-set2.html3952 media/video-currentTime.html3953 3938 media/video-document-types.html 3954 media/video-dom-autoplay.html 3955 media/video-dom-src.html 3956 media/video-error-abort.html 3957 media/video-error-does-not-exist.html 3958 media/video-load-networkState.html 3959 media/video-load-readyState.html 3960 media/video-loop.html 3961 media/video-muted.html 3962 media/video-no-autoplay.html 3963 media/video-pause-empty-events.html 3964 media/video-play-empty-events.html 3965 media/video-play-pause-events.html 3966 media/video-play-pause-exception.html 3939 media/video-played-reset.html 3940 media/video-size-intrinsic-scale.html 3941 media/video-source-error.html 3942 # Tests timing out 3943 media/audio-data-url.html 3944 media/controls-drag-timebar.html 3945 media/event-attributes.html 3946 media/unsupported-rtsp.html 3967 3947 media/video-played-collapse.html 3968 media/video-played-reset.html3969 media/video-played-ranges-1.html3970 media/video-seek-past-end-paused.html3971 media/video-seek-past-end-playing.html3972 media/video-seekable.html3973 media/video-seeking.html3974 media/video-size-intrinsic-scale.html3975 media/video-size.html3976 media/video-source-add-src.html3977 media/video-source-type-params.html3978 media/video-source-type.html3979 media/video-src-change.html3980 media/video-src-invalid-remove.html3981 media/video-src-plus-source.html3982 media/video-src-remove.html3983 media/video-volume.html3984 # Failing media tests with changesets for reference:3985 # http://trac.webkit.org/changeset/453113986 media/video-canvas-source.html3987 # Tests timing out3988 media/unsupported-rtsp.html3989 3948 # Tests generating new results 3990 3949 media/audio-controls-rendering.html 3991 media/controls-drag-timebar.html3992 3950 media/video-aspect-ratio.html 3993 3951 media/video-controls-rendering.html … … 3996 3954 media/video-empty-source.html 3997 3955 media/video-layer-crash.html 3998 media/video-source-error.html 3999 media/video-timeupdate-during-playback.html 3956 media/video-no-audio.html 4000 3957 media/video-transformed.html 4001 3958 media/video-zoom-controls.html 4002 3959 media/video-zoom.html 4003 media/audio-data-url.html4004 media/video-no-audio.html4005 3960 4006 3961 # Tests in plugins/ directory -
trunk/WebCore/ChangeLog
r47708 r47710 1 2009-08-24 Zan Dobersek <zandobersek@gmail.com> 2 3 Reviewed by Gustavo Noronha. 4 5 [GTK] Integrate GStreamer video with the graphics backend 6 https://bugs.webkit.org/show_bug.cgi?id=16356 7 8 Improves GStreamer backend implementation of MediaPlayerPrivate class. 9 10 * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: 11 (WebCore::mediaPlayerPrivateErrorCallback): Send proper MediaPlayer 12 error for different GStreamer errors to MediaPlayerPrivate. 13 (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Move static 14 initialization boolean to a better place. 15 (WebCore::MediaPlayerPrivate::play): 16 (WebCore::MediaPlayerPrivate::pause): 17 (WebCore::MediaPlayerPrivate::duration): Return if error occured, do not 18 consider the source as stream if duration query failed. 19 (WebCore::MediaPlayerPrivate::currentTime): Return if error occured, use 20 an early return. 21 (WebCore::MediaPlayerPrivate::seek): Return if error occured. 22 (WebCore::MediaPlayerPrivate::setEndTime): Remove implementation since this 23 function doesn't seem to be used anywhere in WebCore. 24 (WebCore::MediaPlayerPrivate::paused): 25 (WebCore::MediaPlayerPrivate::seeking): 26 (WebCore::MediaPlayerPrivate::setRate): Seek to current time when rate is set. 27 (WebCore::MediaPlayerPrivate::maxTimeBuffered): Return if error occured. 28 (WebCore::MediaPlayerPrivate::maxTimeSeekable): Ditto. 29 (WebCore::MediaPlayerPrivate::maxTimeLoaded): Ditto. 30 (WebCore::MediaPlayerPrivate::bytesLoaded): 31 (WebCore::MediaPlayerPrivate::totalBytesKnown): 32 (WebCore::MediaPlayerPrivate::totalBytes): Ditto. 33 (WebCore::MediaPlayerPrivate::updateStates): Return if error occured, update 34 after seek ended with a successful change 35 (WebCore::MediaPlayerPrivate::didEnd): Do not pause the playbin when end is reached. 36 (WebCore::MediaPlayerPrivate::loadingFailed): Update network state with the given error. 37 (WebCore::mimeTypeCache): Gather supported mime types from GStreamer. 38 (WebCore::MediaPlayerPrivate::getSupportedTypes): 39 (WebCore::MediaPlayerPrivate::supportsType): 40 (WebCore::MediaPlayerPrivate::hasSingleSecurityOrigin): 41 (WebCore::MediaPlayerPrivate::supportsFullscreen): First step towards fullscreen 42 support. 43 (WebCore::MediaPlayerPrivate::createGSTPlayBin): Use playbin2 instead of playbin, 44 do not set playbin's audio sink. 45 * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: 46 * platform/graphics/gtk/VideoSinkGStreamer.cpp: 47 (webkit_video_sink_idle_func): Use C++ casts, decrease reference count of async 48 queue at the end of the idle function. 49 (webkit_video_sink_render): Increase reference count of async queue. 50 (webkit_video_sink_stop): Remove any idle functions with the sink as data. 51 1 52 2009-08-23 Chris Marrin <cmarrin@apple.com> 2 53 -
trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
r47515 r47710 57 57 58 58 gst_message_parse_error(message, &err.outPtr(), &debug.outPtr()); 59 if (err->code == 3) { 60 LOG_VERBOSE(Media, "File not found"); 61 MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data); 62 if (mp) 63 mp->loadingFailed(); 64 } else 65 LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message); 59 LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message); 60 61 MediaPlayer::NetworkState error = MediaPlayer::Empty; 62 if (err->domain == GST_CORE_ERROR || err->domain == GST_LIBRARY_ERROR) 63 error = MediaPlayer::DecodeError; 64 else if (err->domain == GST_RESOURCE_ERROR) 65 error = MediaPlayer::FormatError; 66 else if (err->domain == GST_STREAM_ERROR) 67 error = MediaPlayer::NetworkError; 68 69 MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data); 70 if (mp) 71 mp->loadingFailed(error); 66 72 } 67 73 return true; … … 112 118 registrar(create, getSupportedTypes, supportsType); 113 119 } 120 121 static bool gstInitialized = false; 114 122 115 123 MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) … … 120 128 , m_rate(1.0f) 121 129 , m_endTime(numeric_limits<float>::infinity()) 122 , m_isEndReached(false)123 130 , m_volume(0.5f) 124 131 , m_networkState(MediaPlayer::Empty) … … 128 135 , m_size(IntSize()) 129 136 , m_visible(true) 130 { 131 132 static bool gstInitialized = false; 137 , m_paused(true) 138 , m_seeking(false) 139 , m_errorOccured(false) 140 { 133 141 // FIXME: We should pass the arguments from the command line 134 142 if (!gstInitialized) { … … 171 179 { 172 180 LOG_VERBOSE(Media, "Play"); 173 // When end reached, rewind for Test video-seek-past-end-playing174 if (m_isEndReached)175 seek(0);176 m_isEndReached = false;177 178 181 gst_element_set_state(m_playBin, GST_STATE_PLAYING); 179 m_startedPlaying = true;180 182 } 181 183 … … 184 186 LOG_VERBOSE(Media, "Pause"); 185 187 gst_element_set_state(m_playBin, GST_STATE_PAUSED); 186 m_startedPlaying = false;187 188 } 188 189 … … 190 191 { 191 192 if (!m_playBin) 193 return 0.0; 194 195 if (m_errorOccured) 192 196 return 0.0; 193 197 … … 202 206 if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeLength <= 0) { 203 207 LOG_VERBOSE(Media, "Time duration query failed."); 204 m_isStreaming = true;205 208 return numeric_limits<float>::infinity(); 206 209 } … … 216 219 if (!m_playBin) 217 220 return 0; 218 // Necessary as sometimes, gstreamer return 0:00 at the EOS 219 if (m_ isEndReached)220 return m_endTime;221 222 float ret ;221 222 if (m_errorOccured) 223 return 0; 224 225 float ret = 0.0; 223 226 224 227 GstQuery* query = gst_query_new_position(GST_FORMAT_TIME); 225 if (gst_element_query(m_playBin, query)) { 226 gint64 position; 227 gst_query_parse_position(query, 0, &position); 228 ret = (float) (position / 1000000000.0); 229 LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position)); 230 } else { 228 if (!gst_element_query(m_playBin, query)) { 231 229 LOG_VERBOSE(Media, "Position query failed..."); 232 ret = 0.0; 233 } 230 gst_query_unref(query); 231 return ret; 232 } 233 234 gint64 position; 235 gst_query_parse_position(query, 0, &position); 236 ret = (float) (position / 1000000000.0); 237 LOG_VERBOSE(Media, "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position)); 238 234 239 gst_query_unref(query); 235 240 … … 247 252 return; 248 253 254 if (m_errorOccured) 255 return; 256 249 257 LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(sec)); 250 // FIXME: What happens when the seeked position is not available?251 258 if (!gst_element_seek( m_playBin, m_rate, 252 259 GST_FORMAT_TIME, … … 255 262 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) 256 263 LOG_VERBOSE(Media, "Seek to %f failed", time); 264 else 265 m_seeking = true; 257 266 } 258 267 259 268 void MediaPlayerPrivate::setEndTime(float time) 260 269 { 261 if (!m_playBin) 262 return; 263 if (m_isStreaming) 264 return; 265 if (m_endTime != time) { 266 m_endTime = time; 267 GstClockTime start = (GstClockTime)(currentTime() * GST_SECOND); 268 GstClockTime end = (GstClockTime)(time * GST_SECOND); 269 LOG_VERBOSE(Media, "setEndTime: %" GST_TIME_FORMAT, GST_TIME_ARGS(end)); 270 // FIXME: What happens when the seeked position is not available? 271 if (!gst_element_seek(m_playBin, m_rate, 272 GST_FORMAT_TIME, 273 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), 274 GST_SEEK_TYPE_SET, start, 275 GST_SEEK_TYPE_SET, end)) 276 LOG_VERBOSE(Media, "Seek to %f failed", time); 277 } 270 notImplemented(); 278 271 } 279 272 … … 295 288 bool MediaPlayerPrivate::paused() const 296 289 { 297 return !m_startedPlaying;290 return m_paused; 298 291 } 299 292 300 293 bool MediaPlayerPrivate::seeking() const 301 294 { 302 return false;295 return m_seeking; 303 296 } 304 297 … … 360 353 return; 361 354 } 355 362 356 if (m_isStreaming) 363 357 return; … … 365 359 m_rate = rate; 366 360 LOG_VERBOSE(Media, "Set Rate to %f", rate); 367 if (!gst_element_seek(m_playBin, rate, 368 GST_FORMAT_TIME, 369 (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE), 370 GST_SEEK_TYPE_SET, (GstClockTime) (currentTime() * GST_SECOND), 371 GST_SEEK_TYPE_SET, (GstClockTime) (m_endTime * GST_SECOND))) 372 LOG_VERBOSE(Media, "Set Rate to %f failed", rate); 361 seek(currentTime()); 373 362 } 374 363 … … 391 380 float MediaPlayerPrivate::maxTimeBuffered() const 392 381 { 393 notImplemented(); 394 LOG_VERBOSE(Media, "maxTimeBuffered"); 395 // rtsp streams are not buffered 382 if (m_errorOccured) 383 return 0.0; 396 384 return m_isStreaming ? 0 : maxTimeLoaded(); 397 385 } … … 399 387 float MediaPlayerPrivate::maxTimeSeekable() const 400 388 { 389 if (m_errorOccured) 390 return 0.0; 391 401 392 // TODO 402 393 LOG_VERBOSE(Media, "maxTimeSeekable"); … … 409 400 float MediaPlayerPrivate::maxTimeLoaded() const 410 401 { 402 if (m_errorOccured) 403 return 0.0; 404 411 405 // TODO 412 406 LOG_VERBOSE(Media, "maxTimeLoaded"); … … 425 419 if (!dur) 426 420 return 0;*/ 421 427 422 return 1;//totalBytes() * maxTime / dur; 428 423 } … … 430 425 bool MediaPlayerPrivate::totalBytesKnown() const 431 426 { 432 notImplemented();433 427 LOG_VERBOSE(Media, "totalBytesKnown"); 434 428 return totalBytes() > 0; … … 437 431 unsigned MediaPlayerPrivate::totalBytes() const 438 432 { 439 notImplemented();440 433 LOG_VERBOSE(Media, "totalBytes"); 441 if (!m_playBin)442 return 0;443 444 434 if (!m_source) 445 435 return 0; 446 436 447 // Do something with m_source to get the total bytes of the media 448 449 return 100; 437 if (m_errorOccured) 438 return 0; 439 440 GstFormat fmt = GST_FORMAT_BYTES; 441 gint64 length = 0; 442 gst_element_query_duration(m_source, &fmt, &length); 443 444 return length; 450 445 } 451 446 … … 460 455 // the state of GStreamer, therefore, when in PAUSED state, 461 456 // we are sure we can display the first frame and go to play 457 458 if (!m_playBin) 459 return; 460 461 if (m_errorOccured) 462 return; 462 463 463 464 MediaPlayer::NetworkState oldNetworkState = m_networkState; … … 466 467 GstState pending; 467 468 468 if (!m_playBin)469 return;470 471 469 GstStateChangeReturn ret = gst_element_get_state(m_playBin, 472 470 &state, &pending, 250 * GST_NSECOND); 473 471 472 bool shouldUpdateAfterSeek = false; 474 473 switch (ret) { 475 474 case GST_STATE_CHANGE_SUCCESS: … … 482 481 } else if (state == GST_STATE_PAUSED) 483 482 m_readyState = MediaPlayer::HaveEnoughData; 483 484 if (state == GST_STATE_PLAYING) 485 m_paused = false; 486 else 487 m_paused = true; 488 489 if (m_seeking) { 490 shouldUpdateAfterSeek = true; 491 m_seeking = false; 492 } 484 493 485 494 m_networkState = MediaPlayer::Loaded; … … 495 504 // Change in progress 496 505 return; 497 break; 506 case GST_STATE_CHANGE_FAILURE: 507 LOG_VERBOSE(Media, "Failure: State: %s, pending: %s", 508 gst_element_state_get_name(state), 509 gst_element_state_get_name(pending)); 510 // Change failed 511 return; 498 512 case GST_STATE_CHANGE_NO_PREROLL: 499 513 LOG_VERBOSE(Media, "No preroll: State: %s, pending: %s", 500 514 gst_element_state_get_name(state), 501 515 gst_element_state_get_name(pending)); 516 502 517 if (state == GST_STATE_READY) { 503 518 m_readyState = MediaPlayer::HaveFutureData; … … 515 530 m_readyState = MediaPlayer::HaveNothing; 516 531 532 if (shouldUpdateAfterSeek) 533 timeChanged(); 534 517 535 if (m_networkState != oldNetworkState) { 518 536 LOG_VERBOSE(Media, "Network State Changed from %u to %u", … … 555 573 void MediaPlayerPrivate::didEnd() 556 574 { 557 m_isEndReached = true;558 pause();559 575 timeChanged(); 560 576 } 561 577 562 void MediaPlayerPrivate::loadingFailed() 563 { 564 if (m_networkState != MediaPlayer::NetworkError) { 565 m_networkState = MediaPlayer::NetworkError; 578 void MediaPlayerPrivate::loadingFailed(MediaPlayer::NetworkState error) 579 { 580 m_errorOccured = true; 581 if (m_networkState != error) { 582 m_networkState = error; 566 583 m_player->networkStateChanged(); 567 584 } … … 607 624 } 608 625 626 static HashSet<String> mimeTypeCache() 627 { 628 if (!gstInitialized) { 629 gst_init(0, NULL); 630 gstInitialized = true; 631 } 632 633 static HashSet<String> cache; 634 static bool typeListInitialized = false; 635 636 if (!typeListInitialized) { 637 // These subtypes are already beeing supported by WebKit itself 638 HashSet<String> ignoredApplicationSubtypes; 639 ignoredApplicationSubtypes.add(String("javascript")); 640 ignoredApplicationSubtypes.add(String("ecmascript")); 641 ignoredApplicationSubtypes.add(String("x-javascript")); 642 ignoredApplicationSubtypes.add(String("xml")); 643 ignoredApplicationSubtypes.add(String("xhtml+xml")); 644 ignoredApplicationSubtypes.add(String("rss+xml")); 645 ignoredApplicationSubtypes.add(String("atom+xml")); 646 ignoredApplicationSubtypes.add(String("x-ftp-directory")); 647 ignoredApplicationSubtypes.add(String("x-java-applet")); 648 ignoredApplicationSubtypes.add(String("x-java-bean")); 649 ignoredApplicationSubtypes.add(String("x-java-vm")); 650 ignoredApplicationSubtypes.add(String("x-shockwave-flash")); 651 652 GList* factories = gst_type_find_factory_get_list(); 653 for (GList* iterator = factories; iterator; iterator = iterator->next) { 654 GstTypeFindFactory* factory = GST_TYPE_FIND_FACTORY(iterator->data); 655 GstCaps* caps = gst_type_find_factory_get_caps(factory); 656 657 // Splitting the capability by comma and taking the first part 658 // as capability can be something like "audio/x-wavpack, framed=(boolean)false" 659 GOwnPtr<gchar> capabilityString(gst_caps_to_string(caps)); 660 gchar** capability = g_strsplit(capabilityString.get(), ",", 2); 661 gchar** mimetype = g_strsplit(capability[0], "/", 2); 662 663 // GStreamer plugins can be capable of supporting types which WebKit supports 664 // by default. In that case, we should not consider these types supportable by GStreamer. 665 // Examples of what GStreamer can support but should not be added: 666 // text/plain, text/html, image/jpeg, application/xml 667 if (g_str_equal(mimetype[0], "audio") || 668 g_str_equal(mimetype[0], "video") || 669 (g_str_equal(mimetype[0], "application") && 670 !ignoredApplicationSubtypes.contains(String(mimetype[1])))) { 671 cache.add(String(capability[0])); 672 } 673 674 g_strfreev(capability); 675 g_strfreev(mimetype); 676 } 677 678 gst_plugin_feature_list_free(factories); 679 typeListInitialized = true; 680 } 681 682 return cache; 683 } 684 609 685 void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types) 610 686 { 611 // FIXME: query the engine to see what types are supported 612 notImplemented(); 613 types.add(String("video/x-theora+ogg")); 687 types = mimeTypeCache(); 614 688 } 615 689 616 690 MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs) 617 691 { 618 // FIXME: query the engine to see what types are supported 619 notImplemented(); 620 return type == "video/x-theora+ogg" ? (codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported; 692 if (mimeTypeCache().contains(type)) 693 return !codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported; 694 return MediaPlayer::IsNotSupported; 695 } 696 697 bool MediaPlayerPrivate::hasSingleSecurityOrigin() const 698 { 699 return true; 700 } 701 702 bool MediaPlayerPrivate::supportsFullscreen() const 703 { 704 return true; 621 705 } 622 706 … … 624 708 { 625 709 ASSERT(!m_playBin); 626 m_playBin = gst_element_factory_make("playbin ", "play");710 m_playBin = gst_element_factory_make("playbin2", "play"); 627 711 628 712 GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_playBin)); … … 636 720 g_object_set(G_OBJECT(m_playBin), "uri", url.utf8().data(), NULL); 637 721 638 GstElement* audioSink = gst_element_factory_make("gconfaudiosink", 0);639 722 m_videoSink = webkit_video_sink_new(m_surface); 640 641 g_object_set(m_playBin, "audio-sink", audioSink, NULL);642 723 g_object_set(m_playBin, "video-sink", m_videoSink, NULL); 643 724 -
trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
r47515 r47710 97 97 void volumeChanged(); 98 98 void didEnd(); 99 void loadingFailed( );99 void loadingFailed(MediaPlayer::NetworkState); 100 100 101 101 void repaint(); 102 102 void paint(GraphicsContext*, const IntRect&); 103 104 bool hasSingleSecurityOrigin() const; 105 106 bool supportsFullscreen() const; 103 107 104 108 private: … … 134 138 bool m_visible; 135 139 cairo_surface_t* m_surface; 140 141 bool m_paused; 142 bool m_seeking; 143 bool m_errorOccured; 136 144 }; 137 145 } -
trunk/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
r46587 r47710 103 103 webkit_video_sink_idle_func(gpointer data) 104 104 { 105 WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(data);105 WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data); 106 106 WebKitVideoSinkPrivate* priv = sink->priv; 107 107 GstBuffer* buffer; 108 109 108 if (!priv->async_queue) 110 109 return FALSE; … … 125 124 cairo_fill(cr); 126 125 cairo_destroy(cr); 127 128 126 gst_buffer_unref(buffer); 127 g_async_queue_unref(priv->async_queue); 129 128 130 129 g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0); … … 139 138 WebKitVideoSinkPrivate* priv = sink->priv; 140 139 140 g_async_queue_ref(priv->async_queue); 141 141 g_async_queue_push(priv->async_queue, gst_buffer_ref(buffer)); 142 142 g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, sink, 0); … … 266 266 g_async_queue_unlock(priv->async_queue); 267 267 268 g_idle_remove_by_data(base_sink); 269 268 270 return TRUE; 269 271 }
Note:
See TracChangeset
for help on using the changeset viewer.