mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
Add broken gst video widget
This commit is contained in:
parent
298f878086
commit
26decbdb97
28
ChangeLog
28
ChangeLog
@ -1,3 +1,31 @@
|
||||
2005-04-26 mallum,,, <mallum@openedhand.com>
|
||||
|
||||
* clutter/Makefile.am:
|
||||
* clutter/cltr-core.c: (cltr_init):
|
||||
* clutter/cltr-events.c: (cltr_events_init), (cltr_main_loop):
|
||||
* clutter/cltr-photo-grid.c:
|
||||
* clutter/cltr-private.h:
|
||||
* clutter/cltr-scratch.c: (cltr_scratch_handle_xevent),
|
||||
(cltr_scratch_paint):
|
||||
* clutter/cltr-texture.c: (cltr_texture_render_to_gl_quad),
|
||||
(init_tiles), (cltr_texture_unrealize), (cltr_texture_realize),
|
||||
(cltr_texture_new), (cltr_texture_no_tile_new),
|
||||
(cltr_texture_get_pixbuf):
|
||||
* clutter/cltr-texture.h:
|
||||
* clutter/cltr-video.c:
|
||||
* clutter/cltr-video.h:
|
||||
* clutter/cltr-widget.c: (cltr_widget_queue_paint):
|
||||
* clutter/cltr.h:
|
||||
* examples/Makefile.am:
|
||||
* examples/player.c:
|
||||
* gst/cltrimagesink.c: (gst_cltrimagesink_fixate),
|
||||
(gst_cltrimagesink_getcaps), (gst_cltrimagesink_sink_link),
|
||||
(gst_cltrimagesink_change_state), (gst_cltrimagesink_chain),
|
||||
(gst_cltrimagesink_set_property), (gst_cltrimagesink_get_property),
|
||||
(gst_cltrimagesink_finalize), (gst_cltrimagesink_class_init):
|
||||
* gst/cltrimagesink.h:
|
||||
Initial go at very hacky gst video widget
|
||||
|
||||
2005-04-22 mallum,,, <mallum@openedhand.com>
|
||||
|
||||
* clutter/Makefile.am:
|
||||
|
@ -7,6 +7,7 @@ source_h = pixbuf.h util.h fonts.h \
|
||||
cltr-widget.h \
|
||||
cltr-window.h \
|
||||
cltr-photo-grid.h \
|
||||
cltr-video.h \
|
||||
cltr-list.h \
|
||||
cltr-overlay.h \
|
||||
cltr-button.h \
|
||||
@ -20,16 +21,17 @@ source_c = pixbuf.c util.c fonts.c \
|
||||
cltr-events.c \
|
||||
cltr-window.c \
|
||||
cltr-photo-grid.c \
|
||||
cltr-video.c \
|
||||
cltr-list.c \
|
||||
cltr-overlay.c \
|
||||
cltr-button.c \
|
||||
cltr-scratch.c
|
||||
|
||||
AM_CFLAGS = @GCC_FLAGS@ @CLTR_CFLAGS@
|
||||
AM_CFLAGS = @GCC_FLAGS@ @CLTR_CFLAGS@ $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libclutter.la
|
||||
libclutter_la_SOURCES = $(source_c) $(source_h)
|
||||
libclutter_la_LIBADD = @CLTR_LIBS@
|
||||
libclutter_la_LIBADD = @CLTR_LIBS@ $(GST_LIBS) $(GCONF_LIBS)
|
||||
|
||||
# http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91
|
||||
# current : revision : age
|
||||
|
@ -34,6 +34,8 @@ cltr_init(int *argc, char ***argv)
|
||||
|
||||
XVisualInfo *vinfo;
|
||||
|
||||
gst_init (argc, argv);
|
||||
|
||||
if (!g_thread_supported ())
|
||||
g_thread_init (NULL);
|
||||
// XInitThreads ();
|
||||
|
@ -137,7 +137,7 @@ cltr_events_init()
|
||||
g_source_attach (source, gmain_context);
|
||||
g_source_unref (source);
|
||||
|
||||
ctx->internal_event_q = g_queue_new();
|
||||
ctx->internal_event_q = g_async_queue_new();
|
||||
}
|
||||
|
||||
void
|
||||
@ -155,12 +155,12 @@ cltr_main_loop()
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!g_queue_is_empty (ctx->internal_event_q))
|
||||
if (g_async_queue_length (ctx->internal_event_q))
|
||||
{
|
||||
CltrWindow *win = CLTR_WINDOW(ctx->window);
|
||||
|
||||
/* Empty the queue */
|
||||
while (g_queue_pop_head(ctx->internal_event_q) != NULL) ;
|
||||
while (g_async_queue_try_pop(ctx->internal_event_q) != NULL) ;
|
||||
|
||||
/* Repaint everything visible from window down - URG.
|
||||
* GL workings make it difficult to paint single part with
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
*/
|
||||
|
||||
#define FPS_TO_TIMEOUT(t) (1000/(t))
|
||||
|
||||
|
||||
struct CltrPhotoGridCell
|
||||
{
|
||||
|
@ -65,11 +65,13 @@ struct ClutterMainContext
|
||||
GLXContext gl_context;
|
||||
|
||||
CltrWidget *window;
|
||||
GQueue *internal_event_q;
|
||||
GAsyncQueue *internal_event_q;
|
||||
};
|
||||
|
||||
ClutterMainContext CltrCntx;
|
||||
|
||||
#define CLTR_CONTEXT() &CltrCntx
|
||||
|
||||
#define FPS_TO_TIMEOUT(t) (1000/(t))
|
||||
|
||||
#endif
|
||||
|
@ -67,7 +67,7 @@ cltr_scratch_handle_xevent (CltrWidget *widget, XEvent *xev)
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_scratch_paint(CltrWidget *widget)
|
||||
cltr_scratch_paint_old(CltrWidget *widget)
|
||||
{
|
||||
CltrScratch *scratch = CLTR_SCRATCH(widget);
|
||||
|
||||
@ -120,8 +120,10 @@ cltr_scratch_paint(CltrWidget *widget)
|
||||
|
||||
|
||||
static void
|
||||
cltr_scratch_paint_old(CltrWidget *widget)
|
||||
cltr_scratch_paint(CltrWidget *widget)
|
||||
{
|
||||
CltrScratch *scratch = CLTR_SCRATCH(widget);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
CLTR_MARK();
|
||||
@ -136,6 +138,15 @@ cltr_scratch_paint_old(CltrWidget *widget)
|
||||
widget->x + widget->width,
|
||||
widget->y + widget->height);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
cltr_texture_render_to_gl_quad(scratch->tex,
|
||||
widget->x,
|
||||
widget->y,
|
||||
widget->x + widget->width ,
|
||||
widget->y + widget->height);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
|
@ -32,8 +32,8 @@ cltr_texture_render_to_gl_quad(CltrTexture *texture,
|
||||
int x2,
|
||||
int y2)
|
||||
{
|
||||
int qx1, qx2, qy1, qy2;
|
||||
int qwidth, qheight;
|
||||
int qx1 = 0, qx2 = 0, qy1 = 0, qy2 = 0;
|
||||
int qwidth = 0, qheight = 0;
|
||||
int x, y, i =0, lastx = 0, lasty = 0;
|
||||
float tx, ty;
|
||||
|
||||
@ -43,6 +43,29 @@ cltr_texture_render_to_gl_quad(CltrTexture *texture,
|
||||
if (texture->tiles == NULL)
|
||||
cltr_texture_realize(texture);
|
||||
|
||||
if (!texture->tiled)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
|
||||
|
||||
tx = (float) texture->pixb->width / texture->width;
|
||||
ty = (float) texture->pixb->height / texture->height;
|
||||
|
||||
qx1 = x1;
|
||||
qx2 = x2;
|
||||
|
||||
qy1 = y1;
|
||||
qy2 = y2;
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (tx, ty); glVertex2i (qx2, qy2);
|
||||
glTexCoord2f (0, ty); glVertex2i (qx1, qy2);
|
||||
glTexCoord2f (0, 0); glVertex2i (qx1, qy1);
|
||||
glTexCoord2f (tx, 0); glVertex2i (qx2, qy1);
|
||||
glEnd ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (x=0; x < texture->n_x_tiles; x++)
|
||||
{
|
||||
lasty = 0;
|
||||
@ -239,10 +262,15 @@ cltr_texture_unrealize(CltrTexture *texture)
|
||||
if (texture->tiles == NULL)
|
||||
return;
|
||||
|
||||
glDeleteTextures(texture->n_x_tiles * texture->n_y_tiles, texture->tiles);
|
||||
if (!texture->tiled)
|
||||
glDeleteTextures(1, texture->tiles);
|
||||
else
|
||||
glDeleteTextures(texture->n_x_tiles * texture->n_y_tiles, texture->tiles);
|
||||
|
||||
g_free(texture->tiles);
|
||||
|
||||
texture->tiles = NULL;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -250,8 +278,41 @@ cltr_texture_realize(CltrTexture *texture)
|
||||
{
|
||||
int x, y, i = 0;
|
||||
|
||||
texture->tiles = g_new (GLuint, texture->n_x_tiles * texture->n_y_tiles);
|
||||
glGenTextures (texture->n_x_tiles * texture->n_y_tiles, texture->tiles);
|
||||
if (!texture->tiled)
|
||||
{
|
||||
if (!texture->tiles)
|
||||
{
|
||||
texture->tiles = g_new (GLuint, 1);
|
||||
glGenTextures (1, texture->tiles);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, /*GL_COMPRESSED_RGBA_ARB*/ GL_RGBA,
|
||||
texture->width,
|
||||
texture->height,
|
||||
0, GL_RGBA,
|
||||
GL_UNSIGNED_INT_8_8_8_8,
|
||||
NULL);
|
||||
|
||||
CLTR_GLERR();
|
||||
|
||||
cltr_texture_sync_pixbuf(texture);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!texture->tiles)
|
||||
{
|
||||
texture->tiles = g_new (GLuint, texture->n_x_tiles * texture->n_y_tiles);
|
||||
glGenTextures (texture->n_x_tiles * texture->n_y_tiles, texture->tiles);
|
||||
}
|
||||
|
||||
for (x=0; x < texture->n_x_tiles; x++)
|
||||
for (y=0; y < texture->n_y_tiles; y++)
|
||||
@ -259,41 +320,40 @@ cltr_texture_realize(CltrTexture *texture)
|
||||
Pixbuf *pixtmp;
|
||||
int src_h, src_w;
|
||||
|
||||
|
||||
|
||||
src_w = texture->tile_x_size[x];
|
||||
src_h = texture->tile_y_size[y];
|
||||
|
||||
|
||||
/*
|
||||
CLTR_DBG("%i+%i, %ix%i to %ix%i, waste %ix%i",
|
||||
texture->tile_x_position[x],
|
||||
texture->tile_y_position[y],
|
||||
texture->tile_x_size[x],
|
||||
texture->tile_y_size[y],
|
||||
texture->width,
|
||||
texture->height,
|
||||
texture->tile_x_waste[x],
|
||||
texture->tile_y_waste[y]);
|
||||
CLTR_DBG("%i+%i, %ix%i to %ix%i, waste %ix%i",
|
||||
texture->tile_x_position[x],
|
||||
texture->tile_y_position[y],
|
||||
texture->tile_x_size[x],
|
||||
texture->tile_y_size[y],
|
||||
texture->width,
|
||||
texture->height,
|
||||
texture->tile_x_waste[x],
|
||||
texture->tile_y_waste[y]);
|
||||
*/
|
||||
|
||||
|
||||
/* Only break the pixbuf up if we have multiple tiles */
|
||||
if (texture->n_x_tiles > 1 && texture->n_y_tiles >1)
|
||||
{
|
||||
pixtmp = pixbuf_new(texture->tile_x_size[x],
|
||||
texture->tile_y_size[y]);
|
||||
|
||||
pixbuf_copy(texture->pixb,
|
||||
pixtmp,
|
||||
texture->tile_x_position[x],
|
||||
texture->tile_y_position[y],
|
||||
texture->tile_x_size[x],
|
||||
texture->tile_y_size[y],
|
||||
0,0);
|
||||
}
|
||||
else pixtmp = texture->pixb;
|
||||
|
||||
/* if (texture->n_x_tiles > 1 && texture->n_y_tiles >1) */
|
||||
{
|
||||
pixtmp = pixbuf_new(texture->tile_x_size[x],
|
||||
texture->tile_y_size[y]);
|
||||
|
||||
pixbuf_copy(texture->pixb,
|
||||
pixtmp,
|
||||
texture->tile_x_position[x],
|
||||
texture->tile_y_position[y],
|
||||
texture->tile_x_size[x],
|
||||
texture->tile_y_size[y],
|
||||
0,0);
|
||||
}
|
||||
/* else pixtmp = texture->pixb; */
|
||||
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tiles[i]);
|
||||
|
||||
|
||||
CLTR_GLERR();
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
@ -311,12 +371,16 @@ cltr_texture_realize(CltrTexture *texture)
|
||||
|
||||
CLTR_GLERR();
|
||||
|
||||
if (pixtmp != texture->pixb)
|
||||
pixbuf_unref(pixtmp);
|
||||
|
||||
CLTR_DBG("pixtmp is %ix%i texture %ix%i\n",
|
||||
pixtmp->width, pixtmp->height,
|
||||
texture->width, texture->height);
|
||||
|
||||
pixbuf_unref(pixtmp);
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CltrTexture*
|
||||
@ -324,24 +388,55 @@ cltr_texture_new(Pixbuf *pixb)
|
||||
{
|
||||
CltrTexture *texture;
|
||||
|
||||
|
||||
CLTR_MARK();
|
||||
|
||||
texture = g_malloc0(sizeof(CltrTexture));
|
||||
|
||||
texture->width = pixb->width;
|
||||
texture->height = pixb->height;
|
||||
texture->tiled = TRUE;
|
||||
|
||||
/* maybe we should copy the pixbuf - a change to refed one would explode */
|
||||
texture->pixb = pixb;
|
||||
texture->mutex = g_mutex_new();
|
||||
|
||||
pixbuf_ref(pixb);
|
||||
|
||||
|
||||
|
||||
init_tiles (texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
CltrTexture*
|
||||
cltr_texture_no_tile_new(Pixbuf *pixb)
|
||||
{
|
||||
CltrTexture *texture;
|
||||
|
||||
CLTR_MARK();
|
||||
|
||||
texture = g_malloc0(sizeof(CltrTexture));
|
||||
|
||||
texture->tiled = FALSE;
|
||||
texture->width = next_p2(pixb->width);
|
||||
texture->height = next_p2(pixb->height);
|
||||
|
||||
if (!can_create (texture->width, texture->height))
|
||||
{
|
||||
free(texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
texture->pixb = pixb;
|
||||
texture->mutex = g_mutex_new();
|
||||
|
||||
pixbuf_ref(pixb);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
Pixbuf*
|
||||
cltr_texture_get_pixbuf(CltrTexture* texture)
|
||||
{
|
||||
@ -349,7 +444,62 @@ cltr_texture_get_pixbuf(CltrTexture* texture)
|
||||
}
|
||||
|
||||
void
|
||||
cltr_texture_resync_pixbuf(CltrTexture* texture)
|
||||
cltr_texture_lock(CltrTexture* texture)
|
||||
{
|
||||
cltr_texture_unrealize(texture);
|
||||
g_mutex_lock(texture->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
cltr_texture_unlock(CltrTexture* texture)
|
||||
{
|
||||
g_mutex_unlock(texture->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
cltr_texture_sync_pixbuf(CltrTexture* texture)
|
||||
{
|
||||
if (texture->tiled)
|
||||
{
|
||||
cltr_texture_realize(texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
|
||||
texture->pixb->width,
|
||||
texture->pixb->height,
|
||||
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
|
||||
texture->pixb->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a nasty hack to work round me not figuring out
|
||||
* how to get RGBA data out of gstreamer in a format clutters
|
||||
* GL setup can handle :(
|
||||
*
|
||||
* The good side is it probably speeds video playback up by
|
||||
* avoiding copys of frame data.
|
||||
*/
|
||||
void
|
||||
cltr_texture_force_rgb_data(CltrTexture *texture,
|
||||
int width,
|
||||
int height,
|
||||
int *data)
|
||||
{
|
||||
if (texture->tiled)
|
||||
return;
|
||||
|
||||
if (!texture->tiles)
|
||||
cltr_texture_realize(texture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->tiles[0]);
|
||||
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
|
||||
width,
|
||||
height,
|
||||
GL_RGB, GL_UNSIGNED_BYTE,
|
||||
data);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "cltr.h"
|
||||
|
||||
typedef struct CltrTexture CltrTexture;
|
||||
|
||||
|
||||
struct CltrTexture
|
||||
{
|
||||
@ -11,12 +11,16 @@ struct CltrTexture
|
||||
|
||||
int width, height;
|
||||
|
||||
gboolean tiled;
|
||||
|
||||
int n_x_tiles, n_y_tiles;
|
||||
int *tile_x_position, *tile_x_size, *tile_x_waste;
|
||||
int *tile_y_position, *tile_y_size, *tile_y_waste;
|
||||
|
||||
GLuint *tiles;
|
||||
|
||||
GMutex *mutex;
|
||||
|
||||
gint refcnt;
|
||||
};
|
||||
|
||||
@ -24,6 +28,9 @@ struct CltrTexture
|
||||
CltrTexture*
|
||||
cltr_texture_new(Pixbuf *pixb);
|
||||
|
||||
CltrTexture*
|
||||
cltr_texture_no_tile_new(Pixbuf *pixb);
|
||||
|
||||
void
|
||||
cltr_texture_unrealize(CltrTexture *texture);
|
||||
|
||||
@ -41,7 +48,19 @@ Pixbuf*
|
||||
cltr_texture_get_pixbuf(CltrTexture* texture);
|
||||
|
||||
void
|
||||
cltr_texture_resync_pixbuf(CltrTexture* texture);
|
||||
cltr_texture_lock(CltrTexture* texture);
|
||||
|
||||
void
|
||||
cltr_texture_unlock(CltrTexture* texture);
|
||||
|
||||
void
|
||||
cltr_texture_sync_pixbuf(CltrTexture* texture);
|
||||
|
||||
void
|
||||
cltr_texture_force_rgb_data(CltrTexture *texture,
|
||||
int width,
|
||||
int height,
|
||||
int *data);
|
||||
|
||||
|
||||
#endif
|
||||
|
425
clutter/cltr-video.c
Normal file
425
clutter/cltr-video.c
Normal file
@ -0,0 +1,425 @@
|
||||
#include "cltr-video.h"
|
||||
#include "cltr-private.h"
|
||||
|
||||
struct CltrVideo
|
||||
{
|
||||
CltrWidget widget;
|
||||
|
||||
GstPlay *play;
|
||||
GstElement *data_src, *video_sink, *audio_sink, *vis_element;
|
||||
|
||||
GAsyncQueue *queue;
|
||||
|
||||
int video_width, video_height;
|
||||
CltrTexture *frame_texture;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
cltr_video_show(CltrWidget *widget);
|
||||
|
||||
static gboolean
|
||||
cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev);
|
||||
|
||||
static void
|
||||
cltr_video_paint(CltrWidget *widget);
|
||||
|
||||
|
||||
|
||||
static gint64 length = 0; /* to go */
|
||||
|
||||
static void
|
||||
cltr_video_print_tag (const GstTagList *list,
|
||||
const gchar *tag,
|
||||
gpointer unused)
|
||||
{
|
||||
gint i, count;
|
||||
|
||||
count = gst_tag_list_get_tag_size (list, tag);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
gchar *str;
|
||||
|
||||
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
|
||||
if (!gst_tag_list_get_string_index (list, tag, i, &str))
|
||||
g_assert_not_reached ();
|
||||
} else {
|
||||
str =
|
||||
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
g_print ("%15s: %s\n", gst_tag_get_nick (tag), str);
|
||||
} else {
|
||||
g_print (" : %s\n", str);
|
||||
}
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_got_found_tag (GstPlay *play,
|
||||
GstElement *source,
|
||||
GstTagList *tag_list,
|
||||
CltrVideo *video)
|
||||
{
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
signal = g_new0 (CltrVideoSignal, 1);
|
||||
signal->signal_id = CLTR_VIDEO_ASYNC_FOUND_TAG;
|
||||
signal->signal_data.found_tag.source = source;
|
||||
signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list);
|
||||
|
||||
g_async_queue_push (video->queue, signal);
|
||||
|
||||
/* gst_tag_list_foreach (tag_list, cltr_video_print_tag, NULL); */
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_got_time_tick (GstPlay *play,
|
||||
gint64 time_nanos,
|
||||
CltrVideo *video)
|
||||
{
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
/*
|
||||
signal = g_new0 (CltrVideoSignal, 1);
|
||||
signal->signal_id = CLTR_VIDEO_ASYNC_FOUND_TAG;
|
||||
signal->signal_data.found_tag.source = source;
|
||||
signal->signal_data.found_tag.tag_list = gst_tag_list_copy (tag_list);
|
||||
|
||||
g_async_queue_push (video->queue, signal);
|
||||
*/
|
||||
|
||||
g_print ("time tick %f\n", time_nanos / (float) GST_SECOND);
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_got_stream_length (GstPlay *play,
|
||||
gint64 length_nanos,
|
||||
CltrVideo *video)
|
||||
{
|
||||
/*
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
signal = g_new0 (CltrVideoSignal, 1);
|
||||
|
||||
signal->signal_id = CLTR_VIDEO_ASYNC_VIDEO_SIZE;
|
||||
signal->signal_data.video_size.width = width;
|
||||
signal->signal_data.video_size.height = height;
|
||||
|
||||
g_async_queue_push (video->queue, signal);
|
||||
*/
|
||||
CLTR_DBG ("got length %" G_GUINT64_FORMAT "\n", length_nanos);
|
||||
length = length_nanos;
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_got_video_size (GstPlay *play,
|
||||
gint width,
|
||||
gint height,
|
||||
CltrVideo *video)
|
||||
{
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
signal = g_new0 (CltrVideoSignal, 1);
|
||||
|
||||
signal->signal_id = CLTR_VIDEO_ASYNC_VIDEO_SIZE;
|
||||
signal->signal_data.video_size.width = width;
|
||||
signal->signal_data.video_size.height = height;
|
||||
|
||||
g_async_queue_push (video->queue, signal);
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_got_eos (GstPlay* play, CltrVideo *video)
|
||||
{
|
||||
CLTR_DBG ("End Of Stream\n");
|
||||
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
signal = g_new0 (CltrVideoSignal, 1);
|
||||
|
||||
signal->signal_id = CLTR_VIDEO_ASYNC_EOS;
|
||||
|
||||
g_async_queue_push (video->queue, signal);
|
||||
|
||||
gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cltr_video_seek_timer (GstPlay * play)
|
||||
{
|
||||
gst_play_seek_to_time (play, length / 2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
caps_set (GObject *obj,
|
||||
GParamSpec *pspec,
|
||||
CltrVideo *video)
|
||||
{
|
||||
GstPad *pad = GST_PAD (obj);
|
||||
GstStructure *s;
|
||||
|
||||
if (!GST_PAD_CAPS (pad))
|
||||
return;
|
||||
|
||||
s = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
|
||||
|
||||
if (s) {
|
||||
|
||||
|
||||
const GValue *par;
|
||||
|
||||
if (!(gst_structure_get_double (s, "framerate", &bvw->priv->video_fps) &&
|
||||
gst_structure_get_int (s, "width", &bvw->priv->video_width) &&
|
||||
gst_structure_get_int (s, "height", &bvw->priv->video_height)))
|
||||
return;
|
||||
if ((par = gst_structure_get_value (s,
|
||||
"pixel-aspect-ratio"))) {
|
||||
gint num = gst_value_get_fraction_numerator (par),
|
||||
den = gst_value_get_fraction_denominator (par);
|
||||
|
||||
if (num > den)
|
||||
bvw->priv->video_width *= (gfloat) num / den;
|
||||
else
|
||||
bvw->priv->video_height *= (gfloat) den / num;
|
||||
}
|
||||
|
||||
got_video_size (bvw->priv->play, bvw->priv->video_width,
|
||||
bvw->priv->video_height, bvw);
|
||||
}
|
||||
*/
|
||||
/* and disable ourselves */
|
||||
//g_signal_handlers_disconnect_by_func (pad, caps_set, bvw);
|
||||
}
|
||||
|
||||
|
||||
CltrWidget*
|
||||
cltr_video_new(int width, int height)
|
||||
{
|
||||
CltrVideo *video;
|
||||
GError *error = NULL;
|
||||
|
||||
video = g_malloc0(sizeof(CltrVideo));
|
||||
|
||||
video->widget.width = width;
|
||||
video->widget.height = height;
|
||||
|
||||
video->widget.show = cltr_video_show;
|
||||
video->widget.paint = cltr_video_paint;
|
||||
|
||||
video->widget.xevent_handler = cltr_video_handle_xevent;
|
||||
|
||||
/* Creating the GstPlay object */
|
||||
|
||||
video->play = gst_play_new (&error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_print ("Error: could not create play object:\n%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Getting default audio and video plugins from GConf */
|
||||
video->vis_element = gst_element_factory_make ("goom", "vis_element");
|
||||
video->data_src = gst_element_factory_make ("gnomevfssrc", "source");
|
||||
|
||||
video->audio_sink = gst_gconf_get_default_audio_sink ();
|
||||
|
||||
if (!GST_IS_ELEMENT (video->audio_sink))
|
||||
g_error ("Could not get default audio sink from GConf");
|
||||
|
||||
video->video_sink = gst_element_factory_make ("cltrimagesink", "cltr-output");
|
||||
|
||||
if (!GST_IS_ELEMENT (video->video_sink))
|
||||
g_error ("Could not get clutter video sink");
|
||||
|
||||
video->queue = g_async_queue_new ();
|
||||
|
||||
gst_element_set(video->video_sink, "queue", video->queue, NULL);
|
||||
|
||||
/* Let's send them to GstPlay object */
|
||||
|
||||
if (!gst_play_set_audio_sink (video->play, video->audio_sink))
|
||||
g_warning ("Could not set audio sink");
|
||||
if (!gst_play_set_video_sink (video->play, video->video_sink))
|
||||
g_warning ("Could not set video sink");
|
||||
if (!gst_play_set_data_src (video->play, video->data_src))
|
||||
g_warning ("Could not set data src");
|
||||
if (!gst_play_set_visualization (video->play, video->vis_element))
|
||||
g_warning ("Could not set visualisation");
|
||||
|
||||
/* Setting location we want to play */
|
||||
|
||||
/* Uncomment that line to get an XML dump of the pipeline */
|
||||
/* gst_xml_write_file (GST_ELEMENT (play), stdout); */
|
||||
|
||||
g_signal_connect (G_OBJECT (video->play), "time_tick",
|
||||
G_CALLBACK (cltr_video_got_time_tick), video);
|
||||
g_signal_connect (G_OBJECT (video->play), "stream_length",
|
||||
G_CALLBACK (cltr_video_got_stream_length), video);
|
||||
g_signal_connect (G_OBJECT (video->play), "have_video_size",
|
||||
G_CALLBACK (cltr_video_got_video_size), video);
|
||||
g_signal_connect (G_OBJECT (video->play), "found_tag",
|
||||
G_CALLBACK (cltr_video_got_found_tag), video);
|
||||
g_signal_connect (G_OBJECT (video->play), "error",
|
||||
G_CALLBACK (gst_element_default_error), NULL);
|
||||
g_signal_connect (G_OBJECT (video->play),
|
||||
"eos", G_CALLBACK (cltr_video_got_eos), video);
|
||||
|
||||
g_signal_connect (G_OBJECT (video->video_sink), "notify::caps",
|
||||
G_CALLBACK (caps_set), video);
|
||||
|
||||
|
||||
/*
|
||||
g_object_set (G_OBJECT (video->play), "volume",
|
||||
(gdouble) (1. * 0 / 100), NULL);
|
||||
*/
|
||||
|
||||
/* gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY); */
|
||||
|
||||
return CLTR_WIDGET(video);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
cltr_video_idler (CltrVideo *video)
|
||||
{
|
||||
gint queue_length;
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
signal = g_async_queue_try_pop (video->queue);
|
||||
|
||||
if (!signal)
|
||||
return TRUE;
|
||||
|
||||
switch (signal->signal_id)
|
||||
{
|
||||
case CLTR_VIDEO_ASYNC_TEXTURE:
|
||||
video->frame_texture = signal->signal_data.texture.ref;
|
||||
|
||||
/*
|
||||
* we can actually grab the width and height from
|
||||
* the textures pixbuf.
|
||||
*/
|
||||
|
||||
cltr_widget_queue_paint(CLTR_WIDGET(video));
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_VIDEO_SIZE:
|
||||
video->video_width = signal->signal_data.video_size.width;
|
||||
video->video_height = signal->signal_data.video_size.height;
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_ERROR:
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_FOUND_TAG:
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_NOTIFY_STREAMINFO:
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_EOS:
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_BUFFERING:
|
||||
break;
|
||||
case CLTR_VIDEO_ASYNC_REDIRECT:
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (signal);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cltr_video_set_source(CltrVideo *video, char *location)
|
||||
{
|
||||
if (!gst_play_set_location (video->play, location))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
cltr_video_play(CltrVideo *video)
|
||||
{
|
||||
/* Change state to PLAYING */
|
||||
if (gst_element_set_state (GST_ELEMENT (video->play),
|
||||
GST_STATE_PLAYING) == GST_STATE_FAILURE)
|
||||
g_error ("Could not set state to PLAYING");
|
||||
|
||||
g_timeout_add(FPS_TO_TIMEOUT(20), (GSourceFunc) cltr_video_idler, video);
|
||||
}
|
||||
|
||||
void
|
||||
cltr_video_pause(CltrVideo *video)
|
||||
{
|
||||
if (gst_element_set_state (GST_ELEMENT (video->play),
|
||||
GST_STATE_PAUSED) == GST_STATE_FAILURE)
|
||||
g_error ("Could not set state to PAUSED");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cltr_video_show(CltrWidget *widget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_hide(CltrWidget *widget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cltr_video_handle_xevent (CltrWidget *widget, XEvent *xev)
|
||||
{
|
||||
CLTR_DBG("X Event");
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
cltr_video_paint(CltrWidget *widget)
|
||||
{
|
||||
CltrVideo *video = CLTR_VIDEO(widget);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
if (video->frame_texture
|
||||
&& video->video_height
|
||||
&& video->video_width)
|
||||
{
|
||||
int dis_x, dis_y, dis_height, dis_width;
|
||||
|
||||
if (video->video_width > video->video_height)
|
||||
{
|
||||
dis_width = widget->width;
|
||||
dis_height = ( video->video_height * widget->width )
|
||||
/ video->video_width;
|
||||
dis_y = (widget->height - dis_height)/2;
|
||||
dis_x = 0;
|
||||
}
|
||||
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
cltr_texture_lock(video->frame_texture);
|
||||
|
||||
cltr_texture_render_to_gl_quad(video->frame_texture,
|
||||
dis_x,
|
||||
dis_y,
|
||||
dis_x + dis_width,
|
||||
dis_y + dis_height);
|
||||
|
||||
cltr_texture_unlock(video->frame_texture);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
73
clutter/cltr-video.h
Normal file
73
clutter/cltr-video.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef _HAVE_CLTR_VIDEO_H
|
||||
#define _HAVE_CLTR_VIDEO_H
|
||||
|
||||
#include "cltr.h"
|
||||
|
||||
#include <gst/play/play.h>
|
||||
#include <gst/gconf/gconf.h>
|
||||
|
||||
typedef struct CltrVideo CltrVideo;
|
||||
|
||||
/* Signals - cltrimagesink needs to deliver texture signals :/ */
|
||||
|
||||
enum {
|
||||
CLTR_VIDEO_ASYNC_TEXTURE,
|
||||
CLTR_VIDEO_ASYNC_VIDEO_SIZE,
|
||||
CLTR_VIDEO_ASYNC_ERROR,
|
||||
CLTR_VIDEO_ASYNC_FOUND_TAG,
|
||||
CLTR_VIDEO_ASYNC_NOTIFY_STREAMINFO,
|
||||
CLTR_VIDEO_ASYNC_EOS,
|
||||
CLTR_VIDEO_ASYNC_BUFFERING,
|
||||
CLTR_VIDEO_ASYNC_REDIRECT
|
||||
};
|
||||
|
||||
typedef struct CltrVideoSignal
|
||||
{
|
||||
gint signal_id;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
} video_size;
|
||||
struct
|
||||
{
|
||||
GstElement *element;
|
||||
GError *error;
|
||||
char *debug_message;
|
||||
} error;
|
||||
struct
|
||||
{
|
||||
GstElement *source;
|
||||
GstTagList *tag_list;
|
||||
} found_tag;
|
||||
struct
|
||||
{
|
||||
gint percent;
|
||||
} buffering;
|
||||
struct
|
||||
{
|
||||
gchar *new_location;
|
||||
} redirect;
|
||||
struct
|
||||
{
|
||||
CltrTexture *ref;
|
||||
} texture;
|
||||
} signal_data;
|
||||
}
|
||||
CltrVideoSignal;
|
||||
|
||||
#define CLTR_VIDEO(w) ((CltrVideo*)(w))
|
||||
|
||||
CltrWidget*
|
||||
cltr_video_new(int width, int height);
|
||||
|
||||
gboolean
|
||||
cltr_video_set_source(CltrVideo *video, char *location);
|
||||
|
||||
void
|
||||
cltr_video_play(CltrVideo *video);
|
||||
|
||||
|
||||
#endif
|
@ -101,7 +101,7 @@ cltr_widget_queue_paint(CltrWidget *widget)
|
||||
{
|
||||
ClutterMainContext *ctx = CLTR_CONTEXT();
|
||||
|
||||
g_queue_push_head (ctx->internal_event_q, (gpointer)widget);
|
||||
g_async_queue_push (ctx->internal_event_q, (gpointer)widget);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <gst/gconf/gconf.h>
|
||||
|
||||
#include "pixbuf.h"
|
||||
#include "fonts.h"
|
||||
|
||||
@ -34,6 +36,8 @@ typedef struct CltrRect
|
||||
}
|
||||
CltrRect;
|
||||
|
||||
typedef struct CltrTexture CltrTexture;
|
||||
|
||||
#define cltr_rect_x1(r) ((r).x)
|
||||
#define cltr_rect_y1(r) ((r).y)
|
||||
#define cltr_rect_x2(r) ((r).x + (r).width)
|
||||
@ -52,5 +56,6 @@ CltrRect;
|
||||
#include "cltr-overlay.h"
|
||||
#include "cltr-button.h"
|
||||
#include "cltr-photo-grid.h"
|
||||
#include "cltr-video.h"
|
||||
|
||||
#endif
|
||||
|
@ -1,15 +1,19 @@
|
||||
noinst_PROGRAMS = scratch photos player
|
||||
|
||||
scratch_SOURCES = scratch.c
|
||||
scratch_CFLAGS = $(CLTR_CFLAGS)
|
||||
scratch_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||
scratch_LDFLAGS = \
|
||||
$(CLTR_LIBS) \
|
||||
$(GST_LIBS) \
|
||||
$(GCONF_LIBS) \
|
||||
$(top_builddir)/clutter/libclutter.la
|
||||
|
||||
photos_SOURCES = photos.c
|
||||
photos_CFLAGS = $(CLTR_CFLAGS)
|
||||
photos_CFLAGS = $(CLTR_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||
photos_LDFLAGS = \
|
||||
$(CLTR_LIBS) \
|
||||
$(GST_LIBS) \
|
||||
$(GCONF_LIBS) \
|
||||
$(top_builddir)/clutter/libclutter.la
|
||||
|
||||
player_SOURCES = player.c
|
||||
|
@ -19,90 +19,11 @@
|
||||
|
||||
#include <clutter/cltr.h>
|
||||
|
||||
#include <gst/play/play.h>
|
||||
#include <gst/gconf/gconf.h>
|
||||
|
||||
static GMainLoop *loop = NULL;
|
||||
static gint64 length = 0;
|
||||
|
||||
static void
|
||||
print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
|
||||
{
|
||||
gint i, count;
|
||||
|
||||
count = gst_tag_list_get_tag_size (list, tag);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
gchar *str;
|
||||
|
||||
if (gst_tag_get_type (tag) == G_TYPE_STRING) {
|
||||
if (!gst_tag_list_get_string_index (list, tag, i, &str))
|
||||
g_assert_not_reached ();
|
||||
} else {
|
||||
str =
|
||||
g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
g_print ("%15s: %s\n", gst_tag_get_nick (tag), str);
|
||||
} else {
|
||||
g_print (" : %s\n", str);
|
||||
}
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
got_found_tag (GstPlay * play, GstElement * source, GstTagList * tag_list)
|
||||
{
|
||||
gst_tag_list_foreach (tag_list, print_tag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
got_time_tick (GstPlay * play, gint64 time_nanos)
|
||||
{
|
||||
g_print ("time tick %f\n", time_nanos / (float) GST_SECOND);
|
||||
}
|
||||
|
||||
static void
|
||||
got_stream_length (GstPlay * play, gint64 length_nanos)
|
||||
{
|
||||
g_print ("got length %" G_GUINT64_FORMAT "\n", length_nanos);
|
||||
length = length_nanos;
|
||||
}
|
||||
|
||||
static void
|
||||
got_video_size (GstPlay * play, gint width, gint height)
|
||||
{
|
||||
g_print ("got video size %d, %d\n", width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
got_eos (GstPlay * play)
|
||||
{
|
||||
g_print ("End Of Stream\n");
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
seek_timer (GstPlay * play)
|
||||
{
|
||||
gst_play_seek_to_time (play, length / 2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GstPlay *play;
|
||||
GstElement *data_src, *video_sink, *audio_sink, *vis_element;
|
||||
GError *error = NULL;
|
||||
CltrWidget *win, *video, *test;
|
||||
|
||||
CltrWidget *win;
|
||||
|
||||
/* Initing GStreamer library */
|
||||
gst_init (&argc, &argv);
|
||||
cltr_init (&argc, &argv);
|
||||
|
||||
if (argc != 2) {
|
||||
@ -111,86 +32,22 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
win = cltr_window_new(800, 600);
|
||||
|
||||
video = cltr_video_new(800, 600);
|
||||
|
||||
cltr_video_set_source(CLTR_VIDEO(video), argv[1]);
|
||||
|
||||
cltr_widget_add_child(win, video, 0, 0);
|
||||
|
||||
test = cltr_scratch_new(300, 300);
|
||||
|
||||
cltr_widget_add_child(win, test, 100, 100);
|
||||
|
||||
cltr_widget_show_all(win);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* Creating the GstPlay object */
|
||||
play = gst_play_new (&error);
|
||||
if (error) {
|
||||
g_print ("Error: could not create play object:\n%s\n", error->message);
|
||||
g_error_free (error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Getting default audio and video plugins from GConf */
|
||||
vis_element = gst_element_factory_make ("goom", "vis_element");
|
||||
data_src = gst_element_factory_make ("gnomevfssrc", "source");
|
||||
|
||||
audio_sink = gst_gconf_get_default_audio_sink ();
|
||||
if (!GST_IS_ELEMENT (audio_sink))
|
||||
g_error ("Could not get default audio sink from GConf");
|
||||
|
||||
/*
|
||||
video_sink = gst_gconf_get_default_video_sink ();
|
||||
if (!GST_IS_ELEMENT (video_sink))
|
||||
g_error ("Could not get default video sink from GConf");
|
||||
*/
|
||||
|
||||
video_sink = gst_element_factory_make ("cltrimagesink", "cltr-output");
|
||||
|
||||
gst_element_set(video_sink, "widget", win, NULL);
|
||||
|
||||
if (video_sink == NULL)
|
||||
g_printf("sink NULL\n");
|
||||
|
||||
/* Let's send them to GstPlay object */
|
||||
if (!gst_play_set_audio_sink (play, audio_sink))
|
||||
g_warning ("Could not set audio sink");
|
||||
if (!gst_play_set_video_sink (play, video_sink))
|
||||
g_warning ("Could not set video sink");
|
||||
if (!gst_play_set_data_src (play, data_src))
|
||||
g_warning ("Could not set data src");
|
||||
if (!gst_play_set_visualization (play, vis_element))
|
||||
g_warning ("Could not set visualisation");
|
||||
|
||||
/* Setting location we want to play */
|
||||
if (!gst_play_set_location (play, argv[1]))
|
||||
g_warning ("Could not set location");
|
||||
|
||||
/* Uncomment that line to get an XML dump of the pipeline */
|
||||
gst_xml_write_file (GST_ELEMENT (play), stdout);
|
||||
|
||||
g_signal_connect (G_OBJECT (play), "time_tick",
|
||||
G_CALLBACK (got_time_tick), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "stream_length",
|
||||
G_CALLBACK (got_stream_length), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "have_video_size",
|
||||
G_CALLBACK (got_video_size), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "found_tag",
|
||||
G_CALLBACK (got_found_tag), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "error",
|
||||
G_CALLBACK (gst_element_default_error), NULL);
|
||||
g_signal_connect (G_OBJECT (play), "eos", G_CALLBACK (got_eos), NULL);
|
||||
|
||||
/* Change state to PLAYING */
|
||||
if (gst_element_set_state (GST_ELEMENT (play),
|
||||
GST_STATE_PLAYING) == GST_STATE_FAILURE)
|
||||
g_error ("Could not set state to PLAYING");
|
||||
|
||||
g_timeout_add (20000, (GSourceFunc) seek_timer, play);
|
||||
|
||||
|
||||
cltr_video_play(CLTR_VIDEO(video));
|
||||
|
||||
cltr_main_loop();
|
||||
// g_main_loop_run (loop);
|
||||
|
||||
g_print ("setting pipeline to ready\n");
|
||||
|
||||
gst_element_set_state (GST_ELEMENT (play), GST_STATE_READY);
|
||||
|
||||
/* unref
|
||||
gst_object_unref (GST_OBJECT (play)); */
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
/* Debugging category */
|
||||
#include <gst/gstinfo.h>
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_debug_cltrimagesink);
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_debug_cltrimagesink);
|
||||
|
||||
#define GST_CAT_DEFAULT gst_debug_cltrimagesink
|
||||
|
||||
@ -70,7 +70,7 @@ static guint gst_cltrimagesink_signals[LAST_SIGNAL] = { 0 };
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_WIDGET,
|
||||
ARG_QUEUE,
|
||||
ARG_SYNCHRONOUS,
|
||||
ARG_SIGNAL_HANDOFFS
|
||||
/* FILL ME */
|
||||
@ -103,6 +103,15 @@ Element stuff
|
||||
=================
|
||||
*/
|
||||
|
||||
#define SWAP_4(x) ( ((x) << 24) | \
|
||||
(((x) << 16) & 0x00ff0000) | \
|
||||
(((x) << 8) & 0x0000ff00) | \
|
||||
0x000000ff )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static GstCaps *
|
||||
gst_cltrimagesink_fixate (GstPad *pad,
|
||||
const GstCaps *caps)
|
||||
@ -110,8 +119,6 @@ gst_cltrimagesink_fixate (GstPad *pad,
|
||||
GstStructure *structure;
|
||||
GstCaps *newcaps;
|
||||
|
||||
DBG("mark");
|
||||
|
||||
if (gst_caps_get_size (caps) > 1)
|
||||
return NULL;
|
||||
|
||||
@ -153,9 +160,11 @@ gst_cltrimagesink_getcaps (GstPad * pad)
|
||||
"bpp", G_TYPE_INT, 24,
|
||||
"depth", G_TYPE_INT, 24,
|
||||
"endianness", G_TYPE_INT, G_BIG_ENDIAN,
|
||||
"red_mask", G_TYPE_INT, 0xff0000,
|
||||
"green_mask", G_TYPE_INT, 0x00ff00,
|
||||
"blue_mask", G_TYPE_INT, 0xff,
|
||||
/*
|
||||
"red_mask", G_TYPE_INT, 0xff0000,
|
||||
"green_mask", G_TYPE_INT, 0x0000ff,
|
||||
"blue_mask", G_TYPE_INT, 0x00ff00,
|
||||
*/
|
||||
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"framerate", GST_TYPE_DOUBLE_RANGE, 1.0, 100.0, NULL);
|
||||
@ -172,8 +181,6 @@ gst_cltrimagesink_sink_link (GstPad * pad, const GstCaps * caps)
|
||||
GstStructure *structure;
|
||||
Pixbuf *pixb = NULL;
|
||||
|
||||
DBG("mark");
|
||||
|
||||
cltrimagesink = GST_CLTRIMAGESINK (gst_pad_get_parent (pad));
|
||||
|
||||
/*
|
||||
@ -220,7 +227,7 @@ gst_cltrimagesink_sink_link (GstPad * pad, const GstCaps * caps)
|
||||
GST_VIDEOSINK_HEIGHT (cltrimagesink));
|
||||
|
||||
/* Is this the right place ? */
|
||||
cltrimagesink->texture = cltr_texture_new(pixb);
|
||||
cltrimagesink->texture = cltr_texture_no_tile_new(pixb);
|
||||
|
||||
pixbuf_unref(pixb);
|
||||
|
||||
@ -249,7 +256,6 @@ gst_cltrimagesink_change_state (GstElement * element)
|
||||
*/
|
||||
break;
|
||||
case GST_STATE_READY_TO_PAUSED:
|
||||
printf ("ready to paused\n");
|
||||
cltrimagesink->time = 0;
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_PLAYING:
|
||||
@ -283,8 +289,6 @@ gst_cltrimagesink_chain (GstPad * pad, GstData * data)
|
||||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
g_return_if_fail (buf != NULL);
|
||||
|
||||
DBG("mark");
|
||||
|
||||
cltrimagesink = GST_CLTRIMAGESINK (gst_pad_get_parent (pad));
|
||||
|
||||
if (GST_IS_EVENT (data))
|
||||
@ -303,8 +307,6 @@ gst_cltrimagesink_chain (GstPad * pad, GstData * data)
|
||||
/* If this buffer has been allocated using our buffer management we
|
||||
* simply put the ximage which is in the PRIVATE pointer */
|
||||
|
||||
DBG("time is is %li", cltrimagesink->time);
|
||||
|
||||
#if 0
|
||||
if (GST_BUFFER_FREE_DATA_FUNC (buf) == gst_cltrimagesink_buffer_free)
|
||||
{
|
||||
@ -323,38 +325,47 @@ gst_cltrimagesink_chain (GstPad * pad, GstData * data)
|
||||
/* need to copy the data into out pixbuf here */
|
||||
Pixbuf *pixb = NULL;
|
||||
|
||||
cltr_texture_lock(cltrimagesink->texture);
|
||||
|
||||
pixb = cltr_texture_get_pixbuf(cltrimagesink->texture);
|
||||
|
||||
if (pixb)
|
||||
memcpy (pixb->data,
|
||||
GST_BUFFER_DATA (buf),
|
||||
MIN (GST_BUFFER_SIZE (buf),
|
||||
pixb->bytes_per_line * pixb->width));
|
||||
{
|
||||
/*
|
||||
memcpy (pixb->data,
|
||||
GST_BUFFER_DATA (buf),
|
||||
MIN (GST_BUFFER_SIZE (buf),
|
||||
pixb->bytes_per_line * pixb->width));
|
||||
*/
|
||||
|
||||
cltr_texture_resync_pixbuf(cltrimagesink->texture);
|
||||
/* EVIL */
|
||||
|
||||
/*
|
||||
cltr_texture_render_to_gl_quad(cltrimagesink->texture,
|
||||
0, 0, 320, 240);
|
||||
*/
|
||||
|
||||
if (GST_BUFFER_SIZE (buf) >= pixb->width * pixb->height * 3)
|
||||
cltr_texture_force_rgb_data(cltrimagesink->texture,
|
||||
pixb->width,
|
||||
pixb->height,
|
||||
GST_BUFFER_DATA (buf));
|
||||
|
||||
#if 0
|
||||
memcpy (cltrimagesink->cltrimage->data,
|
||||
GST_BUFFER_DATA (buf),
|
||||
MIN (GST_BUFFER_SIZE (buf),
|
||||
cltrimagesink->cltrimage->size));
|
||||
|
||||
gst_cltrimagesink_ximage_put (cltrimagesink,
|
||||
cltrimagesink->cltrimage);
|
||||
#endif
|
||||
}
|
||||
|
||||
cltr_texture_unlock(cltrimagesink->texture);
|
||||
|
||||
if (cltrimagesink->queue)
|
||||
{
|
||||
CltrVideoSignal *signal;
|
||||
|
||||
signal = g_new0 (CltrVideoSignal, 1);
|
||||
signal->signal_id = CLTR_VIDEO_ASYNC_TEXTURE;
|
||||
signal->signal_data.texture.ref = cltrimagesink->texture;
|
||||
|
||||
g_async_queue_push(cltrimagesink->queue,
|
||||
(gpointer)signal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No image available. Something went wrong during capsnego ! */
|
||||
|
||||
DBG("MARK, texture == NULL");
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
GST_ELEMENT_ERROR (cltrimagesink, CORE, NEGOTIATION, (NULL),
|
||||
("no format defined before chain function"));
|
||||
@ -406,8 +417,8 @@ gst_cltrimagesink_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case ARG_WIDGET:
|
||||
cltrimagesink->widget = g_value_get_pointer (value);
|
||||
case ARG_QUEUE:
|
||||
cltrimagesink->queue = g_value_get_pointer (value);
|
||||
break;
|
||||
/*
|
||||
case ARG_SIGNAL_HANDOFFS:
|
||||
@ -434,8 +445,8 @@ gst_cltrimagesink_get_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case ARG_WIDGET:
|
||||
g_value_set_pointer (value, cltrimagesink->widget);
|
||||
case ARG_QUEUE:
|
||||
g_value_set_pointer (value, cltrimagesink->queue);
|
||||
break;
|
||||
/*
|
||||
case ARG_SIGNAL_HANDOFFS:
|
||||
@ -472,8 +483,6 @@ gst_cltrimagesink_finalize (GObject *object)
|
||||
static void
|
||||
gst_cltrimagesink_init (GstCltrimageSink * cltrimagesink)
|
||||
{
|
||||
DBG("mark");
|
||||
|
||||
GST_VIDEOSINK_PAD (cltrimagesink)
|
||||
= gst_pad_new_from_template ( gst_static_pad_template_get(&gst_cltrimagesink_sink_template_factory), "sink");
|
||||
|
||||
@ -536,10 +545,10 @@ gst_cltrimagesink_class_init (GstCltrimageSinkClass * klass)
|
||||
|
||||
/* TOGO */
|
||||
g_object_class_install_property (gobject_class,
|
||||
ARG_WIDGET,
|
||||
g_param_spec_pointer ("widget",
|
||||
"Widget",
|
||||
"Cltr drawable widget",
|
||||
ARG_QUEUE,
|
||||
g_param_spec_pointer ("queue",
|
||||
"Queue",
|
||||
"Async Signal Queue",
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
/* TOGO */
|
||||
|
@ -37,9 +37,9 @@ struct _GstCltrimageSink
|
||||
GMutex *pool_lock;
|
||||
GSList *image_pool;
|
||||
|
||||
GstCaps *caps;
|
||||
GstCaps *caps;
|
||||
GAsyncQueue *queue;
|
||||
|
||||
CltrWidget *widget;
|
||||
};
|
||||
|
||||
struct _GstCltrimageSinkClass {
|
||||
@ -52,6 +52,7 @@ struct _GstCltrimageSinkClass {
|
||||
|
||||
GType gst_cltrimagesink_get_type(void); /* XXX needed ? */
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CLTRIMAGESINK_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user