mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-05-04 07:24:46 +00:00
omxvideodec: add hack to pass color format from caps to OMX decoder
This hack tries to pass as much information as possible from caps to the decoder before it receives any buffer. These information can be used by the OMX decoder to, for example, pre-allocate its internal buffers before starting to decode and so reduce its initial latency. This mechanism is currently supported by the zynqultrascaleplus decoder. https://bugzilla.gnome.org/show_bug.cgi?id=792040
This commit is contained in:
parent
0f702d0503
commit
2ca3cf5cfa
4 changed files with 93 additions and 2 deletions
|
@ -14,7 +14,7 @@ component-name=OMX.allegro.h264.decoder
|
|||
in-port-index=0
|
||||
out-port-index=1
|
||||
rank=257
|
||||
hacks=no-disable-outport;pass-profile-to-decoder
|
||||
hacks=no-disable-outport;pass-profile-to-decoder;pass-color-format-to-decoder
|
||||
|
||||
[omxh265enc]
|
||||
type-name=GstOMXH265Enc
|
||||
|
@ -32,4 +32,4 @@ component-name=OMX.allegro.h265.decoder
|
|||
in-port-index=0
|
||||
out-port-index=1
|
||||
rank=257
|
||||
hacks=no-disable-outport;pass-profile-to-decoder
|
||||
hacks=no-disable-outport;pass-profile-to-decoder;pass-color-format-to-decoder
|
||||
|
|
|
@ -2845,6 +2845,8 @@ gst_omx_parse_hacks (gchar ** hacks)
|
|||
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 if (g_str_equal (*hacks, "pass-color-format-to-decoder"))
|
||||
hacks_flags |= GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER;
|
||||
else
|
||||
GST_WARNING ("Unknown hack: %s", *hacks);
|
||||
hacks++;
|
||||
|
|
|
@ -166,6 +166,15 @@ G_BEGIN_DECLS
|
|||
*/
|
||||
#define GST_OMX_HACK_PASS_PROFILE_TO_DECODER G_GUINT64_CONSTANT (0x0000000000000800)
|
||||
|
||||
/* If we should pass the color format information from upstream to the
|
||||
* OMX decoder input. This is a violation of the OMX spec as
|
||||
* the eColorFormat field is supposed to only be used if eCompressionFormat is
|
||||
* set to OMX_IMAGE_CodingUnused.
|
||||
* Do this as a platform specific hack for OMX implementation which may use
|
||||
* this information to pre-allocate internal buffers for example.
|
||||
*/
|
||||
#define GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER G_GUINT64_CONSTANT (0x0000000000001000)
|
||||
|
||||
typedef struct _GstOMXCore GstOMXCore;
|
||||
typedef struct _GstOMXPort GstOMXPort;
|
||||
typedef enum _GstOMXPortDirection GstOMXPortDirection;
|
||||
|
|
|
@ -2308,6 +2308,54 @@ gst_omx_video_dec_enable (GstOMXVideoDec * self, GstBuffer * input)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static OMX_COLOR_FORMATTYPE
|
||||
get_color_format_from_chroma (const gchar * chroma_format,
|
||||
guint bit_depth_luma, guint bit_depth_chroma)
|
||||
{
|
||||
if (chroma_format == NULL)
|
||||
goto out;
|
||||
|
||||
if (!g_strcmp0 (chroma_format, "4:0:0") && bit_depth_chroma == 0) {
|
||||
switch (bit_depth_luma) {
|
||||
case 1:
|
||||
return OMX_COLOR_FormatMonochrome;
|
||||
case 2:
|
||||
return OMX_COLOR_FormatL2;
|
||||
case 4:
|
||||
return OMX_COLOR_FormatL4;
|
||||
case 8:
|
||||
return OMX_COLOR_FormatL8;
|
||||
case 16:
|
||||
return OMX_COLOR_FormatL16;
|
||||
case 24:
|
||||
return OMX_COLOR_FormatL24;
|
||||
case 32:
|
||||
return OMX_COLOR_FormatL32;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bit_depth_luma == 8 && bit_depth_chroma == 8) {
|
||||
if (!g_strcmp0 (chroma_format, "4:2:0"))
|
||||
return OMX_COLOR_FormatYUV420SemiPlanar;
|
||||
else if (!g_strcmp0 (chroma_format, "4:2:2"))
|
||||
return OMX_COLOR_FormatYUV422SemiPlanar;
|
||||
}
|
||||
#ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
|
||||
if (bit_depth_luma == 10 && bit_depth_chroma == 10) {
|
||||
if (!g_strcmp0 (chroma_format, "4:2:0"))
|
||||
return (OMX_COLOR_FORMATTYPE)
|
||||
OMX_ALG_COLOR_FormatYUV420SemiPlanar10bitPacked;
|
||||
else if (!g_strcmp0 (chroma_format, "4:2:2"))
|
||||
return (OMX_COLOR_FORMATTYPE)
|
||||
OMX_ALG_COLOR_FormatYUV422SemiPlanar10bitPacked;
|
||||
}
|
||||
#endif
|
||||
|
||||
out:
|
||||
return OMX_COLOR_FormatUnused;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
|
||||
GstVideoCodecState * state)
|
||||
|
@ -2379,6 +2427,38 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder,
|
|||
port_def.format.video.nFrameHeight = info->height;
|
||||
port_def.format.video.xFramerate = framerate_q16;
|
||||
|
||||
if (klass->cdata.hacks & GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER) {
|
||||
/* Let the decoder know the colar format of the encoded input stream.
|
||||
* It may use it to pre-allocate its internal buffers and so save time when
|
||||
* it will actually start to decode. */
|
||||
GstStructure *s;
|
||||
const gchar *chroma_format;
|
||||
guint bit_depth_luma, bit_depth_chroma;
|
||||
|
||||
s = gst_caps_get_structure (state->caps, 0);
|
||||
chroma_format = gst_structure_get_string (s, "chroma-format");
|
||||
if (s && gst_structure_get_uint (s, "bit-depth-luma", &bit_depth_luma) &&
|
||||
gst_structure_get_uint (s, "bit-depth-chroma", &bit_depth_chroma)) {
|
||||
OMX_COLOR_FORMATTYPE color_format;
|
||||
|
||||
color_format =
|
||||
get_color_format_from_chroma (chroma_format,
|
||||
bit_depth_luma, bit_depth_chroma);
|
||||
if (color_format != OMX_COLOR_FormatUnused) {
|
||||
GST_DEBUG_OBJECT (self, "Setting input eColorFormat to %d",
|
||||
color_format);
|
||||
port_def.format.video.eColorFormat = color_format;
|
||||
} else {
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Unsupported input color format: %s (luma %d bits, chroma %d bits)",
|
||||
chroma_format, bit_depth_luma, bit_depth_chroma);
|
||||
}
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"Input color format info not present in caps, can't pass them to decoder");
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Setting inport port definition");
|
||||
|
||||
if (gst_omx_port_update_port_definition (self->dec_in_port,
|
||||
|
|
Loading…
Reference in a new issue