mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-18 05:16:05 +00:00
v4l2codecs: h264: Improve ABI check
This moves the ABI check to the registration, so we don't expose decoders with the wrong ABI or that are just broken somehow. It also makes few enhancement: - Handle missing, but required controls - Prints the controls macro name instead of id This should fix RK3399 support with a currently release minor regression in the Hantro driver that cause errors. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1599>
This commit is contained in:
parent
4254920b72
commit
47bfa71530
1 changed files with 38 additions and 29 deletions
|
@ -118,37 +118,42 @@ needs_start_codes (GstV4l2CodecH264Dec * self)
|
||||||
return self->start_code == V4L2_STATELESS_H264_START_CODE_ANNEX_B;
|
return self->start_code == V4L2_STATELESS_H264_START_CODE_ANNEX_B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_decoder_h264_api_check (GstV4l2CodecH264Dec * self)
|
gst_v4l2_decoder_h264_api_check (GstV4l2Decoder * decoder)
|
||||||
{
|
{
|
||||||
guint i, ret_size;
|
guint i, ret_size;
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
|
#define SET_ID(cid) .id = (cid), .name = #cid
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
const gchar *name;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
gboolean optional;
|
||||||
} controls[] = {
|
} controls[] = {
|
||||||
{
|
{
|
||||||
.id = V4L2_CID_STATELESS_H264_SPS,
|
SET_ID (V4L2_CID_STATELESS_H264_SPS),
|
||||||
.size = sizeof(struct v4l2_ctrl_h264_sps),
|
.size = sizeof(struct v4l2_ctrl_h264_sps),
|
||||||
}, {
|
}, {
|
||||||
.id = V4L2_CID_STATELESS_H264_PPS,
|
SET_ID (V4L2_CID_STATELESS_H264_PPS),
|
||||||
.size = sizeof(struct v4l2_ctrl_h264_pps),
|
.size = sizeof(struct v4l2_ctrl_h264_pps),
|
||||||
}, {
|
}, {
|
||||||
.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
|
SET_ID (V4L2_CID_STATELESS_H264_SCALING_MATRIX),
|
||||||
.size = sizeof(struct v4l2_ctrl_h264_scaling_matrix),
|
.size = sizeof(struct v4l2_ctrl_h264_scaling_matrix),
|
||||||
}, {
|
}, {
|
||||||
.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
|
SET_ID (V4L2_CID_STATELESS_H264_DECODE_PARAMS),
|
||||||
.size = sizeof(struct v4l2_ctrl_h264_decode_params),
|
.size = sizeof(struct v4l2_ctrl_h264_decode_params),
|
||||||
}, {
|
}, {
|
||||||
.id = V4L2_CID_STATELESS_H264_SLICE_PARAMS,
|
SET_ID (V4L2_CID_STATELESS_H264_SLICE_PARAMS),
|
||||||
.size = sizeof(struct v4l2_ctrl_h264_slice_params),
|
.size = sizeof(struct v4l2_ctrl_h264_slice_params),
|
||||||
|
.optional = TRUE,
|
||||||
}, {
|
}, {
|
||||||
.id = V4L2_CID_STATELESS_H264_PRED_WEIGHTS,
|
SET_ID (V4L2_CID_STATELESS_H264_PRED_WEIGHTS),
|
||||||
.size = sizeof(struct v4l2_ctrl_h264_pred_weights),
|
.size = sizeof(struct v4l2_ctrl_h264_pred_weights),
|
||||||
|
.optional = TRUE,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#undef SET_ID
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -156,12 +161,19 @@ gst_v4l2_decoder_h264_api_check (GstV4l2CodecH264Dec * self)
|
||||||
* the right size.
|
* the right size.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < G_N_ELEMENTS (controls); i++) {
|
for (i = 0; i < G_N_ELEMENTS (controls); i++) {
|
||||||
if (gst_v4l2_decoder_query_control_size (self->decoder, controls[i].id,
|
gboolean control_found;
|
||||||
&ret_size) && ret_size != controls[i].size) {
|
|
||||||
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE,
|
control_found = gst_v4l2_decoder_query_control_size (decoder,
|
||||||
("H264 API mismatch!"),
|
controls[i].id, &ret_size);
|
||||||
("%d control size mismatch: got %d bytes but %d expected.",
|
|
||||||
controls[i].id, ret_size, controls[i].size));
|
if (!controls[i].optional && !control_found) {
|
||||||
|
GST_WARNING ("Driver is missing %s support.", controls[i].name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control_found && ret_size != controls[i].size) {
|
||||||
|
GST_WARNING ("%s control size mismatch: got %d bytes but %d expected.",
|
||||||
|
controls[i].name, ret_size, controls[i].size);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +185,6 @@ static gboolean
|
||||||
gst_v4l2_codec_h264_dec_open (GstVideoDecoder * decoder)
|
gst_v4l2_codec_h264_dec_open (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder);
|
GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder);
|
||||||
guint version;
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
struct v4l2_ext_control control[] = {
|
struct v4l2_ext_control control[] = {
|
||||||
|
@ -193,20 +204,6 @@ gst_v4l2_codec_h264_dec_open (GstVideoDecoder * decoder)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
version = gst_v4l2_decoder_get_version (self->decoder);
|
|
||||||
if (version < V4L2_MIN_KERNEL_VERSION)
|
|
||||||
GST_WARNING_OBJECT (self,
|
|
||||||
"V4L2 API v%u.%u too old, at least v%u.%u required",
|
|
||||||
(version >> 16) & 0xff, (version >> 8) & 0xff,
|
|
||||||
V4L2_MIN_KERNEL_VER_MAJOR, V4L2_MIN_KERNEL_VER_MINOR);
|
|
||||||
|
|
||||||
if (!gst_v4l2_decoder_h264_api_check (self)) {
|
|
||||||
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE,
|
|
||||||
("Failed to open H264 decoder"),
|
|
||||||
("gst_v4l2_decoder_h264_api_check() failed"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_v4l2_decoder_get_controls (self->decoder, control,
|
if (!gst_v4l2_decoder_get_controls (self->decoder, control,
|
||||||
G_N_ELEMENTS (control))) {
|
G_N_ELEMENTS (control))) {
|
||||||
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE,
|
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE,
|
||||||
|
@ -1520,6 +1517,7 @@ gst_v4l2_codec_h264_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder,
|
||||||
GstV4l2CodecDevice * device, guint rank)
|
GstV4l2CodecDevice * device, guint rank)
|
||||||
{
|
{
|
||||||
GstCaps *src_caps;
|
GstCaps *src_caps;
|
||||||
|
guint version;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (v4l2_h264dec_debug, "v4l2codecs-h264dec", 0,
|
GST_DEBUG_CATEGORY_INIT (v4l2_h264dec_debug, "v4l2codecs-h264dec", 0,
|
||||||
"V4L2 stateless h264 decoder");
|
"V4L2 stateless h264 decoder");
|
||||||
|
@ -1535,6 +1533,17 @@ gst_v4l2_codec_h264_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version = gst_v4l2_decoder_get_version (decoder);
|
||||||
|
if (version < V4L2_MIN_KERNEL_VERSION)
|
||||||
|
GST_WARNING ("V4L2 API v%u.%u too old, at least v%u.%u required",
|
||||||
|
(version >> 16) & 0xff, (version >> 8) & 0xff,
|
||||||
|
V4L2_MIN_KERNEL_VER_MAJOR, V4L2_MIN_KERNEL_VER_MINOR);
|
||||||
|
|
||||||
|
if (!gst_v4l2_decoder_h264_api_check (decoder)) {
|
||||||
|
GST_WARNING ("Not registering H264 decoder as it failed ABI check.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
gst_v4l2_decoder_register (plugin,
|
gst_v4l2_decoder_register (plugin,
|
||||||
GST_TYPE_V4L2_CODEC_H264_DEC,
|
GST_TYPE_V4L2_CODEC_H264_DEC,
|
||||||
(GClassInitFunc) gst_v4l2_codec_h264_dec_subclass_init,
|
(GClassInitFunc) gst_v4l2_codec_h264_dec_subclass_init,
|
||||||
|
|
Loading…
Reference in a new issue