gst/tcp/: 0.8 backporting.

Original commit message from CVS:
* gst/tcp/gstfdset.c: (gst_fdset_free):
* gst/tcp/gstmultifdsink.c: (gst_multifdsink_init),
(gst_multifdsink_add), (gst_multifdsink_remove),
(gst_multifdsink_clear), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_queue_buffer), (gst_multifdsink_handle_clients),
(gst_multifdsink_stop):
* gst/tcp/gstmultifdsink.h:
0.8 backporting.

* sys/ximage/ximagesink.c: (gst_ximagesink_show_frame):
Also draw image when not from a pool.
This commit is contained in:
Wim Taymans 2005-07-14 18:22:13 +00:00
parent 3e81aabeea
commit 66b4961d7d
5 changed files with 73 additions and 36 deletions

View file

@ -1,3 +1,21 @@
2005-07-14 Wim Taymans <wim@fluendo.com>
* gst/tcp/gstfdset.c: (gst_fdset_free):
* gst/tcp/gstmultifdsink.c: (gst_multifdsink_init),
(gst_multifdsink_add), (gst_multifdsink_remove),
(gst_multifdsink_clear), (gst_multifdsink_get_stats),
(gst_multifdsink_remove_client_link),
(gst_multifdsink_client_queue_data),
(gst_multifdsink_client_queue_caps),
(gst_multifdsink_client_queue_buffer),
(gst_multifdsink_queue_buffer), (gst_multifdsink_handle_clients),
(gst_multifdsink_stop):
* gst/tcp/gstmultifdsink.h:
0.8 backporting.
* sys/ximage/ximagesink.c: (gst_ximagesink_show_frame):
Also draw image when not from a pool.
2005-07-14 Wim Taymans <wim@fluendo.com> 2005-07-14 Wim Taymans <wim@fluendo.com>
* gst/playback/gstplaybasebin.c: (check_queue), (probe_triggered), * gst/playback/gstplaybasebin.c: (check_queue), (probe_triggered),

View file

@ -152,6 +152,7 @@ gst_fdset_free (GstFDSet * set)
case GST_FDSET_MODE_SELECT: case GST_FDSET_MODE_SELECT:
break; break;
case GST_FDSET_MODE_POLL: case GST_FDSET_MODE_POLL:
g_free (set->testpollfds);
g_free (set->pollfds); g_free (set->pollfds);
g_mutex_free (set->poll_lock); g_mutex_free (set->poll_lock);
break; break;

View file

@ -409,7 +409,7 @@ gst_multifdsink_init (GstMultiFdSink * this)
this->protocol = DEFAULT_PROTOCOL; this->protocol = DEFAULT_PROTOCOL;
this->mode = DEFAULT_MODE; this->mode = DEFAULT_MODE;
this->clientslock = g_mutex_new (); CLIENTS_LOCK_INIT (this);
this->clients = NULL; this->clients = NULL;
this->fd_hash = g_hash_table_new (g_int_hash, g_int_equal); this->fd_hash = g_hash_table_new (g_int_hash, g_int_equal);
@ -453,13 +453,13 @@ gst_multifdsink_add (GstMultiFdSink * sink, int fd)
/* send last activity time to connect time */ /* send last activity time to connect time */
client->last_activity_time = GST_TIMEVAL_TO_TIME (now); client->last_activity_time = GST_TIMEVAL_TO_TIME (now);
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
/* check the hash to find a duplicate fd */ /* check the hash to find a duplicate fd */
clink = g_hash_table_lookup (sink->fd_hash, &client->fd.fd); clink = g_hash_table_lookup (sink->fd_hash, &client->fd.fd);
if (clink != NULL) { if (clink != NULL) {
client->status = GST_CLIENT_STATUS_DUPLICATE; client->status = GST_CLIENT_STATUS_DUPLICATE;
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
GST_WARNING_OBJECT (sink, "[fd %5d] duplicate client found, refusing", fd); GST_WARNING_OBJECT (sink, "[fd %5d] duplicate client found, refusing", fd);
g_signal_emit (G_OBJECT (sink), g_signal_emit (G_OBJECT (sink),
gst_multifdsink_signals[SIGNAL_CLIENT_REMOVED], 0, fd, client->status); gst_multifdsink_signals[SIGNAL_CLIENT_REMOVED], 0, fd, client->status);
@ -489,7 +489,7 @@ gst_multifdsink_add (GstMultiFdSink * sink, int fd)
SEND_COMMAND (sink, CONTROL_RESTART); SEND_COMMAND (sink, CONTROL_RESTART);
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
g_signal_emit (G_OBJECT (sink), g_signal_emit (G_OBJECT (sink),
gst_multifdsink_signals[SIGNAL_CLIENT_ADDED], 0, fd); gst_multifdsink_signals[SIGNAL_CLIENT_ADDED], 0, fd);
@ -502,7 +502,7 @@ gst_multifdsink_remove (GstMultiFdSink * sink, int fd)
GST_DEBUG_OBJECT (sink, "[fd %5d] removing client", fd); GST_DEBUG_OBJECT (sink, "[fd %5d] removing client", fd);
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
clink = g_hash_table_lookup (sink->fd_hash, &fd); clink = g_hash_table_lookup (sink->fd_hash, &fd);
if (clink != NULL) { if (clink != NULL) {
GstTCPClient *client = (GstTCPClient *) clink->data; GstTCPClient *client = (GstTCPClient *) clink->data;
@ -513,7 +513,7 @@ gst_multifdsink_remove (GstMultiFdSink * sink, int fd)
} else { } else {
GST_WARNING_OBJECT (sink, "[fd %5d] no client with this fd found!", fd); GST_WARNING_OBJECT (sink, "[fd %5d] no client with this fd found!", fd);
} }
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
} }
void void
@ -523,7 +523,7 @@ gst_multifdsink_clear (GstMultiFdSink * sink)
GST_DEBUG_OBJECT (sink, "clearing all clients"); GST_DEBUG_OBJECT (sink, "clearing all clients");
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
for (clients = sink->clients; clients; clients = next) { for (clients = sink->clients; clients; clients = next) {
GstTCPClient *client; GstTCPClient *client;
@ -534,7 +534,7 @@ gst_multifdsink_clear (GstMultiFdSink * sink)
gst_multifdsink_remove_client_link (sink, clients); gst_multifdsink_remove_client_link (sink, clients);
} }
SEND_COMMAND (sink, CONTROL_RESTART); SEND_COMMAND (sink, CONTROL_RESTART);
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
} }
GValueArray * GValueArray *
@ -544,7 +544,7 @@ gst_multifdsink_get_stats (GstMultiFdSink * sink, int fd)
GValueArray *result = NULL; GValueArray *result = NULL;
GList *clink; GList *clink;
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
clink = g_hash_table_lookup (sink->fd_hash, &fd); clink = g_hash_table_lookup (sink->fd_hash, &fd);
client = (GstTCPClient *) clink->data; client = (GstTCPClient *) clink->data;
if (client != NULL) { if (client != NULL) {
@ -582,7 +582,7 @@ gst_multifdsink_get_stats (GstMultiFdSink * sink, int fd)
g_value_set_uint64 (&value, client->last_activity_time); g_value_set_uint64 (&value, client->last_activity_time);
result = g_value_array_append (result, &value); result = g_value_array_append (result, &value);
} }
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
/* python doesn't like a NULL pointer yet */ /* python doesn't like a NULL pointer yet */
if (result == NULL) { if (result == NULL) {
@ -650,19 +650,24 @@ gst_multifdsink_remove_client_link (GstMultiFdSink * sink, GList * link)
/* unlock the mutex before signaling because the signal handler /* unlock the mutex before signaling because the signal handler
* might query some properties */ * might query some properties */
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
g_signal_emit (G_OBJECT (sink), g_signal_emit (G_OBJECT (sink),
gst_multifdsink_signals[SIGNAL_CLIENT_REMOVED], 0, fd, client->status); gst_multifdsink_signals[SIGNAL_CLIENT_REMOVED], 0, fd, client->status);
/* lock again before we remove the client completely */ /* lock again before we remove the client completely */
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
if (!g_hash_table_remove (sink->fd_hash, &client->fd.fd)) { if (!g_hash_table_remove (sink->fd_hash, &client->fd.fd)) {
GST_WARNING_OBJECT (sink, GST_WARNING_OBJECT (sink,
"[fd %5d] error removing client %p from hash", client->fd.fd, client); "[fd %5d] error removing client %p from hash", client->fd.fd, client);
} }
sink->clients = g_list_delete_link (sink->clients, link); /* after releasing the lock above, the link could be invalid, more
* precisely, the next and prev pointers could point to invalid list
* links. One optimisation could be to add a cookie to the linked list
* and take a shortcut when it did not change between unlocking and locking
* our mutex. For now we just walk the list again. */
sink->clients = g_list_remove (sink->clients, client);
if (fclass->removed) if (fclass->removed)
fclass->removed (sink, client->fd.fd); fclass->removed (sink, client->fd.fd);
@ -740,12 +745,12 @@ gst_multifdsink_handle_client_read (GstMultiFdSink * sink,
static gboolean static gboolean
gst_multifdsink_client_queue_data (GstMultiFdSink * sink, GstTCPClient * client, gst_multifdsink_client_queue_data (GstMultiFdSink * sink, GstTCPClient * client,
guint8 * data, gint len) gchar * data, gint len)
{ {
GstBuffer *buf; GstBuffer *buf;
buf = gst_buffer_new (); buf = gst_buffer_new ();
GST_BUFFER_DATA (buf) = data; GST_BUFFER_DATA (buf) = (guint8 *) data;
GST_BUFFER_SIZE (buf) = len; GST_BUFFER_SIZE (buf) = len;
GST_LOG_OBJECT (sink, "[fd %5d] queueing data of length %d", GST_LOG_OBJECT (sink, "[fd %5d] queueing data of length %d",
@ -774,10 +779,10 @@ gst_multifdsink_client_queue_caps (GstMultiFdSink * sink, GstTCPClient * client,
GST_DEBUG_OBJECT (sink, "Could not create GDP packet from caps"); GST_DEBUG_OBJECT (sink, "Could not create GDP packet from caps");
return FALSE; return FALSE;
} }
gst_multifdsink_client_queue_data (sink, client, header, length); gst_multifdsink_client_queue_data (sink, client, (gchar *) header, length);
length = gst_dp_header_payload_length (header); length = gst_dp_header_payload_length (header);
gst_multifdsink_client_queue_data (sink, client, payload, length); gst_multifdsink_client_queue_data (sink, client, (gchar *) payload, length);
return TRUE; return TRUE;
} }
@ -806,7 +811,7 @@ gst_multifdsink_client_queue_buffer (GstMultiFdSink * sink,
"[fd %5d] could not create header, removing client", client->fd.fd); "[fd %5d] could not create header, removing client", client->fd.fd);
return FALSE; return FALSE;
} }
gst_multifdsink_client_queue_data (sink, client, header, len); gst_multifdsink_client_queue_data (sink, client, (gchar *) header, len);
} }
GST_LOG_OBJECT (sink, "[fd %5d] queueing buffer of length %d", GST_LOG_OBJECT (sink, "[fd %5d] queueing buffer of length %d",
@ -1171,7 +1176,7 @@ gst_multifdsink_queue_buffer (GstMultiFdSink * sink, GstBuffer * buf)
g_get_current_time (&nowtv); g_get_current_time (&nowtv);
now = GST_TIMEVAL_TO_TIME (nowtv); now = GST_TIMEVAL_TO_TIME (nowtv);
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
/* add buffer to queue */ /* add buffer to queue */
g_array_prepend_val (sink->bufqueue, buf); g_array_prepend_val (sink->bufqueue, buf);
queuelen = sink->bufqueue->len; queuelen = sink->bufqueue->len;
@ -1271,7 +1276,7 @@ gst_multifdsink_queue_buffer (GstMultiFdSink * sink, GstBuffer * buf)
} }
/* save for stats */ /* save for stats */
sink->buffers_queued = max_buffer_usage; sink->buffers_queued = max_buffer_usage;
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
/* and send a signal to thread if fd_set changed */ /* and send a signal to thread if fd_set changed */
if (need_signal) { if (need_signal) {
@ -1316,7 +1321,7 @@ gst_multifdsink_handle_clients (GstMultiFdSink * sink)
if (errno == EBADF) { if (errno == EBADF) {
/* ok, so one or more of the fds is invalid. We loop over them to find /* ok, so one or more of the fds is invalid. We loop over them to find
* the ones that give an error to the F_GETFL fcntl. */ * the ones that give an error to the F_GETFL fcntl. */
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
for (clients = sink->clients; clients; clients = next) { for (clients = sink->clients; clients; clients = next) {
GstTCPClient *client; GstTCPClient *client;
int fd; int fd;
@ -1338,7 +1343,7 @@ gst_multifdsink_handle_clients (GstMultiFdSink * sink)
} }
} }
} }
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
/* after this, go back in the select loop as the read/writefds /* after this, go back in the select loop as the read/writefds
* are not valid */ * are not valid */
try_again = TRUE; try_again = TRUE;
@ -1400,7 +1405,7 @@ gst_multifdsink_handle_clients (GstMultiFdSink * sink)
fclass->wait (sink, sink->fdset); fclass->wait (sink, sink->fdset);
/* Check the clients */ /* Check the clients */
g_mutex_lock (sink->clientslock); CLIENTS_LOCK (sink);
for (clients = sink->clients; clients; clients = next) { for (clients = sink->clients; clients; clients = next) {
GstTCPClient *client; GstTCPClient *client;
@ -1438,7 +1443,7 @@ gst_multifdsink_handle_clients (GstMultiFdSink * sink)
} }
} }
} }
g_mutex_unlock (sink->clientslock); CLIENTS_UNLOCK (sink);
} }
/* we handle the client communication in another thread so that we do not block /* we handle the client communication in another thread so that we do not block
@ -1717,6 +1722,8 @@ gst_multifdsink_stop (GstBaseSink * bsink)
this->fdset = NULL; this->fdset = NULL;
} }
GST_FLAG_UNSET (this, GST_MULTIFDSINK_OPEN); GST_FLAG_UNSET (this, GST_MULTIFDSINK_OPEN);
CLIENTS_LOCK_FREE (this);
g_hash_table_destroy (this->fd_hash);
return TRUE; return TRUE;
} }

View file

@ -116,13 +116,18 @@ typedef struct {
} GstTCPClient; } GstTCPClient;
#define CLIENTS_LOCK_INIT(fdsink) (g_static_rec_mutex_init(&fdsink->clientslock))
#define CLIENTS_LOCK_FREE(fdsink) (g_static_rec_mutex_free(&fdsink->clientslock))
#define CLIENTS_LOCK(fdsink) (g_static_rec_mutex_lock(&fdsink->clientslock))
#define CLIENTS_UNLOCK(fdsink) (g_static_rec_mutex_unlock(&fdsink->clientslock))
struct _GstMultiFdSink { struct _GstMultiFdSink {
GstBaseSink element; GstBaseSink element;
guint64 bytes_to_serve; /* how much bytes we must serve */ guint64 bytes_to_serve; /* how much bytes we must serve */
guint64 bytes_served; /* how much bytes have we served */ guint64 bytes_served; /* how much bytes have we served */
GMutex *clientslock; /* lock to protect the clients list */ GStaticRecMutex clientslock; /* lock to protect the clients list */
GList *clients; /* list of clients we are serving */ GList *clients; /* list of clients we are serving */
GHashTable *fd_hash; /* index on fd to client */ GHashTable *fd_hash; /* index on fd to client */

View file

@ -1234,19 +1234,14 @@ gst_ximagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink, ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_WIDTH (ximagesink),
GST_VIDEO_SINK_HEIGHT (ximagesink)); GST_VIDEO_SINK_HEIGHT (ximagesink));
if (!ximagesink->ximage) { if (!ximagesink->ximage)
/* No image available. That's very bad ! */ goto no_ximage;
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (ximagesink, CORE, NEGOTIATION, (NULL),
("Failed creating an XImage in ximagesink chain function."));
return GST_FLOW_ERROR;
} }
memcpy (ximagesink->ximage->ximage->data, memcpy (ximagesink->ximage->ximage->data,
GST_BUFFER_DATA (buf), GST_BUFFER_DATA (buf),
MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size)); MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size));
gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage); gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage);
} }
}
gst_ximagesink_handle_xevents (ximagesink); gst_ximagesink_handle_xevents (ximagesink);
#if 0 #if 0
@ -1256,6 +1251,17 @@ gst_ximagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
g_mutex_unlock (ximagesink->stream_lock); g_mutex_unlock (ximagesink->stream_lock);
return GST_FLOW_OK; return GST_FLOW_OK;
/* ERRORS */
no_ximage:
{
/* No image available. That's very bad ! */
g_mutex_unlock (ximagesink->stream_lock);
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (ximagesink, CORE, NEGOTIATION, (NULL),
("Failed creating an XImage in ximagesink chain function."));
return GST_FLOW_ERROR;
}
} }
/* Buffer management */ /* Buffer management */