[vlc-devel] [PATCH 14/14] mmal: Use zerocopy ports for opaque mode

Julian Scheel julian at jusst.de
Wed Jun 3 09:50:39 CEST 2015


When running in opaque mode the mmal codec, deinterlace and vout must be used
together, so it is known that all pictures in use are allocated by the mmal
vout and contain an associated mmal_buffer_header. This allows us to enable
the zerocopy feature of mmal, which allocates shared memory between GPU and
CPU for holding the buffer payloads. Albeit the payloads are just small opaque
handles that reference the GPU side pictures it saves a little bit of
performance, because less VCHIQ transfers are required.

Signed-off-by: Julian Scheel <julian at jusst.de>
---
 modules/hw/mmal/codec.c       | 13 +++++++++++++
 modules/hw/mmal/deinterlace.c | 31 ++++++++++++++++++++++++++++++-
 modules/hw/mmal/vout.c        | 12 ++++++++++++
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/modules/hw/mmal/codec.c b/modules/hw/mmal/codec.c
index e89b81d..e11b7b2 100644
--- a/modules/hw/mmal/codec.c
+++ b/modules/hw/mmal/codec.c
@@ -190,6 +190,19 @@ static int OpenDecoder(decoder_t *dec)
             ret = VLC_EGENERIC;
             goto out;
         }
+
+        msg_Dbg(dec, "Activate zero-copy for output port");
+        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
+            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
+            1
+        };
+
+        status = mmal_port_parameter_set(sys->output, &zero_copy.hdr);
+        if (status != MMAL_SUCCESS) {
+           msg_Err(dec, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
+                    sys->output->name, status, mmal_status_to_string(status));
+           goto out;
+        }
     }
 
     status = mmal_port_enable(sys->output, output_port_cb);
diff --git a/modules/hw/mmal/deinterlace.c b/modules/hw/mmal/deinterlace.c
index 9f06ead..e6f6264 100644
--- a/modules/hw/mmal/deinterlace.c
+++ b/modules/hw/mmal/deinterlace.c
@@ -160,8 +160,22 @@ static int Open(filter_t *filter)
         goto out;
     }
     sys->input->buffer_size = sys->input->buffer_size_recommended;
-
     sys->input->buffer_num = sys->input->buffer_num_recommended;
+
+    if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) {
+        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
+            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
+            1
+        };
+
+        status = mmal_port_parameter_set(sys->input, &zero_copy.hdr);
+        if (status != MMAL_SUCCESS) {
+           msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
+                    sys->input->name, status, mmal_status_to_string(status));
+           goto out;
+        }
+    }
+
     status = mmal_port_enable(sys->input, input_port_cb);
     if (status != MMAL_SUCCESS) {
         msg_Err(filter, "Failed to enable input port %s (status=%"PRIx32" %s)",
@@ -183,6 +197,21 @@ static int Open(filter_t *filter)
     }
 
     sys->output->buffer_num = 3;
+
+    if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) {
+        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
+            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
+            1
+        };
+
+        status = mmal_port_parameter_set(sys->output, &zero_copy.hdr);
+        if (status != MMAL_SUCCESS) {
+           msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
+                    sys->output->name, status, mmal_status_to_string(status));
+           goto out;
+        }
+    }
+
     status = mmal_port_enable(sys->output, output_port_cb);
     if (status != MMAL_SUCCESS) {
         msg_Err(filter, "Failed to enable output port %s (status=%"PRIx32" %s)",
diff --git a/modules/hw/mmal/vout.c b/modules/hw/mmal/vout.c
index 24f40a4..0d13572 100644
--- a/modules/hw/mmal/vout.c
+++ b/modules/hw/mmal/vout.c
@@ -462,6 +462,18 @@ static picture_pool_t *vd_pool(vout_display_t *vd, unsigned count)
     if (sys->opaque) {
         if (count <= NUM_ACTUAL_OPAQUE_BUFFERS)
             count = NUM_ACTUAL_OPAQUE_BUFFERS;
+
+        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
+            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
+            1
+        };
+
+        status = mmal_port_parameter_set(sys->input, &zero_copy.hdr);
+        if (status != MMAL_SUCCESS) {
+           msg_Err(vd, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
+                    sys->input->name, status, mmal_status_to_string(status));
+           goto out;
+        }
     }
 
     if (count < sys->input->buffer_num_recommended)
-- 
2.4.0





More information about the vlc-devel mailing list