Changeset 139877 in webkit
- Timestamp:
- Jan 16, 2013 6:15:58 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r139876 r139877 1 2013-01-15 Gustavo Noronha Silva <gustavo.noronha@collabora.com> 2 3 [GStreamer][Soup] Let GStreamer provide the buffer data is downloaded to, to avoid copying 4 https://bugs.webkit.org/show_bug.cgi?id=105552 5 6 Reviewed by Philippe Normand. 7 8 Makes it possible for the GStreamer media backend to provide the buffer to which 9 the Soup networking backend will use to download data to. This makes copying 10 memory unnecessary when ResourceHandle hands data over to the media player's 11 StreamingClient. Thanks to Dan Winship for help designing the interface. 12 13 No behaviour change, covered by existing tests. 14 15 * platform/graphics/gstreamer/GStreamerVersioning.cpp: 16 (getGstBufferSize): Abstract obtaining the size of the buffer, so the code 17 is cleaner while still working for both GST 0.10 and 1.0. 18 (setGstBufferSize): Ditto, but for setting the size. 19 (getGstBufferDataPointer): Ditto, but for grabbing the data pointer. 20 (mapGstBuffer): Convenience method to take care of mapping the buffer so that 21 we can provide the data pointer to ResourceHandle. 22 (unmapGstBuffer): Convenience method which takes care of unmapping the buffer 23 and properly freeing the GstMapInfo. 24 * platform/graphics/gstreamer/GStreamerVersioning.h: 25 * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp: 26 (StreamingClient): New methods. 27 (_WebKitWebSrcPrivate): We now store the GstBuffer we provided the data pointer from 28 so we can later unmap it and push it to the pipeline. 29 (webKitWebSrcDispose): Deal with the GstBuffer in case it exists when the source is 30 destroyed. 31 (webKitWebSrcStop): Also clear the GstBuffer in this case. 32 (StreamingClient::didReceiveData): Handle the hand-over of the buffer. 33 (StreamingClient::getBuffer): Provide ResourceHandle with a new GstBuffer's data pointer. 34 * platform/network/ResourceHandleClient.h: 35 (ResourceHandleClient): 36 (WebCore::ResourceHandleClient::ResourceHandleClient): Constructor to initialize the buffer 37 member variable to 0. 38 (WebCore::ResourceHandleClient::~ResourceHandleClient): Destructor to free the buffer if it 39 has been allocated. 40 (WebCore::ResourceHandleClient::getBuffer): Default implementation which returns a 41 newly allocated char pointer. 42 * platform/network/ResourceHandleInternal.h: 43 (WebCore::ResourceHandleInternal::ResourceHandleInternal): 44 (ResourceHandleInternal): Store actual buffer size, which is no longer a constant. 45 * platform/network/soup/ResourceHandleSoup.cpp: 46 (WebCore::cleanupSoupRequestOperation): Clear the buffer pointer, the life-cycle of the 47 buffer is handled by the ResourceHandleClient. 48 (WebCore::nextMultipartResponsePartCallback): Get a new buffer from the client before reading. 49 (WebCore::sendRequestCallback): Ditto. 50 (WebCore::readCallback): Ditto. 51 1 52 2013-01-16 Jocelyn Turcotte <jocelyn.turcotte@digia.com> 2 53 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
r138919 r139877 1 1 /* 2 2 * Copyright (C) 2012 Igalia, S.L. 3 * Copyright (C) 2013 Collabora Ltd. 3 4 * 4 5 * This library is free software; you can redistribute it and/or … … 32 33 #endif 33 34 35 #ifdef GST_API_VERSION_1 36 const char* webkitGstMapInfoQuarkString = "webkit-gst-map-info"; 37 #endif 38 34 39 void webkitGstObjectRefSink(GstObject* gstObject) 35 40 { … … 122 127 } 123 128 129 int getGstBufferSize(GstBuffer* buffer) 130 { 131 #ifdef GST_API_VERSION_1 132 return gst_buffer_get_size(buffer); 133 #else 134 return GST_BUFFER_SIZE(buffer); 135 #endif 136 } 137 138 void setGstBufferSize(GstBuffer* buffer, int newSize) 139 { 140 #ifdef GST_API_VERSION_1 141 gst_buffer_set_size(buffer, static_cast<gssize>(newSize)); 142 #else 143 GST_BUFFER_SIZE(buffer) = static_cast<gsize>(newSize); 144 #endif 145 } 146 147 char* getGstBufferDataPointer(GstBuffer* buffer) 148 { 149 #ifdef GST_API_VERSION_1 150 static char* webkitGstMapInfoQuarkString = "webkit-gst-map-info"; 151 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 152 GstMapInfo* mapInfo = static_cast<GstMapInfo*>(gst_mini_object_get_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString))); 153 return reinterpret_cast<char*>(mapInfo->data); 154 #else 155 return reinterpret_cast<char*>(GST_BUFFER_DATA(buffer)); 156 #endif 157 } 158 159 #ifdef GST_API_VERSION_1 160 void mapGstBuffer(GstBuffer* buffer) 161 { 162 GstMapInfo* mapInfo = g_slice_new(GstMapInfo); 163 if (!gst_buffer_map(buffer, mapInfo, GST_MAP_WRITE)) { 164 g_slice_free(GstMapInfo, mapInfo); 165 gst_buffer_unref(buffer); 166 return; 167 } 168 169 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 170 gst_mini_object_set_qdata(miniObject, g_quark_from_static_string("webkit-gst-map-info"), mapInfo, 0); 171 } 172 173 void unmapGstBuffer(GstBuffer* buffer) 174 { 175 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 176 GstMapInfo* mapInfo = static_cast<GstMapInfo*>(gst_mini_object_steal_qdata(miniObject, g_quark_from_static_string("webkit-gst-map-info"))); 177 178 if (!mapInfo) 179 return; 180 181 gst_buffer_unmap(buffer, mapInfo); 182 g_slice_free(GstMapInfo, mapInfo); 183 } 184 #endif 185 124 186 void setGstElementClassMetadata(GstElementClass* elementClass, const char* name, const char* longName, const char* description, const char* author) 125 187 { -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
r138786 r139877 37 37 #endif 38 38 GstBuffer* createGstBuffer(GstBuffer*); 39 int getGstBufferSize(GstBuffer*); 40 void setGstBufferSize(GstBuffer*, int newSize); 41 char* getGstBufferDataPointer(GstBuffer*); 42 #ifdef GST_API_VERSION_1 43 void mapGstBuffer(GstBuffer*); 44 void unmapGstBuffer(GstBuffer*); 45 #endif 39 46 void setGstElementClassMetadata(GstElementClass*, const char* name, const char* longName, const char* description, const char* author); 40 47 bool gstObjectIsFloating(GstObject*); -
trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
r135705 r139877 1 1 /* 2 2 * Copyright (C) 2009, 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk> 3 * Copyright (C) 2013 Collabora Ltd. 3 4 * 4 5 * This library is free software; you can redistribute it and/or … … 33 34 #include "ResourceRequest.h" 34 35 #include "ResourceResponse.h" 35 36 36 #include <gst/app/gstappsrc.h> 37 #include <gst/gst.h> 37 38 #include <gst/pbutils/missing-plugins.h> 38 39 39 #include <wtf/Noncopyable.h> 40 40 #include <wtf/gobject/GOwnPtr.h> … … 52 52 virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse&); 53 53 virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); 54 55 virtual char* getBuffer(int, int*); 56 54 57 virtual void didReceiveData(ResourceHandle*, const char*, int, int); 55 58 virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); … … 84 87 guint enoughDataID; 85 88 guint seekID; 89 90 GstBuffer* buffer; 86 91 87 92 // icecast stuff … … 116 121 static void webKitWebSrcUriHandlerInit(gpointer gIface, gpointer ifaceData); 117 122 123 static void webKitWebSrcDispose(GObject*); 118 124 static void webKitWebSrcFinalize(GObject*); 119 125 static void webKitWebSrcSetProperty(GObject*, guint propertyID, const GValue*, GParamSpec*); … … 151 157 GstElementClass* eklass = GST_ELEMENT_CLASS(klass); 152 158 159 oklass->dispose = webKitWebSrcDispose; 153 160 oklass->finalize = webKitWebSrcFinalize; 154 161 oklass->set_property = webKitWebSrcSetProperty; … … 275 282 } 276 283 284 static void webKitWebSrcDispose(GObject* object) 285 { 286 WebKitWebSrc* src = WEBKIT_WEB_SRC(object); 287 WebKitWebSrcPrivate* priv = src->priv; 288 289 if (priv->buffer) { 290 #ifdef GST_API_VERSION_1 291 unmapGstBuffer(priv->buffer); 292 #endif 293 gst_object_unref(priv->buffer); 294 priv->buffer = 0; 295 } 296 297 GST_CALL_PARENT(G_OBJECT_CLASS, dispose, (object)); 298 } 299 277 300 static void webKitWebSrcFinalize(GObject* object) 278 301 { … … 284 307 g_free(priv->uri); 285 308 286 GST_CALL_PARENT(G_OBJECT_CLASS, finalize, ( (GObject* )(src)));309 GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object)); 287 310 } 288 311 … … 354 377 355 378 priv->player = 0; 379 380 if (priv->buffer) { 381 #ifdef GST_API_VERSION_1 382 unmapGstBuffer(priv->buffer); 383 #endif 384 gst_object_unref(priv->buffer); 385 priv->buffer = 0; 386 } 356 387 357 388 GST_OBJECT_LOCK(src); … … 857 888 WebKitWebSrcPrivate* priv = m_src->priv; 858 889 859 GST_LOG_OBJECT(m_src, "Have %d bytes of data", length); 890 ASSERT(priv->buffer); 891 ASSERT(data == getGstBufferDataPointer(priv->buffer)); 892 893 GST_LOG_OBJECT(m_src, "Have %d bytes of data", getGstBufferSize(priv->buffer)); 894 895 #ifdef GST_API_VERSION_1 896 unmapGstBuffer(priv->buffer); 897 #endif 860 898 861 899 if (priv->seekID || handle != priv->resourceHandle) { 862 900 GST_DEBUG_OBJECT(m_src, "Seek in progress, ignoring data"); 901 gst_buffer_unref(priv->buffer); 902 priv->buffer = 0; 863 903 return; 864 904 } 865 905 866 GstBuffer* buffer = gst_buffer_new_and_alloc(length); 867 868 #ifdef GST_API_VERSION_1 869 gst_buffer_fill(buffer, 0, data, length); 870 #else 871 memcpy(GST_BUFFER_DATA(buffer), data, length); 872 #endif 873 GST_BUFFER_OFFSET(buffer) = priv->offset; 906 // We need to update the buffer's knowledge of how much data it carries. 907 setGstBufferSize(priv->buffer, length); 908 909 GST_BUFFER_OFFSET(priv->buffer) = priv->offset; 874 910 priv->offset += length; 875 GST_BUFFER_OFFSET_END( buffer) = priv->offset;876 877 GstFlowReturn ret = gst_app_src_push_buffer(priv->appsrc, buffer);911 GST_BUFFER_OFFSET_END(priv->buffer) = priv->offset; 912 913 GstFlowReturn ret = gst_app_src_push_buffer(priv->appsrc, priv->buffer); 878 914 #ifdef GST_API_VERSION_1 879 915 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS) … … 882 918 #endif 883 919 GST_ELEMENT_ERROR(m_src, CORE, FAILED, (0), (0)); 920 921 priv->buffer = 0; 922 } 923 924 char* StreamingClient::getBuffer(int requestedSize, int* actualSize) 925 { 926 WebKitWebSrcPrivate* priv = m_src->priv; 927 928 ASSERT(!priv->buffer); 929 930 GstBuffer* buffer = gst_buffer_new_and_alloc(requestedSize); 931 932 #ifdef GST_API_VERSION_1 933 mapGstBuffer(buffer); 934 #endif 935 936 priv->buffer = buffer; 937 938 *actualSize = getGstBufferSize(buffer); 939 return getGstBufferDataPointer(buffer); 884 940 } 885 941 -
trunk/Source/WebCore/platform/network/ResourceHandleClient.h
r136998 r139877 36 36 #endif 37 37 38 #if USE(SOUP) 39 #include <glib.h> 40 #endif 41 38 42 #if PLATFORM(WIN) && USE(CFNETWORK) 39 43 #include <ConditionalMacros.h> … … 64 68 class ResourceHandleClient { 65 69 public: 70 #if USE(SOUP) 71 ResourceHandleClient(): m_buffer(0) { } 72 73 virtual ~ResourceHandleClient() 74 { 75 if (m_buffer) { 76 g_free(m_buffer); 77 m_buffer = 0; 78 } 79 } 80 #else 66 81 virtual ~ResourceHandleClient() { } 82 #endif 67 83 68 84 // request may be modified … … 81 97 virtual bool supportsDataArray() { return false; } 82 98 virtual void didReceiveDataArray(ResourceHandle*, CFArrayRef) { } 99 #endif 100 101 #if USE(SOUP) 102 virtual char* getBuffer(int requestedLength, int* actualLength) 103 { 104 *actualLength = requestedLength; 105 106 if (!m_buffer) 107 m_buffer = static_cast<char*>(g_malloc(requestedLength)); 108 109 return m_buffer; 110 } 83 111 #endif 84 112 … … 108 136 virtual AsyncFileStream* createAsyncFileStream(FileStreamClient*) { return 0; } 109 137 #endif 138 139 #if USE(SOUP) 140 private: 141 char* m_buffer; 142 #endif 110 143 }; 111 144 -
trunk/Source/WebCore/platform/network/ResourceHandleInternal.h
r139239 r139877 114 114 , m_cancelled(false) 115 115 , m_buffer(0) 116 , m_bufferSize(0) 116 117 , m_bodySize(0) 117 118 , m_bodyDataSent(0) … … 201 202 GRefPtr<GSource> m_timeoutSource; 202 203 char* m_buffer; 204 int m_bufferSize; 203 205 unsigned long m_bodySize; 204 206 unsigned long m_bodyDataSent; -
trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
r139239 r139877 561 561 562 562 if (d->m_buffer) { 563 g_slice_free1(READ_BUFFER_SIZE, d->m_buffer);564 563 d->m_buffer = 0; 564 d->m_bufferSize = 0; 565 565 } 566 566 … … 634 634 } 635 635 636 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 636 d->m_buffer = client->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 637 638 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, 637 639 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle.get()); 638 640 } … … 698 700 } 699 701 700 d->m_buffer = static_cast<char*>(g_slice_alloc(READ_BUFFER_SIZE));701 702 702 if (soupMessage && d->m_response.isMultipart()) { 703 703 d->m_multipartInputStream = adoptGRef(soup_multipart_input_stream_new(soupMessage, inputStream.get())); … … 708 708 709 709 d->m_inputStream = inputStream; 710 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 710 711 ASSERT(!d->m_buffer); 712 713 d->m_buffer = client->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 714 715 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, 711 716 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle.get()); 712 717 } … … 1363 1368 } 1364 1369 1365 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 1370 d->m_buffer = client->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 1371 1372 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, G_PRIORITY_DEFAULT, 1366 1373 d->m_cancellable.get(), readCallback, handle.get()); 1367 1374 }
Note: See TracChangeset
for help on using the changeset viewer.