mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
rtsp-message: Add support for storing GstBuffers directly as body payload of messages
This makes it unnecessary for callers to first merge together all memories, and it allows API like GstRTSPConnection to write them out without first copying all memories together or using writev()-style API to write multiple memories out in one go. Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/370
This commit is contained in:
parent
3a9148b334
commit
b3c0d8b89b
3 changed files with 207 additions and 17 deletions
|
@ -1955,6 +1955,11 @@ gst_rtsp_message_set_body
|
||||||
gst_rtsp_message_take_body
|
gst_rtsp_message_take_body
|
||||||
gst_rtsp_message_get_body
|
gst_rtsp_message_get_body
|
||||||
gst_rtsp_message_steal_body
|
gst_rtsp_message_steal_body
|
||||||
|
gst_rtsp_message_set_body_buffer
|
||||||
|
gst_rtsp_message_take_body_buffer
|
||||||
|
gst_rtsp_message_has_body_buffer
|
||||||
|
gst_rtsp_message_get_body_buffer
|
||||||
|
gst_rtsp_message_steal_body_buffer
|
||||||
|
|
||||||
GstRTSPAuthCredential
|
GstRTSPAuthCredential
|
||||||
GstRTSPAuthParam
|
GstRTSPAuthParam
|
||||||
|
|
|
@ -507,6 +507,7 @@ gst_rtsp_message_unset (GstRTSPMessage * msg)
|
||||||
g_array_free (msg->hdr_fields, TRUE);
|
g_array_free (msg->hdr_fields, TRUE);
|
||||||
}
|
}
|
||||||
g_free (msg->body);
|
g_free (msg->body);
|
||||||
|
gst_buffer_replace (&msg->body_buffer, NULL);
|
||||||
|
|
||||||
memset (msg, 0, sizeof (GstRTSPMessage));
|
memset (msg, 0, sizeof (GstRTSPMessage));
|
||||||
|
|
||||||
|
@ -586,7 +587,10 @@ gst_rtsp_message_copy (const GstRTSPMessage * msg, GstRTSPMessage ** copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
key_value_foreach (msg->hdr_fields, (GFunc) key_value_append, cp->hdr_fields);
|
key_value_foreach (msg->hdr_fields, (GFunc) key_value_append, cp->hdr_fields);
|
||||||
|
if (msg->body)
|
||||||
gst_rtsp_message_set_body (cp, msg->body, msg->body_size);
|
gst_rtsp_message_set_body (cp, msg->body, msg->body_size);
|
||||||
|
else
|
||||||
|
gst_rtsp_message_set_body_buffer (cp, msg->body_buffer);
|
||||||
|
|
||||||
return GST_RTSP_OK;
|
return GST_RTSP_OK;
|
||||||
}
|
}
|
||||||
|
@ -928,7 +932,8 @@ gst_rtsp_message_append_headers (const GstRTSPMessage * msg, GString * str)
|
||||||
* @data: (array length=size) (transfer none): the data
|
* @data: (array length=size) (transfer none): the data
|
||||||
* @size: the size of @data
|
* @size: the size of @data
|
||||||
*
|
*
|
||||||
* Set the body of @msg to a copy of @data.
|
* Set the body of @msg to a copy of @data. Any existing body or body buffer
|
||||||
|
* will be replaced by the new body.
|
||||||
*
|
*
|
||||||
* Returns: #GST_RTSP_OK.
|
* Returns: #GST_RTSP_OK.
|
||||||
*/
|
*/
|
||||||
|
@ -948,7 +953,7 @@ gst_rtsp_message_set_body (GstRTSPMessage * msg, const guint8 * data,
|
||||||
* @size: the size of @data
|
* @size: the size of @data
|
||||||
*
|
*
|
||||||
* Set the body of @msg to @data and @size. This method takes ownership of
|
* Set the body of @msg to @data and @size. This method takes ownership of
|
||||||
* @data.
|
* @data. Any existing body or body buffer will be replaced by the new body.
|
||||||
*
|
*
|
||||||
* Returns: #GST_RTSP_OK.
|
* Returns: #GST_RTSP_OK.
|
||||||
*/
|
*/
|
||||||
|
@ -958,6 +963,7 @@ gst_rtsp_message_take_body (GstRTSPMessage * msg, guint8 * data, guint size)
|
||||||
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
g_return_val_if_fail (data != NULL || size == 0, GST_RTSP_EINVAL);
|
g_return_val_if_fail (data != NULL || size == 0, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
gst_buffer_replace (&msg->body_buffer, NULL);
|
||||||
g_free (msg->body);
|
g_free (msg->body);
|
||||||
|
|
||||||
msg->body = data;
|
msg->body = data;
|
||||||
|
@ -975,6 +981,10 @@ gst_rtsp_message_take_body (GstRTSPMessage * msg, guint8 * data, guint size)
|
||||||
* Get the body of @msg. @data remains valid for as long as @msg is valid and
|
* Get the body of @msg. @data remains valid for as long as @msg is valid and
|
||||||
* unchanged.
|
* unchanged.
|
||||||
*
|
*
|
||||||
|
* If the message body was set as a #GstBuffer before this will cause the data
|
||||||
|
* to be copied and stored in the message. The #GstBuffer will no longer be
|
||||||
|
* kept in the message.
|
||||||
|
*
|
||||||
* Returns: #GST_RTSP_OK.
|
* Returns: #GST_RTSP_OK.
|
||||||
*/
|
*/
|
||||||
GstRTSPResult
|
GstRTSPResult
|
||||||
|
@ -985,6 +995,16 @@ gst_rtsp_message_get_body (const GstRTSPMessage * msg, guint8 ** data,
|
||||||
g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
|
g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
|
||||||
g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);
|
g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
if (msg->body_buffer) {
|
||||||
|
gsize size;
|
||||||
|
|
||||||
|
gst_buffer_extract_dup (msg->body_buffer, 0,
|
||||||
|
gst_buffer_get_size (msg->body_buffer),
|
||||||
|
(gpointer *) & ((GstRTSPMessage *) msg)->body, &size);
|
||||||
|
gst_buffer_replace (&((GstRTSPMessage *) msg)->body_buffer, NULL);
|
||||||
|
((GstRTSPMessage *) msg)->body_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
*data = msg->body;
|
*data = msg->body;
|
||||||
*size = msg->body_size;
|
*size = msg->body_size;
|
||||||
|
|
||||||
|
@ -1009,6 +1029,16 @@ gst_rtsp_message_steal_body (GstRTSPMessage * msg, guint8 ** data, guint * size)
|
||||||
g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
|
g_return_val_if_fail (data != NULL, GST_RTSP_EINVAL);
|
||||||
g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);
|
g_return_val_if_fail (size != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
if (msg->body_buffer) {
|
||||||
|
gsize size;
|
||||||
|
|
||||||
|
gst_buffer_extract_dup (msg->body_buffer, 0,
|
||||||
|
gst_buffer_get_size (msg->body_buffer),
|
||||||
|
(gpointer *) & msg->body, &size);
|
||||||
|
gst_buffer_replace (&msg->body_buffer, NULL);
|
||||||
|
msg->body_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
*data = msg->body;
|
*data = msg->body;
|
||||||
*size = msg->body_size;
|
*size = msg->body_size;
|
||||||
|
|
||||||
|
@ -1018,6 +1048,134 @@ gst_rtsp_message_steal_body (GstRTSPMessage * msg, guint8 ** data, guint * size)
|
||||||
return GST_RTSP_OK;
|
return GST_RTSP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_message_set_body_buffer:
|
||||||
|
* @msg: a #GstRTSPMessage
|
||||||
|
* @buffer: a #GstBuffer
|
||||||
|
*
|
||||||
|
* Set the body of @msg to @buffer. Any existing body or body buffer
|
||||||
|
* will be replaced by the new body.
|
||||||
|
*
|
||||||
|
* Returns: #GST_RTSP_OK.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
GstRTSPResult
|
||||||
|
gst_rtsp_message_set_body_buffer (GstRTSPMessage * msg, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
return gst_rtsp_message_take_body_buffer (msg,
|
||||||
|
buffer ? gst_buffer_ref (buffer) : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_message_take_body_buffer:
|
||||||
|
* @msg: a #GstRTSPMessage
|
||||||
|
* @buffer: (transfer full): a #GstBuffer
|
||||||
|
*
|
||||||
|
* Set the body of @msg to @buffer. This method takes ownership of @buffer.
|
||||||
|
* Any existing body or body buffer will be replaced by the new body.
|
||||||
|
*
|
||||||
|
* Returns: #GST_RTSP_OK.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
GstRTSPResult
|
||||||
|
gst_rtsp_message_take_body_buffer (GstRTSPMessage * msg, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
g_free (msg->body);
|
||||||
|
msg->body = NULL;
|
||||||
|
if (msg->body_buffer)
|
||||||
|
gst_buffer_unref (msg->body_buffer);
|
||||||
|
msg->body_buffer = buffer;
|
||||||
|
msg->body_size = buffer ? gst_buffer_get_size (buffer) : 0;
|
||||||
|
|
||||||
|
return GST_RTSP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_message_get_body_buffer:
|
||||||
|
* @msg: a #GstRTSPMessage
|
||||||
|
* @buffer: (out) (transfer none): location for the buffer
|
||||||
|
*
|
||||||
|
* Get the body of @msg. @buffer remains valid for as long as @msg is valid and
|
||||||
|
* unchanged.
|
||||||
|
*
|
||||||
|
* If body data was set from raw memory instead of a #GstBuffer this function
|
||||||
|
* will always return %NULL. The caller can check if there is a body buffer by
|
||||||
|
* calling gst_rtsp_message_has_body_buffer().
|
||||||
|
*
|
||||||
|
* Returns: #GST_RTSP_OK.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
GstRTSPResult
|
||||||
|
gst_rtsp_message_get_body_buffer (const GstRTSPMessage * msg,
|
||||||
|
GstBuffer ** buffer)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
|
g_return_val_if_fail (buffer != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
*buffer = msg->body_buffer;
|
||||||
|
|
||||||
|
return GST_RTSP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_message_steal_body_buffer:
|
||||||
|
* @msg: a #GstRTSPMessage
|
||||||
|
* @buffer: (out) (transfer full): location for the buffer
|
||||||
|
*
|
||||||
|
* Take the body of @msg and store it in @buffer. After this method,
|
||||||
|
* the body and size of @msg will be set to %NULL and 0 respectively.
|
||||||
|
*
|
||||||
|
* If body data was set from raw memory instead of a #GstBuffer this function
|
||||||
|
* will always return %NULL. The caller can check if there is a body buffer by
|
||||||
|
* calling gst_rtsp_message_has_body_buffer().
|
||||||
|
*
|
||||||
|
* Returns: #GST_RTSP_OK.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
GstRTSPResult
|
||||||
|
gst_rtsp_message_steal_body_buffer (GstRTSPMessage * msg, GstBuffer ** buffer)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
|
g_return_val_if_fail (buffer != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
if (msg->body_buffer) {
|
||||||
|
*buffer = msg->body_buffer;
|
||||||
|
msg->body_buffer = NULL;
|
||||||
|
msg->body_size = 0;
|
||||||
|
} else {
|
||||||
|
*buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GST_RTSP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_message_has_body_buffer:
|
||||||
|
* @msg: a #GstRTSPMessage
|
||||||
|
*
|
||||||
|
* Checks if @msg has a body and the body is stored as #GstBuffer.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if @msg has a body and it's stored as #GstBuffer, %FALSE
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
|
* Since: 1.16
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_rtsp_message_has_body_buffer (const GstRTSPMessage * msg)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
return msg->body_buffer != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_key_value (gpointer data, gpointer user_data G_GNUC_UNUSED)
|
dump_key_value (gpointer data, gpointer user_data G_GNUC_UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -1043,8 +1201,20 @@ dump_key_value (gpointer data, gpointer user_data G_GNUC_UNUSED)
|
||||||
GstRTSPResult
|
GstRTSPResult
|
||||||
gst_rtsp_message_dump (GstRTSPMessage * msg)
|
gst_rtsp_message_dump (GstRTSPMessage * msg)
|
||||||
{
|
{
|
||||||
guint8 *data;
|
guint8 *data = NULL;
|
||||||
guint size;
|
guint size;
|
||||||
|
GstBuffer *body_buffer = NULL;
|
||||||
|
|
||||||
|
#define PRINT_BODY G_STMT_START { \
|
||||||
|
gst_rtsp_message_get_body_buffer (msg, &body_buffer); \
|
||||||
|
if (body_buffer) { \
|
||||||
|
gst_util_dump_buffer (body_buffer); \
|
||||||
|
} else { \
|
||||||
|
gst_rtsp_message_get_body (msg, &data, &size); \
|
||||||
|
if (data) \
|
||||||
|
gst_util_dump_mem (data, size); \
|
||||||
|
} \
|
||||||
|
} G_STMT_END;
|
||||||
|
|
||||||
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
g_return_val_if_fail (msg != NULL, GST_RTSP_EINVAL);
|
||||||
|
|
||||||
|
@ -1060,8 +1230,7 @@ gst_rtsp_message_dump (GstRTSPMessage * msg)
|
||||||
g_print (" headers:\n");
|
g_print (" headers:\n");
|
||||||
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||||
g_print (" body:\n");
|
g_print (" body:\n");
|
||||||
gst_rtsp_message_get_body (msg, &data, &size);
|
PRINT_BODY;
|
||||||
gst_util_dump_mem (data, size);
|
|
||||||
break;
|
break;
|
||||||
case GST_RTSP_MESSAGE_RESPONSE:
|
case GST_RTSP_MESSAGE_RESPONSE:
|
||||||
g_print ("RTSP response message %p\n", msg);
|
g_print ("RTSP response message %p\n", msg);
|
||||||
|
@ -1072,9 +1241,7 @@ gst_rtsp_message_dump (GstRTSPMessage * msg)
|
||||||
gst_rtsp_version_as_text (msg->type_data.response.version));
|
gst_rtsp_version_as_text (msg->type_data.response.version));
|
||||||
g_print (" headers:\n");
|
g_print (" headers:\n");
|
||||||
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||||
gst_rtsp_message_get_body (msg, &data, &size);
|
PRINT_BODY;
|
||||||
g_print (" body: length %d\n", size);
|
|
||||||
gst_util_dump_mem (data, size);
|
|
||||||
break;
|
break;
|
||||||
case GST_RTSP_MESSAGE_HTTP_REQUEST:
|
case GST_RTSP_MESSAGE_HTTP_REQUEST:
|
||||||
g_print ("HTTP request message %p\n", msg);
|
g_print ("HTTP request message %p\n", msg);
|
||||||
|
@ -1087,8 +1254,7 @@ gst_rtsp_message_dump (GstRTSPMessage * msg)
|
||||||
g_print (" headers:\n");
|
g_print (" headers:\n");
|
||||||
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||||
g_print (" body:\n");
|
g_print (" body:\n");
|
||||||
gst_rtsp_message_get_body (msg, &data, &size);
|
PRINT_BODY;
|
||||||
gst_util_dump_mem (data, size);
|
|
||||||
break;
|
break;
|
||||||
case GST_RTSP_MESSAGE_HTTP_RESPONSE:
|
case GST_RTSP_MESSAGE_HTTP_RESPONSE:
|
||||||
g_print ("HTTP response message %p\n", msg);
|
g_print ("HTTP response message %p\n", msg);
|
||||||
|
@ -1099,22 +1265,21 @@ gst_rtsp_message_dump (GstRTSPMessage * msg)
|
||||||
gst_rtsp_version_as_text (msg->type_data.response.version));
|
gst_rtsp_version_as_text (msg->type_data.response.version));
|
||||||
g_print (" headers:\n");
|
g_print (" headers:\n");
|
||||||
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
key_value_foreach (msg->hdr_fields, dump_key_value, NULL);
|
||||||
gst_rtsp_message_get_body (msg, &data, &size);
|
PRINT_BODY;
|
||||||
g_print (" body: length %d\n", size);
|
|
||||||
gst_util_dump_mem (data, size);
|
|
||||||
break;
|
break;
|
||||||
case GST_RTSP_MESSAGE_DATA:
|
case GST_RTSP_MESSAGE_DATA:
|
||||||
g_print ("RTSP data message %p\n", msg);
|
g_print ("RTSP data message %p\n", msg);
|
||||||
g_print (" channel: '%d'\n", msg->type_data.data.channel);
|
g_print (" channel: '%d'\n", msg->type_data.data.channel);
|
||||||
g_print (" size: '%d'\n", msg->body_size);
|
g_print (" size: '%d'\n", msg->body_size);
|
||||||
gst_rtsp_message_get_body (msg, &data, &size);
|
PRINT_BODY;
|
||||||
gst_util_dump_mem (data, size);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_print ("unsupported message type %d\n", msg->type);
|
g_print ("unsupported message type %d\n", msg->type);
|
||||||
return GST_RTSP_EINVAL;
|
return GST_RTSP_EINVAL;
|
||||||
}
|
}
|
||||||
return GST_RTSP_OK;
|
return GST_RTSP_OK;
|
||||||
|
|
||||||
|
#undef PRINT_BODY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,8 @@ struct _GstRTSPMessage
|
||||||
guint8 *body;
|
guint8 *body;
|
||||||
guint body_size;
|
guint body_size;
|
||||||
|
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
GstBuffer *body_buffer;
|
||||||
|
gpointer _gst_reserved[GST_PADDING-1];
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_RTSP_API
|
GST_RTSP_API
|
||||||
|
@ -258,6 +259,25 @@ GstRTSPResult gst_rtsp_message_steal_body (GstRTSPMessage *msg,
|
||||||
guint8 **data,
|
guint8 **data,
|
||||||
guint *size);
|
guint *size);
|
||||||
|
|
||||||
|
GST_RTSP_API
|
||||||
|
GstRTSPResult gst_rtsp_message_set_body_buffer (GstRTSPMessage *msg,
|
||||||
|
GstBuffer * buffer);
|
||||||
|
|
||||||
|
GST_RTSP_API
|
||||||
|
GstRTSPResult gst_rtsp_message_take_body_buffer(GstRTSPMessage *msg,
|
||||||
|
GstBuffer * buffer);
|
||||||
|
|
||||||
|
GST_RTSP_API
|
||||||
|
GstRTSPResult gst_rtsp_message_get_body_buffer (const GstRTSPMessage *msg,
|
||||||
|
GstBuffer ** buffer);
|
||||||
|
|
||||||
|
GST_RTSP_API
|
||||||
|
GstRTSPResult gst_rtsp_message_steal_body_buffer(GstRTSPMessage *msg,
|
||||||
|
GstBuffer ** buffer);
|
||||||
|
|
||||||
|
GST_RTSP_API
|
||||||
|
gboolean gst_rtsp_message_has_body_buffer(const GstRTSPMessage *msg);
|
||||||
|
|
||||||
typedef struct _GstRTSPAuthCredential GstRTSPAuthCredential;
|
typedef struct _GstRTSPAuthCredential GstRTSPAuthCredential;
|
||||||
typedef struct _GstRTSPAuthParam GstRTSPAuthParam;
|
typedef struct _GstRTSPAuthParam GstRTSPAuthParam;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue