static GstCaps * gst_yadif_transform_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter) { GstCaps *othercaps; othercaps = gst_caps_copy (caps); if (direction == GST_PAD_SRC) { GValue value = G_VALUE_INIT; GValue v = G_VALUE_INIT; g_value_init (&value, GST_TYPE_LIST); g_value_init (&v, G_TYPE_STRING); g_value_set_string (&v, "interleaved"); gst_value_list_append_value (&value, &v); g_value_set_string (&v, "mixed"); gst_value_list_append_value (&value, &v); g_value_set_string (&v, "progressive"); gst_value_list_append_value (&value, &v); gst_caps_set_value (othercaps, "interlace-mode", &value); g_value_unset (&value); g_value_unset (&v); } else { gst_caps_set_simple (othercaps, "interlace-mode", G_TYPE_STRING, "progressive", NULL); } return othercaps; }
/* prepare the source pad for output */ static gboolean mpegpsdemux_prepare_srcpad (MpegPsMux * mux) { GstSegment segment; GValue val = { 0, }; GList *headers, *l; GstCaps *caps; caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, TRUE, NULL); headers = psmux_get_stream_headers (mux->psmux); g_value_init (&val, GST_TYPE_ARRAY); for (l = headers; l != NULL; l = l->next) { GValue buf_val = { 0, }; g_value_init (&buf_val, GST_TYPE_BUFFER); gst_value_take_buffer (&buf_val, GST_BUFFER (l->data)); l->data = NULL; gst_value_array_append_value (&val, &buf_val); g_value_unset (&buf_val); } gst_caps_set_value (caps, "streamheader", &val); g_value_unset (&val); g_list_free (headers); /* Set caps on src pad and push new segment */ gst_pad_push_event (mux->srcpad, gst_event_new_caps (caps)); gst_caps_unref (caps); gst_segment_init (&segment, GST_FORMAT_BYTES); gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment)); return TRUE; }
/** * @param formats - GstCaps from which the format and name shall be used * @param rest - GstCaps from which the rest i.e. width,height,framerate, shall be used, is_fixed has to be true * @return GstCaps containing merged caps, user takes ownership */ GstCaps* create_caps_for_formats (GstCaps* formats, GstCaps* rest) { if (!gst_caps_is_fixed(rest)) { return nullptr; } auto st = gst_caps_get_structure(rest, 0); auto width = gst_structure_get_value(st, "width"); auto height = gst_structure_get_value(st, "height"); auto framerate = gst_structure_get_value(st, "framerate"); auto caps_formats = index_caps_formats(formats); if (caps_formats.empty()) { tcam_error("Could not identify formats for caps creation"); return nullptr; } GstCaps* ret = gst_caps_new_empty(); for (const auto& fmt : caps_formats) { GstCaps* tmp = gst_caps_from_string(fmt.c_str()); if (width) { gst_caps_set_value(tmp, "width", width); } if (height) { gst_caps_set_value(tmp, "height", height); } if (framerate) { gst_caps_set_value(tmp, "framerate", framerate); } tcam_info("%s", gst_caps_to_string(tmp)); gst_caps_append(ret, tmp); } return ret; }
static GstElement * ges_multi_file_source_create_source (GESTrackElement * track_element) { GESMultiFileSource *self; GstElement *bin, *src, *decodebin; GstCaps *disc_caps; GstDiscovererStreamInfo *stream_info; GValue fps = G_VALUE_INIT; GstCaps *caps; GESUriSourceAsset *asset; GESMultiFileURI *uri_data; self = (GESMultiFileSource *) track_element; asset = GES_URI_SOURCE_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE (self))); if (asset != NULL) { stream_info = ges_uri_source_asset_get_stream_info (asset); g_assert (stream_info); disc_caps = gst_discoverer_stream_info_get_caps (stream_info); caps = gst_caps_copy (disc_caps); GST_DEBUG ("Got some nice caps %s", gst_caps_to_string (disc_caps)); gst_object_unref (stream_info); gst_caps_unref (disc_caps); } else { caps = gst_caps_new_empty (); GST_WARNING ("Could not extract asset."); } g_value_init (&fps, GST_TYPE_FRACTION); gst_value_set_fraction (&fps, 25, 1); gst_caps_set_value (caps, "framerate", &fps); bin = GST_ELEMENT (gst_bin_new ("multi-image-bin")); src = gst_element_factory_make ("multifilesrc", NULL); uri_data = ges_multi_file_uri_new (self->uri); g_object_set (src, "start-index", uri_data->start, "stop-index", uri_data->end, "caps", caps, "location", uri_data->location, NULL); g_free (uri_data); decodebin = gst_element_factory_make ("decodebin", NULL); gst_bin_add_many (GST_BIN (bin), src, decodebin, NULL); gst_element_link_pads_full (src, "src", decodebin, "sink", GST_PAD_LINK_CHECK_NOTHING); g_signal_connect (G_OBJECT (decodebin), "pad-added", G_CALLBACK (pad_added_cb), bin); return bin; }
static GstCaps * _caps_intersect_texture_target (GstCaps * caps, GstGLTextureTarget target_mask) { GValue targets = G_VALUE_INIT; GstCaps *ret, *target; target = gst_caps_copy (caps); gst_gl_value_set_texture_target_from_mask (&targets, target_mask); gst_caps_set_value (target, "texture-target", &targets); ret = gst_caps_intersect_full (caps, target, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (target); return ret; }
static gboolean gst_ffmpegdeinterlace_sink_setcaps (GstPad * pad, GstCaps * caps) { GstFFMpegDeinterlace *deinterlace = GST_FFMPEGDEINTERLACE (gst_pad_get_parent (pad)); GstStructure *structure = gst_caps_get_structure (caps, 0); AVCodecContext *ctx; GValue interlaced = { 0 }; GstCaps *srcCaps; GstFlowReturn ret; if (!gst_structure_get_int (structure, "width", &deinterlace->width)) return FALSE; if (!gst_structure_get_int (structure, "height", &deinterlace->height)) return FALSE; ctx = avcodec_alloc_context (); ctx->width = deinterlace->width; ctx->height = deinterlace->height; ctx->pix_fmt = PIX_FMT_NB; gst_ffmpeg_caps_with_codectype (CODEC_TYPE_VIDEO, caps, ctx); if (ctx->pix_fmt == PIX_FMT_NB) { av_free (ctx); return FALSE; } deinterlace->pixfmt = ctx->pix_fmt; av_free (ctx); deinterlace->to_size = avpicture_get_size (deinterlace->pixfmt, deinterlace->width, deinterlace->height); srcCaps = gst_caps_copy (caps); g_value_init (&interlaced, G_TYPE_BOOLEAN); g_value_set_boolean (&interlaced, FALSE); gst_caps_set_value (srcCaps, "interlaced", &interlaced); g_value_unset (&interlaced); ret = gst_pad_set_caps (deinterlace->srcpad, srcCaps); gst_caps_unref (srcCaps); return ret; }
static gboolean mpegpsdemux_prepare_srcpad (MpegPsMux * mux) { GValue val = { 0, }; GList *headers, *l; /* prepare the source pad for output */ GstEvent *new_seg = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0); GstCaps *caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 2, "systemstream", G_TYPE_BOOLEAN, TRUE, NULL); /* gst_static_pad_template_get_caps (&mpegpsmux_src_factory); */ headers = psmux_get_stream_headers (mux->psmux); g_value_init (&val, GST_TYPE_ARRAY); for (l = headers; l != NULL; l = l->next) { GValue buf_val = { 0, }; g_value_init (&buf_val, GST_TYPE_BUFFER); gst_value_take_buffer (&buf_val, GST_BUFFER (l->data)); l->data = NULL; gst_value_array_append_value (&val, &buf_val); g_value_unset (&buf_val); } gst_caps_set_value (caps, "streamheader", &val); g_value_unset (&val); g_list_free (headers); /* Set caps on src pad from our template and push new segment */ gst_pad_set_caps (mux->srcpad, caps); if (!gst_pad_push_event (mux->srcpad, new_seg)) { GST_WARNING_OBJECT (mux, "New segment event was not handled"); return FALSE; } return TRUE; }
GstCaps * gst_vaapi_video_format_new_template_caps_from_list (GArray * formats) { GValue v_formats = G_VALUE_INIT; GstCaps *caps; caps = gst_caps_new_empty_simple ("video/x-raw"); if (!caps) return NULL; if (!gst_vaapi_value_set_format_list (&v_formats, formats)) { gst_caps_unref (caps); return NULL; } gst_caps_set_value (caps, "format", &v_formats); set_video_template_caps (caps); g_value_unset (&v_formats); return caps; }
static GstCaps * stereosplit_get_src_caps (GstGLStereoSplit * split, GstPad * pad, GstVideoMultiviewMode preferred_mode) { GstCaps *outcaps, *tmp, *templ_caps; GValue item = G_VALUE_INIT, list = G_VALUE_INIT; /* Get the template format */ templ_caps = gst_pad_get_pad_template_caps (pad); /* And limit down to the preferred mode or mono */ templ_caps = gst_caps_make_writable (templ_caps); g_value_init (&item, G_TYPE_STRING); g_value_init (&list, GST_TYPE_LIST); g_value_set_static_string (&item, gst_video_multiview_mode_to_caps_string (preferred_mode)); gst_value_list_append_value (&list, &item); g_value_set_static_string (&item, gst_video_multiview_mode_to_caps_string (GST_VIDEO_MULTIVIEW_MODE_MONO)); gst_value_list_append_value (&list, &item); gst_caps_set_value (templ_caps, "multiview-mode", &list); g_value_unset (&list); g_value_unset (&item); /* And intersect with the peer */ if ((tmp = gst_pad_peer_query_caps (pad, NULL)) == NULL) { gst_caps_unref (templ_caps); return NULL; } outcaps = gst_caps_intersect_full (tmp, templ_caps, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (tmp); gst_caps_unref (templ_caps); GST_DEBUG_OBJECT (split, "Src pad %" GST_PTR_FORMAT " caps %" GST_PTR_FORMAT, pad, outcaps); return outcaps; }
static GstCaps * gst_audio_parse_get_caps (GstRawParse * rp) { GstAudioParse *ap = GST_AUDIO_PARSE (rp); GstCaps *caps, *ncaps; GstAudioInfo info; gint fps_n, fps_d; const GValue *val; if (ap->use_sink_caps) { gint rate; GstCaps *caps = gst_pad_get_current_caps (rp->sinkpad); gst_audio_info_from_caps (&info, caps); rate = GST_AUDIO_INFO_RATE (&info); gst_raw_parse_set_fps (GST_RAW_PARSE (ap), rate, 1); return caps; } gst_raw_parse_get_fps (rp, &fps_n, &fps_d); gst_audio_parse_setup_channel_positions (ap); /* yes, even when format not raw */ gst_audio_info_init (&info); gst_audio_info_set_format (&info, ap->raw_format, fps_n, ap->channels, ap->channel_order); info.layout = ap->interleaved ? GST_AUDIO_LAYOUT_INTERLEAVED : GST_AUDIO_LAYOUT_NON_INTERLEAVED; caps = gst_audio_info_to_caps (&info); switch (ap->format) { case GST_AUDIO_PARSE_FORMAT_RAW: break; case GST_AUDIO_PARSE_FORMAT_ALAW: ncaps = gst_caps_new_simple ("audio/x-alaw", "rate", G_TYPE_INT, fps_n, "channels", G_TYPE_INT, ap->channels, NULL); /* pick mask stuff from faked raw format */ val = gst_structure_get_value (gst_caps_get_structure (caps, 0), "channel-mask"); if (val) gst_caps_set_value (ncaps, "channel-mask", val); gst_caps_unref (caps); caps = ncaps; break; case GST_AUDIO_PARSE_FORMAT_MULAW: ncaps = gst_caps_new_simple ("audio/x-mulaw", "rate", G_TYPE_INT, fps_n, "channels", G_TYPE_INT, ap->channels, NULL); /* pick mask stuff from faked raw format */ val = gst_structure_get_value (gst_caps_get_structure (caps, 0), "channel-mask"); if (val) gst_caps_set_value (ncaps, "channel-mask", val); gst_caps_unref (caps); caps = ncaps; break; default: caps = gst_caps_new_empty (); GST_ERROR_OBJECT (rp, "unexpected format %d", ap->format); break; } return caps; }
static GstCaps * gst_tinyalsa_sink_getcaps (GstBaseSink * bsink, GstCaps * filter) { GstTinyalsaSink *sink = GST_TINYALSA_SINK (bsink); GstCaps *caps = NULL; GValue formats = { 0, }; GValue format = { 0, }; struct pcm_params *params = NULL; struct pcm_mask *mask; int rate_min, rate_max, channels_min, channels_max; guint16 m; GST_DEBUG_OBJECT (sink, "Querying caps"); GST_OBJECT_LOCK (sink); if (sink->cached_caps) { GST_DEBUG_OBJECT (sink, "Returning cached caps"); caps = gst_caps_ref (sink->cached_caps); goto done; } if (sink->pcm) { /* We can't query the device while it's open, so return current caps */ caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (bsink)); goto done; } params = pcm_params_get (sink->card, sink->device, PCM_OUT); if (!params) { GST_ERROR_OBJECT (sink, "Could not get PCM params"); goto done; } mask = pcm_params_get_mask (params, PCM_PARAM_FORMAT); m = (mask->bits[1] << 8) | mask->bits[0]; if (!(m & SNDRV_PCM_FORMAT_ANY)) { GST_ERROR_OBJECT (sink, "Could not find any supported format"); goto done; } caps = gst_caps_new_empty_simple ("audio/x-raw"); g_value_init (&formats, GST_TYPE_LIST); g_value_init (&format, G_TYPE_STRING); if (m & (1 << SNDRV_PCM_FORMAT_S8)) { g_value_set_static_string (&format, "S8"); gst_value_list_prepend_value (&formats, &format); } if (m & (1 << SNDRV_PCM_FORMAT_S16_LE)) { g_value_set_static_string (&format, "S16LE"); gst_value_list_prepend_value (&formats, &format); } if (m & (1 << SNDRV_PCM_FORMAT_S24_LE)) { g_value_set_static_string (&format, "S24_32LE"); gst_value_list_prepend_value (&formats, &format); } if (m & (1 << SNDRV_PCM_FORMAT_S32_LE)) { g_value_set_static_string (&format, "S32LE"); gst_value_list_prepend_value (&formats, &format); } gst_caps_set_value (caps, "format", &formats); g_value_unset (&format); g_value_unset (&formats); /* This is a bit of a lie, since the device likely only supports some * standard rates in this range. We should probably filter the range to * those, standard audio rates but even that isn't guaranteed to be accurate. */ rate_min = pcm_params_get_min (params, PCM_PARAM_RATE); rate_max = pcm_params_get_max (params, PCM_PARAM_RATE); if (rate_min == rate_max) gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate_min, NULL); else gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, rate_min, rate_max, NULL); channels_min = pcm_params_get_min (params, PCM_PARAM_CHANNELS); channels_max = pcm_params_get_max (params, PCM_PARAM_CHANNELS); if (channels_min == channels_max) gst_caps_set_simple (caps, "channels", G_TYPE_INT, channels_min, NULL); else gst_caps_set_simple (caps, "channels", GST_TYPE_INT_RANGE, channels_min, channels_max, NULL); gst_caps_replace (&sink->cached_caps, caps); done: GST_OBJECT_UNLOCK (sink); GST_DEBUG_OBJECT (sink, "Got caps %" GST_PTR_FORMAT, caps); if (caps && filter) { GstCaps *intersection = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (caps); caps = intersection; } if (params) pcm_params_free (params); return caps; }
void Caps::setValue(const char *field, const QGlib::Value & value) { gst_caps_set_value(object<GstCaps>(), field, value); }
GstCaps* tcam_gst_find_largest_caps (const GstCaps* incoming) { /** * find_largest_caps tries to find the largest caps * according to the following rules: * * 1. determine the preferred format * prefer bayer 8-bit over everything else * if bayer 8-bit does not exist order according to the following list: * color formats like BGR * formats like MJPEG * GRAY16 * GRAY8 * bayer12/16 * * 2. find the largest resolution * 3. for the format with the largest resolution take the highest framerate */ std::vector<uint32_t> format_fourccs = index_format_fourccs(incoming); uint32_t preferred_fourcc = find_preferred_format(format_fourccs); if(!g_strcmp0(gst_caps_to_string(incoming), "EMPTY")) { return nullptr; } int largest_index = -1; int largest_width = -1; int largest_height = -1; for (guint i = 0; i < gst_caps_get_size(incoming); ++i) { GstStructure* struc = gst_caps_get_structure(incoming, i); const char* format = gst_structure_get_string(struc, "format"); uint32_t fourcc = tcam_fourcc_from_gst_1_0_caps_string(gst_structure_get_name(struc), format); // TODO: what about video/x-raw, format={GRAY8, GRAY16_LE} if (fourcc != preferred_fourcc) { continue; } int width = -1; int height = -1; bool new_width = false; bool new_height = false; // will fail if width is a range so we only handle // halfway fixated caps if (gst_structure_get_int(struc, "width", &width)) { if (largest_width <= width) { largest_width = width; new_width = true; } } else { tcam_warning("Field 'width' does not have the type 'int'"); } if (gst_structure_get_int(struc, "height", &height)) { if (largest_height <= height) { largest_height = height; new_height = true; } } else { tcam_warning("Field 'height' does not have the type 'int'"); } if (new_width && new_height) { largest_index = i; } } GstCaps* largest_caps = gst_caps_copy_nth(incoming, largest_index); tcam_info("Fixating assumed largest caps: %s", gst_caps_to_string(largest_caps)); if (!tcam_gst_fixate_caps(largest_caps)) { tcam_error("Cannot fixate largest caps. Returning NULL"); return nullptr; } GstStructure* s = gst_caps_get_structure(largest_caps, 0); int h; gst_structure_get_int(s, "height", &h); int w; gst_structure_get_int(s, "width", &w); int num; int den; gst_structure_get_fraction(s, "framerate", &num, &den); GValue vh = G_VALUE_INIT; g_value_init(&vh, G_TYPE_INT); g_value_set_int(&vh, h); gst_caps_set_value(largest_caps, "height", &vh); largest_caps = gst_caps_new_simple (gst_structure_get_name(s), "framerate", GST_TYPE_FRACTION, num, den, "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL); if (gst_structure_has_field(s, "format")) { gst_caps_set_value(largest_caps, "format", gst_structure_get_value(s, "format")); } return largest_caps; }