EXPORT_C #endif G_CONST_RETURN GValue * gst_tag_list_get_value_index (const GstTagList * list, const gchar * tag, guint index) { const GValue *value; g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL); g_return_val_if_fail (tag != NULL, NULL); value = gst_structure_get_value ((GstStructure *) list, tag); if (value == NULL) return NULL; if (GST_VALUE_HOLDS_LIST (value)) { if (index >= gst_value_list_get_size (value)) return NULL; return gst_value_list_get_value (value, index); } else { if (index > 0) return NULL; return value; } }
static GstVaapiProfile find_best_profile (GstCaps * caps) { FindBestProfileData data; guint i, j, num_structures, num_values; data.best_profile = GST_VAAPI_PROFILE_UNKNOWN; data.best_score = 0; num_structures = gst_caps_get_size (caps); for (i = 0; i < num_structures; i++) { GstStructure *const structure = gst_caps_get_structure (caps, i); const GValue *const value = gst_structure_get_value (structure, "profile"); if (!value) continue; if (G_VALUE_HOLDS_STRING (value)) find_best_profile_value (&data, value); else if (GST_VALUE_HOLDS_LIST (value)) { num_values = gst_value_list_get_size (value); for (j = 0; j < num_values; j++) find_best_profile_value (&data, gst_value_list_get_value (value, j)); } } return data.best_profile; }
static gboolean get_string_list (GstStructure * s, const gchar * field, GQueue * queue) { const GValue *value; value = gst_structure_get_value (s, field); if (!value) return FALSE; if (GST_VALUE_HOLDS_LIST (value)) { guint i; if (gst_value_list_get_size (value) == 0) return FALSE; for (i = 0; i < gst_value_list_get_size (value); i++) { const GValue *item = gst_value_list_get_value (value, i); if (G_VALUE_HOLDS_STRING (item)) g_queue_push_tail (queue, g_value_dup_string (item)); } } else if (G_VALUE_HOLDS_STRING (value)) { g_queue_push_tail (queue, g_value_dup_string (value)); } return TRUE; }
std::vector<std::string> gst_list_to_vector (const GValue* gst_list) { std::vector<std::string> ret; if (!GST_VALUE_HOLDS_LIST(gst_list)) { tcam_error("Given GValue is not a list."); return ret; } for (unsigned int x = 0; x < gst_value_list_get_size(gst_list); ++x) { const GValue* val = gst_value_list_get_value(gst_list, x); if (G_VALUE_TYPE(val) == G_TYPE_STRING) { ret.push_back(g_value_get_string(val)); } else { tcam_error("NOT IMPLEMENTED. TYPE CAN NOT BE INTERPRETED"); } } return ret; }
static void get_supported_framerates (ofGstVideoFormat &video_format, GstStructure &structure) { const GValue *framerates; int i, j; framerates = gst_structure_get_value (&structure, "framerate"); if (GST_VALUE_HOLDS_FRACTION (framerates)) { video_format.num_framerates = 1; video_format.framerates = new ofGstFramerate[video_format.num_framerates]; video_format.framerates[0].numerator = gst_value_get_fraction_numerator (framerates); video_format.framerates[0].denominator = gst_value_get_fraction_denominator (framerates); } else if (GST_VALUE_HOLDS_LIST (framerates)) { video_format.num_framerates = gst_value_list_get_size (framerates); video_format.framerates = new ofGstFramerate[video_format.num_framerates]; for (i = 0; i < video_format.num_framerates; i++) { const GValue *value; value = gst_value_list_get_value (framerates, i); video_format.framerates[i].numerator = gst_value_get_fraction_numerator (value); video_format.framerates[i].denominator = gst_value_get_fraction_denominator (value); } } else if (GST_VALUE_HOLDS_FRACTION_RANGE (framerates)) { int numerator_min, denominator_min, numerator_max, denominator_max; const GValue *fraction_range_min; const GValue *fraction_range_max; fraction_range_min = gst_value_get_fraction_range_min (framerates); numerator_min = gst_value_get_fraction_numerator (fraction_range_min); denominator_min = gst_value_get_fraction_denominator (fraction_range_min); fraction_range_max = gst_value_get_fraction_range_max (framerates); numerator_max = gst_value_get_fraction_numerator (fraction_range_max); denominator_max = gst_value_get_fraction_denominator (fraction_range_max); g_print ("FractionRange: %d/%d - %d/%d\n", numerator_min, denominator_min, numerator_max, denominator_max); video_format.num_framerates = (numerator_max - numerator_min + 1) * (denominator_max - denominator_min + 1); video_format.framerates = new ofGstFramerate[video_format.num_framerates]; int k = 0; for (i = numerator_min; i <= numerator_max; i++) { for (j = denominator_min; j <= denominator_max; j++) { video_format.framerates[k].numerator = i; video_format.framerates[k].denominator = j; k++; } } } else { g_critical ("GValue type %s, cannot be handled for framerates", G_VALUE_TYPE_NAME (framerates)); } }
static void gst_video_convert_fixate_format (GstBaseTransform * base, GstCaps * caps, GstCaps * result) { GstStructure *ins, *outs; const gchar *in_format; const GstVideoFormatInfo *in_info, *out_info = NULL; gint min_loss = G_MAXINT; guint i, capslen; ins = gst_caps_get_structure (caps, 0); in_format = gst_structure_get_string (ins, "format"); if (!in_format) return; GST_DEBUG_OBJECT (base, "source format %s", in_format); in_info = gst_video_format_get_info (gst_video_format_from_string (in_format)); if (!in_info) return; outs = gst_caps_get_structure (result, 0); capslen = gst_caps_get_size (result); GST_DEBUG_OBJECT (base, "iterate %d structures", capslen); for (i = 0; i < capslen; i++) { GstStructure *tests; const GValue *format; tests = gst_caps_get_structure (result, i); format = gst_structure_get_value (tests, "format"); /* should not happen */ if (format == NULL) continue; if (GST_VALUE_HOLDS_LIST (format)) { gint j, len; len = gst_value_list_get_size (format); GST_DEBUG_OBJECT (base, "have %d formats", len); for (j = 0; j < len; j++) { const GValue *val; val = gst_value_list_get_value (format, j); if (G_VALUE_HOLDS_STRING (val)) { score_value (base, in_info, val, &min_loss, &out_info); if (min_loss == 0) break; } } } else if (G_VALUE_HOLDS_STRING (format)) { score_value (base, in_info, format, &min_loss, &out_info); } } if (out_info) gst_structure_set (outs, "format", G_TYPE_STRING, GST_VIDEO_FORMAT_INFO_NAME (out_info), NULL); }
std::string VideoV4lSource::srcCaps(unsigned int framerateIndex) const { std::ostringstream capsStr; GstStateChangeReturn ret = gst_element_set_state(source_, GST_STATE_READY); if (ret not_eq GST_STATE_CHANGE_SUCCESS) THROW_ERROR("Could not change v4l2src state to READY"); GstPad *srcPad = gst_element_get_static_pad(source_, "src"); GstCaps *caps = gst_pad_get_caps(srcPad); GstStructure *structure = gst_caps_get_structure(caps, 0); const GValue *val = gst_structure_get_value(structure, "framerate"); LOG_DEBUG("Caps structure from v4l2src srcpad: " << gst_structure_to_string(structure)); gint framerate_numerator, framerate_denominator; if (GST_VALUE_HOLDS_LIST(val)) { // trying another one if (framerateIndex >= gst_value_list_get_size(val)) THROW_ERROR("Framerate index out of range"); framerate_numerator = gst_value_get_fraction_numerator((gst_value_list_get_value(val, framerateIndex))); framerate_denominator = gst_value_get_fraction_denominator((gst_value_list_get_value(val, framerateIndex))); } else { // FIXME: this is really bad, we should be iterating over framerates and resolutions until we find a good one if (framerateIndex > 0) LOG_ERROR("Caps parameters haven't been changed and have failed before"); framerate_numerator = gst_value_get_fraction_numerator(val); framerate_denominator = gst_value_get_fraction_denominator(val); } gst_caps_unref(caps); gst_object_unref(srcPad); // use default from gst std::string capsSuffix = boost::lexical_cast<std::string>(framerate_numerator); capsSuffix += "/"; capsSuffix += boost::lexical_cast<std::string>(framerate_denominator); if (v4l2util::isInterlaced(deviceStr())) capsSuffix +=", interlaced=true"; capsSuffix += ", pixel-aspect-ratio="; capsSuffix += config_.pixelAspectRatio(); capsStr << "video/x-raw-yuv, width=" << config_.captureWidth() << ", height=" << config_.captureHeight() << ", framerate=" << capsSuffix; LOG_DEBUG("V4l2src caps are " << capsStr.str()); ret = gst_element_set_state(source_, GST_STATE_NULL); if (ret not_eq GST_STATE_CHANGE_SUCCESS) THROW_ERROR("Could not change v4l2src state to NULL"); return capsStr.str(); }
static void gst_value_fraction_get_extremes (const GValue * v, gint * min_num, gint * min_denom, gint * max_num, gint * max_denom) { if (GST_VALUE_HOLDS_FRACTION (v)) { *min_num = *max_num = gst_value_get_fraction_numerator (v); *min_denom = *max_denom = gst_value_get_fraction_denominator (v); } else if (GST_VALUE_HOLDS_FRACTION_RANGE (v)) { const GValue *min, *max; min = gst_value_get_fraction_range_min (v); *min_num = gst_value_get_fraction_numerator (min); *min_denom = gst_value_get_fraction_denominator (min); max = gst_value_get_fraction_range_max (v); *max_num = gst_value_get_fraction_numerator (max); *max_denom = gst_value_get_fraction_denominator (max); } else if (GST_VALUE_HOLDS_LIST (v)) { gint min_n = G_MAXINT, min_d = 1, max_n = 0, max_d = 1; int i, n; *min_num = G_MAXINT; *min_denom = 1; *max_num = 0; *max_denom = 1; n = gst_value_list_get_size (v); g_assert (n > 0); for (i = 0; i < n; i++) { const GValue *t = gst_value_list_get_value (v, i); gst_value_fraction_get_extremes (t, &min_n, &min_d, &max_n, &max_d); if (gst_util_fraction_compare (min_n, min_d, *min_num, *min_denom) < 0) { *min_num = min_n; *min_denom = min_d; } if (gst_util_fraction_compare (max_n, max_d, *max_num, *max_denom) > 0) { *max_num = max_n; *max_denom = max_d; } } } else { g_warning ("Unknown type for framerate"); *min_num = 0; *min_denom = 1; *max_num = G_MAXINT; *max_denom = 1; } }
static void check_pad_template (GstPadTemplate * tmpl) { const GValue *list_val, *fmt_val; GstStructure *s; gboolean *formats_supported; GstCaps *caps; guint i, num_formats; num_formats = get_num_formats (); formats_supported = g_new0 (gboolean, num_formats); caps = gst_pad_template_get_caps (tmpl); /* If this fails, we need to update this unit test */ fail_unless_equals_int (gst_caps_get_size (caps), 1); s = gst_caps_get_structure (caps, 0); fail_unless (gst_structure_has_name (s, "video/x-raw")); list_val = gst_structure_get_value (s, "format"); fail_unless (list_val != NULL); /* If this fails, we need to update this unit test */ fail_unless (GST_VALUE_HOLDS_LIST (list_val)); for (i = 0; i < gst_value_list_get_size (list_val); ++i) { GstVideoFormat fmt; const gchar *fmt_str; fmt_val = gst_value_list_get_value (list_val, i); fail_unless (G_VALUE_HOLDS_STRING (fmt_val)); fmt_str = g_value_get_string (fmt_val); GST_LOG ("format string: '%s'", fmt_str); fmt = gst_video_format_from_string (fmt_str); fail_unless (fmt != GST_VIDEO_FORMAT_UNKNOWN); formats_supported[(guint) fmt] = TRUE; } gst_caps_unref (caps); for (i = 2; i < num_formats; ++i) { if (!formats_supported[i]) { g_error ("videoconvert doesn't support format '%s'", gst_video_format_to_string ((GstVideoFormat) i)); } } g_free (formats_supported); }
static void get_supported_framerates (ofGstVideoFormat &video_format, GstStructure &structure) { const GValue *framerates; ofGstFramerate framerate; framerates = gst_structure_get_value (&structure, "framerate"); if (GST_VALUE_HOLDS_FRACTION (framerates)){ framerate.numerator = gst_value_get_fraction_numerator (framerates); framerate.denominator = gst_value_get_fraction_denominator (framerates); video_format.framerates.push_back(framerate); ofLog(OF_LOG_NOTICE,"%d/%d ", framerate.numerator, framerate.denominator); }else if (GST_VALUE_HOLDS_LIST (framerates)){ int num_framerates = gst_value_list_get_size (framerates); for (int i = 0; i < num_framerates; i++){ const GValue *value = gst_value_list_get_value (framerates, i); framerate.numerator = gst_value_get_fraction_numerator (value); framerate.denominator = gst_value_get_fraction_denominator (value); video_format.framerates.push_back(framerate); ofLog(OF_LOG_NOTICE,"%d/%d ", framerate.numerator, framerate.denominator); } }else if (GST_VALUE_HOLDS_FRACTION_RANGE (framerates)){ int numerator_min, denominator_min, numerator_max, denominator_max; const GValue *fraction_range_min; const GValue *fraction_range_max; fraction_range_min = gst_value_get_fraction_range_min (framerates); numerator_min = gst_value_get_fraction_numerator (fraction_range_min); denominator_min = gst_value_get_fraction_denominator (fraction_range_min); fraction_range_max = gst_value_get_fraction_range_max (framerates); numerator_max = gst_value_get_fraction_numerator (fraction_range_max); denominator_max = gst_value_get_fraction_denominator (fraction_range_max); ofLog(OF_LOG_NOTICE,"from %d/%d to %d/%d", numerator_min, denominator_max, numerator_max, denominator_min); for (int i = numerator_min; i <= numerator_max; i++){ for (int j = denominator_min; j <= denominator_max; j++){ framerate.numerator = i; framerate.denominator = j; video_format.framerates.push_back(framerate); } } }else{ ofLog (OF_LOG_WARNING,"unknown GValue type %s for framerates", G_VALUE_TYPE_NAME (framerates)); } }
static GstVideoFormat gst_vaapi_find_preferred_format (const GValue * format_list, GstVideoFormat native_format) { const GValue *frmt; GstVideoFormat out_format; guint i; /* if one format, that is the one */ if (G_VALUE_HOLDS_STRING (format_list)) return gst_video_format_from_string (g_value_get_string (format_list)); if (!GST_VALUE_HOLDS_LIST (format_list)) { GST_ERROR ("negotiated caps do not have a valid format"); return GST_VIDEO_FORMAT_UNKNOWN; } if (native_format == GST_VIDEO_FORMAT_UNKNOWN || native_format == GST_VIDEO_FORMAT_ENCODED) { native_format = GST_VIDEO_FORMAT_NV12; /* default VA format */ } /* search our native format in the list */ for (i = 0; i < gst_value_list_get_size (format_list); i++) { frmt = gst_value_list_get_value (format_list, i); out_format = gst_video_format_from_string (g_value_get_string (frmt)); /* GStreamer do not handle encoded formats nicely. Try the next * one. */ if (out_format == GST_VIDEO_FORMAT_ENCODED) continue; if (native_format == out_format) return out_format; } /* just pick the first valid format in the list */ i = 0; do { frmt = gst_value_list_get_value (format_list, i++); out_format = gst_video_format_from_string (g_value_get_string (frmt)); } while (out_format == GST_VIDEO_FORMAT_ENCODED); return out_format; }
/** * Tries to guess the frame rate for a V4L2 source. */ std::string Pipeline::guess_source_caps(unsigned int framerateIndex) const { bool is_verbose = owner_->get_configuration()->get_verbose(); if (is_verbose) LOG_DEBUG("Trying to guess source FPS " << framerateIndex); std::ostringstream capsStr; GstStateChangeReturn ret = gst_element_set_state(videosrc_, GST_STATE_READY); if (ret not_eq GST_STATE_CHANGE_SUCCESS) THROW_ERROR("Could not change v4l2src state to READY"); GstPad *srcPad = gst_element_get_static_pad(videosrc_, "src"); GstCaps *caps = gst_pad_get_caps(srcPad); GstStructure *structure = gst_caps_get_structure(caps, 0); const GValue *val = gst_structure_get_value(structure, "framerate"); if (is_verbose) LOG_DEBUG("Caps structure from v4l2src srcpad: " << gst_structure_to_string(structure)); gint framerate_numerator = 1; gint framerate_denominator = 1; if (GST_VALUE_HOLDS_LIST(val)) { // trying another one if (framerateIndex >= gst_value_list_get_size(val)) THROW_ERROR("Framerate index out of range"); framerate_numerator = gst_value_get_fraction_numerator((gst_value_list_get_value(val, framerateIndex))); framerate_denominator = gst_value_get_fraction_denominator((gst_value_list_get_value(val, framerateIndex))); } else { // FIXME: this is really bad, we should be iterating over framerates and resolutions until we find a good one if (framerateIndex > 0) LOG_ERROR("Caps parameters haven't been changed and have failed before"); framerate_numerator = gst_value_get_fraction_numerator(val); framerate_denominator = gst_value_get_fraction_denominator(val); } gst_caps_unref(caps); gst_object_unref(srcPad); // use default from gst std::string capsSuffix = boost::lexical_cast<std::string>(framerate_numerator); capsSuffix += "/"; capsSuffix += boost::lexical_cast<std::string>(framerate_denominator); // TODO: handle interlaced video capture stream if (v4l2util::isInterlaced(owner_->get_configuration()->videoSource())) { capsSuffix +=", interlaced=true"; } // TODO: handle aspect ratio // capsSuffix += ", pixel-aspect-ratio=1/1"; //capsSuffix += config_.pixelAspectRatio(); //capsSuffix += "4:3"; Configuration *config = owner_->get_configuration(); capsStr << "video/x-raw-yuv, width=" << config->get_capture_width() << ", height=" << config->get_capture_height() << ", framerate=" << capsSuffix; if (is_verbose) LOG_DEBUG("Video source caps are " << capsStr.str()); ret = gst_element_set_state(videosrc_, GST_STATE_NULL); if (ret not_eq GST_STATE_CHANGE_SUCCESS) THROW_ERROR("Could not change v4l2src state to NULL"); return capsStr.str(); }
int main (int argc, char *argv[]) { /* Initialisation */ gst_init (&argc, &argv); GList *element_list = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER, GST_RANK_NONE); GList *iter = element_list; while (iter != NULL) { g_print ("+++++\n"); g_print ("%s -- ", gst_element_factory_get_longname ((GstElementFactory *)iter->data)); g_print ("%s\n", gst_plugin_feature_get_name ((GstPluginFeature *)iter->data)); const GList *static_pads = gst_element_factory_get_static_pad_templates ((GstElementFactory *)iter->data); while (NULL != static_pads) { GstStaticPadTemplate *pad = (GstStaticPadTemplate *)static_pads->data; //the following is EMPTY gchar *caps_str = gst_caps_to_string (&pad->static_caps.caps); //g_free (caps_str); /* g_print ("string: %s\n", */ /* pad->static_caps.string); */ GstCaps *caps = gst_caps_from_string (pad->static_caps.string); guint caps_size = gst_caps_get_size (caps); if (! gst_caps_is_any (caps)) for (guint i = caps_size; i > 0; i--) { GstStructure *caps_struct = gst_caps_get_structure (caps, i-1); if (gst_structure_has_name (caps_struct,"application/x-rtp")) { g_print ("string: %s\n", gst_structure_to_string (caps_struct)); {//payload const GValue *val = gst_structure_get_value (caps_struct, "payload"); if (NULL != val) { //g_print ("payload struct type %s\n", G_VALUE_TYPE_NAME (val)); if(GST_VALUE_HOLDS_INT_RANGE(val)) { g_print ("payload min %d\n", gst_value_get_int_range_min (val)); } if (GST_VALUE_HOLDS_LIST(val)) { for (guint i = 0; i < gst_value_list_get_size (val); i++) { const GValue *item_val = gst_value_list_get_value (val, i); g_print ("payload list %d\n", g_value_get_int (item_val)); } } if (G_VALUE_HOLDS_INT (val)) { g_print ("payload int %d\n", g_value_get_int (val)); } } } { //encodeing-name const GValue *val = gst_structure_get_value (caps_struct, "encoding-name"); if (NULL != val) { //g_print ("encoding-name struct type %s\n", G_VALUE_TYPE_NAME (val)); if (GST_VALUE_HOLDS_LIST(val)) { for (guint i = 0; i < gst_value_list_get_size (val); i++) { const GValue *item_val = gst_value_list_get_value (val, i); g_print ("encoding-name list %s\n", g_value_get_string (item_val)); } } if (G_VALUE_HOLDS_STRING (val)) { g_print ("encoding-name string %s\n", g_value_get_string (val)); } } } {//media const GValue *val = gst_structure_get_value (caps_struct, "media"); if (NULL != val) { if (GST_VALUE_HOLDS_LIST(val)) { for (guint i = 0; i < gst_value_list_get_size (val); i++) { const GValue *item_val = gst_value_list_get_value (val, i); g_print ("media list %s\n", g_value_get_string (item_val)); } } if (G_VALUE_HOLDS_STRING (val)) { g_print ("media string %s\n", g_value_get_string (val)); } } } {//clock rate const GValue *val = gst_structure_get_value (caps_struct, "clock-rate"); if (NULL != val) { //g_print ("payload struct type %s\n", G_VALUE_TYPE_NAME (val)); if(GST_VALUE_HOLDS_INT_RANGE(val)) { g_print ("clock-rate min %d\n", gst_value_get_int_range_min (val)); } if (GST_VALUE_HOLDS_LIST(val)) { for (guint i = 0; i < gst_value_list_get_size (val); i++) { const GValue *item_val = gst_value_list_get_value (val, i); g_print ("clock-rate list %d\n", g_value_get_int (item_val)); } } if (G_VALUE_HOLDS_INT (val)) { g_print ("clock-rate int %d\n", g_value_get_int (val)); } } } /* g_print ("\nencoding-name %s\n", */ /* gst_structure_get_string (caps_struct, */ /* "encoding-name")); */ } } static_pads = g_list_next (static_pads); gst_caps_unref (caps); } iter = g_list_next (iter); } gst_plugin_feature_list_free (element_list); return 0; }
/* * Given a GstCaps, this will return a fixed GstCaps on sucessfull conversion. * If an error occurs, it will return NULL and error_message will contain the * error message. * * error_message must be passed NULL, if an error occurs, the caller has the * ownership of the error_message, it must be freed after use. */ GstCaps *gst_sbc_util_caps_fixate(GstCaps *caps, gchar **error_message) { GstCaps *result; GstStructure *structure; const GValue *value; gboolean error = FALSE; gint temp, rate, channels, blocks, subbands, bitpool; const gchar *allocation = NULL; const gchar *mode = NULL; g_assert(*error_message == NULL); structure = gst_caps_get_structure(caps, 0); if (!gst_structure_has_field(structure, "rate")) { error = TRUE; *error_message = g_strdup("no rate"); goto error; } else { value = gst_structure_get_value(structure, "rate"); if (GST_VALUE_HOLDS_LIST(value)) temp = gst_sbc_select_rate_from_list(value); else temp = g_value_get_int(value); rate = temp; } if (!gst_structure_has_field(structure, "channels")) { error = TRUE; *error_message = g_strdup("no channels"); goto error; } else { value = gst_structure_get_value(structure, "channels"); if (GST_VALUE_HOLDS_INT_RANGE(value)) temp = gst_sbc_select_channels_from_range(value); else temp = g_value_get_int(value); channels = temp; } if (!gst_structure_has_field(structure, "blocks")) { error = TRUE; *error_message = g_strdup("no blocks."); goto error; } else { value = gst_structure_get_value(structure, "blocks"); if (GST_VALUE_HOLDS_LIST(value)) temp = gst_sbc_select_blocks_from_list(value); else temp = g_value_get_int(value); blocks = temp; } if (!gst_structure_has_field(structure, "subbands")) { error = TRUE; *error_message = g_strdup("no subbands"); goto error; } else { value = gst_structure_get_value(structure, "subbands"); if (GST_VALUE_HOLDS_LIST(value)) temp = gst_sbc_select_subbands_from_list(value); else temp = g_value_get_int(value); subbands = temp; } if (!gst_structure_has_field(structure, "bitpool")) { error = TRUE; *error_message = g_strdup("no bitpool"); goto error; } else { value = gst_structure_get_value(structure, "bitpool"); if (GST_VALUE_HOLDS_INT_RANGE(value)) temp = gst_sbc_select_bitpool_from_range(value); else temp = g_value_get_int(value); bitpool = temp; } if (!gst_structure_has_field(structure, "allocation")) { error = TRUE; *error_message = g_strdup("no allocation"); goto error; } else { value = gst_structure_get_value(structure, "allocation"); if (GST_VALUE_HOLDS_LIST(value)) allocation = gst_sbc_get_allocation_from_list(value); else allocation = g_value_get_string(value); } if (!gst_structure_has_field(structure, "mode")) { error = TRUE; *error_message = g_strdup("no mode"); goto error; } else { value = gst_structure_get_value(structure, "mode"); if (GST_VALUE_HOLDS_LIST(value)) { mode = gst_sbc_get_mode_from_list(value, channels); } else mode = g_value_get_string(value); } /* perform validation * if channels is 1, we must have channel mode = mono * if channels is 2, we can't have channel mode = mono */ if ( (channels == 1 && (strcmp(mode, "mono") != 0) ) || ( channels == 2 && ( strcmp(mode, "mono") == 0))) { *error_message = g_strdup_printf("Invalid combination of " "channels (%d) and channel mode (%s)", channels, mode); error = TRUE; } error: if (error) return NULL; result = gst_caps_new_simple("audio/x-sbc", "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, "mode", G_TYPE_STRING, mode, "blocks", G_TYPE_INT, blocks, "subbands", G_TYPE_INT, subbands, "allocation", G_TYPE_STRING, allocation, "bitpool", G_TYPE_INT, bitpool, NULL); return result; }
static gboolean gst_video_crop_transform_dimension_value (const GValue * src_val, gint delta, GValue * dest_val, GstPadDirection direction, gboolean dynamic) { gboolean ret = TRUE; if (G_VALUE_HOLDS_INT (src_val)) { gint ival = g_value_get_int (src_val); ival = gst_video_crop_transform_dimension (ival, delta); if (dynamic) { if (direction == GST_PAD_SRC) { if (ival == G_MAXINT) { g_value_init (dest_val, G_TYPE_INT); g_value_set_int (dest_val, ival); } else { g_value_init (dest_val, GST_TYPE_INT_RANGE); gst_value_set_int_range (dest_val, ival, G_MAXINT); } } else { if (ival == 1) { g_value_init (dest_val, G_TYPE_INT); g_value_set_int (dest_val, ival); } else { g_value_init (dest_val, GST_TYPE_INT_RANGE); gst_value_set_int_range (dest_val, 1, ival); } } } else { g_value_init (dest_val, G_TYPE_INT); g_value_set_int (dest_val, ival); } } else if (GST_VALUE_HOLDS_INT_RANGE (src_val)) { gint min = gst_value_get_int_range_min (src_val); gint max = gst_value_get_int_range_max (src_val); min = gst_video_crop_transform_dimension (min, delta); max = gst_video_crop_transform_dimension (max, delta); if (dynamic) { if (direction == GST_PAD_SRC) max = G_MAXINT; else min = 1; } if (min == max) { g_value_init (dest_val, G_TYPE_INT); g_value_set_int (dest_val, min); } else { g_value_init (dest_val, GST_TYPE_INT_RANGE); gst_value_set_int_range (dest_val, min, max); } } else if (GST_VALUE_HOLDS_LIST (src_val)) { gint i; g_value_init (dest_val, GST_TYPE_LIST); for (i = 0; i < gst_value_list_get_size (src_val); ++i) { const GValue *list_val; GValue newval = { 0, }; list_val = gst_value_list_get_value (src_val, i); if (gst_video_crop_transform_dimension_value (list_val, delta, &newval, direction, dynamic)) gst_value_list_append_value (dest_val, &newval); g_value_unset (&newval); } if (gst_value_list_get_size (dest_val) == 0) { g_value_unset (dest_val); ret = FALSE; } } else { ret = FALSE; } return ret; }
/* * cheese_camera_device_get_highest_framerate: * @framerate: a #GValue holding a framerate cap * @numerator: destination to store the numerator of the highest rate * @denominator: destination to store the denominator of the highest rate * * Get the numerator and denominator for the highest framerate stored in * a framerate cap. * * Note this function does not handle framerate ranges, if @framerate * contains a range it will return 0/0 as framerate */ static void cheese_camera_device_get_highest_framerate (const GValue *framerate, gint *numerator, gint *denominator) { *numerator = 0; *denominator = 0; if (GST_VALUE_HOLDS_FRACTION (framerate)) { *numerator = gst_value_get_fraction_numerator (framerate); *denominator = gst_value_get_fraction_denominator (framerate); } else if (GST_VALUE_HOLDS_ARRAY (framerate)) { float curr, highest = 0; guint i, size = gst_value_array_get_size (framerate); for (i = 0; i < size; i++) { const GValue *val = gst_value_array_get_value (framerate, i); if (!GST_VALUE_HOLDS_FRACTION (val) || gst_value_get_fraction_denominator (val) == 0) { continue; } curr = (float)gst_value_get_fraction_numerator (val) / (float)gst_value_get_fraction_denominator (val); if (curr > highest && curr <= CHEESE_MAXIMUM_RATE) { highest = curr; *numerator = gst_value_get_fraction_numerator (val); *denominator = gst_value_get_fraction_denominator (val); } } } else if (GST_VALUE_HOLDS_LIST (framerate)) { float curr, highest = 0; guint i, size = gst_value_list_get_size (framerate); for (i = 0; i < size; i++) { const GValue *val = gst_value_list_get_value(framerate, i); if (!GST_VALUE_HOLDS_FRACTION (val) || gst_value_get_fraction_denominator (val) == 0) { continue; } curr = (float)gst_value_get_fraction_numerator (val) / (float)gst_value_get_fraction_denominator (val); if (curr > highest && curr <= CHEESE_MAXIMUM_RATE) { highest = curr; *numerator = gst_value_get_fraction_numerator (val); *denominator = gst_value_get_fraction_denominator (val); } } } }
/* If a parent is non-NULL, collected stream information will be appended to it * (and where the information exists, it will be overriden) */ static GstDiscovererStreamInfo * parse_stream_topology (GstDiscoverer * dc, const GstStructure * topology, GstDiscovererStreamInfo * parent) { GstDiscovererStreamInfo *res = NULL; GstCaps *caps = NULL; const GValue *nval = NULL; GST_DEBUG ("parsing: %" GST_PTR_FORMAT, topology); nval = gst_structure_get_value (topology, "next"); if (nval == NULL || GST_VALUE_HOLDS_STRUCTURE (nval)) { GstStructure *st = find_stream_for_node (dc, topology); gboolean add_to_list = TRUE; if (st) { res = collect_information (dc, st, parent); gst_structure_free (st); } else { /* Didn't find a stream structure, so let's just use the caps we have */ res = collect_information (dc, topology, parent); } if (nval == NULL) { /* FIXME : aggregate with information from main streams */ GST_DEBUG ("Coudn't find 'next' ! might be the last entry"); } else { GstCaps *caps; const GstStructure *st; st = gst_value_get_structure (nval); GST_DEBUG ("next is a structure %" GST_PTR_FORMAT, st); if (!parent) parent = res; if (gst_structure_id_get (st, _CAPS_QUARK, GST_TYPE_CAPS, &caps, NULL)) { if (gst_caps_can_intersect (parent->caps, caps)) { /* We sometimes get an extra sub-stream from the parser. If this is * the case, we just replace the parent caps with this stream's caps * since they might contain more information */ gst_caps_unref (parent->caps); parent->caps = caps; parse_stream_topology (dc, st, parent); add_to_list = FALSE; } else if (child_is_raw_stream (parent->caps, caps)) { /* This is the "raw" stream corresponding to the parent. This * contains more information than the parent, tags etc. */ parse_stream_topology (dc, st, parent); add_to_list = FALSE; gst_caps_unref (caps); } else { GstDiscovererStreamInfo *next = parse_stream_topology (dc, st, NULL); res->next = next; next->previous = res; } } } if (add_to_list) { dc->priv->current_info->stream_list = g_list_append (dc->priv->current_info->stream_list, res); } } else if (GST_VALUE_HOLDS_LIST (nval)) { guint i, len; GstDiscovererContainerInfo *cont; GstTagList *tags; if (!gst_structure_id_get (topology, _CAPS_QUARK, GST_TYPE_CAPS, &caps, NULL)) GST_WARNING ("Couldn't find caps !"); len = gst_value_list_get_size (nval); GST_DEBUG ("next is a list of %d entries", len); cont = (GstDiscovererContainerInfo *) gst_mini_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO); cont->parent.caps = caps; res = (GstDiscovererStreamInfo *) cont; if (gst_structure_id_has_field (topology, _TAGS_QUARK)) { GstTagList *tmp; gst_structure_id_get (topology, _TAGS_QUARK, GST_TYPE_STRUCTURE, &tags, NULL); GST_DEBUG ("Merge tags %" GST_PTR_FORMAT, tags); tmp = gst_tag_list_merge (cont->parent.tags, (GstTagList *) tags, GST_TAG_MERGE_APPEND); gst_tag_list_free (tags); if (cont->parent.tags) gst_tag_list_free (cont->parent.tags); cont->parent.tags = tmp; GST_DEBUG ("Container info tags %" GST_PTR_FORMAT, tmp); } for (i = 0; i < len; i++) { const GValue *subv = gst_value_list_get_value (nval, i); const GstStructure *subst = gst_value_get_structure (subv); GstDiscovererStreamInfo *substream; GST_DEBUG ("%d %" GST_PTR_FORMAT, i, subst); substream = parse_stream_topology (dc, subst, NULL); substream->previous = res; cont->streams = g_list_append (cont->streams, gst_discoverer_stream_info_ref (substream)); } } return res; }
static void check_pad_template (GstPadTemplate * tmpl) { const GValue *list_val, *fmt_val; GstStructure *s; gboolean *formats_supported; GstCaps *caps; guint i, num_formats; num_formats = get_num_formats (); formats_supported = g_new0 (gboolean, num_formats); caps = gst_pad_template_get_caps (tmpl); /* If this fails, we need to update this unit test */ fail_unless_equals_int (gst_caps_get_size (caps), 2); /* Remove the ANY caps features structure */ caps = gst_caps_truncate (caps); s = gst_caps_get_structure (caps, 0); fail_unless (gst_structure_has_name (s, "video/x-raw")); list_val = gst_structure_get_value (s, "format"); fail_unless (list_val != NULL); /* If this fails, we need to update this unit test */ fail_unless (GST_VALUE_HOLDS_LIST (list_val)); for (i = 0; i < gst_value_list_get_size (list_val); ++i) { GstVideoFormat fmt; const gchar *fmt_str; fmt_val = gst_value_list_get_value (list_val, i); fail_unless (G_VALUE_HOLDS_STRING (fmt_val)); fmt_str = g_value_get_string (fmt_val); GST_LOG ("format string: '%s'", fmt_str); fmt = gst_video_format_from_string (fmt_str); if (fmt == GST_VIDEO_FORMAT_UNKNOWN) g_error ("Unknown raw format '%s' in pad template caps", fmt_str); formats_supported[(guint) fmt] = TRUE; } gst_caps_unref (caps); for (i = 2; i < num_formats; ++i) { if (!formats_supported[i]) { const gchar *fmt_str = gst_video_format_to_string ((GstVideoFormat) i); switch (i) { case GST_VIDEO_FORMAT_v210: case GST_VIDEO_FORMAT_v216: case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV16: case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_NV24: case GST_VIDEO_FORMAT_UYVP: case GST_VIDEO_FORMAT_A420: case GST_VIDEO_FORMAT_YUV9: case GST_VIDEO_FORMAT_YVU9: case GST_VIDEO_FORMAT_IYU1: case GST_VIDEO_FORMAT_r210:{ static gboolean shown_fixme[100] = { FALSE, }; if (!shown_fixme[i]) { GST_FIXME ("FIXME: add %s support to videoscale", fmt_str); shown_fixme[i] = TRUE; } break; } case GST_VIDEO_FORMAT_BGR16: case GST_VIDEO_FORMAT_BGR15: case GST_VIDEO_FORMAT_RGB8P: case GST_VIDEO_FORMAT_I420_10BE: case GST_VIDEO_FORMAT_I420_10LE: case GST_VIDEO_FORMAT_I422_10BE: case GST_VIDEO_FORMAT_I422_10LE: case GST_VIDEO_FORMAT_Y444_10BE: case GST_VIDEO_FORMAT_Y444_10LE: case GST_VIDEO_FORMAT_GBR: case GST_VIDEO_FORMAT_GBR_10BE: case GST_VIDEO_FORMAT_GBR_10LE: GST_LOG ("Ignoring lack of support for format %s", fmt_str); break; default: g_error ("videoscale doesn't support format '%s'", fmt_str); break; } } } g_free (formats_supported); }
static GstCaps * gst_smpte_alpha_transform_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * from, GstCaps * filter) { GstCaps *result, *tmp_caps, *tmpl_caps = NULL; gint i, j; tmp_caps = gst_caps_new_empty (); for (i = 0; i < gst_caps_get_size (from); i++) { GstStructure *structure; const GValue *val, *lval; GValue list = { 0, }; GValue aval = { 0, }; const gchar *str; structure = gst_structure_copy (gst_caps_get_structure (from, i)); /* we can transform I420 to AYUV, * so need to locate and substitute AYUV for the both of them */ val = gst_structure_get_value (structure, "format"); if (val && GST_VALUE_HOLDS_LIST (val)) { gboolean seen_ayuv = FALSE, seen_i420 = FALSE; g_value_init (&list, GST_TYPE_LIST); for (j = 0; j < gst_value_list_get_size (val); j++) { lval = gst_value_list_get_value (val, j); if ((str = g_value_get_string (lval))) { if (strcmp (str, "AYUV") == 0) { seen_ayuv = TRUE; } else if (strcmp (str, "I420") == 0) { seen_i420 = TRUE; } } } if (seen_ayuv && !seen_i420) { str = "I420"; } else if (seen_i420 && !seen_ayuv) { str = "AYUV"; } else str = NULL; if (str) { g_value_copy (val, &list); g_value_init (&aval, G_TYPE_STRING); g_value_set_string (&aval, str); gst_value_list_append_value (&list, &aval); g_value_reset (&aval); gst_structure_set_value (structure, "format", &list); g_value_unset (&list); } } else if (val && G_VALUE_HOLDS_STRING (val)) { if ((str = g_value_get_string (val)) && ((strcmp (str, "AYUV") == 0) || (strcmp (str, "I420") == 0))) { g_value_init (&list, GST_TYPE_LIST); g_value_init (&aval, G_TYPE_STRING); g_value_set_string (&aval, "AYUV"); gst_value_list_append_value (&list, &aval); g_value_reset (&aval); g_value_set_string (&aval, "I420"); gst_value_list_append_value (&list, &aval); g_value_reset (&aval); gst_structure_set_value (structure, "format", &list); g_value_unset (&list); } } else { gst_structure_remove_field (structure, "format"); } gst_structure_remove_field (structure, "colorimetry"); gst_structure_remove_field (structure, "chroma-site"); gst_caps_append_structure (tmp_caps, structure); } /* Get the appropriate template */ if (direction == GST_PAD_SINK) { tmpl_caps = gst_static_pad_template_get_caps (&gst_smpte_alpha_src_template); } else if (direction == GST_PAD_SRC) { tmpl_caps = gst_static_pad_template_get_caps (&gst_smpte_alpha_sink_template); } else { g_assert_not_reached (); } /* Intersect with our template caps */ result = gst_caps_intersect (tmp_caps, tmpl_caps); gst_caps_unref (tmpl_caps); gst_caps_unref (tmp_caps); result = gst_caps_simplify (result); GST_LOG_OBJECT (trans, "transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, from, result); if (filter) { GstCaps *intersection; GST_DEBUG_OBJECT (trans, "Using filter caps %" GST_PTR_FORMAT, filter); intersection = gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (result); result = intersection; GST_DEBUG_OBJECT (trans, "Intersection %" GST_PTR_FORMAT, result); } return result; }
void test_simplify() { GstStructure *s1, *s2; gboolean did_simplify; GstCaps *caps; caps = gst_caps_from_string (non_simple_caps_string); fail_unless (caps != NULL, "gst_caps_from_string (non_simple_caps_string) failed"); did_simplify = gst_caps_do_simplify (caps); fail_unless (did_simplify == TRUE, "gst_caps_do_simplify() should have worked"); /* check simplified caps, should be: * * video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234, * framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], * height=(int)[ 16, 4096 ]; * video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 }, * width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], * framerate=(fraction)[ 1/100, 100 ] */ fail_unless (gst_caps_get_size (caps) == 2); s1 = gst_caps_get_structure (caps, 0); s2 = gst_caps_get_structure (caps, 1); fail_unless (s1 != NULL); fail_unless (s2 != NULL); if (!gst_structure_has_name (s1, "video/x-raw-rgb")) { GstStructure *tmp; tmp = s1; s1 = s2; s2 = tmp; } fail_unless (gst_structure_has_name (s1, "video/x-raw-rgb")); { const GValue *framerate_value; const GValue *width_value; const GValue *height_value; const GValue *val_fps; GValue test_fps = { 0, }; gint bpp, depth, endianness; gint min_width, max_width; gint min_height, max_height; fail_unless (gst_structure_get_int (s1, "bpp", &bpp)); fail_unless (bpp == 8); fail_unless (gst_structure_get_int (s1, "depth", &depth)); fail_unless (depth == 8); fail_unless (gst_structure_get_int (s1, "endianness", &endianness)); fail_unless (endianness == G_LITTLE_ENDIAN); g_value_init (&test_fps, GST_TYPE_FRACTION); framerate_value = gst_structure_get_value (s1, "framerate"); fail_unless (framerate_value != NULL); fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value)); val_fps = gst_value_get_fraction_range_min (framerate_value); gst_value_set_fraction (&test_fps, 1, 100); fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL); val_fps = gst_value_get_fraction_range_max (framerate_value); gst_value_set_fraction (&test_fps, 100, 1); fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL); g_value_unset (&test_fps); width_value = gst_structure_get_value (s1, "width"); fail_unless (width_value != NULL); fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value)); min_width = gst_value_get_int_range_min (width_value); max_width = gst_value_get_int_range_max (width_value); fail_unless (min_width == 16 && max_width == 4096); height_value = gst_structure_get_value (s1, "height"); fail_unless (height_value != NULL); fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value)); min_height = gst_value_get_int_range_min (height_value); max_height = gst_value_get_int_range_max (height_value); fail_unless (min_height == 16 && max_height == 4096); } fail_unless (gst_structure_has_name (s2, "video/x-raw-yuv")); { const GValue *framerate_value; const GValue *format_value; const GValue *width_value; const GValue *height_value; const GValue *val_fps; GValue test_fps = { 0, }; gint min_width, max_width; gint min_height, max_height; format_value = gst_structure_get_value (s2, "format"); fail_unless (format_value != NULL); fail_unless (GST_VALUE_HOLDS_LIST (format_value)); fail_unless (gst_value_list_get_size (format_value) == 3); fail_unless (check_fourcc_list (format_value) == TRUE); g_value_init (&test_fps, GST_TYPE_FRACTION); framerate_value = gst_structure_get_value (s2, "framerate"); fail_unless (framerate_value != NULL); fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value)); val_fps = gst_value_get_fraction_range_min (framerate_value); gst_value_set_fraction (&test_fps, 1, 100); fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL); val_fps = gst_value_get_fraction_range_max (framerate_value); gst_value_set_fraction (&test_fps, 100, 1); fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL); g_value_unset (&test_fps); width_value = gst_structure_get_value (s2, "width"); fail_unless (width_value != NULL); fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value)); min_width = gst_value_get_int_range_min (width_value); max_width = gst_value_get_int_range_max (width_value); fail_unless (min_width == 16 && max_width == 4096); height_value = gst_structure_get_value (s2, "height"); fail_unless (height_value != NULL); fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value)); min_height = gst_value_get_int_range_min (height_value); max_height = gst_value_get_int_range_max (height_value); fail_unless (min_height == 16 && max_height == 4096); } gst_caps_unref (caps); }