Changeset 175928 in webkit
- Timestamp:
- Nov 11, 2014, 8:13:22 AM (12 years ago)
- Location:
- releases/WebKitGTK/webkit-2.6/Source/WebCore
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
platform/graphics/gstreamer/ImageGStreamer.h (modified) (2 diffs)
-
platform/graphics/gstreamer/ImageGStreamerCairo.cpp (modified) (2 diffs)
-
platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp (modified) (11 diffs)
-
platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h (modified) (4 diffs)
-
platform/graphics/gstreamer/VideoSinkGStreamer.cpp (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog
r175926 r175928 1 2014-10-24 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] Video resolution changes trigger a crash in the TextureMapper 4 https://bugs.webkit.org/show_bug.cgi?id=137065 5 6 Reviewed by Gustavo Noronha Silva. 7 8 Switch to GstSample for buffer+caps communication between the 9 video sink and the player. Using a single object type for this 10 avoid issues where the caps might not correctly describe the 11 buffer contents anymore, for example when the video resolution is 12 changed. 13 14 * platform/graphics/gstreamer/ImageGStreamer.h: Use GstSample 15 instead of GstBuffer+GstCaps. 16 (WebCore::ImageGStreamer::createImage): 17 * platform/graphics/gstreamer/ImageGStreamerCairo.cpp: Ditto. 18 (ImageGStreamer::ImageGStreamer): 19 * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp: 20 (WebCore::mediaPlayerPrivateRepaintCallback): The repaint signal 21 now uses a GstSample instead of a GstBuffer. 22 (WebCore::MediaPlayerPrivateGStreamerBase::MediaPlayerPrivateGStreamerBase): 23 Store the current sample instead of a buffer. Also renamed the 24 mutex protecting access to the sample. 25 (WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase): Ditto. 26 (WebCore::MediaPlayerPrivateGStreamerBase::naturalSize): Return 27 early if no sample is available. The caps used to get the video 28 size are store in the sample. 29 (WebCore::MediaPlayerPrivateGStreamerBase::updateTexture): Use 30 GstSample instead of GstBuffer. 31 (WebCore::MediaPlayerPrivateGStreamerBase::triggerRepaint): Ditto. 32 (WebCore::MediaPlayerPrivateGStreamerBase::paint): Ditto. 33 * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h: 34 * platform/graphics/gstreamer/VideoSinkGStreamer.cpp: Now store a 35 GstSample internally. Also removed the now useless current-caps property. 36 (_WebKitVideoSinkPrivate::_WebKitVideoSinkPrivate): Renamed the 37 mutex protecting access to the sample. 38 (_WebKitVideoSinkPrivate::~_WebKitVideoSinkPrivate): Ditto. 39 (webkit_video_sink_init): Disable last-sample in basesink since we 40 already store one in our sink anyway. 41 (webkitVideoSinkTimeoutCallback): Switch to GstSample. 42 (webkitVideoSinkRender): Ditto. 43 (unlockSampleMutex): Ditto. 44 (webkitVideoSinkUnlock): Ditto. 45 (webkitVideoSinkUnlockStop): Ditto. 46 (webkitVideoSinkStop): Ditto! 47 (webkitVideoSinkStart): Ditto. 48 (webkit_video_sink_class_init): Drop current-caps property. 49 (webkitVideoSinkGetProperty): Deleted. 50 (unlockBufferMutex): Deleted. 51 1 52 2014-10-29 Said Abou-Hallawa <sabouhallawa@apple.com> 2 53 -
releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
r168060 r175928 39 39 class ImageGStreamer : public RefCounted<ImageGStreamer> { 40 40 public: 41 static PassRefPtr<ImageGStreamer> createImage(Gst Buffer* buffer, GstCaps* caps)41 static PassRefPtr<ImageGStreamer> createImage(GstSample* sample) 42 42 { 43 return adoptRef(new ImageGStreamer( buffer, caps));43 return adoptRef(new ImageGStreamer(sample)); 44 44 } 45 45 ~ImageGStreamer(); … … 61 61 62 62 private: 63 ImageGStreamer(Gst Buffer*, GstCaps*);63 ImageGStreamer(GstSample*); 64 64 RefPtr<BitmapImage> m_image; 65 65 FloatRect m_cropRect; -
releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
r168060 r175928 33 33 using namespace WebCore; 34 34 35 ImageGStreamer::ImageGStreamer(Gst Buffer* buffer, GstCaps* caps)35 ImageGStreamer::ImageGStreamer(GstSample* sample) 36 36 { 37 GstCaps* caps = gst_sample_get_caps(sample); 37 38 GstVideoInfo videoInfo; 38 39 gst_video_info_init(&videoInfo); … … 43 44 ASSERT(GST_VIDEO_INFO_N_PLANES(&videoInfo) == 1); 44 45 46 GstBuffer* buffer = gst_sample_get_buffer(sample); 45 47 if (!gst_video_frame_map(&m_videoFrame, &videoInfo, buffer, GST_MAP_READ)) 46 48 return; -
releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
r174638 r175928 80 80 } 81 81 82 static void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, Gst Buffer *buffer, MediaPlayerPrivateGStreamerBase* playerPrivate)83 { 84 playerPrivate->triggerRepaint( buffer);82 static void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstSample* sample, MediaPlayerPrivateGStreamerBase* playerPrivate) 83 { 84 playerPrivate->triggerRepaint(sample); 85 85 } 86 86 … … 90 90 , m_readyState(MediaPlayer::HaveNothing) 91 91 , m_networkState(MediaPlayer::Empty) 92 , m_ buffer(0)92 , m_sample(0) 93 93 , m_repaintHandler(0) 94 94 , m_volumeSignalHandler(0) 95 95 , m_muteSignalHandler(0) 96 96 { 97 g_mutex_init(&m_ bufferMutex);97 g_mutex_init(&m_sampleMutex); 98 98 } 99 99 … … 105 105 } 106 106 107 g_mutex_clear(&m_ bufferMutex);108 109 if (m_ buffer)110 gst_ buffer_unref(m_buffer);111 m_ buffer= 0;107 g_mutex_clear(&m_sampleMutex); 108 109 if (m_sample) 110 gst_sample_unref(m_sample); 111 m_sample = 0; 112 112 113 113 m_player = 0; … … 138 138 return m_videoSize; 139 139 140 GRefPtr<GstCaps> caps = currentVideoSinkCaps(); 140 GMutexLocker<GMutex> lock(m_sampleMutex); 141 if (!m_sample) 142 return IntSize(); 143 144 GstCaps* caps = gst_sample_get_caps(m_sample); 141 145 if (!caps) 142 146 return IntSize(); … … 153 157 IntSize originalSize; 154 158 GstVideoFormat format; 155 if (!getVideoSizeAndFormatFromCaps(caps .get(), originalSize, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride))159 if (!getVideoSizeAndFormatFromCaps(caps, originalSize, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride)) 156 160 return IntSize(); 157 161 … … 276 280 PassRefPtr<BitmapTexture> MediaPlayerPrivateGStreamerBase::updateTexture(TextureMapper* textureMapper) 277 281 { 278 GMutexLocker<GMutex> lock(m_ bufferMutex);279 if (!m_ buffer)282 GMutexLocker<GMutex> lock(m_sampleMutex); 283 if (!m_sample) 280 284 return nullptr; 281 285 282 G RefPtr<GstCaps> caps = currentVideoSinkCaps();286 GstCaps* caps = gst_sample_get_caps(m_sample); 283 287 if (!caps) 284 288 return nullptr; … … 286 290 GstVideoInfo videoInfo; 287 291 gst_video_info_init(&videoInfo); 288 if (!gst_video_info_from_caps(&videoInfo, caps .get()))292 if (!gst_video_info_from_caps(&videoInfo, caps)) 289 293 return nullptr; 290 294 291 295 IntSize size = IntSize(GST_VIDEO_INFO_WIDTH(&videoInfo), GST_VIDEO_INFO_HEIGHT(&videoInfo)); 292 296 RefPtr<BitmapTexture> texture = textureMapper->acquireTextureFromPool(size, GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? BitmapTexture::SupportsAlpha : BitmapTexture::NoFlag); 297 GstBuffer* buffer = gst_sample_get_buffer(m_sample); 293 298 294 299 #if GST_CHECK_VERSION(1, 1, 0) 295 300 GstVideoGLTextureUploadMeta* meta; 296 if ((meta = gst_buffer_get_video_gl_texture_upload_meta( m_buffer))) {301 if ((meta = gst_buffer_get_video_gl_texture_upload_meta(buffer))) { 297 302 if (meta->n_textures == 1) { // BRGx & BGRA formats use only one texture. 298 303 const BitmapTextureGL* textureGL = static_cast<const BitmapTextureGL*>(texture.get()); … … 309 314 310 315 GstVideoFrame videoFrame; 311 if (!gst_video_frame_map(&videoFrame, &videoInfo, m_buffer, GST_MAP_READ))316 if (!gst_video_frame_map(&videoFrame, &videoInfo, buffer, GST_MAP_READ)) 312 317 return nullptr; 313 318 … … 321 326 #endif 322 327 323 void MediaPlayerPrivateGStreamerBase::triggerRepaint(Gst Buffer* buffer)324 { 325 g_return_if_fail(GST_IS_ BUFFER(buffer));328 void MediaPlayerPrivateGStreamerBase::triggerRepaint(GstSample* sample) 329 { 330 g_return_if_fail(GST_IS_SAMPLE(sample)); 326 331 327 332 { 328 GMutexLocker<GMutex> lock(m_bufferMutex); 329 gst_buffer_replace(&m_buffer, buffer); 333 GMutexLocker<GMutex> lock(m_sampleMutex); 334 if (m_sample) 335 gst_sample_unref(m_sample); 336 m_sample = gst_sample_ref(sample); 330 337 } 331 338 … … 358 365 return; 359 366 360 GMutexLocker<GMutex> lock(m_bufferMutex); 361 if (!m_buffer) 362 return; 363 364 GRefPtr<GstCaps> caps = currentVideoSinkCaps(); 365 if (!caps) 366 return; 367 368 RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_buffer, caps.get()); 367 GMutexLocker<GMutex> lock(m_sampleMutex); 368 if (!m_sample) 369 return; 370 371 RefPtr<ImageGStreamer> gstImage = ImageGStreamer::createImage(m_sample); 369 372 if (!gstImage) 370 373 return; … … 408 411 409 412 return MediaPlayer::Download; 410 }411 412 GRefPtr<GstCaps> MediaPlayerPrivateGStreamerBase::currentVideoSinkCaps() const413 {414 if (!m_webkitVideoSink)415 return nullptr;416 417 GRefPtr<GstCaps> currentCaps;418 g_object_get(G_OBJECT(m_webkitVideoSink.get()), "current-caps", ¤tCaps.outPtr(), NULL);419 return currentCaps;420 413 } 421 414 -
releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h
r174638 r175928 37 37 #endif 38 38 39 typedef struct _Gst Buffer GstBuffer;39 typedef struct _GstSample GstSample; 40 40 typedef struct _GstElement GstElement; 41 41 typedef struct _GstMessage GstMessage; … … 78 78 void sizeChanged(); 79 79 80 void triggerRepaint(Gst Buffer*);80 void triggerRepaint(GstSample*); 81 81 void paint(GraphicsContext*, const IntRect&); 82 82 … … 111 111 MediaPlayerPrivateGStreamerBase(MediaPlayer*); 112 112 virtual GstElement* createVideoSink(); 113 GRefPtr<GstCaps> currentVideoSinkCaps() const;114 113 115 114 void setStreamVolumeElement(GstStreamVolume*); … … 124 123 MediaPlayer::NetworkState m_networkState; 125 124 IntSize m_size; 126 GMutex m_bufferMutex;127 Gst Buffer* m_buffer;125 mutable GMutex m_sampleMutex; 126 GstSample* m_sample; 128 127 GThreadSafeMainLoopSource m_volumeTimerHandler; 129 128 GThreadSafeMainLoopSource m_muteTimerHandler; -
releases/WebKitGTK/webkit-2.6/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
r174638 r175928 67 67 }; 68 68 69 enum {70 PROP_0,71 PROP_CAPS72 };73 74 69 static guint webkitVideoSinkSignals[LAST_SIGNAL] = { 0, }; 75 70 … … 77 72 _WebKitVideoSinkPrivate() 78 73 { 79 g_mutex_init(& bufferMutex);74 g_mutex_init(&sampleMutex); 80 75 g_cond_init(&dataCondition); 81 76 gst_video_info_init(&info); … … 84 79 ~_WebKitVideoSinkPrivate() 85 80 { 86 g_mutex_clear(& bufferMutex);81 g_mutex_clear(&sampleMutex); 87 82 g_cond_clear(&dataCondition); 88 83 } 89 84 90 Gst Buffer* buffer;85 GstSample* sample; 91 86 GThreadSafeMainLoopSource timeoutSource; 92 GMutex bufferMutex;87 GMutex sampleMutex; 93 88 GCond dataCondition; 94 89 … … 104 99 // to deadlocks because render() holds the stream lock. 105 100 // 106 // Protected by the buffermutex101 // Protected by the sample mutex 107 102 bool unlocked; 108 103 }; … … 115 110 { 116 111 sink->priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate); 112 g_object_set(GST_BASE_SINK(sink), "enable-last-sample", FALSE, NULL); 117 113 new (sink->priv) WebKitVideoSinkPrivate(); 118 114 } … … 122 118 WebKitVideoSinkPrivate* priv = sink->priv; 123 119 124 GMutexLocker<GMutex> lock(priv-> bufferMutex);125 Gst Buffer* buffer = priv->buffer;126 priv-> buffer= 0;127 128 if (! buffer || priv->unlocked || UNLIKELY(!GST_IS_BUFFER(buffer))) {120 GMutexLocker<GMutex> lock(priv->sampleMutex); 121 GstSample* sample = priv->sample; 122 priv->sample = 0; 123 124 if (!sample || priv->unlocked || UNLIKELY(!GST_IS_SAMPLE(sample))) { 129 125 g_cond_signal(&priv->dataCondition); 130 126 return; 131 127 } 132 128 133 g_signal_emit(sink, webkitVideoSinkSignals[REPAINT_REQUESTED], 0, buffer);134 gst_ buffer_unref(buffer);129 g_signal_emit(sink, webkitVideoSinkSignals[REPAINT_REQUESTED], 0, sample); 130 gst_sample_unref(sample); 135 131 g_cond_signal(&priv->dataCondition); 136 132 } … … 141 137 WebKitVideoSinkPrivate* priv = sink->priv; 142 138 143 GMutexLocker<GMutex> lock(priv-> bufferMutex);139 GMutexLocker<GMutex> lock(priv->sampleMutex); 144 140 145 141 if (priv->unlocked) 146 142 return GST_FLOW_OK; 147 143 148 priv-> buffer = gst_buffer_ref(buffer);144 priv->sample = gst_sample_new(buffer, priv->currentCaps, 0, 0); 149 145 150 146 // The video info structure is valid only if the sink handled an allocation query. 151 147 GstVideoFormat format = GST_VIDEO_INFO_FORMAT(&priv->info); 152 148 if (format == GST_VIDEO_FORMAT_UNKNOWN) { 153 gst_ buffer_unref(buffer);149 gst_sample_unref(priv->sample); 154 150 return GST_FLOW_ERROR; 155 151 } … … 180 176 181 177 if (!gst_video_frame_map(&sourceFrame, &priv->info, buffer, GST_MAP_READ)) { 182 gst_ buffer_unref(buffer);178 gst_sample_unref(priv->sample); 183 179 gst_buffer_unref(newBuffer); 184 180 return GST_FLOW_ERROR; … … 186 182 if (!gst_video_frame_map(&destinationFrame, &priv->info, newBuffer, GST_MAP_WRITE)) { 187 183 gst_video_frame_unmap(&sourceFrame); 188 gst_buffer_unref(buffer);189 184 gst_buffer_unref(newBuffer); 190 185 return GST_FLOW_ERROR; … … 216 211 gst_video_frame_unmap(&sourceFrame); 217 212 gst_video_frame_unmap(&destinationFrame); 218 gst_ buffer_unref(buffer);219 buffer = priv->buffer = newBuffer;213 gst_sample_unref(priv->sample); 214 priv->sample = gst_sample_new(newBuffer, priv->currentCaps, 0, 0); 220 215 } 221 216 #endif … … 228 223 [sink] { gst_object_unref(sink); }); 229 224 230 g_cond_wait(&priv->dataCondition, &priv-> bufferMutex);225 g_cond_wait(&priv->dataCondition, &priv->sampleMutex); 231 226 return GST_FLOW_OK; 232 227 } … … 238 233 } 239 234 240 static void webkitVideoSinkGetProperty(GObject* object, guint propertyId, GValue* value, GParamSpec* parameterSpec) 241 { 242 WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object); 243 WebKitVideoSinkPrivate* priv = sink->priv; 244 245 switch (propertyId) { 246 case PROP_CAPS: { 247 GstCaps* caps = priv->currentCaps; 248 if (caps) 249 gst_caps_ref(caps); 250 g_value_take_boxed(value, caps); 251 break; 252 } 253 default: 254 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, parameterSpec); 255 } 256 } 257 258 static void unlockBufferMutex(WebKitVideoSinkPrivate* priv) 259 { 260 GMutexLocker<GMutex> lock(priv->bufferMutex); 261 262 if (priv->buffer) { 263 gst_buffer_unref(priv->buffer); 264 priv->buffer = 0; 235 static void unlockSampleMutex(WebKitVideoSinkPrivate* priv) 236 { 237 GMutexLocker<GMutex> lock(priv->sampleMutex); 238 239 if (priv->sample) { 240 gst_sample_unref(priv->sample); 241 priv->sample = 0; 265 242 } 266 243 … … 274 251 WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(baseSink); 275 252 276 unlock BufferMutex(sink->priv);253 unlockSampleMutex(sink->priv); 277 254 278 255 return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock, (baseSink), TRUE); … … 284 261 285 262 { 286 GMutexLocker<GMutex> lock(priv-> bufferMutex);263 GMutexLocker<GMutex> lock(priv->sampleMutex); 287 264 priv->unlocked = false; 288 265 } … … 295 272 WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv; 296 273 297 unlock BufferMutex(priv);274 unlockSampleMutex(priv); 298 275 299 276 if (priv->currentCaps) { … … 309 286 WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(baseSink)->priv; 310 287 311 GMutexLocker<GMutex> lock(priv-> bufferMutex);288 GMutexLocker<GMutex> lock(priv->sampleMutex); 312 289 priv->unlocked = false; 313 290 return TRUE; … … 364 341 365 342 gobjectClass->finalize = webkitVideoSinkFinalize; 366 gobjectClass->get_property = webkitVideoSinkGetProperty;367 343 368 344 baseSinkClass->unlock = webkitVideoSinkUnlock; … … 374 350 baseSinkClass->set_caps = webkitVideoSinkSetCaps; 375 351 baseSinkClass->propose_allocation = webkitVideoSinkProposeAllocation; 376 377 g_object_class_install_property(gobjectClass, PROP_CAPS,378 g_param_spec_boxed("current-caps", "Current-Caps", "Current caps", GST_TYPE_CAPS, G_PARAM_READABLE));379 352 380 353 webkitVideoSinkSignals[REPAINT_REQUESTED] = g_signal_new("repaint-requested", … … 387 360 G_TYPE_NONE, // Return type 388 361 1, // Only one parameter 389 GST_TYPE_ BUFFER);362 GST_TYPE_SAMPLE); 390 363 } 391 364
Note:
See TracChangeset
for help on using the changeset viewer.