Beispiel #1
0
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;
}
Beispiel #6
0
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));
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
  }
}
Beispiel #10
0
/*
 * 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)));
}