After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 503743 - dfbvideosink: does not handle external surface correctly
dfbvideosink: does not handle external surface correctly
Status: RESOLVED INCOMPLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
git master
Other Linux
: Normal normal
: NONE
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks: 321240
 
 
Reported: 2007-12-15 14:09 UTC by Huimin He
Modified: 2018-01-25 12:46 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Huimin He 2007-12-15 14:09:39 UTC
Hi,

I'm using gstreamer and DirectFB to create a media player on a ARM11 board.

now I found if i create a surface in my application and pass this surface to dfbvideosink, it's very slow on my board.and if i let dfbvideosink to create the surface itself, it's faster.

then i checked the source code in dfbvideosink.c, and found those: 
1. in  gst_dfbvideosink_setup()  it will not  get  dirctFB initialized  if it's a external surface. just copy some configuation from the ext surface,
2, in  gst_dfbvideosink_surface_create()  , it will not create any surface is DirectFB is not initialized,
3, in gst_dfbvideosink_show_frame(), it will check the buffer has surface or not to decide use Blit or mem_cpy. since using the external surface do not cause a directfb initialized and then no surface created in buffer. mem_cpy is chosen. this cause the video playback slower.

I think dfbvideosink should check the external surface support blit or not, if yes,it should use blit to accelarate.

could you check and fix this?

Best Regards
Joyious
Comment 1 Huimin He 2007-12-16 12:49:43 UTC
Hi,

I just do a simple change,hope this info can help you.

here are the diff results:
100,101d99
< #define HHM_TEST
780,858d773
< #ifdef HHM_TEST
< 
<     if (!dfbvideosink->dfb) {
<       DFBGraphicsDeviceDescription hw_caps;
< 
<       GST_DEBUG_OBJECT (dfbvideosink, "initializing DirectFB");
< 
<       ret = DirectFBInit (0, NULL);
< 
<       if (ret != DFB_OK) {
<         GST_WARNING_OBJECT (dfbvideosink, "DirectFB initialization failed");
<         goto beach;
<       }
< 
<       ret = DirectFBCreate (&(dfbvideosink->dfb));
< 
<       if (ret != DFB_OK) {
<         GST_WARNING_OBJECT (dfbvideosink, "failed creating the DirectFB "
<             "main object");
<         goto beach;
<       }
< 
<             /* Get Hardware capabilities */
<       ret = dfbvideosink->dfb->GetDeviceDescription (dfbvideosink->dfb,
<           &hw_caps);
< 
<       if (ret != DFB_OK) {
<         GST_WARNING_OBJECT (dfbvideosink, "failed grabbing the hardware "
<             "capabilities");
<         goto beach;
<       }
< 
<       GST_DEBUG_OBJECT (dfbvideosink, "video card %s from vendor %s detected "
<           "with %d bytes of video memory", hw_caps.name, hw_caps.vendor,
<           hw_caps.video_memory);
< 
<       if (hw_caps.acceleration_mask & DFXL_BLIT) {
<         GST_DEBUG_OBJECT (dfbvideosink, "Blit is accelerated");
<       }
<       if (hw_caps.acceleration_mask & DFXL_STRETCHBLIT) {
<         GST_DEBUG_OBJECT (dfbvideosink, "StretchBlit is accelerated");
<         dfbvideosink->hw_scaling = TRUE;
<       } else {
<         GST_DEBUG_OBJECT (dfbvideosink, "StretchBlit is not accelerated");
<         dfbvideosink->hw_scaling = FALSE;
<       }
< 
<       dfbvideosink->layer_id = -1;
< 
<       /* Inspect all the Display layers */
<       dfbvideosink->dfb->EnumDisplayLayers (dfbvideosink->dfb,
<           gst_dfbvideosink_enum_layers, dfbvideosink);
<       /* Inspect all Video modes */
<       dfbvideosink->dfb->EnumVideoModes (dfbvideosink->dfb,
<           gst_dfbvideosink_enum_vmodes, dfbvideosink);
< 
< 
<      if (!dfbvideosink->layer) {
<       GList *channels_list = NULL;
<       DFBDisplayLayerDescription dl_desc;
< 
<       /* Get the best Display Layer */
<       ret = dfbvideosink->dfb->GetDisplayLayer (dfbvideosink->dfb,
<           dfbvideosink->layer_id, &dfbvideosink->layer);
<       if (ret != DFB_OK) {
<         GST_WARNING_OBJECT (dfbvideosink, "failed getting display layer");
<         goto beach;
<       }
< 
<       ret = dfbvideosink->layer->SetCooperativeLevel (dfbvideosink->layer,
<           DFSCL_NORMAL);
< 
<       if (ret != DFB_OK) {
<         GST_WARNING_OBJECT (dfbvideosink, "failed setting display layer to "
<             "fullscreen mode");
<         goto beach;
<       }
< 
<       dfbvideosink->layer->GetDescription (dfbvideosink->layer, &dl_desc);
860,943d774
<       /* Check that this layer is able to do colorbalance settings */
<       if (dl_desc.caps & DLCAPS_BRIGHTNESS) {
<         channels_list = g_list_append (channels_list, "BRIGHTNESS");
<       }
<       if (dl_desc.caps & DLCAPS_CONTRAST) {
<         channels_list = g_list_append (channels_list, "CONTRAST");
<       }
<       if (dl_desc.caps & DLCAPS_HUE) {
<         channels_list = g_list_append (channels_list, "HUE");
<       }
<       if (dl_desc.caps & DLCAPS_SATURATION) {
<         channels_list = g_list_append (channels_list, "SATURATION");
<       }
< 
<       if (channels_list) {
<         GList *walk = channels_list;
< 
<         /* Generate Color balance channel list */
<         while (walk) {
<           GstColorBalanceChannel *channel = NULL;
< 
<           GST_DEBUG_OBJECT (dfbvideosink, "adding %s as a colorbalance channel",
<               walk->data);
< 
<           channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
<           channel->label = g_strdup (walk->data);
<           channel->min_value = 0x0000;
<           channel->max_value = 0xFFFF;
< 
<           dfbvideosink->cb_channels = g_list_append (dfbvideosink->cb_channels,
<               channel);
< 
<           walk = g_list_next (walk);
<         }
< 
<         /* If the colorbalance settings have not been touched we get current
<            values as defaults and update our internal variables */
<         if (!dfbvideosink->cb_changed) {
<           DFBColorAdjustment cb_adjust;
< 
<           ret = dfbvideosink->layer->GetColorAdjustment (dfbvideosink->layer,
<               &cb_adjust);
< 
<           if (ret != DFB_OK) {
<             GST_WARNING_OBJECT (dfbvideosink, "failed when getting color "
<                 "adjustment from layer");
<           }
< 
<           if (cb_adjust.flags & DCAF_BRIGHTNESS) {
<             dfbvideosink->brightness = cb_adjust.brightness;
<           } else {
<             dfbvideosink->brightness = 0x8000;
<           }
<           if (cb_adjust.flags & DCAF_CONTRAST) {
<             dfbvideosink->contrast = cb_adjust.contrast;
<           } else {
<             dfbvideosink->contrast = 0x8000;
<           }
<           if (cb_adjust.flags & DCAF_HUE) {
<             dfbvideosink->hue = cb_adjust.hue;
<           } else {
<             dfbvideosink->hue = 0x8000;
<           }
<           if (cb_adjust.flags & DCAF_SATURATION) {
<             dfbvideosink->saturation = cb_adjust.saturation;
<           } else {
<             dfbvideosink->saturation = 0x8000;
<           }
<           GST_DEBUG_OBJECT (dfbvideosink, "brightness %d, contrast %d, "
<               "hue %d, saturation %d", dfbvideosink->brightness,
<               dfbvideosink->contrast, dfbvideosink->hue,
<               dfbvideosink->saturation);
<         }
< 
<         g_list_free (channels_list);
< 
<         gst_dfbvideosink_update_colorbalance (dfbvideosink);
<       }
< 
<       dfbvideosink->layer->SetBackgroundColor (dfbvideosink->layer,
<           0x00, 0x00, 0x00, 0xFF);
<         }
<         }
< #endif
1809,1813d1639
< #ifdef HHM_TEST
< if (dfbvideosink ->ext_surface)
< {
<     GST_DEBUG_OBJECT (dfbvideosink, "blitting to a External surface (vsync %d)",
<         dfbvideosink->vsync);
1815,1858d1640
<     src.w = GST_VIDEO_SINK_WIDTH (dfbvideosink);
<     src.h = GST_VIDEO_SINK_HEIGHT (dfbvideosink);
< 
<     dfbvideosink->ext_surface->GetSize (dfbvideosink->ext_surface, &dst.w, &dst.h);
< 
<     /* Unlocking surface before blit */
<     if (surface->locked) {
<       surface->surface->Unlock (surface->surface);
<       surface->locked = FALSE;
<     }
< 
<     gst_video_sink_center_rect (src, dst, &result, dfbvideosink->hw_scaling);
< 
<     /* If we are not using Flip we wait for VSYNC before blit */
<     if (!dfbvideosink->backbuffer && dfbvideosink->vsync) {
<       dfbvideosink->layer->WaitForSync (dfbvideosink->layer);
<     }
< 
< dfbvideosink->ext_surface->Clear(dfbvideosink->ext_surface, 0x00,0x00,0x00,0x00);
< 
<     if (dfbvideosink->hw_scaling) {
<       dfbvideosink->ext_surface->StretchBlit (dfbvideosink->ext_surface,
<           surface->surface, NULL, (DFBRectangle *) & result);
<     } else {
<       DFBRectangle clip;
< 
<       clip.x = clip.y = 0;
<       clip.w = result.w;
<       clip.h = result.h;
<       dfbvideosink->ext_surface->Blit (dfbvideosink->ext_surface, surface->surface,
<           &clip, result.x, result.y);
<     }
< 
<     if (dfbvideosink->backbuffer) {
<       if (dfbvideosink->vsync) {
<         dfbvideosink->ext_surface->Flip (dfbvideosink->ext_surface, NULL,
<             DSFLIP_ONSYNC);
<       } else {
<         dfbvideosink->ext_surface->Flip (dfbvideosink->ext_surface, NULL, DSFLIP_NONE);
<       }
<     }
<     goto beach;
< }
< #endif

Comment 2 Sebastian Dröge (slomo) 2007-12-17 09:25:40 UTC
Problem seems to be, that you can't create another surface with only the surface known. you need to know the IDirectFB context somehow but this would probably cause threading problems.

I'll try to find a good solution though...
Comment 3 Edward Hervey 2013-10-02 12:22:35 UTC
directfb has been ported to 1.x.

Huimin, Sebastian, Does this bug still apply in 1.x ?
Comment 4 Tim-Philipp Müller 2018-01-25 12:46:02 UTC
Closing this bug report as no further information has been provided. Please feel free to reopen this bug report if you can provide the information that was asked for in a previous comment.
Thanks!