All pastes #55987 Raw Edit

C

public c v1 · immutable
#55987 ·published 2006-05-15 14:17 UTC
rendered paste body
#include <string.h>#include <stdlib.h>#include <glib.h>#include <glib/gprintf.h>#include <gdk/gdkkeysyms.h>#include <gtk/gtk.h>#include <GL/gl.h>#include <GL/glu.h>#include <gtk/gtkgl.h>#include <gst/gst.h>#define FOVY_2 20.0#define Z_NEAR 3.0GLfloat			g_afAngle[3] = {0.0f, 0.0f, 0.0f};GLfloat			g_fScale = 1.0f;gint			g_iFrames = 0;GTimer*			g_pTimerId = NULL;gboolean		g_bKeepRunning = TRUE;gdouble			g_fLastTimeStamp = 0.0f;gdouble			g_fCurrentTimeStamp = 0.0f;gdouble			g_fLastFullSecond = 0.0f;gboolean		g_bLMBPressed = FALSE;gboolean		g_bRMBPressed = FALSE;GLuint			g_uiColorBuffer;gdouble			g_fCurrentX;gdouble			g_fCurrentY;gdouble			g_fDeltaX;gdouble			g_fDeltaY;gdouble			g_fLastX;gdouble			g_fLastY;gint			g_iWidth = 1;gint			g_iHeight = 1;GstElement*		g_pPipeline = NULL;GstElement*		pVideo = NULL;GstElement*		g_pPipelineH264 = NULL;GstElement*		pVideoH264 = NULL;gboolean		g_bInitialized = FALSE;gchar*			g_pcFrameBuffer = NULL;GMutex*			g_pFrameBufferMutex = NULL;GLfloat			g_afAlpha = 1.0f;GLfloat			g_fMovieAspect = 1.0f;GLuint			g_uiDisplayList = 0;GstBuffer*		g_pTheBuffer = NULL;gint get_pad_width (GstPad* pVideoPad){	gint iWidth = 0;	GstCaps* pCaps = NULL;	GstStructure* pStructure = NULL;	pCaps = gst_pad_get_negotiated_caps (pVideoPad);	if (pCaps)	{		pStructure = gst_caps_get_structure (pCaps, 0);		gst_structure_get_int (pStructure, "width", &iWidth);	}	else		g_print ("gst_pad_width() - Could not get caps for the pad!\n");	return iWidth;}gint get_pad_height (GstPad* pVideoPad){	gint iHeight = 0;	GstCaps* pCaps = NULL;	GstStructure* pStructure = NULL;	pCaps = gst_pad_get_negotiated_caps (pVideoPad);	if (pCaps)	{		pStructure = gst_caps_get_structure (pCaps, 0);		gst_structure_get_int (pStructure, "height", &iHeight);	}	else		g_print ("gst_pad_height() - Could not get caps for the pad!\n");	return iHeight;}gdouble get_pad_fps (GstPad* pVideoPad){	gint aiFps[2] = {0, 0};	GstCaps* pCaps = NULL;	GstStructure* pStructure = NULL;	gdouble fFpsRate = 0.0f;	pCaps = gst_pad_get_negotiated_caps (pVideoPad);	if (pCaps)	{		pStructure = gst_caps_get_structure (pCaps, 0);		gst_structure_get_fraction (pStructure,									"framerate",									&aiFps[0],									&aiFps[1]);		fFpsRate = (gdouble) aiFps[0] / (gdouble) aiFps[1];	}	else		g_print ("gst_pad_fps() - Could not get caps for the pad!\n");	return fFpsRate;}gdouble get_pad_movie_aspect (GstPad* pVideoPad){	gint iWidth = 0;	gint iHeight = 0;	gint aiPixelAspect[2] = {0, 0};	gdouble fAspectRatio = 0.0f;	GstCaps* pCaps = NULL;	GstStructure* pStructure = NULL;	pCaps = gst_pad_get_negotiated_caps (pVideoPad);	if (pCaps)	{		pStructure = gst_caps_get_structure (pCaps, 0);		gst_structure_get_int (pStructure, "width", &iWidth);		gst_structure_get_int (pStructure, "height", &iHeight);		gst_structure_get_fraction (pStructure,									"pixel-aspect-ratio",									&aiPixelAspect[0],									&aiPixelAspect[1]);		if (aiPixelAspect[0] == 0)			fAspectRatio = (gdouble) iWidth / (gdouble) g_iHeight;		else		{			fAspectRatio = (gdouble) aiPixelAspect[0] /						   (gdouble) aiPixelAspect[1] *						   (gdouble) iWidth /						   (gdouble) iHeight;		}	}	else		g_print ("get_pad_movie_aspect() - Could not get caps for the pad!\n");	return fAspectRatio;}gint64 get_pipeline_current_position (GstElement* pPipeline){	GstFormat fmt = GST_FORMAT_TIME;	gint64 iPosition = 0L;	gst_element_query_position (pPipeline, &fmt, &iPosition);	return iPosition;}gint64 get_pipeline_total_duration (GstElement* pPipeline){	GstFormat fmt = GST_FORMAT_TIME;	gint64 iLength = 0L;	gst_element_query_duration (pPipeline, &fmt, &iLength);	return iLength;}void seek_to_time (GstElement* pPipeline,				   gint64 time_nanoseconds){	if (!gst_element_seek (pPipeline,						   1.0,						   GST_FORMAT_TIME,						   GST_SEEK_FLAG_FLUSH,						   GST_SEEK_TYPE_SET,						   time_nanoseconds,						   GST_SEEK_TYPE_NONE,						   GST_CLOCK_TIME_NONE))	{		g_print ("Seek failed!\n");	}}gboolean end_func (GtkWidget* pWidget,				   GdkEvent* pEvent,				   gpointer data){	gtk_main_quit ();	return TRUE;}gboolean draw_handler (GtkWidget* pWidget){	static gboolean bNeedsRedraw = FALSE;	if (g_bInitialized && g_mutex_trylock (g_pFrameBufferMutex))	{		glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_uiColorBuffer);		glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,					  0,					  GL_RGB,					  g_iWidth,					  g_iHeight,					  0,					  GL_RGB,					  GL_UNSIGNED_BYTE,					  g_pcFrameBuffer);		g_mutex_unlock (g_pFrameBufferMutex);		bNeedsRedraw = TRUE;	}	if (bNeedsRedraw)		gtk_widget_queue_draw (pWidget);	return TRUE;}void realize (GtkWidget* pWidget, gpointer data){	GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);	GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);	if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))		return;    glEnable (GL_BLEND);	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	glColor4f (0.0f, 0.0f, 0.0f, 0.0f);	glClearColor (0.0f, 0.0f, 0.0f, 0.0f);	glClearDepth (1.0f);	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );	glEnable (GL_NORMALIZE);	g_print ("OpenGL version: %s\n", glGetString (GL_VERSION));	g_print ("OpenGL vendor: %s\n", glGetString (GL_VENDOR));	g_print ("OpenGL renderer: %s\n", glGetString (GL_RENDERER));	gdk_gl_drawable_gl_end (pGlDrawable);}gboolean configure_event (GtkWidget* pWidget,						  GdkEventConfigure* pEvent,						  gpointer data){	GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);	GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);	GLsizei w = pWidget->allocation.width;	GLsizei h = pWidget->allocation.height;	if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))		return FALSE;	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glViewport (0, 0, w, h);	glMatrixMode (GL_PROJECTION);	glLoadIdentity ();	gluPerspective (2.0f * FOVY_2, (GLfloat) w / (GLfloat) h, 0.1f, 50.0f);	glMatrixMode (GL_MODELVIEW);	glLoadIdentity ();	gluLookAt (0.0f, 0.0f, Z_NEAR,			   0.0f, 0.0f, 0.0f,			   0.0f, 1.0f, 0.0f);	glTranslatef (0.0f, 0.0f, -Z_NEAR);	glEnable (GL_DEPTH_TEST);	glEnable (GL_TEXTURE_RECTANGLE_ARB);	glLineWidth (1.0f);	glEnable (GL_LIGHTING);	glEnable (GL_LIGHT0);	glPolygonMode (GL_BACK, GL_FILL);	glPolygonMode (GL_FRONT, GL_FILL);	glDisable (GL_CULL_FACE);	glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, 1.0f);	glEnable (GL_LINE_SMOOTH);	glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);	glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);	glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);	glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glGenTextures (1, &g_uiColorBuffer);	glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_uiColorBuffer);	glTexImage2D (GL_TEXTURE_RECTANGLE_ARB,				  0,				  GL_RGB,				  g_iWidth,				  g_iHeight,				  0,				  GL_RGB,				  GL_UNSIGNED_BYTE,				  NULL);	g_uiDisplayList = glGenLists (1);	gdk_gl_drawable_gl_end (pGlDrawable);	return TRUE;}static gboolean expose_event(GtkWidget* pWidget,							 GdkEventExpose* pEvent,							 gpointer data){	GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);	GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);	GLfloat afMatDiffuseFront[4] = {1.0f * g_afAlpha, 1.0f * g_afAlpha, 1.0f * g_afAlpha, g_afAlpha};	GLfloat afMatDiffuseBack[4] = {0.0f * g_afAlpha, 0.0f * g_afAlpha, 0.0f * g_afAlpha, g_afAlpha};	GLfloat afVector[3];	GLfloat afMatrixBase[16];	gulong ulMilliSeconds = 0L;	gdouble fFrameTimeDelta = 0.0f;	gdouble fFullSecond = 0.0f;	if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))		return FALSE;	glPushMatrix ();	glTranslatef (0.0f, 0.0f, 0.5f);	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glGetFloatv (GL_MODELVIEW_MATRIX, afMatrixBase);	afVector[0] = afMatrixBase[0];	afVector[1] = afMatrixBase[4];	afVector[2] = afMatrixBase[8];	glRotatef (g_afAngle[1] * 0.5f, afVector[0], afVector[1], afVector[2]);	afVector[0] = afMatrixBase[1];	afVector[1] = afMatrixBase[5];	afVector[2] = afMatrixBase[9];	glRotatef (g_afAngle[0] * 0.5f, afVector[0], afVector[1], afVector[2]);	glScalef (g_fScale, g_fScale, g_fScale);	glEnable (GL_TEXTURE_RECTANGLE_ARB);	glBindTexture (GL_TEXTURE_RECTANGLE_ARB, g_uiColorBuffer);	glMaterialfv (GL_FRONT, GL_DIFFUSE, afMatDiffuseFront);	glMaterialfv (GL_BACK, GL_DIFFUSE, afMatDiffuseBack);	glCallList (g_uiDisplayList);	glPopMatrix ();	if (gdk_gl_drawable_is_double_buffered (pGlDrawable))		gdk_gl_drawable_swap_buffers (pGlDrawable);	else		glFlush ();	gdk_gl_drawable_gl_end (pGlDrawable);	g_fCurrentTimeStamp = g_timer_elapsed (g_pTimerId, &ulMilliSeconds);	fFrameTimeDelta = g_fCurrentTimeStamp - g_fLastTimeStamp;	fFullSecond = g_fCurrentTimeStamp - g_fLastFullSecond;	if (fFullSecond < 1.0f)		g_iFrames++;	else	{		g_print ("fps: %d, last frame-time: %f\n", g_iFrames, fFrameTimeDelta);		g_iFrames = 0;		g_fLastFullSecond = g_fCurrentTimeStamp;	}	g_fLastTimeStamp = g_fCurrentTimeStamp;	return TRUE;}gboolean key_press_handler (GtkWidget* pWidget,							GdkEventKey* pEvent,							GMainLoop* pLoop){	static gboolean bPlaying = TRUE;	if (pEvent->type == GDK_KEY_PRESS)	{		switch (pEvent->keyval)		{			case GDK_q :			case GDK_Escape :				end_func (pWidget, NULL, NULL);			break;			case GDK_p :				if (bPlaying)				{					gst_element_set_state (g_pPipelineH264, GST_STATE_PAUSED);					g_print ("pipeline paused\n");					bPlaying = FALSE;				}				else				{					gst_element_set_state (g_pPipelineH264, GST_STATE_PLAYING);					g_print ("pipeline playing\n");					bPlaying = TRUE;				}			break;			case GDK_s :				g_main_loop_quit (pLoop);				g_print ("stopping playback\n");				gst_element_set_state (g_pPipelineH264, GST_STATE_NULL);				g_print ("deleting pipeline\n");				gst_object_unref (GST_OBJECT (g_pPipelineH264));				pLoop = NULL;				g_pPipelineH264 = NULL;			break;			default :			break;		}	}	return TRUE;}gboolean button_handler (GtkWidget* pWidget,						 GdkEventButton* pEvent,						 gpointer data){	switch (pEvent->button)	{		case 1:			if (pEvent->type == GDK_BUTTON_PRESS)			{				g_fCurrentX = pEvent->x;				g_fCurrentY = pEvent->y;				g_fLastX = g_fCurrentX;				g_fLastY = g_fCurrentY;				g_bLMBPressed = TRUE;			}			else if (pEvent->type == GDK_BUTTON_RELEASE)				g_bLMBPressed = FALSE;		break;		case 3:			if (pEvent->type == GDK_BUTTON_PRESS)			{				g_fCurrentX = pEvent->x;				g_fCurrentY = pEvent->y;				g_fLastX = g_fCurrentX;				g_fLastY = g_fCurrentY;				g_bRMBPressed = TRUE;			}			else if (pEvent->type == GDK_BUTTON_RELEASE)				g_bRMBPressed = FALSE;		break;	}	return TRUE;}gboolean scroll_handler (GtkWidget* pWidget,						 GdkEventScroll* pEvent,						 gpointer data){	switch (pEvent->direction)	{		case GDK_SCROLL_UP:			if (g_afAlpha < 1.0f)				g_afAlpha += 0.05f;		break;		case GDK_SCROLL_DOWN:			if (g_afAlpha > 0.0f)				g_afAlpha -= 0.05f;		break;		/* just silence gcc */		default:		break;	}	return TRUE;}gboolean motion_handler (GtkWidget* pWidget,						 GdkEventMotion *pEvent,						 gpointer data){	if (g_bLMBPressed)	{		g_fCurrentX = pEvent->x;		g_fCurrentY = pEvent->y;		g_fDeltaX = g_fLastX - g_fCurrentX;		g_fDeltaY = g_fLastY - g_fCurrentY;		g_fLastX = g_fCurrentX;		g_fLastY = g_fCurrentY;		g_afAngle[0] -= g_fDeltaX;		g_afAngle[1] -= g_fDeltaY;		gtk_widget_queue_draw (pWidget);	}	if (g_bRMBPressed)	{		g_fCurrentY = pEvent->y;		g_fDeltaY = g_fLastY - g_fCurrentY;		g_fLastY = g_fCurrentY;		g_fScale -= g_fDeltaY / 100.0f;		gtk_widget_queue_draw (pWidget);	}	return TRUE;}static gboolean bus_call (GstBus* pBus,						  GstMessage* pMessage,						  gpointer data){	GMainLoop* pLoop = data;	switch (GST_MESSAGE_TYPE (pMessage))	{		case GST_MESSAGE_EOS:			g_print ("End-of-stream\n");			g_main_loop_quit (pLoop);		break;		case GST_MESSAGE_ERROR:		{			gchar* pcDebug = NULL;			GError* pError = NULL;			gst_message_parse_error (pMessage, &pError, &pcDebug);			g_free (pcDebug);			g_print ("Error: %s\n", pError->message);			g_error_free (pError);			g_main_loop_quit (pLoop);			break;		}		default:		break;	}	return TRUE;}static void on_pad_added (GstElement* pDemuxer,						  GstPad* pPad,						  GstElement* pDecoder){	gchar* pcName = NULL;	pcName = gst_pad_get_name (pPad);	if (!g_ascii_strncasecmp (pcName, "video", 5))		if (!gst_element_link_pads (pDemuxer, pcName, pDecoder, "sink"))			g_print ("could not link demuxer with decoder\n");	g_free (pcName);}static void on_handoff (GstElement* pFakeSink,						GstBuffer* pBuffer,						GstPad* pPad,						GtkWidget* pWidget){	g_iWidth = get_pad_width (pPad);	g_iHeight = get_pad_height (pPad);	g_fMovieAspect = get_pad_movie_aspect (pPad);	if (g_bInitialized)	{		g_mutex_lock (g_pFrameBufferMutex);		g_memmove (g_pcFrameBuffer,				   GST_BUFFER_DATA (pBuffer),				   g_iWidth * g_iHeight * 3);		g_mutex_unlock (g_pFrameBufferMutex);	}}gboolean spit_out_clip_stats (GstPad* pVideoPad){	GLfloat afTexCoords[2] = {(GLfloat) g_iWidth, (GLfloat) g_iHeight};	g_print ("The video is %dx%d at %6.3f fps, movie-aspect is %3.2f:1\n",			 get_pad_width (pVideoPad),			 get_pad_height (pVideoPad),			 get_pad_fps (pVideoPad),			 get_pad_movie_aspect (pVideoPad));	g_mutex_lock (g_pFrameBufferMutex);	g_pcFrameBuffer = g_malloc0 (g_iWidth * g_iHeight * 3);	if (g_pcFrameBuffer)		g_bInitialized = TRUE;	g_mutex_unlock (g_pFrameBufferMutex);	if (g_uiDisplayList)	{		glNewList (g_uiDisplayList, GL_COMPILE);		glBegin (GL_QUADS);		glNormal3f (0.0f, 0.0f, 1.0f);		glTexCoord2f (afTexCoords[0], 0.0f);		glVertex3f (g_fMovieAspect, 1.0f, 0.0f);		glTexCoord2f (0.0f, 0.0f);		glVertex3f (-g_fMovieAspect, 1.0f, 0.0f);		glTexCoord2f (0.0f, afTexCoords[1]);		glVertex3f (-g_fMovieAspect, -1.0f, 0.0f);		glTexCoord2f (afTexCoords[0], afTexCoords[1]);		glVertex3f (g_fMovieAspect, -1.0f, 0.0f);		glEnd ();		glEndList ();	}	else		g_print ("configure_event() - Crap, no display-list was generated!\n");	/* remove callback after the first call */	return FALSE;}gboolean build_pipeline (gchar* pcFilename,						 GMainLoop** pLoopH264,						 GstElement** pPipelineH264,						 GstBusFunc busCallbackFunc,						 GCallback padAddedFunc,						 GstPad** pVideoPadH264,						 GCallback handoffHandlerFunc,						 gpointer pDrawingArea){	GstElement* pSourceH264 = NULL;	GstElement* pDemuxerH264 = NULL;	GstElement* pDecoderH264 = NULL;	GstElement* pVideoConverterH264  = NULL;	GstElement* pVideoSinkH264 = NULL;	*pLoopH264 = g_main_loop_new (NULL, FALSE);	*pPipelineH264 = gst_pipeline_new ("pipeline-h264");	gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (*pPipelineH264)),					   busCallbackFunc,					   *pLoopH264);	pSourceH264 = gst_element_factory_make ("filesrc", "source-h264");	g_object_set (G_OBJECT (pSourceH264), "location", pcFilename, NULL);	pDemuxerH264 = gst_element_factory_make ("qtdemux", "demuxer-h264");	pDecoderH264 = gst_element_factory_make ("ffdec_h264", "decoder-h264");	gst_bin_add_many (GST_BIN (*pPipelineH264), pSourceH264, pDemuxerH264, pDecoderH264, NULL);	if (!gst_element_link_pads (pSourceH264, "src", pDemuxerH264, "sink"))		g_print ("build_pipeline() - could not link filesrc with qtdemux\n");	g_signal_connect (pDemuxerH264, "pad-added", padAddedFunc, pDecoderH264);	pVideoH264 = gst_bin_new ("videobin-h264");	pVideoConverterH264 = gst_element_factory_make ("ffmpegcolorspace", "vconv");	*pVideoPadH264 = gst_element_get_pad (pVideoConverterH264, "sink");	pVideoSinkH264 = gst_element_factory_make ("fakesink", "sink-h264");	g_object_set (G_OBJECT (pVideoSinkH264), "sync", TRUE, "signal-handoffs", TRUE, NULL);	g_signal_connect (pVideoSinkH264, "handoff", handoffHandlerFunc, pDrawingArea);	gst_bin_add_many (GST_BIN (pVideoH264), pVideoConverterH264, pVideoSinkH264, NULL);	gst_element_link_filtered (pVideoConverterH264, pVideoSinkH264, gst_caps_new_simple ("video/x-raw-rgb", NULL));	gst_element_add_pad (pVideoH264, gst_ghost_pad_new ("sink", *pVideoPadH264));	gst_object_unref (*pVideoPadH264);	gst_bin_add (GST_BIN (*pPipelineH264), pVideoH264);	if (!gst_element_link_pads (pDecoderH264, "src", pVideoH264, "sink"))		g_print ("build_pipeline() - could not link ffdec_h264 with ffmpegcolorspace\n");	return TRUE;}int main (int argc, char** argv){	GtkWidget* pWindow = NULL;	GdkGLConfig* pGlConfig = NULL;	GtkWidget* pDrawingArea = NULL;	guint uiDrawHandlerId = 0;	gint iWidth;	gint iHeight;	GMainLoop* pLoopH264 = NULL;	GstPad* pVideoPadH264 = NULL;	g_thread_init (NULL);	gtk_init (&argc,&argv);	gtk_gl_init (&argc,&argv);	gst_init (&argc, &argv);	g_pFrameBufferMutex = g_mutex_new ();	pGlConfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB	 |										   GDK_GL_MODE_ALPHA |										   GDK_GL_MODE_DEPTH |										   GDK_GL_MODE_DOUBLE);	if (!pGlConfig)		return 1;	pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);	if (!pWindow)		return 2;	gtk_widget_add_events (pWindow,						   GDK_POINTER_MOTION_MASK |						   GDK_BUTTON_PRESS_MASK |						   GDK_BUTTON_RELEASE_MASK);	g_signal_connect (G_OBJECT (pWindow),					  "delete-event",					  G_CALLBACK (end_func),					  NULL);	g_signal_connect (G_OBJECT (pWindow),					  "button-press-event",					  G_CALLBACK (button_handler),					  NULL);	g_signal_connect (G_OBJECT (pWindow),					  "button-release-event",					  G_CALLBACK (button_handler),					  NULL);	g_signal_connect (G_OBJECT (pWindow),					  "scroll-event",					  G_CALLBACK (scroll_handler),					  NULL);	g_signal_connect (G_OBJECT (pWindow),					  "motion-notify-event",					  G_CALLBACK (motion_handler),					  (gpointer) pDrawingArea);	pDrawingArea = gtk_drawing_area_new ();	if (!pDrawingArea)		return 3;	iWidth = 800;	iHeight = 400;	gtk_widget_set_size_request (pDrawingArea, iWidth, iHeight);	gtk_widget_set_gl_capability (pDrawingArea,								  pGlConfig,								  NULL,								  TRUE,								  GDK_GL_RGBA_TYPE);	g_signal_connect_after (G_OBJECT (pDrawingArea),							"realize",							G_CALLBACK (realize),							NULL);	g_signal_connect (G_OBJECT (pDrawingArea),					  "configure-event",					  G_CALLBACK (configure_event),					  NULL);	g_signal_connect (G_OBJECT (pDrawingArea),					  "expose-event",					  G_CALLBACK (expose_event),					  NULL);	gtk_container_add (GTK_CONTAINER (pWindow), pDrawingArea);	gtk_widget_show (pDrawingArea);	gtk_window_set_resizable (GTK_WINDOW (pWindow), FALSE);	gtk_widget_set_app_paintable (pWindow, FALSE);	gtk_window_set_decorated (GTK_WINDOW (pWindow), TRUE);	gtk_widget_show (pWindow);	uiDrawHandlerId = g_timeout_add (16,									 (GSourceFunc) draw_handler,									 pDrawingArea);	g_pTimerId = g_timer_new ();	/* make sure we got some input */	if (argc != 2)	{		g_print ("Usage: %s <filename>\n", argv[0]);		return -1;	}	build_pipeline (argv[1],					&pLoopH264,					&g_pPipelineH264,					bus_call,					(GCallback) on_pad_added,					&pVideoPadH264,					(GCallback) on_handoff,					(gpointer) pDrawingArea);	g_signal_connect (G_OBJECT (pWindow),					  "key-press-event",					  G_CALLBACK (key_press_handler),					  pLoopH264);	g_timeout_add (1000, (GSourceFunc) spit_out_clip_stats, pVideoPadH264);	/* Now set to playing and iterate. */	gst_element_set_state (g_pPipelineH264, GST_STATE_PLAYING);	g_main_loop_run (pLoopH264);	gtk_main ();	glDeleteTextures (1, &g_uiColorBuffer);	if (g_bInitialized)	{		g_mutex_lock (g_pFrameBufferMutex);		g_free (g_pcFrameBuffer);		g_mutex_unlock (g_pFrameBufferMutex);	}	g_mutex_free (g_pFrameBufferMutex);	if (g_pPipelineH264)	{		gst_element_set_state (g_pPipelineH264, GST_STATE_NULL);		gst_object_unref (GST_OBJECT (g_pPipelineH264));	}	return 0;}