/* Check if the element can use this caps */ static gint find_decoder_func( gconstpointer p_p1, gconstpointer p_p2 ) { GstElementFactory *p_factory; sink_src_caps_t *p_caps; p_factory = ( GstElementFactory* )p_p1; p_caps = ( sink_src_caps_t* )p_p2; return !( gst_element_factory_can_sink_any_caps( p_factory, p_caps->p_sinkcaps ) && gst_element_factory_can_src_any_caps( p_factory, p_caps->p_srccaps )); }
GstCaps* find_input_caps_dutils (GstCaps* available_caps, GstCaps* wanted_caps, bool& /*requires_bayer*/, bool& requires_vidoeconvert, bool& /*requires_jpegdec*/, bool& requires_dutils, bool& requires_biteater) { requires_vidoeconvert = true; GstElementFactory* dutils = gst_element_factory_find("tcamdutils"); if (dutils) { // check if only dutils suffice if (gst_element_factory_can_src_any_caps(dutils, wanted_caps) && gst_element_factory_can_sink_any_caps(dutils, available_caps)) { requires_dutils = true; gst_object_unref(dutils); GstElementFactory* biteater = gst_element_factory_find("tcambiteater"); // check if dutils + biteater suffice if (!tcam_gst_contains_bayer_8_bit(available_caps) && ((tcam_gst_contains_bayer_12_bit(available_caps) || tcam_gst_contains_bayer_16_bit(available_caps))) && gst_element_factory_can_src_any_caps(biteater, wanted_caps)) { requires_biteater = true; gst_object_unref(biteater); return available_caps; } else // dutils only { gst_object_unref(biteater); GstCaps* ret; if (!gst_caps_is_fixed(available_caps)) { if (!gst_caps_is_empty(wanted_caps) && g_strcmp0(gst_caps_to_string(wanted_caps), "NULL") != 0) { GstCaps* possible_matches = create_caps_for_formats(available_caps, wanted_caps); if (!possible_matches || gst_caps_is_empty(possible_matches)) { tcam_error("No possible matches for dutils."); return nullptr; } ret = gst_caps_intersect(available_caps, possible_matches); gst_caps_unref(possible_matches); } else { ret = tcam_gst_find_largest_caps(available_caps); } } else // is fixed { ret = gst_caps_copy(available_caps); } if (!ret) { // TODO not compatible tcam_error("No intersecting caps between dutils and src"); return nullptr; } return ret; } gst_object_unref(biteater); } gst_object_unref(dutils); } tcam_error("Could not create dutils."); return nullptr; }
// TODO: bayer and videoconvert should consider eachother GstCaps* find_input_caps (GstCaps* available_caps, GstCaps* wanted_caps, bool& requires_bayer, bool& requires_vidoeconvert, bool& requires_jpegdec, bool& requires_dutils, bool& requires_biteater, bool use_dutils ) { requires_bayer = false; requires_vidoeconvert = false; requires_jpegdec = false; requires_dutils = false; requires_biteater = false; requires_bayer = false; if (!GST_IS_CAPS(available_caps)) { return nullptr; } if (wanted_caps == nullptr || gst_caps_is_empty(wanted_caps)) { GST_INFO("No sink caps specified. Continuing with caps from source device."); wanted_caps = gst_caps_copy(available_caps); } // GstCaps* intersect = gst_caps_intersect(available_caps, wanted_caps); // if (!gst_caps_is_empty(intersect)) // { // return intersect; // } // gst_caps_unref(intersect); GstElementFactory* dutils = gst_element_factory_find("tcamdutils"); if (use_dutils && dutils) { gst_object_unref(dutils); return find_input_caps_dutils(available_caps, wanted_caps, requires_bayer, requires_vidoeconvert, requires_jpegdec, requires_dutils, requires_biteater); } GstElementFactory* debayer = gst_element_factory_find("bayer2rgb"); if (debayer) { if (gst_element_factory_can_src_any_caps(debayer, wanted_caps) && gst_element_factory_can_sink_any_caps(debayer, available_caps)) { requires_bayer = true; // wanted_caps can be fixed, etc. // thus change name to be compatible to bayer2rgb sink pad // and create a correct intersection GstCaps* temp = gst_caps_copy(wanted_caps); gst_caps_change_name(temp, "video/x-bayer"); GstCaps* ret = gst_caps_intersect(available_caps, temp); gst_caps_unref(temp); gst_object_unref(debayer); return ret; } } gst_object_unref(debayer); GstElementFactory* convert = gst_element_factory_find("videoconvert"); if (convert) { if (gst_element_factory_can_src_any_caps(convert, wanted_caps) && gst_element_factory_can_sink_any_caps(convert, available_caps)) { // this intersection check is to ensure that we can't just pass // the caps through and really need this additional element GstCaps* intersect = gst_caps_intersect(available_caps, wanted_caps); if (!gst_caps_is_empty(intersect)) { return intersect; } gst_caps_unref(intersect); requires_vidoeconvert = true; // wanted_caps can be fixed, etc. GstCaps* in = get_caps_from_element_name("videoconvert", "sink"); // this removes things like jpeg GstCaps* ret = gst_caps_intersect(available_caps, in); GstCaps* temp = gst_caps_copy(wanted_caps); for (unsigned int i = 0; i < gst_caps_get_size(temp); ++i) { gst_structure_remove_field(gst_caps_get_structure(temp, i), "format"); } GstCaps* ret2 = gst_caps_intersect(ret, temp); gst_caps_unref(in); gst_caps_unref(ret); gst_object_unref(convert); return ret2; } gst_object_unref(convert); } GstElementFactory* jpegdec = gst_element_factory_find("jpegdec"); if (jpegdec) { if (gst_element_factory_can_src_any_caps(jpegdec, wanted_caps) && gst_element_factory_can_sink_any_caps(jpegdec, available_caps)) { requires_jpegdec = true; requires_vidoeconvert = true; // wanted_caps can be fixed, etc. // thus change name to be compatible to jpegdec sink pad // and create a correct intersection GstCaps* temp = gst_caps_copy(wanted_caps); gst_caps_change_name(temp, "image/jpeg"); for (unsigned int i = 0; i < gst_caps_get_size(temp); ++i) { gst_structure_remove_field(gst_caps_get_structure(temp, i), "format"); } GstCaps* ret = gst_caps_intersect(available_caps, temp); gst_caps_unref(temp); gst_object_unref(jpegdec); return ret; } gst_object_unref(jpegdec); } GstCaps* intersect = gst_caps_intersect(available_caps, wanted_caps); if (!gst_caps_is_empty(intersect)) { return intersect; } gst_caps_unref(intersect); return nullptr; }