All pastes #54364 Raw Edit

MacSlow

public c v1 · immutable
#54364 ·published 2006-05-08 18:06 UTC
rendered paste body
#include <string.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};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;GLuint			g_uiFrameBuffer;GLuint			g_uiColorBuffer;GLuint			g_uiSomeTexture;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*		pPipeline = NULL;GstElement*		pVideo = NULL;gboolean		g_bGLInitialized = FALSE;gint next_power_of_two (gint iValue){	gint iResult = 1;	while (iValue > iResult)		iResult = iResult << 1;	return iResult;}gbooleanend_func (GtkWidget* pWidget,          GdkEvent* pEvent,          gpointer data){	gtk_main_quit ();	return TRUE;}gboolean draw_handler (GtkWidget* pWidget){	if (!g_bLMBPressed)	{		g_afAngle[0] += 2.1f;		g_afAngle[1] -= 1.6f;		g_afAngle[2] += 1.1f;		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);	/* OpenGL BEGIN */	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 );	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);	/* OpenGL END */}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;	/* OpenGL BEGIN */	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, 10.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_2D);	glLineWidth (2.5f);	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);	glGenTextures (1, &g_uiColorBuffer);	glBindTexture (GL_TEXTURE_2D, g_uiColorBuffer);	glTexImage2D (GL_TEXTURE_2D,				  0,				  GL_RGB,				  next_power_of_two (g_iWidth),				  next_power_of_two (g_iHeight),				  0,				  GL_RGB,				  GL_UNSIGNED_BYTE,				  NULL);	g_bGLInitialized = TRUE;	gdk_gl_drawable_gl_end (pGlDrawable);	/* OpenGL END */	return TRUE;}static gboolean expose_event(GtkWidget* pWidget,							 GdkEventExpose* pEvent,							 gpointer data){	GLfloat fAspectRatio = (GLfloat) g_iWidth / (GLfloat) g_iHeight;	GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);	GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);	GLfloat afAlpha = 1.0f;	GLfloat afMatDiffuseFront[4] = {0.5f * afAlpha, 0.25f * afAlpha, 0.125f * afAlpha, afAlpha};	GLfloat afMatAmbientFront[4] = {0.1f * afAlpha, 0.05f * afAlpha, 0.025f * afAlpha, afAlpha};	GLfloat afMatSpecularFront[4] = {0.5f * afAlpha, 0.45f * afAlpha, 0.4f * afAlpha, afAlpha};	GLfloat afMatDiffuseBack[4] = {0.0f * afAlpha, 0.0f * afAlpha, 0.5f * afAlpha, afAlpha};	GLfloat afMatAmbientBack[4] = {0.0f * afAlpha, 0.0f * afAlpha, 0.25f * afAlpha, afAlpha};	GLfloat afMatSpecularBack[4] = {0.4f * afAlpha, 0.4f * afAlpha, 0.5f * afAlpha, afAlpha};	GLfloat afVector[3];	GLfloat afMatrixBase[16];	gulong ulMilliSeconds = 0L;	gdouble fFrameTimeDelta = 0.0f;	gdouble fFullSecond = 0.0f;	GLfloat afTexCoords[2] = {(GLfloat) g_iWidth / (GLfloat) next_power_of_two (g_iWidth),							  (GLfloat) g_iHeight / (GLfloat) next_power_of_two (g_iHeight)};	/* OpenGL BEGIN */	if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))		return FALSE;	/* draw a spinning rectangle */	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]);	g_afAngle[0] = g_afAngle[1] = g_afAngle[2] = 0.0f;	glEnable (GL_TEXTURE_2D);	glBindTexture (GL_TEXTURE_2D, g_uiColorBuffer);	glBegin (GL_QUADS);	glColor4f (1.0f * afAlpha, 0.0f * afAlpha, 1.0f * afAlpha, afAlpha);	glMaterialfv (GL_FRONT, GL_DIFFUSE, afMatDiffuseFront);	glMaterialfv (GL_FRONT, GL_AMBIENT, afMatAmbientFront);	glMaterialfv (GL_FRONT, GL_SPECULAR, afMatSpecularFront);	glMaterialfv (GL_BACK, GL_DIFFUSE, afMatDiffuseBack);	glMaterialfv (GL_BACK, GL_AMBIENT, afMatAmbientBack);	glMaterialfv (GL_BACK, GL_SPECULAR, afMatSpecularBack);	glNormal3f (0.0f, 0.0f, 1.0f);	glTexCoord2f (0.0f, 0.0f);	glVertex3f (fAspectRatio, 1.0f, 0.0f);	glTexCoord2f (afTexCoords[0], 0.0f);	glVertex3f (-fAspectRatio, 1.0f, 0.0f);	glTexCoord2f (afTexCoords[0], afTexCoords[1]);	glVertex3f (-fAspectRatio, -1.0f, 0.0f);	glTexCoord2f (0.0f, afTexCoords[1]);	glVertex3f (fAspectRatio, -1.0f, 0.0f);	glEnd ();	if (gdk_gl_drawable_is_double_buffered (pGlDrawable))		gdk_gl_drawable_swap_buffers (pGlDrawable);	else		glFlush ();	gdk_gl_drawable_gl_end (pGlDrawable);	/* OpenGL END */	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,							gpointer data){	if (pEvent->type == GDK_KEY_PRESS)	{		switch (pEvent->keyval)		{			case GDK_q :			case GDK_Escape :				end_func (pWidget, NULL, data);			break;			default :			break;		}	}	return TRUE;}gbooleanbutton_handler (GtkWidget* pWidget,				GdkEventButton* pEvent,				gpointer data){	if (pEvent->button == 1 && 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->button == 1 && pEvent->type == GDK_BUTTON_RELEASE)		g_bLMBPressed = FALSE;	return TRUE;}gbooleanmotion_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);	}	return TRUE;}/*---8< 8<---*/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_newpad (GstElement* pDecodeBin,					   GstPad* pPad,					   gboolean bLast,					   gpointer data){	GstCaps* pCaps = NULL;	GstStructure* pStructure = NULL;	GstPad* pVideoPad = NULL;	/* only link once */	pVideoPad = gst_element_get_pad (pVideo, "sink");	if (GST_PAD_IS_LINKED (pVideoPad))	{		g_object_unref (pVideoPad);		return;	}	/* check media type */	pCaps = gst_pad_get_caps (pPad);	pStructure = gst_caps_get_structure (pCaps, 0);	if (!g_strrstr (gst_structure_get_name (pStructure), "video"))	{		gst_caps_unref (pCaps);		gst_object_unref (pVideoPad);	}	gst_caps_unref (pCaps);	gst_pad_link (pPad, pVideoPad);}static void on_handoff (GstElement* pFakeSink,						GstBuffer* pBuffer,						GstPad* pPad,						GtkWidget* pWidget){	GstCaps* pCaps = NULL;	GstStructure* pStructure = NULL;	gint iWidth;	gint iHeight;		pCaps = gst_pad_get_negotiated_caps (pPad);	if (pCaps)	{		pStructure = gst_caps_get_structure (pCaps, 0);		gst_structure_get_int (pStructure, "width", &iWidth);		gst_structure_get_int (pStructure, "height", &iHeight);	}	else		g_print ("on_handoff() - could not get the negotiated pad\n");	if (!g_bGLInitialized)		return;	glBindTexture (GL_TEXTURE_2D, g_uiColorBuffer);	glTexImage2D (GL_TEXTURE_2D,				  0,				  GL_RGB,				  next_power_of_two (iWidth),				  next_power_of_two (iHeight),				  0,				  GL_RGB,				  GL_UNSIGNED_BYTE,				  GST_BUFFER_DATA (pBuffer));	gtk_widget_queue_draw (pWidget);}gboolean spit_out_dims (GstPad* pVideoPad){	gint aiFrameRate[2] = {0, 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", &g_iWidth);		gst_structure_get_int (pStructure, "height", &g_iHeight);		gst_structure_get_fraction (pStructure,									"framerate",									&aiFrameRate[0],									&aiFrameRate[1]);		g_print ("The video is %dx%d at %6.3f fps (%dx%d)\n",				 g_iWidth,				 g_iHeight,				 (float) aiFrameRate[0] / (float) aiFrameRate[1],				 next_power_of_two (g_iWidth), 				 next_power_of_two (g_iHeight));	}	else		g_print ("get_dims() - could not get the negotiated pad\n");	/* remove callback after the first call */	return FALSE;}/*--->8 >8---*/int main (int argc, char** argv){	GtkWidget* pWindow = NULL;	GdkGLConfig* pGlConfig = NULL;	GtkWidget* pDrawingArea = NULL;	guint uiDrawHandlerId = 0;	gint iWidth;	gint iHeight;	GMainLoop* pLoop = NULL;	GstElement* pSource = NULL;	GstElement* pDecoder = NULL;	GstElement* pVideoConverter  = NULL;	GstElement* pVideoSink = NULL;	GstPad* pVideoPad = NULL;	gtk_init (&argc,&argv);	gtk_gl_init (&argc,&argv);	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),					  "key-press-event",					  G_CALLBACK (key_press_handler),					  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),					  "motion-notify-event",					  G_CALLBACK (motion_handler),					  (gpointer) pDrawingArea);	pDrawingArea = gtk_drawing_area_new ();	if (!pDrawingArea)		return 3;	iWidth = 800;	iHeight = 600;	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_decorated (GTK_WINDOW (pWindow), TRUE);	gtk_window_set_resizable (GTK_WINDOW (pWindow), TRUE);	gtk_widget_show (pWindow);	uiDrawHandlerId = g_timeout_add (16,									 (GSourceFunc) draw_handler,									 pDrawingArea);	g_pTimerId = g_timer_new ();	/* init GStreamer */	gst_init (&argc, &argv);	pLoop = g_main_loop_new (NULL, FALSE);	/* make sure we have input */	if (argc != 2)	{		g_print ("Usage: %s <filename>\n", argv[0]);		return -1;	}	/* setup */	pPipeline = gst_pipeline_new ("pipeline");	gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pPipeline)),					   bus_call,					   pLoop);	pSource = gst_element_factory_make ("filesrc", "source");	g_object_set (G_OBJECT (pSource), "location", argv[1], NULL);	pDecoder = gst_element_factory_make ("decodebin", "decoder");	g_signal_connect (pDecoder, "new-decoded-pad", G_CALLBACK (on_newpad), NULL);	gst_bin_add_many (GST_BIN (pPipeline), pSource, pDecoder, NULL);	gst_element_link (pSource, pDecoder);	/* create video output */	pVideo = gst_bin_new ("videobin");	pVideoConverter = gst_element_factory_make ("ffmpegcolorspace", "vconv");	pVideoPad = gst_element_get_pad (pVideoConverter, "sink");	pVideoSink = gst_element_factory_make ("fakesink", "sink");	g_object_set (G_OBJECT (pVideoSink),				  "sync", TRUE,				  "signal-handoffs", TRUE,				  NULL);	g_signal_connect (pVideoSink,					  "handoff",					  G_CALLBACK (on_handoff),					  (gpointer) pDrawingArea);	gst_bin_add_many (GST_BIN (pVideo),					  pVideoConverter,					  pVideoSink,					  NULL);	gst_element_link_filtered (pVideoConverter,							   pVideoSink,							   gst_caps_new_simple ("video/x-raw-rgb",													NULL));	gst_element_add_pad (pVideo, gst_ghost_pad_new ("sink", pVideoPad));	gst_object_unref (pVideoPad);	gst_bin_add (GST_BIN (pPipeline), pVideo);	g_timeout_add (1000, (GSourceFunc) spit_out_dims, pVideoPad);	/* Now set to playing and iterate. */	g_print ("Setting to PLAYING\n");	gst_element_set_state (pPipeline, GST_STATE_PLAYING);	g_print ("Running\n");	g_main_loop_run (pLoop);	gtk_main ();	glDeleteTextures (1, &g_uiColorBuffer);	/* clean up nicely */	g_print ("Returned, stopping playback\n");	gst_element_set_state (pPipeline, GST_STATE_NULL);	g_print ("Deleting pipeline\n");	gst_object_unref (GST_OBJECT (pPipeline));	return 0;}