Changeset 50284 in webkit
- Timestamp:
- Oct 29, 2009 10:50:49 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r50283 r50284 1 2009-10-29 Sebastian Dröge <sebastian.droege@collabora.co.uk> 2 3 Reviewed by Gustavo Noronha. 4 5 https://bugs.webkit.org/show_bug.cgi?id=30308 6 7 Add support for ARGB videos. 8 9 * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: 10 (WebCore::MediaPlayerPrivate::paint): 11 Create the Cairo image surface for ARGB32 or RGB24 12 depending on the buffer's caps. 13 14 * platform/graphics/gtk/VideoSinkGStreamer.cpp: 15 (webkit_video_sink_timeout_func): 16 (webkit_video_sink_render): 17 Handle ARGB video and convert GStreamer's ARGB to 18 Cairo's for displaying. 19 1 20 2009-10-29 Anton Muhin <antonm@chromium.org> 2 21 -
trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
r50122 r50284 632 632 double displayHeight; 633 633 double scale, gapHeight, gapWidth; 634 GstVideoFormat format; 634 635 635 636 GstCaps *caps = gst_buffer_get_caps(m_buffer); 636 637 637 if ( !gst_video_format_parse_caps(caps, NULL, &width, &height) ||638 !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator)) {638 if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height) || 639 !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator))) { 639 640 gst_caps_unref(caps); 640 641 return; … … 646 647 doublePixelAspectRatioDenominator = pixelAspectRatioDenominator; 647 648 649 cairo_format_t cairoFormat; 650 if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA) 651 cairoFormat = CAIRO_FORMAT_ARGB32; 652 else 653 cairoFormat = CAIRO_FORMAT_RGB24; 654 648 655 cairo_t* cr = context->platformContext(); 649 656 cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(m_buffer), 650 CAIRO_FORMAT_RGB24,657 cairoFormat, 651 658 width, height, 652 659 4 * width); -
trunk/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
r49623 r50284 38 38 // CAIRO_FORMAT_RGB24 used to render the video buffers is little/big endian dependant. 39 39 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 40 GST_STATIC_CAPS(GST_VIDEO_CAPS_BGRx )40 GST_STATIC_CAPS(GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_BGRA) 41 41 #else 42 GST_STATIC_CAPS(GST_VIDEO_CAPS_xRGB )42 GST_STATIC_CAPS(GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_ARGB) 43 43 #endif 44 44 ); … … 130 130 } 131 131 132 if (G_UNLIKELY(!GST_BUFFER_CAPS(buffer))) {133 buffer = gst_buffer_make_metadata_writable(buffer);134 gst_buffer_set_caps(buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(sink)));135 }136 137 132 g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0, buffer); 138 133 gst_buffer_unref(buffer); … … 157 152 158 153 priv->buffer = gst_buffer_ref(buffer); 154 155 // For the unlikely case where the buffer has no caps, the caps 156 // are implicitely the caps of the pad. This shouldn't happen. 157 if (G_UNLIKELY(!GST_BUFFER_CAPS(buffer))) { 158 buffer = priv->buffer = gst_buffer_make_metadata_writable(priv->buffer); 159 gst_buffer_set_caps(priv->buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(bsink))); 160 } 161 162 GstCaps *caps = GST_BUFFER_CAPS(buffer); 163 GstVideoFormat format; 164 int width, height; 165 if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height))) { 166 gst_buffer_unref(buffer); 167 g_mutex_unlock(priv->buffer_mutex); 168 return GST_FLOW_ERROR; 169 } 170 171 // Cairo's ARGB has pre-multiplied alpha while GStreamer's doesn't. 172 // Here we convert to Cairo's ARGB. 173 if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA) { 174 // Because GstBaseSink::render() only owns the buffer reference in the 175 // method scope we can't use gst_buffer_make_writable() here. Also 176 // The buffer content should not be changed here because the same buffer 177 // could be passed multiple times to this method (in theory) 178 GstBuffer *newBuffer = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buffer)); 179 180 // Check if allocation failed 181 if (G_UNLIKELY(!newBuffer)) { 182 gst_buffer_unref(buffer); 183 g_mutex_unlock(priv->buffer_mutex); 184 return GST_FLOW_ERROR; 185 } 186 187 gst_buffer_copy_metadata(newBuffer, buffer, (GstBufferCopyFlags) GST_BUFFER_COPY_ALL); 188 189 // We don't use Color::premultipliedARGBFromColor() here because 190 // one function call per video pixel is just too expensive: 191 // For 720p/PAL for example this means 1280*720*25=23040000 192 // function calls per second! 193 unsigned short alpha; 194 const guint8 *source = GST_BUFFER_DATA(buffer); 195 guint8 *destination = GST_BUFFER_DATA(newBuffer); 196 197 for (int x = 0; x < height; x++) { 198 for (int y = 0; y < width; y++) { 199 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 200 alpha = source[3]; 201 destination[0] = (source[0] * alpha + 128) / 255; 202 destination[1] = (source[1] * alpha + 128) / 255; 203 destination[2] = (source[2] * alpha + 128) / 255; 204 destination[3] = alpha; 205 #else 206 alpha = source[0]; 207 destination[0] = alpha; 208 destination[1] = (source[1] * alpha + 128) / 255; 209 destination[2] = (source[2] * alpha + 128) / 255; 210 destination[3] = (source[3] * alpha + 128) / 255; 211 #endif 212 source += 4; 213 destination += 4; 214 } 215 } 216 gst_buffer_unref(buffer); 217 buffer = priv->buffer = newBuffer; 218 } 159 219 160 220 // Use HIGH_IDLE+20 priority, like Gtk+ for redrawing operations.
Note: See TracChangeset
for help on using the changeset viewer.