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

Reply via email to