Changeset 140420 in webkit
- Timestamp:
- Jan 22, 2013, 6:40:50 AM (14 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
-
ChangeLog (modified) (1 diff)
-
platform/graphics/gstreamer/GStreamerVersioning.cpp (modified) (3 diffs)
-
platform/graphics/gstreamer/GStreamerVersioning.h (modified) (1 diff)
-
platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (modified) (11 diffs)
-
platform/network/ResourceHandleClient.h (modified) (4 diffs)
-
platform/network/ResourceHandleInternal.h (modified) (2 diffs)
-
platform/network/soup/ResourceHandleSoup.cpp (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r140419 r140420 1 2013-01-22 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 (createGstBufferForData): New helper to create a GstBuffer when 17 we have a data pointer and a length. 18 (getGstBufferSize): Abstract obtaining the size of the buffer, so the code 19 is cleaner while still working for both GST 0.10 and 1.0. 20 (setGstBufferSize): Ditto, but for setting the size. 21 (getGstBufferDataPointer): Ditto, but for grabbing the data pointer. 22 (mapGstBuffer): Convenience method to take care of mapping the buffer so that 23 we can provide the data pointer to ResourceHandle. 24 (unmapGstBuffer): Convenience method which takes care of unmapping the buffer 25 and properly freeing the GstMapInfo. 26 * platform/graphics/gstreamer/GStreamerVersioning.h: 27 * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp: 28 (StreamingClient): New methods. 29 (_WebKitWebSrcPrivate): We now store the GstBuffer we provided the data pointer from 30 so we can later unmap it and push it to the pipeline. 31 (webKitWebSrcDispose): Deal with the GstBuffer in case it exists when the source is 32 destroyed. 33 (webKitWebSrcStop): Also clear the GstBuffer in this case. 34 (StreamingClient::didReceiveData): Handle the hand-over of the buffer. 35 (StreamingClient::getBuffer): Provide ResourceHandle with a new GstBuffer's data pointer. 36 * platform/network/ResourceHandleClient.h: 37 (ResourceHandleClient): 38 (WebCore::ResourceHandleClient::ResourceHandleClient): Constructor to initialize the buffer 39 member variable to 0. 40 (WebCore::ResourceHandleClient::~ResourceHandleClient): Destructor to free the buffer if it 41 has been allocated. 42 (WebCore::ResourceHandleClient::getBuffer): Default implementation which returns a 43 newly allocated char pointer. 44 * platform/network/ResourceHandleInternal.h: 45 (WebCore::ResourceHandleInternal::ResourceHandleInternal): 46 (ResourceHandleInternal): Store actual buffer size, which is no longer a constant. 47 * platform/network/soup/ResourceHandleSoup.cpp: 48 (WebCore::cleanupSoupRequestOperation): Clear the buffer pointer, the life-cycle of the 49 buffer is handled by the ResourceHandleClient. 50 (WebCore::nextMultipartResponsePartCallback): Get a new buffer from the client before reading. 51 (WebCore::sendRequestCallback): Ditto. 52 (WebCore::readCallback): Ditto. 53 1 54 2013-01-22 Michał Pakuła vel Rutka <m.pakula@samsung.com> 2 55 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
r139884 r140420 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 GstBuffer* createGstBufferForData(const char* data, int length) 130 { 131 GstBuffer* buffer = gst_buffer_new_and_alloc(length); 132 133 #ifdef GST_API_VERSION_1 134 gst_buffer_fill(buffer, 0, data, length); 135 #else 136 memcpy(GST_BUFFER_DATA(buffer), data, length); 137 #endif 138 139 return buffer; 140 } 141 142 int getGstBufferSize(GstBuffer* buffer) 143 { 144 #ifdef GST_API_VERSION_1 145 return gst_buffer_get_size(buffer); 146 #else 147 return GST_BUFFER_SIZE(buffer); 148 #endif 149 } 150 151 void setGstBufferSize(GstBuffer* buffer, int newSize) 152 { 153 #ifdef GST_API_VERSION_1 154 gst_buffer_set_size(buffer, static_cast<gssize>(newSize)); 155 #else 156 GST_BUFFER_SIZE(buffer) = static_cast<gsize>(newSize); 157 #endif 158 } 159 160 char* getGstBufferDataPointer(GstBuffer* buffer) 161 { 162 #ifdef GST_API_VERSION_1 163 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 164 GstMapInfo* mapInfo = static_cast<GstMapInfo*>(gst_mini_object_get_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString))); 165 return reinterpret_cast<char*>(mapInfo->data); 166 #else 167 return reinterpret_cast<char*>(GST_BUFFER_DATA(buffer)); 168 #endif 169 } 170 171 #ifdef GST_API_VERSION_1 172 void mapGstBuffer(GstBuffer* buffer) 173 { 174 GstMapInfo* mapInfo = g_slice_new(GstMapInfo); 175 if (!gst_buffer_map(buffer, mapInfo, GST_MAP_WRITE)) { 176 g_slice_free(GstMapInfo, mapInfo); 177 gst_buffer_unref(buffer); 178 return; 179 } 180 181 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 182 gst_mini_object_set_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString), mapInfo, 0); 183 } 184 185 void unmapGstBuffer(GstBuffer* buffer) 186 { 187 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 188 GstMapInfo* mapInfo = static_cast<GstMapInfo*>(gst_mini_object_steal_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString))); 189 190 if (!mapInfo) 191 return; 192 193 gst_buffer_unmap(buffer, mapInfo); 194 g_slice_free(GstMapInfo, mapInfo); 195 } 196 #endif 197 124 198 void setGstElementClassMetadata(GstElementClass* elementClass, const char* name, const char* longName, const char* description, const char* author) 125 199 { -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
r139884 r140420 37 37 #endif 38 38 GstBuffer* createGstBuffer(GstBuffer*); 39 GstBuffer* createGstBufferForData(const char* data, int length); 40 int getGstBufferSize(GstBuffer*); 41 void setGstBufferSize(GstBuffer*, int newSize); 42 char* getGstBufferDataPointer(GstBuffer*); 43 #ifdef GST_API_VERSION_1 44 void mapGstBuffer(GstBuffer*); 45 void unmapGstBuffer(GstBuffer*); 46 #endif 39 47 void setGstElementClassMetadata(GstElementClass*, const char* name, const char* longName, const char* description, const char* author); 40 48 bool gstObjectIsFloating(GstObject*); -
trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
r139884 r140420 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 GRefPtr<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.get()); 292 #endif 293 priv->buffer.clear(); 294 } 295 296 GST_CALL_PARENT(G_OBJECT_CLASS, dispose, (object)); 297 } 298 277 299 static void webKitWebSrcFinalize(GObject* object) 278 300 { … … 284 306 g_free(priv->uri); 285 307 286 GST_CALL_PARENT(G_OBJECT_CLASS, finalize, ( (GObject* )(src)));308 GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object)); 287 309 } 288 310 … … 354 376 355 377 priv->player = 0; 378 379 if (priv->buffer) { 380 #ifdef GST_API_VERSION_1 381 unmapGstBuffer(priv->buffer.get()); 382 #endif 383 priv->buffer.clear(); 384 } 356 385 357 386 GST_OBJECT_LOCK(src); … … 857 886 WebKitWebSrcPrivate* priv = m_src->priv; 858 887 859 GST_LOG_OBJECT(m_src, "Have %d bytes of data", length); 888 GST_LOG_OBJECT(m_src, "Have %d bytes of data", priv->buffer ? getGstBufferSize(priv->buffer.get()) : length); 889 890 #ifdef GST_API_VERSION_1 891 if (priv->buffer) 892 unmapGstBuffer(priv->buffer.get()); 893 #endif 860 894 861 895 if (priv->seekID || handle != priv->resourceHandle) { 862 896 GST_DEBUG_OBJECT(m_src, "Seek in progress, ignoring data"); 897 priv->buffer.clear(); 863 898 return; 864 899 } 865 900 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; 901 ASSERT(!priv->buffer || data == getGstBufferDataPointer(priv->buffer.get())); 902 903 // Ports using the GStreamer backend but not the soup implementation of ResourceHandle 904 // won't be using buffers provided by this client, the buffer is created here in that case. 905 if (!priv->buffer) 906 priv->buffer = adoptGRef(createGstBufferForData(data, length)); 907 else 908 setGstBufferSize(priv->buffer.get(), length); 909 910 GST_BUFFER_OFFSET(priv->buffer.get()) = priv->offset; 874 911 priv->offset += length; 875 GST_BUFFER_OFFSET_END( buffer) = priv->offset;876 877 GstFlowReturn ret = gst_app_src_push_buffer(priv->appsrc, buffer);912 GST_BUFFER_OFFSET_END(priv->buffer.get()) = priv->offset; 913 914 GstFlowReturn ret = gst_app_src_push_buffer(priv->appsrc, priv->buffer.leakRef()); 878 915 #ifdef GST_API_VERSION_1 879 916 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS) … … 884 921 } 885 922 923 char* StreamingClient::getBuffer(int requestedSize, int* actualSize) 924 { 925 WebKitWebSrcPrivate* priv = m_src->priv; 926 927 ASSERT(!priv->buffer); 928 929 GstBuffer* buffer = gst_buffer_new_and_alloc(requestedSize); 930 931 #ifdef GST_API_VERSION_1 932 mapGstBuffer(buffer); 933 #endif 934 935 priv->buffer = adoptGRef(buffer); 936 937 *actualSize = getGstBufferSize(buffer); 938 return getGstBufferDataPointer(buffer); 939 } 940 886 941 void StreamingClient::didFinishLoading(ResourceHandle*, double) 887 942 { -
trunk/Source/WebCore/platform/network/ResourceHandleClient.h
r139884 r140420 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
r139884 r140420 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
r140338 r140420 566 566 567 567 if (d->m_buffer) { 568 g_slice_free1(READ_BUFFER_SIZE, d->m_buffer);569 568 d->m_buffer = 0; 569 d->m_bufferSize = 0; 570 570 } 571 571 … … 634 634 client->didReceiveResponse(handle.get(), d->m_response); 635 635 636 // didReceiveResponse may cause the client to be changed. 637 client = d->client(); 638 636 639 if (d->m_cancelled || !client) { 637 640 cleanupSoupRequestOperation(handle.get()); … … 639 642 } 640 643 641 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 644 d->m_buffer = client->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 645 646 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, 642 647 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle.get()); 643 648 } … … 669 674 } 670 675 671 d->m_buffer = static_cast<char*>(g_slice_alloc(READ_BUFFER_SIZE)); 676 ASSERT(!d->m_buffer); 677 678 d->m_buffer = client->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 672 679 673 680 if (soupMessage) { … … 703 710 client->didReceiveResponse(handle.get(), d->m_response); 704 711 705 if (d->m_cancelled) { 712 // didReceiveResponse may cause the client to be changed. 713 client = d->client(); 714 715 if (d->m_cancelled || !client) { 706 716 cleanupSoupRequestOperation(handle.get()); 707 717 return; … … 716 726 717 727 d->m_inputStream = inputStream; 718 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 728 729 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, 719 730 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle.get()); 720 731 } … … 1369 1380 1370 1381 // didReceiveData may cancel the load, which may release the last reference. 1371 if (d->m_cancelled || ! client) {1382 if (d->m_cancelled || !handle->client()) { 1372 1383 cleanupSoupRequestOperation(handle.get()); 1373 1384 return; 1374 1385 } 1375 1386 1376 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 1387 d->m_buffer = client->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 1388 1389 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, G_PRIORITY_DEFAULT, 1377 1390 d->m_cancellable.get(), readCallback, handle.get()); 1378 1391 }
Note:
See TracChangeset
for help on using the changeset viewer.