sctpenc: Report errors when sending out data and the association is in error or disconnected state

This commit is contained in:
Sebastian Dröge 2020-01-30 17:29:40 +02:00
parent 6d22e80f30
commit e6c6b5ea29
3 changed files with 34 additions and 16 deletions

View file

@ -625,19 +625,21 @@ gst_sctp_enc_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
g_mutex_lock (&sctpenc_pad->lock); g_mutex_lock (&sctpenc_pad->lock);
while (!sctpenc_pad->flushing) { while (!sctpenc_pad->flushing) {
gint32 bytes_sent; guint32 bytes_sent;
g_mutex_unlock (&sctpenc_pad->lock); g_mutex_unlock (&sctpenc_pad->lock);
bytes_sent = flow_ret =
gst_sctp_association_send_data (self->sctp_association, data, gst_sctp_association_send_data (self->sctp_association, data,
length, sctpenc_pad->stream_id, ppid, ordered, pr, pr_param); length, sctpenc_pad->stream_id, ppid, ordered, pr, pr_param,
&bytes_sent);
g_mutex_lock (&sctpenc_pad->lock); g_mutex_lock (&sctpenc_pad->lock);
if (bytes_sent < 0) { if (flow_ret != GST_FLOW_OK) {
GST_ELEMENT_ERROR (self, RESOURCE, WRITE, (NULL), if (flow_ret != GST_FLOW_EOS) {
("Failed to send data")); GST_ELEMENT_ERROR (self, RESOURCE, WRITE, (NULL),
flow_ret = GST_FLOW_ERROR; ("Failed to send data"));
}
goto out; goto out;
} else if (bytes_sent < length && !sctpenc_pad->flushing) { } else if (bytes_sent < length && !sctpenc_pad->flushing) {
gint64 end_time = g_get_monotonic_time () + BUFFER_FULL_SLEEP_TIME; gint64 end_time = g_get_monotonic_time () + BUFFER_FULL_SLEEP_TIME;

View file

@ -432,19 +432,29 @@ gst_sctp_association_incoming_packet (GstSctpAssociation * self,
usrsctp_conninput ((void *) self, (const void *) buf, (size_t) length, 0); usrsctp_conninput ((void *) self, (const void *) buf, (size_t) length, 0);
} }
gint32 GstFlowReturn
gst_sctp_association_send_data (GstSctpAssociation * self, const guint8 * buf, gst_sctp_association_send_data (GstSctpAssociation * self, const guint8 * buf,
guint32 length, guint16 stream_id, guint32 ppid, gboolean ordered, guint32 length, guint16 stream_id, guint32 ppid, gboolean ordered,
GstSctpAssociationPartialReliability pr, guint32 reliability_param) GstSctpAssociationPartialReliability pr, guint32 reliability_param,
guint32 * bytes_sent_)
{ {
GstFlowReturn flow_ret;
struct sctp_sendv_spa spa; struct sctp_sendv_spa spa;
gint32 bytes_sent = -1; gint32 bytes_sent = 0;
struct sockaddr_conn remote_addr; struct sockaddr_conn remote_addr;
g_rec_mutex_lock (&self->association_mutex); g_rec_mutex_lock (&self->association_mutex);
if (self->state != GST_SCTP_ASSOCIATION_STATE_CONNECTED) { if (self->state != GST_SCTP_ASSOCIATION_STATE_CONNECTED) {
GST_ERROR_OBJECT (self, "Association not connected yet"); if (self->state == GST_SCTP_ASSOCIATION_STATE_DISCONNECTED ||
goto end; self->state == GST_SCTP_ASSOCIATION_STATE_DISCONNECTING) {
GST_ERROR_OBJECT (self, "Disconnected");
flow_ret = GST_FLOW_EOS;
goto end;
} else {
GST_ERROR_OBJECT (self, "Association not connected yet");
flow_ret = GST_FLOW_ERROR;
goto end;
}
} }
memset (&spa, 0, sizeof (spa)); memset (&spa, 0, sizeof (spa));
@ -475,19 +485,24 @@ gst_sctp_association_send_data (GstSctpAssociation * self, const guint8 * buf,
if (errno == EAGAIN || errno == EWOULDBLOCK) { if (errno == EAGAIN || errno == EWOULDBLOCK) {
bytes_sent = 0; bytes_sent = 0;
/* Resending this buffer is taken care of by the gstsctpenc */ /* Resending this buffer is taken care of by the gstsctpenc */
flow_ret = GST_FLOW_OK;
goto end; goto end;
} else { } else {
GST_ERROR_OBJECT (self, "Error sending data on stream %u: (%u) %s", GST_ERROR_OBJECT (self, "Error sending data on stream %u: (%u) %s",
stream_id, errno, g_strerror (errno)); stream_id, errno, g_strerror (errno));
flow_ret = GST_FLOW_ERROR;
goto end; goto end;
} }
} }
flow_ret = GST_FLOW_OK;
end: end:
g_rec_mutex_unlock (&self->association_mutex); g_rec_mutex_unlock (&self->association_mutex);
return bytes_sent; if (bytes_sent_)
} *bytes_sent_ = bytes_sent;
return flow_ret;
}
void void
gst_sctp_association_reset_stream (GstSctpAssociation * self, guint16 stream_id) gst_sctp_association_reset_stream (GstSctpAssociation * self, guint16 stream_id)

View file

@ -27,6 +27,7 @@
#define __GST_SCTP_ASSOCIATION_H__ #define __GST_SCTP_ASSOCIATION_H__
#include <glib-object.h> #include <glib-object.h>
#include <gst/gst.h>
#define INET #define INET
#define INET6 #define INET6
#include <usrsctp.h> #include <usrsctp.h>
@ -112,10 +113,10 @@ void gst_sctp_association_set_on_packet_received (GstSctpAssociation * self,
GstSctpAssociationPacketReceivedCb packet_received_cb, gpointer user_data, GDestroyNotify destroy_notify); GstSctpAssociationPacketReceivedCb packet_received_cb, gpointer user_data, GDestroyNotify destroy_notify);
void gst_sctp_association_incoming_packet (GstSctpAssociation * self, void gst_sctp_association_incoming_packet (GstSctpAssociation * self,
const guint8 * buf, guint32 length); const guint8 * buf, guint32 length);
gint32 gst_sctp_association_send_data (GstSctpAssociation * self, GstFlowReturn gst_sctp_association_send_data (GstSctpAssociation * self,
const guint8 * buf, guint32 length, guint16 stream_id, guint32 ppid, const guint8 * buf, guint32 length, guint16 stream_id, guint32 ppid,
gboolean ordered, GstSctpAssociationPartialReliability pr, gboolean ordered, GstSctpAssociationPartialReliability pr,
guint32 reliability_param); guint32 reliability_param, guint32 *bytes_sent);
void gst_sctp_association_reset_stream (GstSctpAssociation * self, void gst_sctp_association_reset_stream (GstSctpAssociation * self,
guint16 stream_id); guint16 stream_id);
void gst_sctp_association_force_close (GstSctpAssociation * self); void gst_sctp_association_force_close (GstSctpAssociation * self);