static gboolean event_func (GstPad * pad, GstObject * noparent, GstEvent * event) { switch (GST_EVENT_TYPE (event)) { case GST_EVENT_CAPS: { GstCaps *caps; GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps"); GstCaps *caps_no_ssrc; GstCaps *caps2_no_ssrc; gst_event_parse_caps (event, &caps); caps_no_ssrc = remove_ssrc_from_caps (caps); caps2_no_ssrc = remove_ssrc_from_caps (*caps2); fail_unless (caps2 != NULL && *caps2 != NULL); fail_unless (gst_caps_is_fixed (caps)); fail_unless (gst_caps_is_fixed (*caps2)); fail_unless (gst_caps_is_equal_fixed (caps_no_ssrc, caps2_no_ssrc)); gst_caps_unref (caps_no_ssrc); gst_caps_unref (caps2_no_ssrc); break; } default: break; } gst_event_unref (event); return TRUE; }
static gboolean _rtpbin_pad_have_data_callback (GstPad *pad, GstMiniObject *miniobj, gpointer user_data) { FsRtpSubStream *self = FS_RTP_SUB_STREAM (user_data); gboolean ret = TRUE; gboolean remove = FALSE; FsRtpSession *session; if (fs_rtp_session_has_disposed_enter (self->priv->session, NULL)) return FALSE; if (fs_rtp_sub_stream_has_stopped_enter (self)) { fs_rtp_session_has_disposed_exit (self->priv->session); return FALSE; } g_object_ref (self); session = g_object_ref (self->priv->session); FS_RTP_SESSION_LOCK (self->priv->session); if (!self->priv->codecbin || !self->codec || !self->priv->caps) { ret = FALSE; } else if (GST_IS_BUFFER (miniobj)) { if (!gst_caps_is_equal_fixed (GST_BUFFER_CAPS (miniobj), self->priv->caps)) { if (!gst_caps_can_intersect (GST_BUFFER_CAPS (miniobj), self->priv->caps)) ret = FALSE; } else { remove = TRUE; } } if (remove && self->priv->blocking_id) { gst_pad_remove_data_probe (pad, self->priv->blocking_id); self->priv->blocking_id = 0; } FS_RTP_SESSION_UNLOCK (self->priv->session); fs_rtp_sub_stream_has_stopped_exit (self); fs_rtp_session_has_disposed_exit (self->priv->session); g_object_unref (self); g_object_unref (session); return ret; }
static gboolean gst_vdp_output_src_pad_acceptcaps (GstPad * pad, GstCaps * caps) { GstVdpOutputSrcPad *vdp_pad = GST_VDP_OUTPUT_SRC_PAD (pad); if (!vdp_pad->lock_caps) return TRUE; return gst_caps_is_equal_fixed (caps, GST_PAD_CAPS (pad)); }
gboolean gst_validate_media_info_compare (GstValidateMediaInfo * expected, GstValidateMediaInfo * extracted) { gboolean ret = TRUE; if (expected->duration != extracted->duration) { g_print ("Duration changed: %" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (expected->duration), GST_TIME_ARGS (extracted->duration)); ret = FALSE; } if (expected->file_size != extracted->file_size) { g_print ("File size changed: %" G_GUINT64_FORMAT " -> %" G_GUINT64_FORMAT "\n", expected->file_size, extracted->file_size); ret = FALSE; } if (expected->seekable && !extracted->seekable) { g_print ("File isn't seekable anymore\n"); ret = FALSE; } if (extracted->discover_only == FALSE) { if (expected->playback_error == NULL && extracted->playback_error) { g_print ("Playback is now failing with: %s\n", extracted->playback_error); ret = FALSE; } if (expected->reverse_playback_error == NULL && extracted->reverse_playback_error) { g_print ("Reverse playback is now failing with: %s\n", extracted->reverse_playback_error); ret = FALSE; } if (expected->track_switch_error == NULL && extracted->track_switch_error) { g_print ("Track switching is now failing with: %s\n", extracted->track_switch_error); ret = FALSE; } } if (extracted->stream_info == NULL || expected->stream_info == NULL) { g_print ("Stream infos could not be retrieved, an error occured\n"); ret = FALSE; } else if (expected->stream_info && !gst_caps_is_equal_fixed (expected->stream_info->caps, extracted->stream_info->caps)) { gchar *caps1 = gst_caps_to_string (expected->stream_info->caps); gchar *caps2 = gst_caps_to_string (extracted->stream_info->caps); g_print ("Media caps changed: '%s' -> '%s'\n", caps1, caps2); g_free (caps1); g_free (caps2); ret = FALSE; } return ret; }
gboolean gtk_gst_widget_set_caps (GtkGstWidget * widget, GstCaps * caps) { GMainContext *main_context = g_main_context_default (); GstVideoInfo v_info; g_return_val_if_fail (GTK_IS_GST_WIDGET (widget), FALSE); g_return_val_if_fail (GST_IS_CAPS (caps), FALSE); g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE); if (widget->priv->caps && gst_caps_is_equal_fixed (widget->priv->caps, caps)) return TRUE; if (!gst_video_info_from_caps (&v_info, caps)) return FALSE; /* FIXME: support other formats */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&v_info) == GST_VIDEO_FORMAT_BGRA || GST_VIDEO_INFO_FORMAT (&v_info) == GST_VIDEO_FORMAT_BGRx, FALSE); #else g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&v_info) == GST_VIDEO_FORMAT_ARGB || GST_VIDEO_INFO_FORMAT (&v_info) == GST_VIDEO_FORMAT_xRGB, FALSE); #endif g_mutex_lock (&widget->priv->lock); if (!_calculate_par (widget, &v_info)) { g_mutex_unlock (&widget->priv->lock); return FALSE; } gst_caps_replace (&widget->priv->caps, caps); widget->priv->v_info = v_info; widget->priv->negotiated = TRUE; g_mutex_unlock (&widget->priv->lock); gtk_widget_queue_resize (GTK_WIDGET (widget)); g_main_context_invoke (main_context, (GSourceFunc) _queue_resize, widget); return TRUE; }
static gboolean _rtpbin_pad_have_data_callback (GstPad *pad, GstMiniObject *miniobj, gpointer user_data) { FsRtpSubStream *self = FS_RTP_SUB_STREAM (user_data); gboolean ret = TRUE; gboolean remove = FALSE; FS_RTP_SESSION_LOCK (self->priv->session); if (!self->priv->codecbin || !self->codec || !self->priv->caps) { ret = FALSE; } else if (GST_IS_BUFFER (miniobj)) { if (!gst_caps_is_equal_fixed (GST_BUFFER_CAPS (miniobj), self->priv->caps)) { GstCaps *intersect = gst_caps_intersect (GST_BUFFER_CAPS (miniobj), self->priv->caps); if (gst_caps_is_empty (intersect)) ret = FALSE; else gst_buffer_set_caps (GST_BUFFER (miniobj), self->priv->caps); gst_caps_unref (intersect); } else { remove = TRUE; } } if (remove && self->priv->blocking_id) { gst_pad_remove_data_probe (pad, self->priv->blocking_id); self->priv->blocking_id = 0; } FS_RTP_SESSION_UNLOCK (self->priv->session); return ret; }
static void run_decoding_test (GstElement * mpg123audiodec, gchar const *filename) { GstBus *bus; unsigned int num_input_buffers, num_decoded_buffers; gint expected_size; GstCaps *out_caps, *caps; GstAudioInfo audioinfo; GstElement *input_pipeline, *input_appsink; int i; GstBuffer *outbuffer; /* 440 Hz = frequency of sine wave in audio data * 44100 Hz = sample rate * (44100 / 2) Hz = Nyquist frequency */ static double const expected_frequency_spot = 440.0 / (44100.0 / 2.0); fail_unless (gst_element_set_state (mpg123audiodec, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); bus = gst_bus_new (); gst_element_set_bus (mpg123audiodec, bus); setup_input_pipeline (filename, &input_pipeline, &input_appsink); num_input_buffers = 0; while (TRUE) { GstSample *sample; GstBuffer *input_buffer; sample = gst_app_sink_pull_sample (GST_APP_SINK (input_appsink)); if (sample == NULL) break; fail_unless (GST_IS_SAMPLE (sample)); input_buffer = gst_sample_get_buffer (sample); fail_if (input_buffer == NULL); /* This is done to be on the safe side - docs say lifetime of the input buffer * depends *solely* on the sample */ input_buffer = gst_buffer_copy (input_buffer); fail_unless_equals_int (gst_pad_push (mysrcpad, input_buffer), GST_FLOW_OK); ++num_input_buffers; gst_sample_unref (sample); } num_decoded_buffers = g_list_length (buffers); /* check number of decoded buffers */ fail_unless_equals_int (num_decoded_buffers, num_input_buffers - 2); caps = gst_pad_get_current_caps (mysinkpad); GST_LOG ("output caps %" GST_PTR_FORMAT, caps); fail_unless (gst_audio_info_from_caps (&audioinfo, caps), "Getting audio info from caps failed"); /* check caps */ out_caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S32LE", "layout", G_TYPE_STRING, "interleaved", "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL); fail_unless (gst_caps_is_equal_fixed (caps, out_caps), "Incorrect out caps"); gst_caps_unref (out_caps); gst_caps_unref (caps); /* here, test if decoded data is a sine tone, and if the sine frequency is at the * right spot in the spectrum */ for (i = 0; i < num_decoded_buffers; ++i) { outbuffer = GST_BUFFER (buffers->data); fail_if (outbuffer == NULL, "Invalid buffer retrieved"); /* MPEG 1 layer 2 uses 1152 samples per frame */ expected_size = 1152 * GST_AUDIO_INFO_BPF (&audioinfo); fail_unless_equals_int (gst_buffer_get_size (outbuffer), expected_size); check_main_frequency_spot_S32 (outbuffer, expected_frequency_spot); buffers = g_list_remove (buffers, outbuffer); gst_buffer_unref (outbuffer); outbuffer = NULL; } g_list_free (buffers); buffers = NULL; cleanup_input_pipeline (input_pipeline); gst_bus_set_flushing (bus, TRUE); gst_element_set_bus (mpg123audiodec, NULL); gst_object_unref (GST_OBJECT (bus)); }
static gboolean gst_droidadec_set_format (GstAudioDecoder * decoder, GstCaps * caps) { GstDroidADec *dec = GST_DROIDADEC (decoder); GstStructure *str = gst_caps_get_structure (caps, 0); const GValue *value = gst_structure_get_value (str, "codec_data"); GstBuffer *codec_data = value ? gst_value_get_buffer (value) : NULL; /* * destroying the droidmedia codec here will cause stagefright to call abort. * That is why we create it after we are sure that everything is correct */ GST_DEBUG_OBJECT (dec, "set format %" GST_PTR_FORMAT, caps); if (dec->codec) { /* If we get a format change then we stop */ GstCaps *current = gst_pad_get_current_caps (GST_AUDIO_DECODER_SINK_PAD (decoder)); gboolean equal = gst_caps_is_equal_fixed (caps, current); gst_caps_unref (current); GST_DEBUG_OBJECT (dec, "new format is similar to old format? %d", equal); if (!equal) { GST_ELEMENT_ERROR (dec, LIBRARY, SETTINGS, (NULL), ("codec already configured")); } return equal; } dec->codec_type = gst_droid_codec_new_from_caps (caps, GST_DROID_CODEC_DECODER_AUDIO); if (!dec->codec_type) { GST_ELEMENT_ERROR (dec, LIBRARY, FAILED, (NULL), ("Unknown codec type for caps %" GST_PTR_FORMAT, caps)); return FALSE; } if (!gst_structure_get_int (str, "channels", &dec->channels) || !gst_structure_get_int (str, "rate", &dec->rate)) { GST_ELEMENT_ERROR (dec, STREAM, FORMAT, (NULL), ("Failed to parse caps %" GST_PTR_FORMAT, caps)); return FALSE; } GST_INFO_OBJECT (dec, "configuring decoder. rate=%d, channels=%d", dec->rate, dec->channels); gst_buffer_replace (&dec->codec_data, codec_data); /* handle_frame will create the codec */ dec->dirty = TRUE; dec->spf = gst_droid_codec_get_samples_per_frane (caps); GST_INFO_OBJECT (dec, "samples per frame: %d", dec->spf); return TRUE; }
static void gst_hls_demux_stream_loop (GstHLSDemux * demux) { GstFragment *fragment; GstBuffer *buf; GstFlowReturn ret; GstCaps *bufcaps, *srccaps = NULL; /* Loop for the source pad task. The task is started when we have * received the main playlist from the source element. It tries first to * cache the first fragments and then it waits until it has more data in the * queue. This task is woken up when we push a new fragment to the queue or * when we reached the end of the playlist */ if (G_UNLIKELY (demux->need_cache)) { if (!gst_hls_demux_cache_fragments (demux)) goto cache_error; /* we can start now the updates thread (only if on playing) */ if (GST_STATE (demux) == GST_STATE_PLAYING) gst_task_start (demux->updates_task); GST_INFO_OBJECT (demux, "First fragments cached successfully"); } if (g_queue_is_empty (demux->queue)) { if (demux->end_of_playlist) goto end_of_playlist; goto pause_task; } fragment = g_queue_pop_head (demux->queue); buf = gst_fragment_get_buffer (fragment); /* Figure out if we need to create/switch pads */ if (G_LIKELY (demux->srcpad)) srccaps = gst_pad_get_current_caps (demux->srcpad); bufcaps = gst_fragment_get_caps (fragment); if (G_UNLIKELY (!srccaps || !gst_caps_is_equal_fixed (bufcaps, srccaps) || demux->need_segment)) { switch_pads (demux, bufcaps); demux->need_segment = TRUE; } gst_caps_unref (bufcaps); if (G_LIKELY (srccaps)) gst_caps_unref (srccaps); g_object_unref (fragment); if (demux->need_segment) { GstSegment segment; GstClockTime start = GST_BUFFER_PTS (buf); start += demux->position_shift; /* And send a newsegment */ GST_DEBUG_OBJECT (demux, "Sending new-segment. segment start:%" GST_TIME_FORMAT, GST_TIME_ARGS (start)); gst_segment_init (&segment, GST_FORMAT_TIME); segment.start = start; segment.time = start; gst_pad_push_event (demux->srcpad, gst_event_new_segment (&segment)); demux->need_segment = FALSE; demux->position_shift = 0; } ret = gst_pad_push (demux->srcpad, buf); if (ret != GST_FLOW_OK) goto error_pushing; return; end_of_playlist: { GST_DEBUG_OBJECT (demux, "Reached end of playlist, sending EOS"); gst_pad_push_event (demux->srcpad, gst_event_new_eos ()); gst_hls_demux_stop (demux); return; } cache_error: { gst_task_pause (demux->stream_task); if (!demux->cancelled) { GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not cache the first fragments"), (NULL)); gst_hls_demux_stop (demux); } return; } error_pushing: { /* FIXME: handle error */ GST_DEBUG_OBJECT (demux, "Error pushing buffer: %s... stopping task", gst_flow_get_name (ret)); gst_hls_demux_stop (demux); return; } pause_task: { gst_task_pause (demux->stream_task); return; } }
/* * Method: equal_fixed?(caps) * caps: another Gst::Caps. * * Returns: whether the given fixed caps represent the same set of caps than self * (self must be fixed as well). */ static VALUE rg_equal_fixed_p (VALUE self, VALUE caps) { return CBOOL2RVAL (gst_caps_is_equal_fixed (RGST_CAPS (self), RGST_CAPS (caps))); }