mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
omxvideodec/enc: add hack updating nBufferCountActual before allocating
The OMX specs states that the nBufferCountActual of a port has to default to its nBufferCountMin. If we don't change nBufferCountActual we purely rely on this default. But in some cases, OMX may change nBufferCountMin before we allocate buffers. Like for example when configuring the input ports with the actual format, it may decrease the number of minimal buffers required. This method checks this and update nBufferCountActual if needed so we'll use less buffers than the worst case in such scenarios. SetParameter() needs to be called when the port is either disabled or the component in the Loaded state. Don't do this for the decoder output as gst_omx_video_dec_allocate_output_buffers() already check nBufferCountMin when computing the number of output buffers. On some platform, like rpi, the default nBufferCountActual is much higher than nBufferCountMin so only enable this using a specific gst-omx hack. https://bugzilla.gnome.org/show_bug.cgi?id=791211
This commit is contained in:
parent
338ff34e5e
commit
9a8e863862
4 changed files with 101 additions and 0 deletions
30
omx/gstomx.c
30
omx/gstomx.c
|
@ -2543,6 +2543,34 @@ done:
|
|||
return err;
|
||||
}
|
||||
|
||||
/* The OMX specs states that the nBufferCountActual of a port has to default
|
||||
* to its nBufferCountMin. If we don't change nBufferCountActual we purely rely
|
||||
* on this default. But in some cases, OMX may change nBufferCountMin before we
|
||||
* allocate buffers. Like for example when configuring the input ports with the
|
||||
* actual format, it may decrease the number of minimal buffers required.
|
||||
* This method checks this and update nBufferCountActual if needed so we'll use
|
||||
* less buffers than the worst case in such scenarios.
|
||||
*/
|
||||
gboolean
|
||||
gst_omx_port_ensure_buffer_count_actual (GstOMXPort * port)
|
||||
{
|
||||
OMX_PARAM_PORTDEFINITIONTYPE port_def;
|
||||
|
||||
gst_omx_port_get_port_definition (port, &port_def);
|
||||
if (port_def.nBufferCountActual != port_def.nBufferCountMin) {
|
||||
port_def.nBufferCountActual = port_def.nBufferCountMin;
|
||||
|
||||
GST_DEBUG_OBJECT (port->comp->parent,
|
||||
"set port %d nBufferCountActual to %d",
|
||||
(guint) port->index, (guint) port_def.nBufferCountActual);
|
||||
|
||||
if (gst_omx_port_update_port_definition (port, &port_def) != OMX_ErrorNone)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef GType (*GGetTypeFunction) (void);
|
||||
|
||||
static const GGetTypeFunction types[] = {
|
||||
|
@ -2858,6 +2886,8 @@ gst_omx_parse_hacks (gchar ** hacks)
|
|||
hacks_flags |= GST_OMX_HACK_PASS_PROFILE_TO_DECODER;
|
||||
else if (g_str_equal (*hacks, "pass-color-format-to-decoder"))
|
||||
hacks_flags |= GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER;
|
||||
else if (g_str_equal (*hacks, "ensure-buffer-count-actual"))
|
||||
hacks_flags |= GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL;
|
||||
else
|
||||
GST_WARNING ("Unknown hack: %s", *hacks);
|
||||
hacks++;
|
||||
|
|
|
@ -200,6 +200,13 @@ G_BEGIN_DECLS
|
|||
*/
|
||||
#define GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER G_GUINT64_CONSTANT (0x0000000000001000)
|
||||
|
||||
/* If set, automatically update nBufferCountActual to nBufferCountMin before
|
||||
* allocating buffers. This can be used on OMX implementation decreasing
|
||||
* nBufferCountMin depending of the format and so can reduce the number
|
||||
* of allocated buffers.
|
||||
*/
|
||||
#define GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL G_GUINT64_CONSTANT (0x0000000000002000)
|
||||
|
||||
typedef struct _GstOMXCore GstOMXCore;
|
||||
typedef struct _GstOMXPort GstOMXPort;
|
||||
typedef enum _GstOMXPortDirection GstOMXPortDirection;
|
||||
|
@ -448,6 +455,7 @@ OMX_ERRORTYPE gst_omx_port_mark_reconfigured (GstOMXPort * port);
|
|||
OMX_ERRORTYPE gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled);
|
||||
OMX_ERRORTYPE gst_omx_port_wait_enabled (GstOMXPort * port, GstClockTime timeout);
|
||||
gboolean gst_omx_port_is_enabled (GstOMXPort * port);
|
||||
gboolean gst_omx_port_ensure_buffer_count_actual (GstOMXPort * port);
|
||||
|
||||
/* OMX 1.2.0 dynamic allocation mode */
|
||||
gboolean gst_omx_is_dynamic_allocation_supported (void);
|
||||
|
|
|
@ -2340,6 +2340,19 @@ gst_omx_video_dec_pick_input_allocation_mode (GstOMXVideoDec * self,
|
|||
return GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_dec_ensure_nb_in_buffers (GstOMXVideoDec * self)
|
||||
{
|
||||
GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (self);
|
||||
|
||||
if ((klass->cdata.hacks & GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL)) {
|
||||
if (!gst_omx_port_ensure_buffer_count_actual (self->dec_in_port))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
|
||||
{
|
||||
|
@ -2351,6 +2364,8 @@ gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
|
|||
input);
|
||||
|
||||
if (self->disabled) {
|
||||
if (!gst_omx_video_dec_ensure_nb_in_buffers (self))
|
||||
return FALSE;
|
||||
if (gst_omx_port_set_enabled (self->dec_in_port, TRUE) != OMX_ErrorNone)
|
||||
return FALSE;
|
||||
if (!gst_omx_video_dec_allocate_in_buffers (self))
|
||||
|
@ -2376,6 +2391,9 @@ gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
|
|||
if (!gst_omx_video_dec_negotiate (self))
|
||||
GST_LOG_OBJECT (self, "Negotiation failed, will get output format later");
|
||||
|
||||
if (!gst_omx_video_dec_ensure_nb_in_buffers (self))
|
||||
return FALSE;
|
||||
|
||||
if (!(klass->cdata.hacks & GST_OMX_HACK_NO_DISABLE_OUTPORT)) {
|
||||
/* Disable output port */
|
||||
if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone)
|
||||
|
@ -2802,6 +2820,11 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder,
|
|||
goto reconfigure_error;
|
||||
}
|
||||
|
||||
if (!gst_omx_video_dec_ensure_nb_in_buffers (self)) {
|
||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||
goto reconfigure_error;
|
||||
}
|
||||
|
||||
err = gst_omx_port_set_enabled (port, TRUE);
|
||||
if (err != OMX_ErrorNone) {
|
||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||
|
|
|
@ -1368,6 +1368,19 @@ gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
|
|||
return flow_ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_enc_ensure_nb_out_buffers (GstOMXVideoEnc * self)
|
||||
{
|
||||
GstOMXVideoEncClass *klass = GST_OMX_VIDEO_ENC_GET_CLASS (self);
|
||||
|
||||
if ((klass->cdata.hacks & GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL)) {
|
||||
if (!gst_omx_port_ensure_buffer_count_actual (self->enc_out_port))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_omx_video_enc_loop (GstOMXVideoEnc * self)
|
||||
{
|
||||
|
@ -1444,6 +1457,9 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
|
|||
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
|
||||
|
||||
if (acq_return == GST_OMX_ACQUIRE_BUFFER_RECONFIGURE) {
|
||||
if (!gst_omx_video_enc_ensure_nb_out_buffers (self))
|
||||
goto reconfigure_error;
|
||||
|
||||
err = gst_omx_port_set_enabled (port, TRUE);
|
||||
if (err != OMX_ErrorNone)
|
||||
goto reconfigure_error;
|
||||
|
@ -1874,6 +1890,19 @@ gst_omx_video_enc_configure_input_buffer (GstOMXVideoEnc * self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_enc_ensure_nb_in_buffers (GstOMXVideoEnc * self)
|
||||
{
|
||||
GstOMXVideoEncClass *klass = GST_OMX_VIDEO_ENC_GET_CLASS (self);
|
||||
|
||||
if ((klass->cdata.hacks & GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL)) {
|
||||
if (!gst_omx_port_ensure_buffer_count_actual (self->enc_in_port))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_enc_allocate_in_buffers (GstOMXVideoEnc * self)
|
||||
{
|
||||
|
@ -2008,6 +2037,12 @@ gst_omx_video_enc_enable (GstOMXVideoEnc * self, GstBuffer * input)
|
|||
#endif
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Enabling component");
|
||||
|
||||
if (!gst_omx_video_enc_ensure_nb_in_buffers (self))
|
||||
return FALSE;
|
||||
if (!gst_omx_video_enc_ensure_nb_out_buffers (self))
|
||||
return FALSE;
|
||||
|
||||
if (self->disabled) {
|
||||
if (gst_omx_port_set_enabled (self->enc_in_port, TRUE) != OMX_ErrorNone)
|
||||
return FALSE;
|
||||
|
@ -2650,6 +2685,11 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
|
|||
goto reconfigure_error;
|
||||
}
|
||||
|
||||
if (!gst_omx_video_enc_ensure_nb_in_buffers (self)) {
|
||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||
goto reconfigure_error;
|
||||
}
|
||||
|
||||
err = gst_omx_port_set_enabled (port, TRUE);
|
||||
if (err != OMX_ErrorNone) {
|
||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||
|
|
Loading…
Reference in a new issue