mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
gdppay: optimise payloading of buffers with multiple memories
Add function to calculate a payload CRC across multiple memories so we don't have to merge buffers with multiple memories just to calculate the CRC. Also make CRC calculation function static, since it's not used outside dataprotocol.h and move special-casing of length = 0 -> CRC = 0 into CRC function (from caller). Perhaps more importantly, since payload CRC is off by default: don't map buffer (and possibly merge memories in the process) if we are not going to use it to calculate a CRC anyway.
This commit is contained in:
parent
3853f8c070
commit
d790ba9a06
2 changed files with 80 additions and 11 deletions
|
@ -125,6 +125,10 @@ G_STMT_START { \
|
|||
#define POLY 0x1021
|
||||
#define CRC_INIT 0xFFFF
|
||||
|
||||
static guint16 gst_dp_crc (const guint8 * buffer, guint length);
|
||||
static guint16 gst_dp_crc_from_memory_maps (const GstMapInfo * maps,
|
||||
guint n_maps);
|
||||
|
||||
/*** HELPER FUNCTIONS ***/
|
||||
|
||||
static gboolean
|
||||
|
@ -133,7 +137,8 @@ gst_dp_header_from_buffer_any (GstBuffer * buffer, GstDPHeaderFlag flags,
|
|||
{
|
||||
guint8 *h;
|
||||
guint16 flags_mask;
|
||||
GstMapInfo map;
|
||||
guint16 header_crc = 0, crc = 0;
|
||||
gsize buffer_size;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||
g_return_val_if_fail (length, FALSE);
|
||||
|
@ -145,10 +150,35 @@ gst_dp_header_from_buffer_any (GstBuffer * buffer, GstDPHeaderFlag flags,
|
|||
/* version, flags, type */
|
||||
GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_BUFFER);
|
||||
|
||||
gst_buffer_map ((GstBuffer *) buffer, &map, GST_MAP_READ);
|
||||
if ((flags & GST_DP_HEADER_FLAG_CRC_PAYLOAD)) {
|
||||
GstMapInfo *maps;
|
||||
guint n_maps, i;
|
||||
|
||||
buffer_size = 0;
|
||||
|
||||
n_maps = gst_buffer_n_memory (buffer);
|
||||
if (n_maps > 0) {
|
||||
maps = g_newa (GstMapInfo, n_maps);
|
||||
|
||||
for (i = 0; i < n_maps; ++i) {
|
||||
GstMemory *mem;
|
||||
|
||||
mem = gst_buffer_peek_memory (buffer, i);
|
||||
gst_memory_map (mem, &maps[i], GST_MAP_READ);
|
||||
buffer_size += maps[i].size;
|
||||
}
|
||||
|
||||
crc = gst_dp_crc_from_memory_maps (maps, n_maps);
|
||||
|
||||
for (i = 0; i < n_maps; ++i)
|
||||
gst_memory_unmap (maps[i].memory, &maps[i]);
|
||||
}
|
||||
} else {
|
||||
buffer_size = gst_buffer_get_size (buffer);
|
||||
}
|
||||
|
||||
/* buffer properties */
|
||||
GST_WRITE_UINT32_BE (h + 6, map.size);
|
||||
GST_WRITE_UINT32_BE (h + 6, buffer_size);
|
||||
GST_WRITE_UINT64_BE (h + 10, GST_BUFFER_TIMESTAMP (buffer));
|
||||
GST_WRITE_UINT64_BE (h + 18, GST_BUFFER_DURATION (buffer));
|
||||
GST_WRITE_UINT64_BE (h + 26, GST_BUFFER_OFFSET (buffer));
|
||||
|
@ -164,9 +194,17 @@ gst_dp_header_from_buffer_any (GstBuffer * buffer, GstDPHeaderFlag flags,
|
|||
/* from gstreamer 1.x, buffers also have the DTS */
|
||||
GST_WRITE_UINT64_BE (h + 44, GST_BUFFER_DTS (buffer));
|
||||
|
||||
GST_DP_SET_CRC (h, flags, map.data, map.size);
|
||||
/* header CRC */
|
||||
if ((flags & GST_DP_HEADER_FLAG_CRC_HEADER))
|
||||
/* we don't crc the last four bytes since they are crc's */
|
||||
header_crc = gst_dp_crc (h, 58);
|
||||
else
|
||||
header_crc = 0;
|
||||
|
||||
gst_buffer_unmap ((GstBuffer *) buffer, &map);
|
||||
GST_WRITE_UINT16_BE (h + 58, header_crc);
|
||||
|
||||
/* payload CRC */
|
||||
GST_WRITE_UINT16_BE (h + 60, crc);
|
||||
|
||||
GST_MEMDUMP ("created header from buffer", h, GST_DP_HEADER_LENGTH);
|
||||
*header = h;
|
||||
|
@ -259,12 +297,15 @@ static const guint16 gst_dp_crc_table[256] = {
|
|||
*
|
||||
* Returns: a two-byte CRC checksum.
|
||||
*/
|
||||
guint16
|
||||
static guint16
|
||||
gst_dp_crc (const guint8 * buffer, guint length)
|
||||
{
|
||||
guint16 crc_register = CRC_INIT;
|
||||
|
||||
g_return_val_if_fail (buffer != NULL || length == 0, 0);
|
||||
if (length == 0)
|
||||
return 0;
|
||||
|
||||
g_assert (buffer != NULL);
|
||||
|
||||
/* calc CRC */
|
||||
for (; length--;) {
|
||||
|
@ -274,6 +315,38 @@ gst_dp_crc (const guint8 * buffer, guint length)
|
|||
return (0xffff ^ crc_register);
|
||||
}
|
||||
|
||||
static guint16
|
||||
gst_dp_crc_from_memory_maps (const GstMapInfo * maps, guint n_maps)
|
||||
{
|
||||
guint16 crc_register = CRC_INIT;
|
||||
gsize total_length = 0;
|
||||
|
||||
if (n_maps == 0)
|
||||
return 0;
|
||||
|
||||
g_assert (maps != NULL);
|
||||
|
||||
/* calc CRC */
|
||||
while (n_maps > 0) {
|
||||
guint8 *buffer = maps->data;
|
||||
gsize length = maps->size;
|
||||
|
||||
total_length += length;
|
||||
|
||||
while (length-- > 0) {
|
||||
crc_register = (guint16) ((crc_register << 8) ^
|
||||
gst_dp_crc_table[((crc_register >> 8) & 0x00ff) ^ *buffer++]);
|
||||
}
|
||||
--n_maps;
|
||||
++maps;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (total_length == 0))
|
||||
return 0;
|
||||
|
||||
return (0xffff ^ crc_register);
|
||||
}
|
||||
|
||||
GType
|
||||
gst_dp_version_get_type (void)
|
||||
{
|
||||
|
|
|
@ -140,10 +140,6 @@ GstDPPacketizer *
|
|||
gst_dp_packetizer_new (GstDPVersion version);
|
||||
void gst_dp_packetizer_free (GstDPPacketizer *packetizer);
|
||||
|
||||
/* crc checksum */
|
||||
guint16 gst_dp_crc (const guint8 * buffer,
|
||||
guint length);
|
||||
|
||||
/* payload information from header */
|
||||
guint32 gst_dp_header_payload_length (const guint8 * header);
|
||||
GstDPPayloadType
|
||||
|
|
Loading…
Reference in a new issue