summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2019-06-20 08:59:22 +0300
committerTim-Philipp Müller <tim@centricular.com>2019-08-09 16:57:28 +0100
commitcbdbb9da2958845f1582454bbb32ef63b691113f (patch)
treee195b5bc36522637acff9512dd80990c6b70fc60 /sys
parent16203addbb585c1c4600cd578bbc35768f39b4d8 (diff)
downloadgstreamer-plugins-bad-cbdbb9da2958845f1582454bbb32ef63b691113f.tar.gz
decklink: Correctly ensure >=16 byte alignment for the buffers we allocate
We'll ensure at least 64 byte alignment for AVX2 but 16 byte alignment is what is required by the decklink SDK. Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/986
Diffstat (limited to 'sys')
-rw-r--r--sys/decklink/gstdecklink.cpp37
1 files changed, 30 insertions, 7 deletions
diff --git a/sys/decklink/gstdecklink.cpp b/sys/decklink/gstdecklink.cpp
index a366f3ca5..920d04f68 100644
--- a/sys/decklink/gstdecklink.cpp
+++ b/sys/decklink/gstdecklink.cpp
@@ -1022,8 +1022,11 @@ private:
if (!m_buffers)
return;
- while ((buf = (uint8_t *) gst_queue_array_pop_head (m_buffers)))
- g_free (buf - 128);
+ while ((buf = (uint8_t *) gst_queue_array_pop_head (m_buffers))) {
+ uint8_t offset = *(buf - 1);
+ void *alloc_buf = buf - 128 + offset;
+ g_free (alloc_buf);
+ }
}
public:
@@ -1083,6 +1086,7 @@ public:
AllocateBuffer (uint32_t bufferSize, void **allocatedBuffer)
{
uint8_t *buf;
+ uint8_t offset = 0;
g_mutex_lock (&m_mutex);
@@ -1096,8 +1100,23 @@ public:
if (!(buf = (uint8_t *) gst_queue_array_pop_head (m_buffers))) {
/* If not, alloc a new one */
buf = (uint8_t *) g_malloc (bufferSize + 128);
+
+ /* The Decklink SDK requires 16 byte aligned memory at least but for us
+ * to work nicely let's align to 64 bytes (512 bits) as this allows
+ * aligned AVX2 operations for example */
+ if (((guintptr) buf) % 64 != 0) {
+ offset = ((guintptr) buf) % 64;
+ }
+
+ /* Write the allocation size at the very beginning. It's guaranteed by
+ * malloc() to be allocated aligned enough for doing this. */
*((uint32_t *) buf) = bufferSize;
- buf += 128;
+
+ /* Align our buffer */
+ buf += 128 - offset;
+
+ /* And write the alignment offset right before the buffer */
+ *(buf - 1) = offset;
}
*allocatedBuffer = (void *) buf;
@@ -1105,8 +1124,10 @@ public:
* remove one of them every fifth call */
if (gst_queue_array_get_length (m_buffers) > 0) {
if (++m_nonEmptyCalls >= 5) {
- buf = (uint8_t *) gst_queue_array_pop_head (m_buffers) - 128;
- g_free (buf);
+ buf = (uint8_t *) gst_queue_array_pop_head (m_buffers);
+ uint8_t offset = *(buf - 1);
+ void *alloc_buf = buf - 128 + offset;
+ g_free (alloc_buf);
m_nonEmptyCalls = 0;
}
} else {
@@ -1123,11 +1144,13 @@ public:
g_mutex_lock (&m_mutex);
/* Put the buffer back to the pool if size matches with current pool */
- uint32_t size = *(uint32_t *) ((uint8_t *) buffer - 128);
+ uint8_t offset = *(((uint8_t *) buffer) - 1);
+ uint8_t *alloc_buffer = ((uint8_t *) buffer) - 128 + offset;
+ uint32_t size = *(uint32_t *) alloc_buffer;
if (size == m_lastBufferSize) {
gst_queue_array_push_tail (m_buffers, buffer);
} else {
- g_free (((uint8_t *) buffer) - 128);
+ g_free (alloc_buffer);
}
g_mutex_unlock (&m_mutex);