Author: miguel
Date: 2007-06-01 00:57:06 -0400 (Fri, 01 Jun 2007)
New Revision: 78394
Modified:
trunk/moon/src/demo.cpp
trunk/moon/src/ffvideo.cpp
trunk/moon/src/runtime.cpp
trunk/moon/src/shape.cpp
Log:
2007-06-01 Miguel de Icaza <[EMAIL PROTECTED]>
* ffvideo.cpp: No longer use CMD_INITED, instead use g_idle_add to
notify a special function (callback_video_inited). Makes me
wonder if I should do the same for the new-frame call
Initialize the cairo surface on the callback_video_inited routine
instead of doing this on the decoder thread (that was a mistake).
This solves the misterious case of the video that randomly did not
show up.
Modified: trunk/moon/src/demo.cpp
===================================================================
--- trunk/moon/src/demo.cpp 2007-06-01 03:23:06 UTC (rev 78393)
+++ trunk/moon/src/demo.cpp 2007-06-01 04:57:06 UTC (rev 78394)
@@ -4,6 +4,7 @@
#include <malloc.h>
#include <glib.h>
#include <stdlib.h>
+#include <unistd.h>
#include "runtime.h"
@@ -51,10 +52,9 @@
// Create our objects
Surface *t = surface_new (600, 600);
- gtk_widget_set_usize (t->drawing_area, 400, 400);
gtk_container_add (GTK_CONTAINER(w), t->drawing_area);
- r = rectangle_new (100, 100, 100, 100);
+ r = rectangle_new (50, 50, 100, 100);
Color c = Color (1.0, 0.0, 0.5, 0.5);
shape_set_stroke (r, new SolidColorBrush (c));
cairo_matrix_init_rotate (&trans, 0.4);
@@ -70,7 +70,7 @@
panel_child_add (t, r);
-#ifdef VIDEO_DEMO1
+#ifdef VIDEO_DEMO
Item *v2 = video_new ("file:///tmp/Countdown-Colbert-BestNailings.wmv",
100, 100);
//Item *v2 = video_new ("file:///tmp/BoxerSmacksdownInhoffe.wmv", 100,
100);
panel_child_add (t, v2);
Modified: trunk/moon/src/ffvideo.cpp
===================================================================
--- trunk/moon/src/ffvideo.cpp 2007-06-01 03:23:06 UTC (rev 78393)
+++ trunk/moon/src/ffvideo.cpp 2007-06-01 04:57:06 UTC (rev 78394)
@@ -41,9 +41,6 @@
typedef enum {
// When a new frame is ready
CMD_NEWFRAME,
-
- // When the video has been loaded, this updates the bounding box in the
Gtk+ GUI thread.
- CMD_INITED
} GuiCommand;
class VideoFfmpeg : public Video {
@@ -77,10 +74,6 @@
snd_pcm_t *pcm;
- // The decoding thread will wait until the main thread reads our
CMD_INITED
- // command
- GCond *cond_decode_thread_proceed;
-
GAsyncQueue *video_frames;
//
@@ -133,12 +126,14 @@
if (affine != NULL)
cairo_set_matrix (s->cairo, (cairo_matrix_t *) affine);
- cairo_rectangle (s->cairo, x, y, x + cc->width, y + cc->height);
+ cairo_rectangle (s->cairo, x, y, cc->width, cc->height);
cairo_fill_extents (s->cairo, &x1, &y1, &x2, &y2);
cairo_restore (s->cairo);
}
+static void restart_timer (VideoFfmpeg *video);
+
static void
send_command (VideoFfmpeg *video, uint8_t cmd)
{
@@ -149,6 +144,28 @@
} while (ret == -1 && errno == EINTR);
}
+gboolean
+callback_video_inited (gpointer data)
+{
+ VideoFfmpeg *video = (VideoFfmpeg *) data;
+ AVCodecContext *cc;
+
+ cc = video->video_stream->codec;
+ video->video_cairo_surface = cairo_image_surface_create_for_data (
+ video->video_rgb_buffer, CAIRO_FORMAT_ARGB32,
+ cc->width, cc->height, cc->width * 4);
+
+ item_update_bounds ((Item *) video);
+ video->w = video->video_stream->codec->width;
+ video->h = video->video_stream->codec->height;
+
+ // Track where we are at now
+ video->initial_pts = video->video_stream->start_time;
+ restart_timer (video);
+
+ return FALSE;
+}
+
//
// The decoder thread, runs until complete
//
@@ -220,10 +237,6 @@
cc = video->video_stream->codec;
video->video_rgb_buffer = (unsigned char *) malloc
(cc->width * cc->height * 4);
- video->video_cairo_surface =
cairo_image_surface_create_for_data (
- video->video_rgb_buffer, CAIRO_FORMAT_ARGB32,
- cc->width, cc->height, cc->width * 4);
-
// The YUB to RGB scaleter/translator
printf ("Pix_fmt=%d\n", cc->pix_fmt);
video->video_scale_context = sws_getContext (
@@ -232,14 +245,13 @@
break;
}
}
+ g_mutex_unlock (video_lock);
//
- // Notify the main thread that we are done loading the video, and that
it
+ // notify the main thread that we are done loading the video, and that
it
// can pull the width/height information out of this video
//
- send_command (video, CMD_INITED);
- g_cond_wait (video->cond_decode_thread_proceed, video_lock);
- g_mutex_unlock (video_lock);
+ g_idle_add (callback_video_inited, video);
while (TRUE){
AVPacket packet, *pkt = &packet;
@@ -251,7 +263,6 @@
printf ("Failed to read frame, terminating\n");
break;
}
-
if (pkt->stream_index == audio_stream_idx){
//snd_pcm_writei (video->pcm,
}
@@ -268,7 +279,7 @@
//printf ("pkt=%7.2f %8d\r\n", (double) pkt->pts,
count++);
//fflush (stdout);
avcodec_decode_video (video->video_stream->codec,
video_frame, &got_picture, pkt->data, pkt->size);
-
+
if (got_picture){
// Copy the PTS here, dont know why decode
video does not set it
if (video_frame->pts == 0)
@@ -276,9 +287,10 @@
//printf ("Adding PTS=%ld\n", video_frame->pts);
g_mutex_lock (video->video_mutex);
- send_command (video, CMD_NEWFRAME);
g_async_queue_push (video->video_frames,
video_frame);
g_mutex_unlock (video->video_mutex);
+
+ send_command (video, CMD_NEWFRAME);
}
}
av_free_packet (pkt);
@@ -358,7 +370,7 @@
return cont;
}
-void
+static void
restart_timer (VideoFfmpeg *video)
{
//video->frame_size = (int) (1000 * av_q2d
(video->video_stream->time_base) * av_q2d (video->video_stream->r_frame_rate));
@@ -381,6 +393,7 @@
AVFrame *frame;
int8_t commands [32];
int ret, i;
+ AVCodecContext *cc;
do {
ret = read (video->pipes [0], &commands, sizeof (commands));
@@ -397,21 +410,6 @@
restart_timer (video);
break;
- case CMD_INITED:
- // Track where we are at now
- video->initial_pts = video->video_stream->start_time;
- restart_timer (video);
-
- //
- // Poor man's [play] command.
- //
- g_cond_signal (video->cond_decode_thread_proceed);
-
- item_update_bounds ((Item *) video);
- video->w = video->video_stream->codec->width;
- video->h = video->video_stream->codec->height;
- break;
-
default:
fprintf (stderr, "video_ready: unknown command from
decoding thread (%d)\n", commands [i]);
}
@@ -427,6 +425,10 @@
double *use_affine = item_get_affine (affine, xform, actual);
cairo_pattern_t *pattern, *old_pattern;
+ // If we are not initialized yet, return.
+ if (video_cairo_surface == NULL)
+ return;
+
cairo_save (s->cairo);
if (use_affine != NULL)
cairo_set_matrix (s->cairo, (cairo_matrix_t *) use_affine);
@@ -435,8 +437,6 @@
cairo_set_source_surface (s->cairo, video_cairo_surface, 0, 0);
cairo_paint (s->cairo);
- cairo_rectangle (s->cairo, x, y, w, h);
-
cairo_restore (s->cairo);
}
@@ -463,7 +463,7 @@
ffmpeg_init ();
video = new VideoFfmpeg (filename, x, y);
-
+
return (Video *) video;
}
@@ -480,7 +480,6 @@
initial_pts = 0;
play_start_time = 0;
frame_size = 0;
-
pipe (pipes);
fcntl (pipes [0], F_SETFL, O_NONBLOCK);
@@ -490,8 +489,6 @@
pipe_channel = g_io_channel_unix_new (pipes [0]);
g_io_add_watch (pipe_channel, G_IO_IN, video_ready, this);
- cond_decode_thread_proceed = g_cond_new ();
-
decode_thread_id = g_thread_create (decoder, this, TRUE, NULL);
}
Modified: trunk/moon/src/runtime.cpp
===================================================================
--- trunk/moon/src/runtime.cpp 2007-06-01 03:23:06 UTC (rev 78393)
+++ trunk/moon/src/runtime.cpp 2007-06-01 04:57:06 UTC (rev 78394)
@@ -351,6 +351,7 @@
s->drawing_area = gtk_drawing_area_new ();
gtk_widget_show (s->drawing_area);
+ gtk_widget_set_usize (s->drawing_area, width, height);
s->buffer = NULL;
s->flags |= Item::IS_SURFACE;
s->width = width;
Modified: trunk/moon/src/shape.cpp
===================================================================
--- trunk/moon/src/shape.cpp 2007-06-01 03:23:06 UTC (rev 78393)
+++ trunk/moon/src/shape.cpp 2007-06-01 04:57:06 UTC (rev 78394)
@@ -17,6 +17,10 @@
#include <stdlib.h>
#include "runtime.h"
+//
+// This routine is useful for Shape derivatives: it can be used
+// to either get the bounding box from cairo, or to paint it
+//
void
Shape::DoDraw (Surface *s, double *affine, bool do_op)
{
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches