mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
h264dec: add hack to pass profile and level to OMX
This information can be useful to zynqultrascaleplus decoders. They may use this information to reduce startup latency by configuring itself before receiving the first frames. We also have a custom OMX extension allowing the decoder to report the latency. The profile/level information helps it reporting a more accurate latency earlier. https://bugzilla.gnome.org/show_bug.cgi?id=783114
This commit is contained in:
parent
1e570fed17
commit
0aa4c9db4e
4 changed files with 80 additions and 4 deletions
|
@ -14,4 +14,4 @@ component-name=OMX.allegro.h264.decoder
|
|||
in-port-index=0
|
||||
out-port-index=1
|
||||
rank=257
|
||||
hacks=no-disable-outport
|
||||
hacks=no-disable-outport;pass-profile-to-decoder
|
||||
|
|
|
@ -2508,6 +2508,8 @@ gst_omx_parse_hacks (gchar ** hacks)
|
|||
hacks_flags |= GST_OMX_HACK_SIGNALS_PREMATURE_EOS;
|
||||
else if (g_str_equal (*hacks, "height-multiple-16"))
|
||||
hacks_flags |= GST_OMX_HACK_HEIGHT_MULTIPLE_16;
|
||||
else if (g_str_equal (*hacks, "pass-profile-to-decoder"))
|
||||
hacks_flags |= GST_OMX_HACK_PASS_PROFILE_TO_DECODER;
|
||||
else
|
||||
GST_WARNING ("Unknown hack: %s", *hacks);
|
||||
hacks++;
|
||||
|
|
|
@ -150,6 +150,13 @@ G_BEGIN_DECLS
|
|||
*/
|
||||
#define GST_OMX_HACK_HEIGHT_MULTIPLE_16 G_GUINT64_CONSTANT (0x0000000000000200)
|
||||
|
||||
/* If we should pass the profile/level information from upstream to the
|
||||
* OMX decoder. This is a violation of the OMX spec as
|
||||
* OMX_IndexParamVideoProfileLevelCurrent is supposed to be r-o so
|
||||
* do it as a platform specific hack.
|
||||
*/
|
||||
#define GST_OMX_HACK_PASS_PROFILE_TO_DECODER G_GUINT64_CONSTANT (0x0000000000000800)
|
||||
|
||||
typedef struct _GstOMXCore GstOMXCore;
|
||||
typedef struct _GstOMXPort GstOMXPort;
|
||||
typedef enum _GstOMXPortDirection GstOMXPortDirection;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
#include "gstomxh264dec.h"
|
||||
#include "gstomxh264utils.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_omx_h264_dec_debug_category);
|
||||
#define GST_CAT_DEFAULT gst_omx_h264_dec_debug_category
|
||||
|
@ -110,16 +111,82 @@ gst_omx_h264_dec_is_format_change (GstOMXVideoDec * dec,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_profile_and_level (GstOMXH264Dec * self, GstVideoCodecState * state)
|
||||
{
|
||||
OMX_ERRORTYPE err;
|
||||
OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
|
||||
const gchar *profile_string, *level_string;
|
||||
GstStructure *s;
|
||||
|
||||
GST_OMX_INIT_STRUCT (¶m);
|
||||
param.nPortIndex = GST_OMX_VIDEO_DEC (self)->dec_in_port->index;
|
||||
|
||||
/* Pass profile and level to the decoder if we have both info from the
|
||||
* caps. */
|
||||
s = gst_caps_get_structure (state->caps, 0);
|
||||
profile_string = gst_structure_get_string (s, "profile");
|
||||
if (!profile_string)
|
||||
return TRUE;
|
||||
|
||||
param.eProfile = gst_omx_h264_utils_get_profile_from_str (profile_string);
|
||||
if (param.eProfile == OMX_VIDEO_AVCProfileMax)
|
||||
goto unsupported_profile;
|
||||
|
||||
level_string = gst_structure_get_string (s, "level");
|
||||
if (!level_string)
|
||||
return TRUE;
|
||||
|
||||
param.eLevel = gst_omx_h264_utils_get_level_from_str (level_string);
|
||||
if (param.eLevel == OMX_VIDEO_AVCLevelMax)
|
||||
goto unsupported_level;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Set profile (%s) and level (%s) on decoder",
|
||||
profile_string, level_string);
|
||||
|
||||
err =
|
||||
gst_omx_component_set_parameter (GST_OMX_VIDEO_DEC (self)->dec,
|
||||
OMX_IndexParamVideoProfileLevelCurrent, ¶m);
|
||||
if (err == OMX_ErrorUnsupportedIndex) {
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Setting profile/level not supported by component");
|
||||
} else if (err != OMX_ErrorNone) {
|
||||
GST_ERROR_OBJECT (self,
|
||||
"Error setting profile %u and level %u: %s (0x%08x)",
|
||||
(guint) param.eProfile, (guint) param.eLevel,
|
||||
gst_omx_error_to_string (err), err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
unsupported_profile:
|
||||
GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string);
|
||||
return FALSE;
|
||||
|
||||
unsupported_level:
|
||||
GST_ERROR_OBJECT (self, "Unsupported level %s", level_string);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_h264_dec_set_format (GstOMXVideoDec * dec, GstOMXPort * port,
|
||||
GstVideoCodecState * state)
|
||||
{
|
||||
gboolean ret;
|
||||
GstOMXVideoDecClass *klass = GST_OMX_VIDEO_DEC_GET_CLASS (dec);
|
||||
OMX_PARAM_PORTDEFINITIONTYPE port_def;
|
||||
OMX_ERRORTYPE err;
|
||||
|
||||
gst_omx_port_get_port_definition (port, &port_def);
|
||||
port_def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
|
||||
ret = gst_omx_port_update_port_definition (port, &port_def) == OMX_ErrorNone;
|
||||
err = gst_omx_port_update_port_definition (port, &port_def);
|
||||
if (err != OMX_ErrorNone)
|
||||
return FALSE;
|
||||
|
||||
return ret;
|
||||
if (klass->cdata.hacks & GST_OMX_HACK_PASS_PROFILE_TO_DECODER) {
|
||||
if (!set_profile_and_level (GST_OMX_H264_DEC (dec), state))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue