Changeset 248721 in webkit
- Timestamp:
- Aug 15, 2019 10:17:52 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r248718 r248721 1 2019-08-15 Thibault Saunier <tsaunier@igalia.com> 2 3 [GStreamer] Deal with slow buffer consumption in GStreamerMediaStreamSource 4 https://bugs.webkit.org/show_bug.cgi?id=200633 5 6 Refactoring the GStreamerMediaStreamSource factoring out streams specific 7 data in a dedicated structure. 8 9 Reviewed by Philippe Normand. 10 11 No new tests, since I do not see how to reproduce that in a test in a simple way, 12 this aims at enhancing user experience when running under high load. 13 14 * platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp: 15 (WebCore::_WebKitMediaStreamSrc::SourceData::reset): 16 (WebCore::_WebKitMediaStreamSrc::SourceData::src): 17 (WebCore::_WebKitMediaStreamSrc::SourceData::setSrc): 18 (WebCore::_WebKitMediaStreamSrc::SourceData::isUsed): 19 (WebCore::_WebKitMediaStreamSrc::SourceData::pushSample): 20 (WebCore::webkitMediaStreamSrcDispose): 21 (WebCore::webkit_media_stream_src_init): 22 (WebCore::webkitMediaStreamSrcNeedDataCb): 23 (WebCore::webkitMediaStreamSrcEnoughDataCb): 24 (WebCore::webkitMediaStreamSrcSetupAppSrc): 25 (WebCore::webkitMediaStreamSrcRemoveTrackByType): 26 (WebCore::webkitMediaStreamSrcPushVideoSample): 27 (WebCore::webkitMediaStreamSrcPushAudioSample): 28 1 29 2019-08-15 Youenn Fablet <youenn@apple.com> 2 30 -
trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp
r246677 r248721 172 172 gchar* uri; 173 173 174 GstElement* audioSrc; 175 GstClockTime firstAudioBufferPts; 176 GstElement* videoSrc; 177 GstClockTime firstFramePts; 174 struct SourceData { 175 GRefPtr<GstElement> m_src; 176 void reset(bool isVideo) 177 { 178 m_firstBufferPts = GST_CLOCK_TIME_NONE; 179 m_isVideo = isVideo; 180 m_src = nullptr; 181 } 182 183 GstElement* src() 184 { 185 return m_src.get(); 186 } 187 188 static void needDataCb(GstElement*, guint, WebKitMediaStreamSrc::SourceData *self) 189 { 190 self->setEnoughData(false); 191 } 192 193 static void enoughDataCb(GstElement*, WebKitMediaStreamSrc::SourceData *self) 194 { 195 self->setEnoughData(true); 196 } 197 198 199 void setSrc(GstElement *src) 200 { 201 m_src = adoptGRef(GST_ELEMENT(g_object_ref_sink(src))); 202 if (GST_IS_APP_SRC(src)) { 203 g_object_set(src, "is-live", true, "format", GST_FORMAT_TIME, "emit-signals", TRUE, "min-percent", 100, nullptr); 204 g_signal_connect(src, "enough-data", G_CALLBACK(enoughDataCb), this); 205 g_signal_connect(src, "need-data", G_CALLBACK(needDataCb), this); 206 } 207 } 208 209 bool isUsed() 210 { 211 return !!m_src; 212 } 213 214 void setEnoughData(bool enough) 215 { 216 m_enoughData = enough; 217 } 218 219 void pushSample(GstSample *sample) 220 { 221 if (!m_src) 222 return; 223 224 bool drop = m_enoughData; 225 auto buffer = gst_sample_get_buffer(sample); 226 auto caps = gst_sample_get_caps(sample); 227 if (!GST_CLOCK_TIME_IS_VALID(m_firstBufferPts)) { 228 m_firstBufferPts = GST_BUFFER_PTS(buffer); 229 auto pad = adoptGRef(gst_element_get_static_pad(m_src.get(), "src")); 230 gst_pad_set_offset(pad.get(), -m_firstBufferPts); 231 } 232 233 if (m_isVideo && drop) { 234 drop = (gst_structure_has_name(gst_caps_get_structure(caps, 0), "video/x-raw") 235 || GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)); 236 } 237 238 if (drop) { 239 m_needsDiscont = true; 240 GST_INFO_OBJECT(m_src.get(), "%s queue full already... not pushing", m_isVideo ? "Video" : "Audio"); 241 return; 242 } 243 244 if (m_needsDiscont) { 245 GST_BUFFER_FLAG_SET(buffer, GST_BUFFER_FLAG_DISCONT); 246 m_needsDiscont = false; 247 } 248 249 gst_app_src_push_sample(GST_APP_SRC(m_src.get()), sample); 250 } 251 private: 252 GstClockTime m_firstBufferPts; 253 bool m_enoughData; 254 bool m_needsDiscont; 255 bool m_isVideo; 256 }; 257 258 SourceData audioSrc; 259 SourceData videoSrc; 178 260 179 261 std::unique_ptr<WebKitMediaStreamTrackObserver> mediaStreamTrackObserver; … … 275 357 WebKitMediaStreamSrc* self = WEBKIT_MEDIA_STREAM_SRC(object); 276 358 277 if (self->audioSrc ) {278 gst_bin_remove(GST_BIN(self), self->audioSrc );279 self->audioSrc = nullptr;280 } 281 282 if (self->videoSrc ) {283 gst_bin_remove(GST_BIN(self), self->videoSrc );284 self->videoSrc = nullptr;359 if (self->audioSrc.isUsed()) { 360 gst_bin_remove(GST_BIN(self), self->audioSrc.src()); 361 self->audioSrc.reset(false); 362 } 363 364 if (self->videoSrc.isUsed()) { 365 gst_bin_remove(GST_BIN(self), self->videoSrc.src()); 366 self->videoSrc.reset(true); 285 367 } 286 368 } … … 355 437 self->mediaStreamObserver = std::make_unique<WebKitMediaStreamObserver>(self); 356 438 self->flowCombiner = gst_flow_combiner_new(); 357 self-> firstAudioBufferPts = GST_CLOCK_TIME_NONE;358 self-> firstFramePts = GST_CLOCK_TIME_NONE;439 self->videoSrc.reset(true); 440 self->audioSrc.reset(false); 359 441 } 360 442 … … 468 550 469 551 static gboolean webkitMediaStreamSrcSetupAppSrc(WebKitMediaStreamSrc* self, 470 MediaStreamTrackPrivate* track, GstElement** element,552 MediaStreamTrackPrivate* track, WebKitMediaStreamSrc::SourceData* data, 471 553 GstStaticPadTemplate* pad_template, bool onlyTrack) 472 554 { 473 *element = gst_element_factory_make("appsrc", nullptr); 474 g_object_set(*element, "is-live", true, "format", GST_FORMAT_TIME, nullptr); 475 476 return webkitMediaStreamSrcSetupSrc(self, track, *element, pad_template, TRUE, onlyTrack); 555 data->setSrc(gst_element_factory_make("appsrc", nullptr)); 556 if (track->isCaptureTrack()) 557 g_object_set(data->src(), "do-timestamp", true, nullptr); 558 559 return webkitMediaStreamSrcSetupSrc(self, track, data->src(), pad_template, TRUE, onlyTrack); 477 560 } 478 561 … … 511 594 { 512 595 if (trackType == RealtimeMediaSource::Type::Audio) { 513 if (self->audioSrc ) {514 gst_element_set_state(self->audioSrc , GST_STATE_NULL);515 gst_bin_remove(GST_BIN(self), self->audioSrc );516 self->audioSrc = nullptr;596 if (self->audioSrc.isUsed()) { 597 gst_element_set_state(self->audioSrc.src(), GST_STATE_NULL); 598 gst_bin_remove(GST_BIN(self), self->audioSrc.src()); 599 self->audioSrc.reset(false); 517 600 } 518 601 } else if (trackType == RealtimeMediaSource::Type::Video) { 519 if (self->videoSrc ) {520 gst_element_set_state(self->videoSrc , GST_STATE_NULL);521 gst_bin_remove(GST_BIN(self), self->videoSrc );522 self->videoSrc = nullptr;602 if (self->videoSrc.isUsed()) { 603 gst_element_set_state(self->videoSrc.src(), GST_STATE_NULL); 604 gst_bin_remove(GST_BIN(self), self->videoSrc.src()); 605 self->videoSrc.reset(true); 523 606 } 524 607 } else … … 545 628 static void webkitMediaStreamSrcPushVideoSample(WebKitMediaStreamSrc* self, GstSample* gstsample) 546 629 { 547 if (self->videoSrc) { 548 if (!GST_CLOCK_TIME_IS_VALID(self->firstFramePts)) { 549 auto buffer = gst_sample_get_buffer(gstsample); 550 551 self->firstFramePts = GST_BUFFER_PTS(buffer); 552 auto pad = adoptGRef(gst_element_get_static_pad(self->videoSrc, "src")); 553 gst_pad_set_offset(pad.get(), -self->firstFramePts); 554 } 555 556 gst_app_src_push_sample(GST_APP_SRC(self->videoSrc), gstsample); 557 } 630 self->videoSrc.pushSample(gstsample); 558 631 } 559 632 560 633 static void webkitMediaStreamSrcPushAudioSample(WebKitMediaStreamSrc* self, GstSample* gstsample) 561 634 { 562 if (self->audioSrc) { 563 if (!GST_CLOCK_TIME_IS_VALID(self->firstAudioBufferPts)) { 564 auto buffer = gst_sample_get_buffer(gstsample); 565 566 self->firstAudioBufferPts = GST_BUFFER_PTS(buffer); 567 auto pad = adoptGRef(gst_element_get_static_pad(self->audioSrc, "src")); 568 gst_pad_set_offset(pad.get(), -self->firstAudioBufferPts); 569 } 570 gst_app_src_push_sample(GST_APP_SRC(self->audioSrc), gstsample); 571 } 635 self->audioSrc.pushSample(gstsample); 572 636 } 573 637
Note: See TracChangeset
for help on using the changeset viewer.