当前位置: 技术问答>linux和unix
GTK drawingarea 影响UI速度问题
来源: 互联网 发布时间:2016-06-02
本文导语: Dear All: 本人开发Linux嵌入式视频播放软件,遇到一个问题。描述如下 软件分两个window:viewwin(包含drawingarea控件),controlwin(可以隐含)。 现象是,在播放流媒体的时候,click viewwin,controlwin会弹出。但是,...
Dear All:
本人开发Linux嵌入式视频播放软件,遇到一个问题。描述如下
软件分两个window:viewwin(包含drawingarea控件),controlwin(可以隐含)。
现象是,在播放流媒体的时候,click viewwin,controlwin会弹出。但是,有的时候弹出会很慢。感觉UI 在不停的刷新控件上的图片。只有在播放A/V的时候会发生,如果播放audio就不会有慢得现象。
问题:这种现象是怎么回事?
on_drawingarea_expose_event代码如下。
gboolean
on_drawingarea_expose_event (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data)
{
//g_print("[on_drawingarea_expose_event]-----------------------------------------n");
GtkWidget *drawing = GTK_WIDGET (user_data);
stx_dtvGstPipe *dtvGst =
(stx_dtvGstPipe *) g_object_get_qdata (G_OBJECT (widget), g_dtvGstQrk);
stx_windStates *winSta = (stx_windStates *) g_object_get_qdata (G_OBJECT (g_winList->mainWin), g_winStaQrk);
GQuark pixBufQrk;
stx_logoPixbuf *logos;
static gint imgIdx = 0;
GstXOverlay *xoverlay = NULL;
gulong xwin_id = 0;
Gstvmixif *pIface=NULL;
GstvmixifClass *ifclass=NULL;
// gint x, y;
g_printf ("on_drawingarea_expose_eventnn");
if (dtvGst)
{
if (GST_IS_ELEMENT (dtvGst->vsink) && GST_IS_X_OVERLAY (dtvGst->vsink))
{
xoverlay = GST_X_OVERLAY (dtvGst->vsink);
xwin_id = GDK_WINDOW_XWINDOW (drawing->window);
if (xoverlay) {
gst_object_ref (xoverlay);
if (xwin_id) {
gst_x_overlay_set_xwindow_id (xoverlay, xwin_id);
}
else
DBGDVB (printf ("xwin_id is NULLn"));
DBGDVB (g_printf ("finish setting xoverlay"));
}
}
}
gdk_draw_rectangle (drawing->window, drawing->style->black_gc, TRUE, 0, 0,
drawing->allocation.width, drawing->allocation.height);
pixBufQrk = g_quark_from_string ("logoPixbuf");
logos = g_object_get_qdata (G_OBJECT (g_winList->mainWin), pixBufQrk);
if (winSta->logoMode == PLAYING)
{
DBGDVB (printf ("nPlaying.........n"));
_ImgIdx = 0; // reset the image index for no signal condition
if (xoverlay) {
if (firstoverlay) gst_x_overlay_expose (xoverlay); // Modified by Thomas Lin, 2008-12-01, set at first time to skip showing the image
firstoverlay = FALSE;
}
}
if (xoverlay)
{
gst_object_unref (xoverlay);
}
DBGDVB (printf ("BYE BYE ....."));
return FALSE;
}
本人开发Linux嵌入式视频播放软件,遇到一个问题。描述如下
软件分两个window:viewwin(包含drawingarea控件),controlwin(可以隐含)。
现象是,在播放流媒体的时候,click viewwin,controlwin会弹出。但是,有的时候弹出会很慢。感觉UI 在不停的刷新控件上的图片。只有在播放A/V的时候会发生,如果播放audio就不会有慢得现象。
问题:这种现象是怎么回事?
on_drawingarea_expose_event代码如下。
gboolean
on_drawingarea_expose_event (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data)
{
//g_print("[on_drawingarea_expose_event]-----------------------------------------n");
GtkWidget *drawing = GTK_WIDGET (user_data);
stx_dtvGstPipe *dtvGst =
(stx_dtvGstPipe *) g_object_get_qdata (G_OBJECT (widget), g_dtvGstQrk);
stx_windStates *winSta = (stx_windStates *) g_object_get_qdata (G_OBJECT (g_winList->mainWin), g_winStaQrk);
GQuark pixBufQrk;
stx_logoPixbuf *logos;
static gint imgIdx = 0;
GstXOverlay *xoverlay = NULL;
gulong xwin_id = 0;
Gstvmixif *pIface=NULL;
GstvmixifClass *ifclass=NULL;
// gint x, y;
g_printf ("on_drawingarea_expose_eventnn");
if (dtvGst)
{
if (GST_IS_ELEMENT (dtvGst->vsink) && GST_IS_X_OVERLAY (dtvGst->vsink))
{
xoverlay = GST_X_OVERLAY (dtvGst->vsink);
xwin_id = GDK_WINDOW_XWINDOW (drawing->window);
if (xoverlay) {
gst_object_ref (xoverlay);
if (xwin_id) {
gst_x_overlay_set_xwindow_id (xoverlay, xwin_id);
}
else
DBGDVB (printf ("xwin_id is NULLn"));
DBGDVB (g_printf ("finish setting xoverlay"));
}
}
}
gdk_draw_rectangle (drawing->window, drawing->style->black_gc, TRUE, 0, 0,
drawing->allocation.width, drawing->allocation.height);
pixBufQrk = g_quark_from_string ("logoPixbuf");
logos = g_object_get_qdata (G_OBJECT (g_winList->mainWin), pixBufQrk);
if (winSta->logoMode == PLAYING)
{
DBGDVB (printf ("nPlaying.........n"));
_ImgIdx = 0; // reset the image index for no signal condition
if (xoverlay) {
if (firstoverlay) gst_x_overlay_expose (xoverlay); // Modified by Thomas Lin, 2008-12-01, set at first time to skip showing the image
firstoverlay = FALSE;
}
}
if (xoverlay)
{
gst_object_unref (xoverlay);
}
DBGDVB (printf ("BYE BYE ....."));
return FALSE;
}
|
你启动软件的时候先把那个控制窗口隐藏起来,不要临时新建,然后再显示。
如果视频在播放的话,你没必要处理expose的,因为每帧都会重新显示
再者我处理这种情况,我会使用一个单独的线程更新UI,不过要注意用
gdk_threads_enter同步
如果视频在播放的话,你没必要处理expose的,因为每帧都会重新显示
再者我处理这种情况,我会使用一个单独的线程更新UI,不过要注意用
gdk_threads_enter同步