1.1 --- a/gmyth-stream/gmemcoder/src/gmencoder.c Wed Aug 15 20:52:44 2007 +0100
1.2 +++ b/gmyth-stream/gmemcoder/src/gmencoder.c Thu Aug 16 14:46:11 2007 +0100
1.3 @@ -18,6 +18,9 @@
1.4 #define G_MENCODER_GET_PRIVATE(obj) \
1.5 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
1.6
1.7 +#define USE_MANUAL_SINK
1.8 +#define GMENCODER_TIMEOUT 5000
1.9 +
1.10 typedef struct _GMencoderPrivate GMencoderPrivate;
1.11 typedef struct _SetupInfo SetupInfo;
1.12
1.13 @@ -42,7 +45,7 @@
1.14 GstElement *sink;
1.15 GstElement *src;
1.16
1.17 - gint out_fd;
1.18 + GnomeVFSHandle *handle;
1.19
1.20 gboolean ready;
1.21 SetupInfo *info;
1.22 @@ -52,7 +55,7 @@
1.23 gint tick_id;
1.24 gint64 duration;
1.25 gboolean send_chunked;
1.26 -
1.27 + gint timeout_id;
1.28
1.29 //V4l info
1.30 GstElement *v4lsrc;
1.31 @@ -110,10 +113,16 @@
1.32 gchar ** audio_encode_prop,
1.33 guint audio_rate,
1.34 gboolean deinterlace);
1.35 +static gboolean _process_timeout_cb (gpointer user_data);
1.36 +#ifdef USE_MANUAL_SINK
1.37 static void _flush_queue (GMencoder *self);
1.38 static void _buffer_arrive_cb (GstElement* object,
1.39 GstBuffer* buff,
1.40 + GstPad* pad,
1.41 gpointer user_data);
1.42 +#endif
1.43 +
1.44 +
1.45 static gboolean _tick_cb(gpointer data);
1.46
1.47 static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
1.48 @@ -638,7 +647,15 @@
1.49 g_return_if_fail(priv->ready == FALSE);
1.50 priv->ready = TRUE;
1.51 gst_element_set_state(priv->pipe, GST_STATE_PLAYING);
1.52 + if (priv->tick_id != 0) {
1.53 + g_source_remove (priv->tick_id);
1.54 + }
1.55 priv->tick_id = g_timeout_add(500, _tick_cb, self);
1.56 +
1.57 + if (priv->timeout_id != 0) {
1.58 + g_source_remove (priv->timeout_id);
1.59 + }
1.60 + priv->timeout_id = g_timeout_add(GMENCODER_TIMEOUT, _process_timeout_cb, self);
1.61 }
1.62
1.63 void
1.64 @@ -659,6 +676,11 @@
1.65 priv->tick_id = 0;
1.66 }
1.67
1.68 + if (priv->timeout_id != 0) {
1.69 + g_source_remove (priv->timeout_id);
1.70 + priv->timeout_id = 0;
1.71 + }
1.72 +
1.73 if (priv->pipe != NULL) {
1.74 // TODO: fixe pipeline dispose
1.75 //gst_element_set_state (priv->pipe, GST_STATE_NULL);
1.76 @@ -670,6 +692,7 @@
1.77 priv->pipe = NULL;
1.78 priv->abin = NULL;
1.79 priv->vbin = NULL;
1.80 + priv->sink = NULL;
1.81 }
1.82 priv->ready = FALSE;
1.83 }
1.84 @@ -694,10 +717,8 @@
1.85 GstElement *abin = NULL;
1.86 GstElement *vbin = NULL;
1.87 GstElement *queue = NULL;
1.88 - GstElement *identity = NULL;
1.89 GstPad *aux_pad = NULL;
1.90 GstPad *mux_pad = NULL;
1.91 - GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
1.92
1.93 pipe = gst_pipeline_new("pipe");
1.94
1.95 @@ -708,10 +729,11 @@
1.96 goto error;
1.97
1.98 queue = gst_element_factory_make("queue", "queueu_sink");
1.99 - identity = gst_element_factory_make ("identity", "identity");
1.100 - sink = gst_element_factory_make("fdsink", "sink");
1.101 - g_object_set (sink, "fd", priv->out_fd, NULL);
1.102 - g_signal_connect (G_OBJECT (identity),
1.103 +
1.104 +
1.105 + sink = gst_element_factory_make("fakesink", "sink");
1.106 + g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
1.107 + g_signal_connect (G_OBJECT (sink),
1.108 "handoff",
1.109 G_CALLBACK (_buffer_arrive_cb),
1.110 self);
1.111 @@ -727,7 +749,7 @@
1.112 goto error;
1.113
1.114 // Finish Pipe
1.115 - gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, identity, sink, NULL);
1.116 + gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, sink, NULL);
1.117
1.118
1.119 // Link bins with mux
1.120 @@ -767,12 +789,11 @@
1.121 mux_pad = NULL;
1.122
1.123 // Link mux with sink
1.124 - gst_element_link_many(mux, queue, identity, sink, NULL);
1.125 + gst_element_link_many(mux, queue, sink, NULL);
1.126
1.127 bus = gst_pipeline_get_bus(GST_PIPELINE(pipe));
1.128 gst_bus_add_watch(bus, _pipeline_bus_cb, self);
1.129 gst_object_unref(bus);
1.130 -
1.131 return pipe;
1.132
1.133 error:
1.134 @@ -928,19 +949,24 @@
1.135 _open_output(GMencoder * self, const gchar * uri)
1.136 {
1.137 gchar **i;
1.138 + GnomeVFSResult result;
1.139 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
1.140
1.141 - priv->out_fd = 0;
1.142 -
1.143 i = g_strsplit(uri, "://", 0);
1.144 if (strcmp(i[0], "fd") == 0) {
1.145 - priv->out_fd = atoi (i[1]);
1.146 + result = gnome_vfs_open_fd (&priv->handle, atoi(i[1]));
1.147 } else {
1.148 - priv->out_fd = open (i[1], O_CREAT|O_WRONLY|O_TRUNC, 0666);
1.149 + if (g_file_test (i[1], G_FILE_TEST_EXISTS) == FALSE) {
1.150 + result = gnome_vfs_create (&priv->handle, uri, GNOME_VFS_OPEN_WRITE, TRUE,
1.151 + GNOME_VFS_PERM_USER_WRITE | GNOME_VFS_PERM_USER_READ | GNOME_VFS_PERM_GROUP_READ);
1.152 + } else {
1.153 + result = gnome_vfs_open (&priv->handle, uri,
1.154 + GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_TRUNCATE);
1.155 + }
1.156 }
1.157
1.158 g_strfreev(i);
1.159 - return (priv->out_fd > 0);
1.160 + return (result == GNOME_VFS_OK);
1.161 }
1.162
1.163 static gboolean
1.164 @@ -1003,7 +1029,9 @@
1.165
1.166 case GST_MESSAGE_EOS:
1.167 priv->ready = FALSE;
1.168 +#ifdef USE_MANUAL_SINK
1.169 _flush_queue (G_MENCODER (user_data));
1.170 +#endif
1.171 g_signal_emit(user_data, g_mencoder_signals[EOS], 0);
1.172 break;
1.173
1.174 @@ -1085,40 +1113,50 @@
1.175 return TRUE;
1.176 }
1.177
1.178 +static gboolean
1.179 +_process_timeout_cb (gpointer user_data)
1.180 +{
1.181 + GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1.182
1.183 -static void
1.184 -_chunke_buffer (GstBuffer *buf)
1.185 + g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "timeout");
1.186 + priv->timeout_id = 0;
1.187 + return FALSE;
1.188 +}
1.189 +
1.190 +
1.191 +#ifdef USE_MANUAL_SINK
1.192 +static gboolean
1.193 +_send_buffer (GnomeVFSHandle *handle, gpointer buff, gint size)
1.194 {
1.195 gchar *msg;
1.196 GByteArray *b_send;
1.197 + GnomeVFSResult result;
1.198 + GnomeVFSFileSize bytes_written;
1.199
1.200 b_send = g_byte_array_new ();
1.201 - msg = g_strdup_printf ("%x\r\n", GST_BUFFER_SIZE(buf));
1.202 + msg = g_strdup_printf ("%x\r\n", size);
1.203 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1.204 g_free (msg);
1.205
1.206 - b_send = g_byte_array_append (b_send, GST_BUFFER_DATA(buf), GST_BUFFER_SIZE(buf));
1.207 + b_send = g_byte_array_append (b_send, buff, size);
1.208
1.209 msg = g_strdup ("\r\n");
1.210 b_send = g_byte_array_append (b_send, (const guint8*) msg, strlen (msg) * sizeof (gchar));
1.211 g_free (msg);
1.212
1.213 - g_free (GST_BUFFER_DATA(buf));
1.214 + result = gnome_vfs_write (handle, b_send->data, b_send->len, &bytes_written);
1.215 + g_byte_array_free (b_send, TRUE);
1.216
1.217 - GST_BUFFER_SIZE(buf)=b_send->len;
1.218 - GST_BUFFER_DATA(buf)=b_send->data;
1.219 -
1.220 - g_byte_array_free (b_send, FALSE);
1.221 + return (result == GNOME_VFS_OK);
1.222 }
1.223
1.224 static void
1.225 _flush_queue (GMencoder *self)
1.226 {
1.227 - /*
1.228 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
1.229
1.230 -
1.231 if (priv->send_chunked) {
1.232 + GnomeVFSFileSize bytes_written;
1.233 gchar *end_msg;
1.234 end_msg = g_strdup ("0\r\n\r\n");
1.235 gnome_vfs_write (priv->handle,
1.236 @@ -1127,17 +1165,46 @@
1.237 &bytes_written);
1.238 g_free (end_msg);
1.239 }
1.240 - */
1.241 }
1.242
1.243 static void
1.244 _buffer_arrive_cb (GstElement* object,
1.245 - GstBuffer* buf,
1.246 + GstBuffer* buff,
1.247 + GstPad* pad,
1.248 gpointer user_data)
1.249 {
1.250 GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
1.251
1.252 + if (priv->timeout_id != 0) {
1.253 + g_source_remove (priv->timeout_id);
1.254 + priv->timeout_id = 0;
1.255 + }
1.256 +
1.257 if (priv->send_chunked) {
1.258 - _chunke_buffer (buf);
1.259 + if (_send_buffer (priv->handle, GST_BUFFER_DATA (buff), GST_BUFFER_SIZE (buff)) == FALSE)
1.260 + goto error;
1.261 + } else {
1.262 + GnomeVFSResult result;
1.263 + GnomeVFSFileSize bytes_written;
1.264 +
1.265 + result = gnome_vfs_write (priv->handle,
1.266 + GST_BUFFER_DATA (buff),
1.267 + GST_BUFFER_SIZE (buff),
1.268 + &bytes_written);
1.269 +
1.270 + if (result != GNOME_VFS_OK)
1.271 + goto error;
1.272 }
1.273 +
1.274 + return;
1.275 +
1.276 +error:
1.277 + if (priv->tick_id != 0) {
1.278 + g_source_remove(priv->tick_id);
1.279 + priv->tick_id = 0;
1.280 + }
1.281 + g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, "Fail to write on socket");
1.282 + gst_element_set_state (priv->pipe, GST_STATE_PAUSED);
1.283 }
1.284 +
1.285 +#endif