Changeset 141821 in webkit
- Timestamp:
- Feb 4, 2013 3:18:33 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r141818 r141821 1 2013-02-04 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-02-04 Mark Pilgrim <pilgrim@chromium.org> 2 55 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.cpp
r140443 r141821 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 { … … 133 138 } 134 139 140 GstBuffer* createGstBufferForData(const char* data, int length) 141 { 142 GstBuffer* buffer = gst_buffer_new_and_alloc(length); 143 144 #ifdef GST_API_VERSION_1 145 gst_buffer_fill(buffer, 0, data, length); 146 #else 147 memcpy(GST_BUFFER_DATA(buffer), data, length); 148 #endif 149 150 return buffer; 151 } 152 153 int getGstBufferSize(GstBuffer* buffer) 154 { 155 #ifdef GST_API_VERSION_1 156 return gst_buffer_get_size(buffer); 157 #else 158 return GST_BUFFER_SIZE(buffer); 159 #endif 160 } 161 162 void setGstBufferSize(GstBuffer* buffer, int newSize) 163 { 164 #ifdef GST_API_VERSION_1 165 gst_buffer_set_size(buffer, static_cast<gssize>(newSize)); 166 #else 167 GST_BUFFER_SIZE(buffer) = static_cast<gsize>(newSize); 168 #endif 169 } 170 171 char* getGstBufferDataPointer(GstBuffer* buffer) 172 { 173 #ifdef GST_API_VERSION_1 174 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 175 GstMapInfo* mapInfo = static_cast<GstMapInfo*>(gst_mini_object_get_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString))); 176 return reinterpret_cast<char*>(mapInfo->data); 177 #else 178 return reinterpret_cast<char*>(GST_BUFFER_DATA(buffer)); 179 #endif 180 } 181 182 #ifdef GST_API_VERSION_1 183 void mapGstBuffer(GstBuffer* buffer) 184 { 185 GstMapInfo* mapInfo = g_slice_new(GstMapInfo); 186 if (!gst_buffer_map(buffer, mapInfo, GST_MAP_WRITE)) { 187 g_slice_free(GstMapInfo, mapInfo); 188 gst_buffer_unref(buffer); 189 return; 190 } 191 192 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 193 gst_mini_object_set_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString), mapInfo, 0); 194 } 195 196 void unmapGstBuffer(GstBuffer* buffer) 197 { 198 GstMiniObject* miniObject = reinterpret_cast<GstMiniObject*>(buffer); 199 GstMapInfo* mapInfo = static_cast<GstMapInfo*>(gst_mini_object_steal_qdata(miniObject, g_quark_from_static_string(webkitGstMapInfoQuarkString))); 200 201 if (!mapInfo) 202 return; 203 204 gst_buffer_unmap(buffer, mapInfo); 205 g_slice_free(GstMapInfo, mapInfo); 206 } 207 #endif 208 135 209 void setGstElementClassMetadata(GstElementClass* elementClass, const char* name, const char* longName, const char* description, const char* author) 136 210 { -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerVersioning.h
r140443 r141821 38 38 #endif 39 39 GstBuffer* createGstBuffer(GstBuffer*); 40 GstBuffer* createGstBufferForData(const char* data, int length); 41 int getGstBufferSize(GstBuffer*); 42 void setGstBufferSize(GstBuffer*, int newSize); 43 char* getGstBufferDataPointer(GstBuffer*); 44 #ifdef GST_API_VERSION_1 45 void mapGstBuffer(GstBuffer*); 46 void unmapGstBuffer(GstBuffer*); 47 #endif 40 48 void setGstElementClassMetadata(GstElementClass*, const char* name, const char* longName, const char* description, const char* author); 41 49 bool gstObjectIsFloating(GstObject*); -
trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
r141695 r141821 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 … … 34 35 #include "ResourceRequest.h" 35 36 #include "ResourceResponse.h" 36 37 37 #include <gst/app/gstappsrc.h> 38 #include <gst/gst.h> 38 39 #include <gst/pbutils/missing-plugins.h> 39 40 40 #include <wtf/Noncopyable.h> 41 41 #include <wtf/gobject/GOwnPtr.h> … … 53 53 virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse&); 54 54 virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); 55 56 virtual char* getBuffer(int, int*); 57 55 58 virtual void didReceiveData(ResourceHandle*, const char*, int, int); 56 59 virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/); … … 85 88 guint enoughDataID; 86 89 guint seekID; 90 91 GRefPtr<GstBuffer> buffer; 87 92 88 93 // icecast stuff … … 117 122 static void webKitWebSrcUriHandlerInit(gpointer gIface, gpointer ifaceData); 118 123 124 static void webKitWebSrcDispose(GObject*); 119 125 static void webKitWebSrcFinalize(GObject*); 120 126 static void webKitWebSrcSetProperty(GObject*, guint propertyID, const GValue*, GParamSpec*); … … 152 158 GstElementClass* eklass = GST_ELEMENT_CLASS(klass); 153 159 160 oklass->dispose = webKitWebSrcDispose; 154 161 oklass->finalize = webKitWebSrcFinalize; 155 162 oklass->set_property = webKitWebSrcSetProperty; … … 276 283 } 277 284 285 static void webKitWebSrcDispose(GObject* object) 286 { 287 WebKitWebSrc* src = WEBKIT_WEB_SRC(object); 288 WebKitWebSrcPrivate* priv = src->priv; 289 290 if (priv->buffer) { 291 #ifdef GST_API_VERSION_1 292 unmapGstBuffer(priv->buffer.get()); 293 #endif 294 priv->buffer.clear(); 295 } 296 297 GST_CALL_PARENT(G_OBJECT_CLASS, dispose, (object)); 298 } 299 278 300 static void webKitWebSrcFinalize(GObject* object) 279 301 { … … 285 307 g_free(priv->uri); 286 308 287 GST_CALL_PARENT(G_OBJECT_CLASS, finalize, ( (GObject* )(src)));309 GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object)); 288 310 } 289 311 … … 355 377 356 378 priv->player = 0; 379 380 if (priv->buffer) { 381 #ifdef GST_API_VERSION_1 382 unmapGstBuffer(priv->buffer.get()); 383 #endif 384 priv->buffer.clear(); 385 } 357 386 358 387 GST_OBJECT_LOCK(src); … … 858 887 WebKitWebSrcPrivate* priv = m_src->priv; 859 888 860 GST_LOG_OBJECT(m_src, "Have %d bytes of data", length); 889 GST_LOG_OBJECT(m_src, "Have %d bytes of data", priv->buffer ? getGstBufferSize(priv->buffer.get()) : length); 890 891 ASSERT(!priv->buffer || data == getGstBufferDataPointer(priv->buffer.get())); 892 893 #ifdef GST_API_VERSION_1 894 if (priv->buffer) 895 unmapGstBuffer(priv->buffer.get()); 896 #endif 861 897 862 898 if (priv->seekID || handle != priv->resourceHandle) { 863 899 GST_DEBUG_OBJECT(m_src, "Seek in progress, ignoring data"); 900 priv->buffer.clear(); 864 901 return; 865 902 } 866 903 867 GstBuffer* buffer = gst_buffer_new_and_alloc(length);868 869 #ifdef GST_API_VERSION_1 870 gst_buffer_fill(buffer, 0, data, length);871 #else872 memcpy(GST_BUFFER_DATA(buffer), data, length);873 #endif 874 GST_BUFFER_OFFSET( buffer) = priv->offset;904 // Ports using the GStreamer backend but not the soup implementation of ResourceHandle 905 // won't be using buffers provided by this client, the buffer is created here in that case. 906 if (!priv->buffer) 907 priv->buffer = adoptGRef(createGstBufferForData(data, length)); 908 else 909 setGstBufferSize(priv->buffer.get(), length); 910 911 GST_BUFFER_OFFSET(priv->buffer.get()) = priv->offset; 875 912 priv->offset += length; 876 GST_BUFFER_OFFSET_END( buffer) = priv->offset;877 878 GstFlowReturn ret = gst_app_src_push_buffer(priv->appsrc, buffer);913 GST_BUFFER_OFFSET_END(priv->buffer.get()) = priv->offset; 914 915 GstFlowReturn ret = gst_app_src_push_buffer(priv->appsrc, priv->buffer.leakRef()); 879 916 #ifdef GST_API_VERSION_1 880 917 if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS) … … 885 922 } 886 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 = adoptGRef(buffer); 937 938 *actualSize = getGstBufferSize(buffer); 939 return getGstBufferDataPointer(buffer); 940 } 941 887 942 void StreamingClient::didFinishLoading(ResourceHandle*, double) 888 943 { -
trunk/Source/WebCore/platform/network/ResourceHandleClient.h
r140425 r141821 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
r141350 r141821 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
r141749 r141821 533 533 534 534 if (bytesSkipped > 0) { 535 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 535 d->m_buffer = handle->client()->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 536 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, G_PRIORITY_DEFAULT, 536 537 d->m_cancellable.get(), redirectSkipCallback, handle.get()); 537 538 return; … … 574 575 575 576 if (d->m_buffer) { 576 g_slice_free1(READ_BUFFER_SIZE, d->m_buffer);577 577 d->m_buffer = 0; 578 d->m_bufferSize = 0; 578 579 } 579 580 … … 646 647 } 647 648 648 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 649 d->m_buffer = handle->client()->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 650 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, 649 651 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle.get()); 650 652 } … … 676 678 } 677 679 678 d->m_buffer = static_cast<char*>(g_slice_alloc(READ_BUFFER_SIZE));680 ASSERT(!d->m_buffer); 679 681 680 682 if (soupMessage) { … … 684 686 // https://bugzilla.gnome.org/show_bug.cgi?id=691489 until we can 685 687 // depend on glib > 2.35.4 686 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 688 d->m_buffer = handle->client()->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 689 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, G_PRIORITY_DEFAULT, 687 690 d->m_cancellable.get(), redirectSkipCallback, handle.get()); 688 691 return; … … 723 726 724 727 d->m_inputStream = inputStream; 725 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, 728 729 d->m_buffer = handle->client()->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 730 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, 726 731 G_PRIORITY_DEFAULT, d->m_cancellable.get(), readCallback, handle.get()); 727 732 } … … 1380 1385 } 1381 1386 1382 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 1387 d->m_buffer = handle->client()->getBuffer(READ_BUFFER_SIZE, &d->m_bufferSize); 1388 g_input_stream_read_async(d->m_inputStream.get(), d->m_buffer, d->m_bufferSize, G_PRIORITY_DEFAULT, 1383 1389 d->m_cancellable.get(), readCallback, handle.get()); 1384 1390 }
Note: See TracChangeset
for help on using the changeset viewer.