/****************************************************************************** * gst_tiaudenc1_init * Initializes a new element instance, instantiates pads and sets the pad * callback functions. ******************************************************************************/ static void gst_tiaudenc1_init(GstTIAudenc1 *audenc1, GstTIAudenc1Class *gclass) { /* Instantiate RAW audio sink pad. * * Fixate on our static template caps instead of writing a getcaps * function, which is overkill for this element. */ audenc1->sinkpad = gst_pad_new_from_static_template(&sink_factory, "sink"); gst_pad_set_setcaps_function( audenc1->sinkpad, GST_DEBUG_FUNCPTR(gst_tiaudenc1_set_sink_caps)); gst_pad_set_event_function( audenc1->sinkpad, GST_DEBUG_FUNCPTR(gst_tiaudenc1_sink_event)); gst_pad_set_chain_function( audenc1->sinkpad, GST_DEBUG_FUNCPTR(gst_tiaudenc1_chain)); gst_pad_fixate_caps(audenc1->sinkpad, gst_caps_make_writable( gst_caps_copy(gst_pad_get_pad_template_caps(audenc1->sinkpad)))); /* Instantiate encoded audio source pad. * * Fixate on our static template caps instead of writing a getcaps * function, which is overkill for this element. */ audenc1->srcpad = gst_pad_new_from_static_template(&src_factory, "src"); gst_pad_fixate_caps(audenc1->srcpad, gst_caps_make_writable( gst_caps_copy(gst_pad_get_pad_template_caps(audenc1->srcpad)))); /* Add pads to TIAudenc1 element */ gst_element_add_pad(GST_ELEMENT(audenc1), audenc1->sinkpad); gst_element_add_pad(GST_ELEMENT(audenc1), audenc1->srcpad); /* Initialize TIAudenc1 state */ g_object_set(audenc1, "engineName", DEFAULT_ENGINE_NAME, (gchar*)NULL); audenc1->displayBuffer = DEFAULT_DISPLAY_BUFFER; audenc1->genTimeStamps = DEFAULT_GENTIMESTAMPS; audenc1->codecName = NULL; audenc1->hEngine = NULL; audenc1->hAe = NULL; audenc1->channels = DEFAULT_NUM_CHANNELES; audenc1->bitrate = DEFAULT_BITRATE; audenc1->samplefreq = DEFAULT_SAMPLEFREQ; audenc1->drainingEOS = FALSE; audenc1->threadStatus = 0UL; audenc1->waitOnEncodeThread = NULL; audenc1->waitOnEncodeDrain = NULL; audenc1->numOutputBufs = DEFAULT_NUMOUTPUT_BUFS; audenc1->hOutBufTab = NULL; audenc1->circBuf = NULL; gst_tiaudenc1_init_env(audenc1); }
static void gst_proxy_pad_do_fixatecaps (GstPad * pad, GstCaps * caps) { GstPad *target = gst_proxy_pad_get_target (pad); if (target) { gst_pad_fixate_caps (target, caps); gst_object_unref (target); } }
static GstFlowReturn gst_vdp_vpp_sink_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf) { GstVdpVideoPostProcess *vpp = GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad)); GstVdpOutputBuffer *outbuf; GstFlowReturn ret = GST_FLOW_ERROR; GstVdpDevice *device = NULL; GstStructure *structure; gint width, height; gint chroma_type; if (!vpp->device) { /* if we haven't got a device yet we must alloc a buffer downstream to get it */ GstCaps *src_caps = gst_pad_get_allowed_caps (vpp->srcpad); gst_pad_fixate_caps (vpp->srcpad, src_caps); ret = gst_pad_alloc_buffer (vpp->srcpad, 0, 0, src_caps, (GstBuffer **) & outbuf); gst_caps_unref (src_caps); if (ret != GST_FLOW_OK) goto error; device = outbuf->device; gst_buffer_unref (GST_BUFFER (outbuf)); } else device = vpp->device; structure = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (structure, "width", &width) || !gst_structure_get_int (structure, "height", &height) || !gst_structure_get_int (structure, "chroma-type", &chroma_type)) goto error; *buf = GST_BUFFER (gst_vdp_video_buffer_new (device, chroma_type, width, height)); if (*buf == NULL) goto error; GST_BUFFER_SIZE (*buf) = size; GST_BUFFER_OFFSET (*buf) = offset; gst_buffer_set_caps (*buf, caps); ret = GST_FLOW_OK; error: gst_object_unref (vpp); return ret; }
static gboolean sink_setcaps (GstPad * pad, GstCaps * caps) { GstStructure *structure; GstOmxBaseFilter *omx_base; GOmxCore *gomx; gint rate = 0; omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad)); gomx = (GOmxCore *) omx_base->gomx; GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "rate", &rate); /* Input port configuration. */ { OMX_AUDIO_PARAM_PCMMODETYPE param; G_OMX_INIT_PARAM (param); param.nPortIndex = omx_base->out_port->port_index; OMX_GetParameter (gomx->omx_handle, OMX_IndexParamAudioPcm, ¶m); param.nSamplingRate = rate; OMX_SetParameter (gomx->omx_handle, OMX_IndexParamAudioPcm, ¶m); } /* set caps on the srcpad */ { GstCaps *tmp_caps; tmp_caps = gst_pad_get_allowed_caps (omx_base->srcpad); tmp_caps = gst_caps_make_writable (tmp_caps); gst_caps_truncate (tmp_caps); gst_pad_fixate_caps (omx_base->srcpad, tmp_caps); if (gst_caps_is_fixed (tmp_caps)) { GST_INFO_OBJECT (omx_base, "fixated to: %" GST_PTR_FORMAT, tmp_caps); gst_pad_set_caps (omx_base->srcpad, tmp_caps); } gst_caps_unref (tmp_caps); } return gst_pad_set_caps (pad, caps); }
gboolean gst_base_video_decoder_set_src_caps (GstBaseVideoDecoder * base_video_decoder) { GstCaps *caps; GstVideoState *state = &base_video_decoder->state; if (base_video_decoder->have_src_caps) return TRUE; caps = gst_pad_get_allowed_caps (base_video_decoder->srcpad); if (!caps) goto null_allowed_caps; if (gst_caps_is_empty (caps)) goto empty_allowed_caps; gst_caps_set_simple (caps, "width", G_TYPE_INT, state->width, "height", G_TYPE_INT, state->height, "pixel-aspect-ratio", GST_TYPE_FRACTION, state->par_n, state->par_d, "interlaced", G_TYPE_BOOLEAN, state->interlaced, NULL); if (state->fps_d != 0) gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, state->fps_n, state->fps_d, NULL); gst_pad_fixate_caps (base_video_decoder->srcpad, caps); GST_DEBUG ("setting caps %" GST_PTR_FORMAT, caps); base_video_decoder->have_src_caps = gst_pad_set_caps (GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder), caps); gst_caps_unref (caps); return base_video_decoder->have_src_caps; null_allowed_caps: GST_ERROR_OBJECT (base_video_decoder, "Got null from gst_pad_get_allowed_caps"); return FALSE; empty_allowed_caps: GST_ERROR_OBJECT (base_video_decoder, "Got EMPTY caps from gst_pad_get_allowed_caps"); gst_caps_unref (caps); return FALSE; }
static gboolean start_image_capture (GstWrapperCameraBinSrc * self) { GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self); GstPhotography *photography = gst_base_camera_src_get_photography (bcamsrc); gboolean ret = FALSE; GstCaps *caps; GST_DEBUG_OBJECT (self, "Starting image capture"); if (self->image_renegotiate) { /* clean capsfilter caps so they don't interfere here */ g_object_set (self->src_filter, "caps", NULL, NULL); if (self->src_zoom_filter) g_object_set (self->src_zoom_filter, "caps", NULL, NULL); caps = gst_pad_get_allowed_caps (self->imgsrc); caps = gst_caps_make_writable (caps); gst_pad_fixate_caps (self->imgsrc, caps); gst_caps_replace (&self->image_capture_caps, caps); gst_caps_unref (caps); self->image_renegotiate = FALSE; } if (photography) { GST_DEBUG_OBJECT (self, "prepare image capture caps %" GST_PTR_FORMAT, self->image_capture_caps); ret = gst_photography_prepare_for_capture (photography, (GstPhotoCapturePrepared) img_capture_prepared, self->image_capture_caps, self); } else { g_mutex_unlock (bcamsrc->capturing_mutex); gst_wrapper_camera_bin_reset_video_src_caps (self, self->image_capture_caps); g_mutex_lock (bcamsrc->capturing_mutex); ret = TRUE; } return ret; }
static gboolean gst_wrapper_camera_bin_src_start_capture (GstBaseCameraSrc * camerasrc) { GstWrapperCameraBinSrc *src = GST_WRAPPER_CAMERA_BIN_SRC (camerasrc); /* TODO should we access this directly? Maybe a macro is better? */ if (src->mode == MODE_IMAGE) { start_image_capture (src); src->image_capture_count = 1; } else if (src->mode == MODE_VIDEO) { GstCaps *caps = NULL; g_mutex_unlock (camerasrc->capturing_mutex); gst_wrapper_camera_bin_reset_video_src_caps (src, NULL); g_mutex_lock (camerasrc->capturing_mutex); if (src->video_renegotiate) { /* clean capsfilter caps so they don't interfere here */ g_object_set (src->src_filter, "caps", NULL, NULL); if (src->src_zoom_filter) g_object_set (src->src_zoom_filter, "caps", NULL, NULL); caps = gst_pad_get_allowed_caps (src->vidsrc); caps = gst_caps_make_writable (caps); gst_pad_fixate_caps (src->vidsrc, caps); GST_DEBUG_OBJECT (src, "Vidsrc caps fixated to %" GST_PTR_FORMAT, caps); src->video_renegotiate = FALSE; g_mutex_unlock (camerasrc->capturing_mutex); gst_wrapper_camera_bin_reset_video_src_caps (src, caps); g_mutex_lock (camerasrc->capturing_mutex); gst_caps_unref (caps); } if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) { src->video_rec_status = GST_VIDEO_RECORDING_STATUS_STARTING; } } else { g_assert_not_reached (); return FALSE; } return TRUE; }
static gboolean gst_v4l2src_negotiate (GstBaseSrc * basesrc) { GstCaps *thiscaps; GstCaps *caps = NULL; GstCaps *peercaps = NULL; gboolean result = FALSE; /* first see what is possible on our source pad */ thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc)); GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps); LOG_CAPS (basesrc, thiscaps); /* nothing or anything is allowed, we're done */ if (thiscaps == NULL || gst_caps_is_any (thiscaps)) goto no_nego_needed; /* get the peer caps */ peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc)); GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps); LOG_CAPS (basesrc, peercaps); if (peercaps && !gst_caps_is_any (peercaps)) { GstCaps *icaps = NULL; int i; /* Prefer the first caps we are compatible with that the peer proposed */ for (i = 0; i < gst_caps_get_size (peercaps); i++) { /* get intersection */ GstCaps *ipcaps = gst_caps_copy_nth (peercaps, i); GST_DEBUG_OBJECT (basesrc, "peer: %" GST_PTR_FORMAT, ipcaps); LOG_CAPS (basesrc, ipcaps); icaps = gst_caps_intersect (thiscaps, ipcaps); gst_caps_unref (ipcaps); if (!gst_caps_is_empty (icaps)) break; gst_caps_unref (icaps); icaps = NULL; } GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps); LOG_CAPS (basesrc, icaps); if (icaps) { /* If there are multiple intersections pick the one with the smallest * resolution strictly bigger then the first peer caps */ if (gst_caps_get_size (icaps) > 1) { GstStructure *s = gst_caps_get_structure (peercaps, 0); int best = 0; int twidth, theight; int width = G_MAXINT, height = G_MAXINT; if (gst_structure_get_int (s, "width", &twidth) && gst_structure_get_int (s, "height", &theight)) { /* Walk the structure backwards to get the first entry of the * smallest resolution bigger (or equal to) the preferred resolution) */ for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) { GstStructure *is = gst_caps_get_structure (icaps, i); int w, h; if (gst_structure_get_int (is, "width", &w) && gst_structure_get_int (is, "height", &h)) { if (w >= twidth && w <= width && h >= theight && h <= height) { width = w; height = h; best = i; } } } } caps = gst_caps_copy_nth (icaps, best); gst_caps_unref (icaps); } else { caps = icaps; } } gst_caps_unref (thiscaps); gst_caps_unref (peercaps); } else { /* no peer or peer have ANY caps, work with our own caps then */ caps = thiscaps; } if (caps) { caps = gst_caps_make_writable (caps); gst_caps_truncate (caps); /* now fixate */ if (!gst_caps_is_empty (caps)) { gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps); GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps); LOG_CAPS (basesrc, caps); if (gst_caps_is_any (caps)) { /* hmm, still anything, so element can do anything and * nego is not needed */ result = TRUE; } else if (gst_caps_is_fixed (caps)) { /* yay, fixed caps, use those then */ if (gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps)) result = TRUE; } } gst_caps_unref (caps); } return result; no_nego_needed: { GST_DEBUG_OBJECT (basesrc, "no negotiation needed"); if (thiscaps) gst_caps_unref (thiscaps); return TRUE; } }
static GstFlowReturn gst_jasper_dec_negotiate (GstJasperDec * dec, jas_image_t * image) { GstFlowReturn flow_ret = GST_FLOW_OK; gint width, height, channels; gint i, j; gboolean negotiate = FALSE; jas_clrspc_t clrspc; GstCaps *allowed_caps, *caps; width = jas_image_width (image); height = jas_image_height (image); channels = jas_image_numcmpts (image); GST_LOG_OBJECT (dec, "%d x %d, %d components", width, height, channels); /* jp2c bitstream has no real colour space info (kept in container), * so decoder may only pretend to know, where it really does not */ if (!jas_clrspc_isunknown (dec->clrspc)) { clrspc = dec->clrspc; GST_DEBUG_OBJECT (dec, "forcing container supplied colour space %d", clrspc); jas_image_setclrspc (image, clrspc); } else clrspc = jas_image_clrspc (image); if (!width || !height || !channels || jas_clrspc_isunknown (clrspc)) goto fail_image; if (dec->width != width || dec->height != height || dec->channels != channels || dec->clrspc != clrspc) negotiate = TRUE; if (channels != 3) goto not_supported; for (i = 0; i < channels; i++) { gint cheight, cwidth, depth, sgnd; cheight = jas_image_cmptheight (image, i); cwidth = jas_image_cmptwidth (image, i); depth = jas_image_cmptprec (image, i); sgnd = jas_image_cmptsgnd (image, i); GST_LOG_OBJECT (dec, "image component %d, %dx%d, depth %d, sgnd %d", i, cwidth, cheight, depth, sgnd); if (depth != 8 || sgnd) goto not_supported; if (dec->cheight[i] != cheight || dec->cwidth[i] != cwidth) { dec->cheight[i] = cheight; dec->cwidth[i] = cwidth; negotiate = TRUE; } } if (!negotiate && dec->format != GST_VIDEO_FORMAT_UNKNOWN) goto done; /* clear and refresh to new state */ flow_ret = GST_FLOW_NOT_NEGOTIATED; dec->format = GST_VIDEO_FORMAT_UNKNOWN; dec->width = width; dec->height = height; dec->channels = channels; /* retrieve allowed caps, and find the first one that reasonably maps * to the parameters of the colourspace */ caps = gst_pad_get_allowed_caps (dec->srcpad); if (!caps) { GST_DEBUG_OBJECT (dec, "... but no peer, using template caps"); /* need to copy because get_allowed_caps returns a ref, and get_pad_template_caps doesn't */ caps = gst_caps_copy (gst_pad_get_pad_template_caps (dec->srcpad)); } /* avoid lists of fourcc, etc */ allowed_caps = gst_caps_normalize (caps); caps = NULL; GST_LOG_OBJECT (dec, "allowed source caps %" GST_PTR_FORMAT, allowed_caps); for (i = 0; i < gst_caps_get_size (allowed_caps); i++) { GstVideoFormat format; gboolean ok; if (caps) gst_caps_unref (caps); caps = gst_caps_copy_nth (allowed_caps, i); /* sigh, ds and _parse_caps need fixed caps for parsing, fixate */ gst_pad_fixate_caps (dec->srcpad, caps); GST_LOG_OBJECT (dec, "checking caps %" GST_PTR_FORMAT, caps); if (!gst_video_format_parse_caps (caps, &format, NULL, NULL)) continue; if (gst_video_format_is_rgb (format) && jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_RGB) { GST_DEBUG_OBJECT (dec, "trying RGB"); if ((dec->cmpt[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_R))) < 0 || (dec->cmpt[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_G))) < 0 || (dec->cmpt[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_RGB_B))) < 0) { GST_DEBUG_OBJECT (dec, "missing RGB color component"); continue; } } else if (gst_video_format_is_yuv (format) && jas_clrspc_fam (clrspc) == JAS_CLRSPC_FAM_YCBCR) { GST_DEBUG_OBJECT (dec, "trying YUV"); if ((dec->cmpt[0] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_Y))) < 0 || (dec->cmpt[1] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CB))) < 0 || (dec->cmpt[2] = jas_image_getcmptbytype (image, JAS_IMAGE_CT_COLOR (JAS_CLRSPC_CHANIND_YCBCR_CR))) < 0) { GST_DEBUG_OBJECT (dec, "missing YUV color component"); continue; } } else continue; /* match format with validity checks */ ok = TRUE; for (j = 0; j < channels; j++) { gint cmpt; cmpt = dec->cmpt[j]; if (dec->cwidth[cmpt] != gst_video_format_get_component_width (format, j, width) || dec->cheight[cmpt] != gst_video_format_get_component_height (format, j, height)) ok = FALSE; } /* commit to this format */ if (ok) { dec->format = format; break; } } if (caps) gst_caps_unref (caps); gst_caps_unref (allowed_caps); if (dec->format != GST_VIDEO_FORMAT_UNKNOWN) { /* cache some video format properties */ for (j = 0; j < channels; ++j) { dec->offset[j] = gst_video_format_get_component_offset (dec->format, j, dec->width, dec->height); dec->inc[j] = gst_video_format_get_pixel_stride (dec->format, j); dec->stride[j] = gst_video_format_get_row_stride (dec->format, j, dec->width); } dec->image_size = gst_video_format_get_size (dec->format, width, height); dec->alpha = gst_video_format_has_alpha (dec->format); if (dec->buf) g_free (dec->buf); dec->buf = g_new0 (glong, dec->width); caps = gst_video_format_new_caps (dec->format, dec->width, dec->height, dec->framerate_numerator, dec->framerate_denominator, 1, 1); GST_DEBUG_OBJECT (dec, "Set format to %d, size to %dx%d", dec->format, dec->width, dec->height); if (!gst_pad_set_caps (dec->srcpad, caps)) flow_ret = GST_FLOW_NOT_NEGOTIATED; else flow_ret = GST_FLOW_OK; gst_caps_unref (caps); } done: return flow_ret; /* ERRORS */ fail_image: { GST_DEBUG_OBJECT (dec, "Failed to process decoded image."); flow_ret = GST_FLOW_NOT_NEGOTIATED; goto done; } not_supported: { GST_DEBUG_OBJECT (dec, "Decoded image has unsupported colour space."); GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Unsupported colorspace")); flow_ret = GST_FLOW_ERROR; goto done; } }
static gboolean gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps) { GstVdpVideoPostProcess *vpp = GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad)); GstStructure *structure; GstCaps *video_caps = NULL; gboolean res = FALSE; GstCaps *allowed_caps, *output_caps, *src_caps; /* check if the input is non native */ structure = gst_caps_get_structure (caps, 0); if (gst_structure_has_name (structure, "video/x-raw-yuv")) { if (!gst_structure_get_fourcc (structure, "format", &vpp->fourcc)) goto done; vpp->native_input = FALSE; video_caps = gst_vdp_yuv_to_video_caps (caps); if (!video_caps) goto done; if (!vpp->vpool) vpp->vpool = gst_vdp_video_buffer_pool_new (vpp->device); gst_vdp_buffer_pool_set_caps (vpp->vpool, video_caps); } else { vpp->native_input = TRUE; video_caps = gst_caps_ref (caps); if (vpp->vpool) { g_object_unref (vpp->vpool); vpp->vpool = NULL; } } structure = gst_caps_get_structure (video_caps, 0); if (!gst_structure_get_int (structure, "width", &vpp->width) || !gst_structure_get_int (structure, "height", &vpp->height) || !gst_structure_get_int (structure, "chroma-type", (gint *) & vpp->chroma_type)) goto done; /* get interlaced flag */ gst_structure_get_boolean (structure, "interlaced", &vpp->interlaced); /* extract par */ if (gst_structure_has_field_typed (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION)) { gst_structure_get_fraction (structure, "pixel-aspect-ratio", &vpp->par_n, &vpp->par_d); vpp->got_par = TRUE; } else vpp->got_par = FALSE; allowed_caps = gst_pad_get_allowed_caps (vpp->srcpad); if (G_UNLIKELY (!allowed_caps)) goto null_allowed_caps; if (G_UNLIKELY (gst_caps_is_empty (allowed_caps))) goto empty_allowed_caps; GST_DEBUG ("allowed_caps: %" GST_PTR_FORMAT, allowed_caps); output_caps = gst_vdp_video_to_output_caps (video_caps); src_caps = gst_caps_intersect (output_caps, allowed_caps); gst_caps_unref (allowed_caps); gst_caps_unref (output_caps); if (gst_caps_is_empty (src_caps)) goto not_negotiated; gst_pad_fixate_caps (vpp->srcpad, src_caps); if (gst_vdp_vpp_is_interlaced (vpp)) { gint fps_n, fps_d; if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) { gst_fraction_double (&fps_n, &fps_d); gst_caps_set_simple (src_caps, "framerate", GST_TYPE_FRACTION, fps_n, fps_d, NULL); vpp->field_duration = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n); } gst_caps_set_simple (src_caps, "interlaced", G_TYPE_BOOLEAN, FALSE, NULL); } GST_DEBUG ("src_caps: %" GST_PTR_FORMAT, src_caps); res = gst_pad_set_caps (vpp->srcpad, src_caps); gst_caps_unref (src_caps); done: gst_object_unref (vpp); if (video_caps) gst_caps_unref (video_caps); return res; null_allowed_caps: GST_ERROR_OBJECT (vpp, "Got null from gst_pad_get_allowed_caps"); goto done; empty_allowed_caps: GST_ERROR_OBJECT (vpp, "Got EMPTY caps from gst_pad_get_allowed_caps"); gst_caps_unref (allowed_caps); goto done; not_negotiated: gst_caps_unref (src_caps); GST_ERROR_OBJECT (vpp, "Couldn't find suitable output format"); goto done; }
/* This is essentially gst_base_src_negotiate_default() but the caps * are guaranteed to have a channel layout for > 2 channels */ static gboolean gst_pulsesrc_negotiate (GstBaseSrc * basesrc) { GstCaps *thiscaps; GstCaps *caps = NULL; GstCaps *peercaps = NULL; gboolean result = FALSE; /* first see what is possible on our source pad */ thiscaps = gst_pad_get_caps_reffed (GST_BASE_SRC_PAD (basesrc)); GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps); /* nothing or anything is allowed, we're done */ if (thiscaps == NULL || gst_caps_is_any (thiscaps)) goto no_nego_needed; /* get the peer caps */ peercaps = gst_pad_peer_get_caps_reffed (GST_BASE_SRC_PAD (basesrc)); GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps); if (peercaps) { /* get intersection */ caps = gst_caps_intersect (thiscaps, peercaps); GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, caps); gst_caps_unref (thiscaps); gst_caps_unref (peercaps); } else { /* no peer, work with our own caps then */ caps = thiscaps; } if (caps) { /* take first (and best, since they are sorted) possibility */ caps = gst_caps_make_writable (caps); gst_caps_truncate (caps); /* now fixate */ if (!gst_caps_is_empty (caps)) { gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps); GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps); if (gst_caps_is_any (caps)) { /* hmm, still anything, so element can do anything and * nego is not needed */ result = TRUE; } else if (gst_caps_is_fixed (caps)) { /* yay, fixed caps, use those then */ result = gst_pulsesrc_create_stream (GST_PULSESRC_CAST (basesrc), caps); if (result) result = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps); } } gst_caps_unref (caps); } return result; no_nego_needed: { GST_DEBUG_OBJECT (basesrc, "no negotiation needed"); if (thiscaps) gst_caps_unref (thiscaps); return TRUE; } }
static gboolean gst_xvidenc_setcaps (GstPad * pad, GstCaps * vscaps) { GstXvidEnc *xvidenc; GstStructure *structure; gint w, h; const GValue *fps, *par; gint xvid_cs = -1; xvidenc = GST_XVIDENC (GST_PAD_PARENT (pad)); /* if there's something old around, remove it */ if (xvidenc->handle) { gst_xvidenc_flush_buffers (xvidenc, TRUE); xvid_encore (xvidenc->handle, XVID_ENC_DESTROY, NULL, NULL); xvidenc->handle = NULL; } structure = gst_caps_get_structure (vscaps, 0); if (!gst_structure_get_int (structure, "width", &w) || !gst_structure_get_int (structure, "height", &h)) { return FALSE; } fps = gst_structure_get_value (structure, "framerate"); if (fps == NULL || !GST_VALUE_HOLDS_FRACTION (fps)) { GST_WARNING_OBJECT (pad, "no framerate specified, or not a GstFraction"); return FALSE; } /* optional par info */ par = gst_structure_get_value (structure, "pixel-aspect-ratio"); xvid_cs = gst_xvid_structure_to_csp (structure); if (xvid_cs == -1) { gchar *sstr; sstr = gst_structure_to_string (structure); GST_DEBUG_OBJECT (xvidenc, "Did not find xvid colourspace for caps %s", sstr); g_free (sstr); return FALSE; } xvidenc->csp = xvid_cs; xvidenc->width = w; xvidenc->height = h; xvidenc->fbase = gst_value_get_fraction_numerator (fps); xvidenc->fincr = gst_value_get_fraction_denominator (fps); if ((par != NULL) && GST_VALUE_HOLDS_FRACTION (par)) { xvidenc->par_width = gst_value_get_fraction_numerator (par); xvidenc->par_height = gst_value_get_fraction_denominator (par); } else { xvidenc->par_width = 1; xvidenc->par_height = 1; } /* wipe xframe cache given possible change caps properties */ g_free (xvidenc->xframe_cache); xvidenc->xframe_cache = NULL; if (gst_xvidenc_setup (xvidenc)) { gboolean ret = FALSE; GstCaps *new_caps = NULL, *allowed_caps; /* please downstream with preferred caps */ allowed_caps = gst_pad_get_allowed_caps (xvidenc->srcpad); GST_DEBUG_OBJECT (xvidenc, "allowed caps: %" GST_PTR_FORMAT, allowed_caps); if (allowed_caps && !gst_caps_is_empty (allowed_caps)) { new_caps = gst_caps_copy_nth (allowed_caps, 0); } else { new_caps = gst_caps_new_simple ("video/x-xvid", NULL); } if (allowed_caps) gst_caps_unref (allowed_caps); gst_caps_set_simple (new_caps, "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, "framerate", GST_TYPE_FRACTION, xvidenc->fbase, xvidenc->fincr, "pixel-aspect-ratio", GST_TYPE_FRACTION, xvidenc->par_width, xvidenc->par_height, NULL); /* just to be sure */ gst_pad_fixate_caps (xvidenc->srcpad, new_caps); if (xvidenc->used_profile != 0) { switch (xvidenc->used_profile) { case XVID_PROFILE_S_L0: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "0", NULL); break; case XVID_PROFILE_S_L1: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "1", NULL); break; case XVID_PROFILE_S_L2: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "2", NULL); break; case XVID_PROFILE_S_L3: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "3", NULL); break; /* case XVID_PROFILE_S_L4a: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "4a", NULL); break; case XVID_PROFILE_S_L5: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "5", NULL); break; case XVID_PROFILE_S_L6: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "simple", "level", G_TYPE_STRING, "6", NULL); break;*/ case XVID_PROFILE_ARTS_L1: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-real-time-simple", "level", G_TYPE_STRING, "1", NULL); break; case XVID_PROFILE_ARTS_L2: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-real-time-simple", "level", G_TYPE_STRING, "2", NULL); break; case XVID_PROFILE_ARTS_L3: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-real-time-simple", "level", G_TYPE_STRING, "3", NULL); break; case XVID_PROFILE_ARTS_L4: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-real-time-simple", "level", G_TYPE_STRING, "4", NULL); break; case XVID_PROFILE_AS_L0: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-simple", "level", G_TYPE_STRING, "0", NULL); break; case XVID_PROFILE_AS_L1: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-simple", "level", G_TYPE_STRING, "1", NULL); break; case XVID_PROFILE_AS_L2: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-simple", "level", G_TYPE_STRING, "2", NULL); break; case XVID_PROFILE_AS_L3: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-simple", "level", G_TYPE_STRING, "3", NULL); break; case XVID_PROFILE_AS_L4: gst_caps_set_simple (new_caps, "profile", G_TYPE_STRING, "advanced-simple", "level", G_TYPE_STRING, "4", NULL); break; default: g_assert_not_reached (); break; } } /* src pad should accept anyway */ ret = gst_pad_set_caps (xvidenc->srcpad, new_caps); gst_caps_unref (new_caps); if (!ret && xvidenc->handle) { xvid_encore (xvidenc->handle, XVID_ENC_DESTROY, NULL, NULL); xvidenc->handle = NULL; } return ret; } else /* setup did not work out */ return FALSE; }
static gboolean gst_droid_cam_src_vfsrc_negotiate (GstDroidCamSrc * src) { GstCaps *caps; GstCaps *peer; GstCaps *common; gboolean ret; GstDroidCamSrcClass *klass; GST_DEBUG_OBJECT (src, "vfsrc negotiate"); klass = GST_DROID_CAM_SRC_GET_CLASS (src); caps = gst_droid_cam_src_vfsrc_getcaps (src->vfsrc); if (!caps || gst_caps_is_empty (caps)) { GST_ELEMENT_ERROR (src, STREAM, FORMAT, ("Failed to get any supported caps"), (NULL)); if (caps) { gst_caps_unref (caps); } ret = FALSE; goto out; } GST_LOG_OBJECT (src, "caps %" GST_PTR_FORMAT, caps); peer = gst_pad_peer_get_caps_reffed (src->vfsrc); if (!peer || gst_caps_is_empty (peer) || gst_caps_is_any (peer)) { if (peer) { gst_caps_unref (peer); } gst_caps_unref (caps); /* Use default. */ GST_CAMERA_BUFFER_POOL_LOCK (src->pool); caps = gst_caps_new_simple (GST_NATIVE_BUFFER_NAME, "width", G_TYPE_INT, DEFAULT_VF_WIDTH, "height", G_TYPE_INT, DEFAULT_VF_HEIGHT, "framerate", GST_TYPE_FRACTION, DEFAULT_FPS, 1, "orientation-angle", G_TYPE_INT, src->pool->orientation, NULL); GST_CAMERA_BUFFER_POOL_UNLOCK (src->pool); GST_DEBUG_OBJECT (src, "using default caps %" GST_PTR_FORMAT, caps); ret = gst_pad_set_caps (src->vfsrc, caps); gst_caps_unref (caps); goto out; } GST_DEBUG_OBJECT (src, "peer caps %" GST_PTR_FORMAT, peer); common = gst_caps_intersect (caps, peer); GST_LOG_OBJECT (src, "caps intersection %" GST_PTR_FORMAT, common); gst_caps_unref (caps); gst_caps_unref (peer); if (gst_caps_is_empty (common)) { GST_ELEMENT_ERROR (src, STREAM, FORMAT, ("No common caps"), (NULL)); gst_caps_unref (common); ret = FALSE; goto out; } if (!gst_caps_is_fixed (common)) { gst_pad_fixate_caps (src->vfsrc, common); } ret = gst_pad_set_caps (src->vfsrc, common); gst_caps_unref (common); out: if (ret) { /* set camera parameters */ ret = klass->set_camera_params (src); } return ret; }