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>
* gst/playback/gstplaybasebin.c: (check_queue), (probe_triggered),

View file

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

View file

@ -409,7 +409,7 @@ gst_multifdsink_init (GstMultiFdSink * this)
this->protocol = DEFAULT_PROTOCOL;
this->mode = DEFAULT_MODE;
this->clientslock = g_mutex_new ();
CLIENTS_LOCK_INIT (this);
this->clients = NULL;
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 */
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 */
clink = g_hash_table_lookup (sink->fd_hash, &client->fd.fd);
if (clink != NULL) {
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);
g_signal_emit (G_OBJECT (sink),
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);
g_mutex_unlock (sink->clientslock);
CLIENTS_UNLOCK (sink);
g_signal_emit (G_OBJECT (sink),
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);
g_mutex_lock (sink->clientslock);
CLIENTS_LOCK (sink);
clink = g_hash_table_lookup (sink->fd_hash, &fd);
if (clink != NULL) {
GstTCPClient *client = (GstTCPClient *) clink->data;
@ -513,7 +513,7 @@ gst_multifdsink_remove (GstMultiFdSink * sink, int fd)
} else {
GST_WARNING_OBJECT (sink, "[fd %5d] no client with this fd found!", fd);
}
g_mutex_unlock (sink->clientslock);
CLIENTS_UNLOCK (sink);
}
void
@ -523,7 +523,7 @@ gst_multifdsink_clear (GstMultiFdSink * sink)
GST_DEBUG_OBJECT (sink, "clearing all clients");
g_mutex_lock (sink->clientslock);
CLIENTS_LOCK (sink);
for (clients = sink->clients; clients; clients = next) {
GstTCPClient *client;
@ -534,7 +534,7 @@ gst_multifdsink_clear (GstMultiFdSink * sink)
gst_multifdsink_remove_client_link (sink, clients);
}
SEND_COMMAND (sink, CONTROL_RESTART);
g_mutex_unlock (sink->clientslock);
CLIENTS_UNLOCK (sink);
}
GValueArray *
@ -544,7 +544,7 @@ gst_multifdsink_get_stats (GstMultiFdSink * sink, int fd)
GValueArray *result = NULL;
GList *clink;
g_mutex_lock (sink->clientslock);
CLIENTS_LOCK (sink);
clink = g_hash_table_lookup (sink->fd_hash, &fd);
client = (GstTCPClient *) clink->data;
if (client != NULL) {
@ -582,7 +582,7 @@ gst_multifdsink_get_stats (GstMultiFdSink * sink, int fd)
g_value_set_uint64 (&value, client->last_activity_time);
result = g_value_array_append (result, &value);
}
g_mutex_unlock (sink->clientslock);
CLIENTS_UNLOCK (sink);
/* python doesn't like a NULL pointer yet */
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
* might query some properties */
g_mutex_unlock (sink->clientslock);
CLIENTS_UNLOCK (sink);
g_signal_emit (G_OBJECT (sink),
gst_multifdsink_signals[SIGNAL_CLIENT_REMOVED], 0, fd, client->status);
/* 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)) {
GST_WARNING_OBJECT (sink,
"[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)
fclass->removed (sink, client->fd.fd);
@ -740,12 +745,12 @@ gst_multifdsink_handle_client_read (GstMultiFdSink * sink,
static gboolean
gst_multifdsink_client_queue_data (GstMultiFdSink * sink, GstTCPClient * client,
guint8 * data, gint len)
gchar * data, gint len)
{
GstBuffer *buf;
buf = gst_buffer_new ();
GST_BUFFER_DATA (buf) = data;
GST_BUFFER_DATA (buf) = (guint8 *) data;
GST_BUFFER_SIZE (buf) = len;
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");
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);
gst_multifdsink_client_queue_data (sink, client, payload, length);
gst_multifdsink_client_queue_data (sink, client, (gchar *) payload, length);
return TRUE;
}
@ -806,7 +811,7 @@ gst_multifdsink_client_queue_buffer (GstMultiFdSink * sink,
"[fd %5d] could not create header, removing client", client->fd.fd);
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",
@ -1171,7 +1176,7 @@ gst_multifdsink_queue_buffer (GstMultiFdSink * sink, GstBuffer * buf)
g_get_current_time (&nowtv);
now = GST_TIMEVAL_TO_TIME (nowtv);
g_mutex_lock (sink->clientslock);
CLIENTS_LOCK (sink);
/* add buffer to queue */
g_array_prepend_val (sink->bufqueue, buf);
queuelen = sink->bufqueue->len;
@ -1271,7 +1276,7 @@ gst_multifdsink_queue_buffer (GstMultiFdSink * sink, GstBuffer * buf)
}
/* save for stats */
sink->buffers_queued = max_buffer_usage;
g_mutex_unlock (sink->clientslock);
CLIENTS_UNLOCK (sink);
/* and send a signal to thread if fd_set changed */
if (need_signal) {
@ -1316,7 +1321,7 @@ gst_multifdsink_handle_clients (GstMultiFdSink * sink)
if (errno == EBADF) {
/* 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. */
g_mutex_lock (sink->clientslock);
CLIENTS_LOCK (sink);
for (clients = sink->clients; clients; clients = next) {
GstTCPClient *client;
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
* are not valid */
try_again = TRUE;
@ -1400,7 +1405,7 @@ gst_multifdsink_handle_clients (GstMultiFdSink * sink)
fclass->wait (sink, sink->fdset);
/* Check the clients */
g_mutex_lock (sink->clientslock);
CLIENTS_LOCK (sink);
for (clients = sink->clients; clients; clients = next) {
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
@ -1717,6 +1722,8 @@ gst_multifdsink_stop (GstBaseSink * bsink)
this->fdset = NULL;
}
GST_FLAG_UNSET (this, GST_MULTIFDSINK_OPEN);
CLIENTS_LOCK_FREE (this);
g_hash_table_destroy (this->fd_hash);
return TRUE;
}

View file

@ -116,13 +116,18 @@ typedef struct {
} 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 {
GstBaseSink element;
guint64 bytes_to_serve; /* how much bytes we must serve */
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 */
GHashTable *fd_hash; /* index on fd to client */

View file

@ -1234,18 +1234,13 @@ gst_ximagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink,
GST_VIDEO_SINK_WIDTH (ximagesink),
GST_VIDEO_SINK_HEIGHT (ximagesink));
if (!ximagesink->ximage) {
/* No image available. That's very bad ! */
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,
GST_BUFFER_DATA (buf),
MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size));
gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage);
if (!ximagesink->ximage)
goto no_ximage;
}
memcpy (ximagesink->ximage->ximage->data,
GST_BUFFER_DATA (buf),
MIN (GST_BUFFER_SIZE (buf), ximagesink->ximage->size));
gst_ximagesink_ximage_put (ximagesink, ximagesink->ximage);
}
gst_ximagesink_handle_xevents (ximagesink);
@ -1256,6 +1251,17 @@ gst_ximagesink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
g_mutex_unlock (ximagesink->stream_lock);
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 */