return self->start_code == V4L2_STATELESS_H264_START_CODE_ANNEX_B;
}
-
static gboolean
-gst_v4l2_decoder_h264_api_check (GstV4l2CodecH264Dec * self)
+gst_v4l2_decoder_h264_api_check (GstV4l2Decoder * decoder)
{
guint i, ret_size;
/* *INDENT-OFF* */
+ #define SET_ID(cid) .id = (cid), .name = #cid
struct
{
+ const gchar *name;
unsigned int id;
unsigned int size;
+ gboolean optional;
} controls[] = {
{
- .id = V4L2_CID_STATELESS_H264_SPS,
+ SET_ID (V4L2_CID_STATELESS_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),
}, {
- .id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
+ SET_ID (V4L2_CID_STATELESS_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),
}, {
- .id = V4L2_CID_STATELESS_H264_SLICE_PARAMS,
+ SET_ID (V4L2_CID_STATELESS_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),
+ .optional = TRUE,
}
};
+ #undef SET_ID
/* *INDENT-ON* */
/*
* the right size.
*/
for (i = 0; i < G_N_ELEMENTS (controls); i++) {
- if (gst_v4l2_decoder_query_control_size (self->decoder, controls[i].id,
- &ret_size) && ret_size != controls[i].size) {
- GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE,
- ("H264 API mismatch!"),
- ("%d control size mismatch: got %d bytes but %d expected.",
- controls[i].id, ret_size, controls[i].size));
+ gboolean control_found;
+
+ control_found = gst_v4l2_decoder_query_control_size (decoder,
+ controls[i].id, &ret_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;
}
}
gst_v4l2_codec_h264_dec_open (GstVideoDecoder * decoder)
{
GstV4l2CodecH264Dec *self = GST_V4L2_CODEC_H264_DEC (decoder);
- guint version;
/* *INDENT-OFF* */
struct v4l2_ext_control control[] = {
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,
G_N_ELEMENTS (control))) {
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ_WRITE,
GstV4l2CodecDevice * device, guint rank)
{
GstCaps *src_caps;
+ guint version;
GST_DEBUG_CATEGORY_INIT (v4l2_h264dec_debug, "v4l2codecs-h264dec", 0,
"V4L2 stateless h264 decoder");
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_TYPE_V4L2_CODEC_H264_DEC,
(GClassInitFunc) gst_v4l2_codec_h264_dec_subclass_init,