예제 #1
0
/**
 * _gst_caps_set_buffer_array:
 * @caps: a #GstCaps
 * @field: field in caps to set
 * @buf: header buffers
 *
 * Adds given buffers to an array of buffers set as the given @field
 * on the given @caps.  List of buffer arguments must be NULL-terminated.
 *
 * Returns: input caps with a streamheader field added, or NULL if some error
 */
static GstCaps *
_gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
                            GstBuffer * buf, ...)
{
    GstStructure *structure = NULL;
    va_list va;
    GValue array = { 0 };
    GValue value = { 0 };

    g_return_val_if_fail (caps != NULL, NULL);
    g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
    g_return_val_if_fail (field != NULL, NULL);

    caps = gst_caps_make_writable (caps);
    structure = gst_caps_get_structure (caps, 0);

    g_value_init (&array, GST_TYPE_ARRAY);

    va_start (va, buf);
    /* put buffers in a fixed list */
    while (buf) {
        g_assert (gst_buffer_is_writable (buf));

        /* mark buffer */
        GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);

        g_value_init (&value, GST_TYPE_BUFFER);
        buf = gst_buffer_copy (buf);
        GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
        gst_value_set_buffer (&value, buf);
        gst_buffer_unref (buf);
        gst_value_array_append_value (&array, &value);
        g_value_unset (&value);

        buf = va_arg (va, GstBuffer *);
    }

    gst_structure_set_value (structure, field, &array);
    g_value_unset (&array);

    return caps;
}
예제 #2
0
파일: gstcmmlenc.c 프로젝트: jwzl/ossbuild
static GstCaps *
gst_cmml_enc_set_header_on_caps (GstCmmlEnc * enc, GstCaps * caps,
                                 GstBuffer * ident, GstBuffer * preamble, GstBuffer * head)
{
    GValue array = { 0 };
    GValue value = { 0 };
    GstStructure *structure;
    GstBuffer *buffer;

    caps = gst_caps_make_writable (caps);
    structure = gst_caps_get_structure (caps, 0);

    g_value_init (&array, GST_TYPE_ARRAY);
    g_value_init (&value, GST_TYPE_BUFFER);

    /* Make copies of header buffers to avoid circular references */
    buffer = gst_buffer_copy (ident);
    gst_value_set_buffer (&value, buffer);
    gst_value_array_append_value (&array, &value);
    gst_buffer_unref (buffer);

    buffer = gst_buffer_copy (preamble);
    gst_value_set_buffer (&value, buffer);
    gst_value_array_append_value (&array, &value);
    gst_buffer_unref (buffer);

    buffer = gst_buffer_copy (head);
    gst_value_set_buffer (&value, buffer);
    gst_value_array_append_value (&array, &value);
    gst_buffer_unref (buffer);

    GST_BUFFER_FLAG_SET (ident, GST_BUFFER_FLAG_IN_CAPS);
    GST_BUFFER_FLAG_SET (preamble, GST_BUFFER_FLAG_IN_CAPS);
    GST_BUFFER_FLAG_SET (head, GST_BUFFER_FLAG_IN_CAPS);

    gst_structure_set_value (structure, "streamheader", &array);

    g_value_unset (&value);
    g_value_unset (&array);

    return caps;
}
예제 #3
0
/*!
 * \brief CvCapture_GStreamer::setFilter
 * \param prop the property name
 * \param type glib property type
 * \param v1 the value
 * \param v2 second value of property type requires it, else NULL
 * Filter the output formats by setting appsink caps properties
 */
void CvCapture_GStreamer::setFilter(const char *prop, int type, int v1, int v2)
{
    //printf("GStreamer: setFilter \n");
    if(!caps || !( GST_IS_CAPS (caps) ))
    {
        if(type == G_TYPE_INT)
        {
#if GST_VERSION_MAJOR == 0
            caps = gst_caps_new_simple("video/x-raw-rgb", prop, type, v1, NULL);
#else
            caps = gst_caps_new_simple("video/x-raw","format",G_TYPE_STRING,"BGR", prop, type, v1, NULL);
#endif
        }
        else
        {
#if GST_VERSION_MAJOR == 0
            caps = gst_caps_new_simple("video/x-raw-rgb", prop, type, v1, v2, NULL);
#else
            caps = gst_caps_new_simple("video/x-raw","format",G_TYPE_STRING,"BGR", prop, type, v1, v2, NULL);
#endif
        }
    }
    else
    {
#if GST_VERSION_MAJOR > 0
        if (! gst_caps_is_writable(caps))
            caps = gst_caps_make_writable (caps);
#endif
        if(type == G_TYPE_INT){
            gst_caps_set_simple(caps, prop, type, v1, NULL);
        }else{
            gst_caps_set_simple(caps, prop, type, v1, v2, NULL);
        }
    }

#if GST_VERSION_MAJOR > 0
    caps = gst_caps_fixate(caps);
#endif

    gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
    //printf("filtering with %s\n", gst_caps_to_string(caps));
}
예제 #4
0
static GstCaps *
gst_rpi_cam_src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstStructure *structure;
  gint i;
  GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);
  caps = gst_caps_make_writable (caps);
  for (i = 0; i < gst_caps_get_size (caps); ++i) {
    structure = gst_caps_get_structure (caps, i);
    /* Fixate to 1920x1080 resolution if possible */
    gst_structure_fixate_field_nearest_int (structure, "width", 1920);
    gst_structure_fixate_field_nearest_int (structure, "height", 1080);
    gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
    gst_structure_fixate_field (structure, "format");
  }

  GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);
  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (basesrc, caps);
  return caps;
}
static GstCaps *
gst_opus_dec_negotiate (GstOpusDec * dec)
{
  GstCaps *caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dec));
  GstStructure *s;

  caps = gst_caps_make_writable (caps);
  gst_caps_truncate (caps);

  s = gst_caps_get_structure (caps, 0);
  gst_structure_fixate_field_nearest_int (s, "rate", 48000);
  gst_structure_get_int (s, "rate", &dec->sample_rate);
  gst_structure_fixate_field_nearest_int (s, "channels", dec->n_channels);
  gst_structure_get_int (s, "channels", &dec->n_channels);

  GST_INFO_OBJECT (dec, "Negotiated %d channels, %d Hz", dec->n_channels,
      dec->sample_rate);

  return caps;
}
예제 #6
0
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;
}
예제 #7
0
GstCaps *
gst_kate_util_set_header_on_caps (GstElement * element, GstCaps * caps,
    GList * headers)
{
  GstStructure *structure;
  GValue array = { 0 };

  GST_LOG_OBJECT (element, "caps: %" GST_PTR_FORMAT, caps);

  if (G_UNLIKELY (!caps))
    return NULL;
  if (G_UNLIKELY (!headers))
    return NULL;

  caps = gst_caps_make_writable (caps);
  structure = gst_caps_get_structure (caps, 0);

  g_value_init (&array, GST_TYPE_ARRAY);

  while (headers) {
    GValue value = { 0 };
    GstBuffer *buffer = headers->data;
    g_assert (buffer);
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
    g_value_init (&value, GST_TYPE_BUFFER);
    /* as in theoraenc, we need to copy to avoid circular references */
    buffer = gst_buffer_copy (buffer);
    gst_value_set_buffer (&value, buffer);
    gst_buffer_unref (buffer);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);
    headers = headers->next;
  }

  gst_structure_set_value (structure, "streamheader", &array);
  g_value_unset (&array);
  GST_LOG_OBJECT (element, "here are the newly set caps: %" GST_PTR_FORMAT,
      caps);

  return caps;
}
예제 #8
0
static GstCaps *
gst_video_scale_get_capslist (void)
{
  static GstCaps *caps = NULL;
  static volatile gsize inited = 0;

  if (g_once_init_enter (&inited)) {
    gint i;

    g_assert (caps == NULL);

    caps = gst_caps_new_empty ();
    for (i = 0; i < G_N_ELEMENTS (gst_video_scale_format_caps); i++)
      gst_caps_append (caps,
          gst_caps_make_writable
          (gst_static_caps_get (&gst_video_scale_format_caps[i])));
    g_once_init_leave (&inited, 1);
  }

  return caps;
}
예제 #9
0
static GstCaps *
gst_rtp_L24_pay_getcaps (GstRTPBasePayload * rtppayload, GstPad * pad,
                         GstCaps * filter)
{
    GstCaps *otherpadcaps;
    GstCaps *caps;

    caps = gst_pad_get_pad_template_caps (pad);

    otherpadcaps = gst_pad_get_allowed_caps (rtppayload->srcpad);
    if (otherpadcaps) {
        if (!gst_caps_is_empty (otherpadcaps)) {
            GstStructure *structure;
            gint channels;
            gint rate;

            structure = gst_caps_get_structure (otherpadcaps, 0);
            caps = gst_caps_make_writable (caps);

            if (gst_structure_get_int (structure, "channels", &channels)) {
                gst_caps_set_simple (caps, "channels", G_TYPE_INT, channels, NULL);
            }

            if (gst_structure_get_int (structure, "clock-rate", &rate)) {
                gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate, NULL);
            }

        }
        gst_caps_unref (otherpadcaps);
    }

    if (filter) {
        GstCaps *tcaps = caps;

        caps = gst_caps_intersect_full (filter, tcaps, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (tcaps);
    }

    return caps;
}
예제 #10
0
static GstCaps *
gst_interlace_getcaps (GstPad * pad, GstInterlace * interlace, GstCaps * filter)
{
  GstPad *otherpad;
  GstCaps *othercaps, *tcaps;
  GstCaps *icaps;
  const char *mode;

  otherpad =
      (pad == interlace->srcpad) ? interlace->sinkpad : interlace->srcpad;

  tcaps = gst_pad_get_pad_template_caps (otherpad);
  othercaps = gst_pad_peer_query_caps (otherpad, filter);

  if (othercaps) {
    icaps = gst_caps_intersect (othercaps, tcaps);
    gst_caps_unref (othercaps);
  } else {
    icaps = tcaps;
  }

  if (filter) {
    othercaps = gst_caps_intersect (icaps, filter);
    gst_caps_unref (icaps);
    icaps = othercaps;
  }

  icaps = gst_caps_make_writable (icaps);
  if (interlace->pattern > GST_INTERLACE_PATTERN_2_2) {
    mode = "mixed";
  } else {
    mode = "interleaved";
  }
  gst_caps_set_simple (icaps, "interlace-mode", G_TYPE_STRING,
      pad == interlace->srcpad ? mode : "progressive", NULL);

  gst_caps_unref (tcaps);

  return icaps;
}
예제 #11
0
static GstCaps *
theora_set_header_on_caps (GstCaps * caps, GList * buffers)
{
    GstStructure *structure;
    GValue array = { 0 };
    GValue value = { 0 };
    GstBuffer *buffer;
    GList *walk;

    caps = gst_caps_make_writable (caps);
    structure = gst_caps_get_structure (caps, 0);

    /* put copies of the buffers in a fixed list */
    g_value_init (&array, GST_TYPE_ARRAY);

    for (walk = buffers; walk; walk = walk->next) {
        buffer = walk->data;

        /* mark buffer */
        GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);

        /* Copy buffer, because we can't use the original -
         * it creates a circular refcount with the caps<->buffers */
        buffer = gst_buffer_copy (buffer);

        g_value_init (&value, GST_TYPE_BUFFER);
        gst_value_set_buffer (&value, buffer);
        gst_value_array_append_value (&array, &value);
        g_value_unset (&value);

        /* Unref our copy */
        gst_buffer_unref (buffer);
    }

    gst_structure_set_value (structure, "streamheader", &array);
    g_value_unset (&array);

    return caps;
}
예제 #12
0
static GstCaps *
fs_videoanyrate_fixate_caps (GstBaseTransform * base,
                             GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
    GstStructure *ins, *outs;

    const GValue *from_fr, *to_fr;

    g_return_val_if_fail (gst_caps_is_fixed (caps), othercaps);

    othercaps = gst_caps_make_writable (othercaps);

    GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT
                      " based on caps %" GST_PTR_FORMAT, othercaps, caps);

    ins = gst_caps_get_structure (caps, 0);
    outs = gst_caps_get_structure (othercaps, 0);

    from_fr = gst_structure_get_value (ins, "framerate");
    to_fr = gst_structure_get_value (outs, "framerate");

    /* we have both PAR but they might not be fixated */
    if (from_fr && to_fr && !gst_value_is_fixed (to_fr)) {
        gint from_fr_n, from_fr_d;

        /* from_fr should be fixed */
        g_return_val_if_fail (gst_value_is_fixed (from_fr), othercaps);

        from_fr_n = gst_value_get_fraction_numerator (from_fr);
        from_fr_d = gst_value_get_fraction_denominator (from_fr);

        GST_DEBUG_OBJECT (base, "fixating to_fr nearest to %d/%d",
                          from_fr_n, from_fr_d);
        gst_structure_fixate_field_nearest_fraction (outs, "framerate",
                from_fr_n, from_fr_d);
    }

    return gst_caps_fixate (othercaps);
}
예제 #13
0
/* we return the padtemplate caps with the mode field fixated to a value if we
 * can */
static GstCaps *
gst_rtp_bv_pay_sink_getcaps (GstRTPBasePayload * rtppayload, GstPad * pad,
    GstCaps * filter)
{
  GstCaps *otherpadcaps;
  GstCaps *caps;

  caps = gst_pad_get_pad_template_caps (pad);

  otherpadcaps = gst_pad_get_allowed_caps (rtppayload->srcpad);
  if (otherpadcaps) {
    if (!gst_caps_is_empty (otherpadcaps)) {
      GstStructure *structure;
      const gchar *mode_str;
      gint mode;

      structure = gst_caps_get_structure (otherpadcaps, 0);

      /* construct mode, if we can */
      mode_str = gst_structure_get_string (structure, "encoding-name");
      if (mode_str) {
        if (!strcmp (mode_str, "BV16"))
          mode = 16;
        else if (!strcmp (mode_str, "BV32"))
          mode = 32;
        else
          mode = -1;

        if (mode == 16 || mode == 32) {
          caps = gst_caps_make_writable (caps);
          structure = gst_caps_get_structure (caps, 0);
          gst_structure_set (structure, "mode", G_TYPE_INT, mode, NULL);
        }
      }
    }
    gst_caps_unref (otherpadcaps);
  }
  return caps;
}
예제 #14
0
static GstCaps *
gst_dirac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
{
    GstCaps *peercaps, *templ;
    GstCaps *res;

    templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
    if (filter) {
        GstCaps *fcopy = gst_caps_copy (filter);
        /* Remove the fields we convert */
        remove_fields (fcopy);
        peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
        gst_caps_unref (fcopy);
    } else
        peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);

    if (peercaps) {
        /* Remove the parsed field */
        peercaps = gst_caps_make_writable (peercaps);
        remove_fields (peercaps);

        res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (peercaps);
        gst_caps_unref (templ);
    } else {
        res = templ;
    }

    if (filter) {
        GstCaps *intersection;

        intersection =
            gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (res);
        res = intersection;
    }

    return res;
}
예제 #15
0
static GstCaps *
gst_video_rate_fixate_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
  GstStructure *s;
  gint num, denom;
  const GValue *par;

  s = gst_caps_get_structure (caps, 0);
  if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
    return othercaps;

  othercaps = gst_caps_truncate (othercaps);
  othercaps = gst_caps_make_writable (othercaps);
  s = gst_caps_get_structure (othercaps, 0);
  gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);

  if ((par = gst_structure_get_value (s, "pixel-aspect-ratio")))
    gst_structure_fixate_field_nearest_fraction (s, "pixel-aspect-ratio", 1, 1);

  return othercaps;
}
예제 #16
0
static GstCaps *
gst_image_freeze_sink_getcaps (GstImageFreeze * self, GstCaps * filter)
{
    GstCaps *ret, *tmp, *templ;
    GstPad *pad;

    pad = self->sinkpad;
    if (gst_pad_has_current_caps (pad)) {
        ret = gst_pad_get_current_caps (pad);
        goto done;
    }

    if (filter) {
        filter = gst_caps_copy (filter);
        gst_image_freeze_remove_fps (self, filter);
    }
    templ = gst_pad_get_pad_template_caps (pad);
    tmp = gst_pad_peer_query_caps (self->srcpad, filter);
    if (tmp) {
        GST_LOG_OBJECT (self, "peer caps %" GST_PTR_FORMAT, tmp);
        ret = gst_caps_intersect (tmp, templ);
        gst_caps_unref (tmp);
    } else {
        GST_LOG_OBJECT (self, "going to copy");
        ret = gst_caps_copy (templ);
    }
    gst_caps_unref (templ);
    if (filter)
        gst_caps_unref (filter);

    ret = gst_caps_make_writable (ret);
    gst_image_freeze_remove_fps (self, ret);

done:
    GST_LOG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);

    return ret;
}
예제 #17
0
static gboolean
_track_is_compatible_with_profile (GESPipeline * self, GESTrack * track,
    GstEncodingProfile * prof)
{
  if (TRACK_COMPATIBLE_PROFILE (track->type, prof)) {
    if (self->priv->mode == GES_PIPELINE_MODE_SMART_RENDER) {
      GstCaps *ocaps, *rcaps;

      GST_DEBUG ("Smart Render mode, setting input caps");
      ocaps = gst_encoding_profile_get_input_caps (prof);
      ocaps = gst_caps_make_writable (ocaps);
      if (track->type == GES_TRACK_TYPE_AUDIO)
        rcaps = gst_caps_new_empty_simple ("audio/x-raw");
      else
        rcaps = gst_caps_new_empty_simple ("video/x-raw");
      gst_caps_append (ocaps, rcaps);
      ges_track_set_caps (track, ocaps);
      gst_caps_unref (ocaps);
    } else {
      GstCaps *caps = NULL;

      /* Raw preview or rendering mode */
      if (track->type == GES_TRACK_TYPE_VIDEO)
        caps = gst_caps_new_empty_simple ("video/x-raw");
      else if (track->type == GES_TRACK_TYPE_AUDIO)
        caps = gst_caps_new_empty_simple ("audio/x-raw");

      if (caps) {
        ges_track_set_caps (track, caps);
        gst_caps_unref (caps);
      }
    }

    return TRUE;
  }

  return FALSE;
}
예제 #18
0
static gboolean
gst_gl_mixer_query_caps (GstPad * pad, GstAggregator * agg, GstQuery * query)
{
  GstCaps *filter, *caps;
  GstStructure *s;
  gint n;

  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (agg);

  gst_query_parse_caps (query, &filter);

  if (GST_VIDEO_INFO_FORMAT (&vagg->info) != GST_VIDEO_FORMAT_UNKNOWN) {
    caps = gst_video_info_to_caps (&vagg->info);
  } else {
    caps = gst_pad_get_pad_template_caps (agg->srcpad);
  }

  caps = gst_caps_make_writable (caps);

  n = gst_caps_get_size (caps) - 1;
  for (; n >= 0; n--) {
    s = gst_caps_get_structure (caps, n);
    gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
        "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
    if (GST_VIDEO_INFO_FPS_D (&vagg->info) != 0) {
      gst_structure_set (s,
          "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
    }
  }

  if (filter)
    caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);

  gst_query_set_caps_result (query, caps);
  gst_caps_unref (caps);

  return TRUE;
}
예제 #19
0
/* this function is a bit of a last resort */
static GstCaps *
gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstStructure *structure;
  gint i;

  GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);

  caps = gst_caps_make_writable (caps);

  for (i = 0; i < gst_caps_get_size (caps); ++i) {
    structure = gst_caps_get_structure (caps, i);

    /* We are fixating to a reasonable 320x200 resolution
       and the maximum framerate resolution for that size */
    if (gst_structure_has_field (structure, "width"))
      gst_structure_fixate_field_nearest_int (structure, "width", 320);

    if (gst_structure_has_field (structure, "height"))
      gst_structure_fixate_field_nearest_int (structure, "height", 200);

    if (gst_structure_has_field (structure, "framerate"))
      gst_structure_fixate_field_nearest_fraction (structure, "framerate",
          G_MAXINT, 1);

    if (gst_structure_has_field (structure, "format"))
      gst_structure_fixate_field (structure, "format");

    if (gst_structure_has_field (structure, "interlace-mode"))
      gst_structure_fixate_field (structure, "interlace-mode");
  }

  GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);

  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (basesrc, caps);

  return caps;
}
예제 #20
0
파일: gstspeexenc.c 프로젝트: zsx/ossbuild
static GstCaps *
gst_speex_enc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
    GstBuffer * buf2)
{
  GstStructure *structure = NULL;
  GstBuffer *buf;
  GValue array = { 0 };
  GValue value = { 0 };

  caps = gst_caps_make_writable (caps);
  structure = gst_caps_get_structure (caps, 0);

  g_assert (gst_buffer_is_metadata_writable (buf1));
  g_assert (gst_buffer_is_metadata_writable (buf2));

  /* mark buffers */
  GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
  GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);

  /* put buffers in a fixed list */
  g_value_init (&array, GST_TYPE_ARRAY);
  g_value_init (&value, GST_TYPE_BUFFER);
  buf = gst_buffer_copy (buf1);
  gst_value_set_buffer (&value, buf);
  gst_buffer_unref (buf);
  gst_value_array_append_value (&array, &value);
  g_value_unset (&value);
  g_value_init (&value, GST_TYPE_BUFFER);
  buf = gst_buffer_copy (buf2);
  gst_value_set_buffer (&value, buf);
  gst_buffer_unref (buf);
  gst_value_array_append_value (&array, &value);
  gst_structure_set_value (structure, "streamheader", &array);
  g_value_unset (&value);
  g_value_unset (&array);

  return caps;
}
예제 #21
0
static GstCaps *
strip_mview_fields (GstCaps * incaps, GstVideoMultiviewFlags keep_flags)
{
  GstCaps *outcaps = gst_caps_make_writable (incaps);

  gint i, n;

  n = gst_caps_get_size (outcaps);
  for (i = 0; i < n; i++) {
    GstStructure *st = gst_caps_get_structure (outcaps, i);
    GstVideoMultiviewFlags flags, mask;

    gst_structure_remove_field (st, "multiview-mode");
    if (gst_structure_get_flagset (st, "multiview-flags", &flags, &mask)) {
      flags &= keep_flags;
      mask = keep_flags;
      gst_structure_set (st, "multiview-flags",
          GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, flags, mask, NULL);
    }
  }

  return outcaps;
}
예제 #22
0
static gboolean
gst_dtmf_src_negotiate (GstBaseSrc * basesrc)
{
  GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (basesrc);
  GstCaps *caps;
  GstStructure *s;
  gboolean ret;

  caps = gst_pad_get_allowed_caps (GST_BASE_SRC_PAD (basesrc));

  if (!caps)
    caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (basesrc));

  if (gst_caps_is_empty (caps)) {
    gst_caps_unref (caps);
    return FALSE;
  }

  caps = gst_caps_truncate (caps);

  caps = gst_caps_make_writable (caps);
  s = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (s, "rate", DEFAULT_SAMPLE_RATE);

  if (!gst_structure_get_int (s, "rate", &dtmfsrc->sample_rate)) {
    GST_ERROR_OBJECT (dtmfsrc, "Could not get rate");
    gst_caps_unref (caps);
    return FALSE;
  }

  ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);

  gst_caps_unref (caps);

  return ret;
}
예제 #23
0
static GstCaps *
gst_audio_test_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
  GstAudioTestSrc *src = GST_AUDIO_TEST_SRC (bsrc);
  GstStructure *structure;

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  GST_DEBUG_OBJECT (src, "fixating samplerate to %d", GST_AUDIO_DEF_RATE);

  gst_structure_fixate_field_nearest_int (structure, "rate",
      GST_AUDIO_DEF_RATE);

  gst_structure_fixate_field_string (structure, "format", DEFAULT_FORMAT_STR);

  /* fixate to mono unless downstream requires stereo, for backwards compat */
  gst_structure_fixate_field_nearest_int (structure, "channels", 1);

  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps);

  return caps;
}
예제 #24
0
static GstCaps *
gstbt_audio_synth_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstBtAudioSynth *self = GSTBT_AUDIO_SYNTH (basesrc);
  GstBtAudioSynthClass *klass = GSTBT_AUDIO_SYNTH_GET_CLASS (self);
  gint i, n = gst_caps_get_size (caps);

  GST_INFO_OBJECT (self, "fixate");

  caps = gst_caps_make_writable (caps);
  for (i = 0; i < n; i++) {
    gst_structure_fixate_field_nearest_int (gst_caps_get_structure (caps, i),
        "rate", self->info.rate);
  }
  GST_INFO_OBJECT (self, "fixated to %" GST_PTR_FORMAT, caps);

  if (klass->negotiate) {
    klass->negotiate (self, caps);
  }
  GST_INFO_OBJECT (self, "fixated to %" GST_PTR_FORMAT, caps);

  return GST_BASE_SRC_CLASS (gstbt_audio_synth_parent_class)->fixate (basesrc,
      caps);
}
예제 #25
0
static GstCaps *
gst_lv2_source_fixate (GstBaseSrc * base, GstCaps * caps)
{
  GstLV2Source *lv2 = (GstLV2Source *) base;
  GstStructure *structure;

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  GST_DEBUG_OBJECT (lv2, "fixating samplerate to %d", GST_AUDIO_DEF_RATE);

  gst_structure_fixate_field_nearest_int (structure, "rate",
      GST_AUDIO_DEF_RATE);

  gst_structure_fixate_field_string (structure, "format", GST_AUDIO_NE (F32));

  gst_structure_fixate_field_nearest_int (structure, "channels",
      lv2->lv2.klass->out_group.ports->len);

  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (base, caps);

  return caps;
}
static gboolean
same_clock_rate_fold (const GValue * item, GValue * ret, gpointer user_data)
{
  GstPad *mypad = user_data;
  GstPad *pad = g_value_get_object (item);
  GstCaps *peercaps;
  GstCaps *accumcaps;

  if (pad == mypad)
    return TRUE;

  accumcaps = g_value_get_boxed (ret);
  peercaps = gst_pad_peer_query_caps (pad, accumcaps);
  if (!peercaps) {
    g_warning ("no peercaps");
    return TRUE;
  }
  peercaps = gst_caps_make_writable (peercaps);
  clear_caps (peercaps, TRUE);

  g_value_take_boxed (ret, peercaps);

  return !gst_caps_is_empty (peercaps);
}
예제 #27
0
static void
gst_opus_dec_negotiate (GstOpusDec * dec, const GstAudioChannelPosition * pos)
{
  GstCaps *caps = gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dec));
  GstStructure *s;
  GstAudioInfo info;

  if (caps) {
    caps = gst_caps_truncate (caps);
    caps = gst_caps_make_writable (caps);
    s = gst_caps_get_structure (caps, 0);

    if (gst_structure_has_field (s, "rate"))
      gst_structure_fixate_field_nearest_int (s, "rate", dec->sample_rate);
    else
      gst_structure_set (s, "rate", G_TYPE_INT, dec->sample_rate, NULL);
    gst_structure_get_int (s, "rate", &dec->sample_rate);

    if (gst_structure_has_field (s, "channels"))
      gst_structure_fixate_field_nearest_int (s, "channels", dec->n_channels);
    else
      gst_structure_set (s, "channels", G_TYPE_INT, dec->n_channels, NULL);
    gst_structure_get_int (s, "channels", &dec->n_channels);

    gst_caps_unref (caps);
  }

  if (dec->n_channels == 0) {
    GST_DEBUG_OBJECT (dec, "Using a default of 2 channels");
    dec->n_channels = 2;
    pos = NULL;
  }

  if (dec->sample_rate == 0) {
    GST_DEBUG_OBJECT (dec, "Using a default of 48kHz sample rate");
    dec->sample_rate = 48000;
  }

  GST_INFO_OBJECT (dec, "Negotiated %d channels, %d Hz", dec->n_channels,
      dec->sample_rate);

  /* pass valid order to audio info */
  if (pos) {
    memcpy (dec->opus_pos, pos, sizeof (pos[0]) * dec->n_channels);
    gst_audio_channel_positions_to_valid_order (dec->opus_pos, dec->n_channels);
  }

  /* set up source format */
  gst_audio_info_init (&info);
  gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S16,
      dec->sample_rate, dec->n_channels, pos ? dec->opus_pos : NULL);
  gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (dec), &info);

  /* but we still need the opus order for later reordering */
  if (pos) {
    memcpy (dec->opus_pos, pos, sizeof (pos[0]) * dec->n_channels);
    gst_audio_channel_positions_to_valid_order (dec->opus_pos, dec->n_channels);
  } else {
    dec->opus_pos[0] = GST_AUDIO_CHANNEL_POSITION_INVALID;
  }

  dec->info = info;
}
예제 #28
0
/* we can only accept caps that we and downstream can handle.
 * if we have filtercaps set, use those to constrain the target caps.
 */
static GstCaps *
gst_audiomixer_sink_getcaps (GstAggregator * agg, GstPad * pad,
    GstCaps * filter)
{
  GstAudioAggregator *aagg;
  GstAudioMixer *audiomixer;
  GstCaps *result, *peercaps, *current_caps, *filter_caps;
  GstStructure *s;
  gint i, n;

  audiomixer = GST_AUDIO_MIXER (agg);
  aagg = GST_AUDIO_AGGREGATOR (agg);

  GST_OBJECT_LOCK (audiomixer);
  /* take filter */
  if ((filter_caps = audiomixer->filter_caps)) {
    if (filter)
      filter_caps =
          gst_caps_intersect_full (filter, filter_caps,
          GST_CAPS_INTERSECT_FIRST);
    else
      gst_caps_ref (filter_caps);
  } else {
    filter_caps = filter ? gst_caps_ref (filter) : NULL;
  }
  GST_OBJECT_UNLOCK (audiomixer);

  if (filter_caps && gst_caps_is_empty (filter_caps)) {
    GST_WARNING_OBJECT (pad, "Empty filter caps");
    return filter_caps;
  }

  /* get the downstream possible caps */
  peercaps = gst_pad_peer_query_caps (agg->srcpad, filter_caps);

  /* get the allowed caps on this sinkpad */
  GST_OBJECT_LOCK (audiomixer);
  current_caps = aagg->current_caps ? gst_caps_ref (aagg->current_caps) : NULL;
  if (current_caps == NULL) {
    current_caps = gst_pad_get_pad_template_caps (pad);
    if (!current_caps)
      current_caps = gst_caps_new_any ();
  }
  GST_OBJECT_UNLOCK (audiomixer);

  if (peercaps) {
    /* if the peer has caps, intersect */
    GST_DEBUG_OBJECT (audiomixer, "intersecting peer and our caps");
    result =
        gst_caps_intersect_full (peercaps, current_caps,
        GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
    gst_caps_unref (current_caps);
  } else {
    /* the peer has no caps (or there is no peer), just use the allowed caps
     * of this sinkpad. */
    /* restrict with filter-caps if any */
    if (filter_caps) {
      GST_DEBUG_OBJECT (audiomixer, "no peer caps, using filtered caps");
      result =
          gst_caps_intersect_full (filter_caps, current_caps,
          GST_CAPS_INTERSECT_FIRST);
      gst_caps_unref (current_caps);
    } else {
      GST_DEBUG_OBJECT (audiomixer, "no peer caps, using our caps");
      result = current_caps;
    }
  }

  result = gst_caps_make_writable (result);

  n = gst_caps_get_size (result);
  for (i = 0; i < n; i++) {
    GstStructure *sref;

    s = gst_caps_get_structure (result, i);
    sref = gst_structure_copy (s);
    gst_structure_set (sref, "channels", GST_TYPE_INT_RANGE, 0, 2, NULL);
    if (gst_structure_is_subset (s, sref)) {
      /* This field is irrelevant when in mono or stereo */
      gst_structure_remove_field (s, "channel-mask");
    }
    gst_structure_free (sref);
  }

  if (filter_caps)
    gst_caps_unref (filter_caps);

  GST_LOG_OBJECT (audiomixer, "getting caps on pad %p,%s to %" GST_PTR_FORMAT,
      pad, GST_PAD_NAME (pad), result);

  return result;
}
static GstCaps *
gst_video_scale_fixate_caps (GstBaseTransform * base, GstPadDirection direction,
                             GstCaps * caps, GstCaps * othercaps)
{
    GstStructure *ins, *outs;
    const GValue *from_par, *to_par;
    GValue fpar = { 0, }, tpar = {
        0,
    };

    othercaps = gst_caps_truncate (othercaps);
    othercaps = gst_caps_make_writable (othercaps);

    GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT
                      " based on caps %" GST_PTR_FORMAT, othercaps, caps);

    ins = gst_caps_get_structure (caps, 0);
    outs = gst_caps_get_structure (othercaps, 0);

    from_par = gst_structure_get_value (ins, "pixel-aspect-ratio");
    to_par = gst_structure_get_value (outs, "pixel-aspect-ratio");

    /* If we're fixating from the sinkpad we always set the PAR and
     * assume that missing PAR on the sinkpad means 1/1 and
     * missing PAR on the srcpad means undefined
     */
    if (direction == GST_PAD_SINK) {
        if (!from_par) {
            g_value_init (&fpar, GST_TYPE_FRACTION);
            gst_value_set_fraction (&fpar, 1, 1);
            from_par = &fpar;
        }
        if (!to_par) {
            g_value_init (&tpar, GST_TYPE_FRACTION_RANGE);
            gst_value_set_fraction_range_full (&tpar, 1, G_MAXINT, G_MAXINT, 1);
            to_par = &tpar;
        }
    } else {
        if (!to_par) {
            g_value_init (&tpar, GST_TYPE_FRACTION);
            gst_value_set_fraction (&tpar, 1, 1);
            to_par = &tpar;

            gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
                               NULL);
        }
        if (!from_par) {
            g_value_init (&fpar, GST_TYPE_FRACTION);
            gst_value_set_fraction (&fpar, 1, 1);
            from_par = &fpar;
        }
    }

    /* we have both PAR but they might not be fixated */
    {
        gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
        gint w = 0, h = 0;
        gint from_dar_n, from_dar_d;
        gint num, den;

        /* from_par should be fixed */
        g_return_val_if_fail (gst_value_is_fixed (from_par), othercaps);

        from_par_n = gst_value_get_fraction_numerator (from_par);
        from_par_d = gst_value_get_fraction_denominator (from_par);

        gst_structure_get_int (ins, "width", &from_w);
        gst_structure_get_int (ins, "height", &from_h);

        gst_structure_get_int (outs, "width", &w);
        gst_structure_get_int (outs, "height", &h);

        /* if both width and height are already fixed, we can't do anything
         * about it anymore */
        if (w && h) {
            guint n, d;

            GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating",
                              w, h);
            if (!gst_value_is_fixed (to_par)) {
                if (gst_video_calculate_display_ratio (&n, &d, from_w, from_h,
                                                       from_par_n, from_par_d, w, h)) {
                    GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", n, d);
                    if (gst_structure_has_field (outs, "pixel-aspect-ratio"))
                        gst_structure_fixate_field_nearest_fraction (outs,
                                "pixel-aspect-ratio", n, d);
                    else if (n != d)
                        gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                           n, d, NULL);
                }
            }
            goto done;
        }

        /* Calculate input DAR */
        if (!gst_util_fraction_multiply (from_w, from_h, from_par_n, from_par_d,
                                         &from_dar_n, &from_dar_d)) {
            GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                               ("Error calculating the output scaled size - integer overflow"));
            goto done;
        }

        GST_DEBUG_OBJECT (base, "Input DAR is %d/%d", from_dar_n, from_dar_d);

        /* If either width or height are fixed there's not much we
         * can do either except choosing a height or width and PAR
         * that matches the DAR as good as possible
         */
        if (h) {
            GstStructure *tmp;
            gint set_w, set_par_n, set_par_d;

            GST_DEBUG_OBJECT (base, "height is fixed (%d)", h);

            /* If the PAR is fixed too, there's not much to do
             * except choosing the width that is nearest to the
             * width with the same DAR */
            if (gst_value_is_fixed (to_par)) {
                to_par_n = gst_value_get_fraction_numerator (to_par);
                to_par_d = gst_value_get_fraction_denominator (to_par);

                GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d);

                if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d,
                                                 to_par_n, &num, &den)) {
                    GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                       ("Error calculating the output scaled size - integer overflow"));
                    goto done;
                }

                w = (guint) gst_util_uint64_scale_int (h, num, den);
                gst_structure_fixate_field_nearest_int (outs, "width", w);

                goto done;
            }

            /* The PAR is not fixed and it's quite likely that we can set
             * an arbitrary PAR. */

            /* Check if we can keep the input width */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "width", from_w);
            gst_structure_get_int (tmp, "width", &set_w);

            /* Might have failed but try to keep the DAR nonetheless by
             * adjusting the PAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, h, set_w,
                                             &to_par_n, &to_par_d)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                gst_structure_free (tmp);
                goto done;
            }

            if (!gst_structure_has_field (tmp, "pixel-aspect-ratio"))
                gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par);
            gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio",
                    to_par_n, to_par_d);
            gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n,
                                        &set_par_d);
            gst_structure_free (tmp);

            /* Check if the adjusted PAR is accepted */
            if (set_par_n == to_par_n && set_par_d == to_par_d) {
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "width", G_TYPE_INT, set_w,
                                       "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d,
                                       NULL);
                goto done;
            }

            /* Otherwise scale the width to the new PAR and check if the
             * adjusted with is accepted. If all that fails we can't keep
             * the DAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d,
                                             set_par_n, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            w = (guint) gst_util_uint64_scale_int (h, num, den);
            gst_structure_fixate_field_nearest_int (outs, "width", w);
            if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                    set_par_n != set_par_d)
                gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                   set_par_n, set_par_d, NULL);

            goto done;
        } else if (w) {
            GstStructure *tmp;
            gint set_h, set_par_n, set_par_d;

            GST_DEBUG_OBJECT (base, "width is fixed (%d)", w);

            /* If the PAR is fixed too, there's not much to do
             * except choosing the height that is nearest to the
             * height with the same DAR */
            if (gst_value_is_fixed (to_par)) {
                to_par_n = gst_value_get_fraction_numerator (to_par);
                to_par_d = gst_value_get_fraction_denominator (to_par);

                GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d);

                if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d,
                                                 to_par_n, &num, &den)) {
                    GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                       ("Error calculating the output scaled size - integer overflow"));
                    goto done;
                }

                h = (guint) gst_util_uint64_scale_int (w, den, num);
                gst_structure_fixate_field_nearest_int (outs, "height", h);

                goto done;
            }

            /* The PAR is not fixed and it's quite likely that we can set
             * an arbitrary PAR. */

            /* Check if we can keep the input height */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", from_h);
            gst_structure_get_int (tmp, "height", &set_h);

            /* Might have failed but try to keep the DAR nonetheless by
             * adjusting the PAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, w,
                                             &to_par_n, &to_par_d)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                gst_structure_free (tmp);
                goto done;
            }
            if (!gst_structure_has_field (tmp, "pixel-aspect-ratio"))
                gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par);
            gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio",
                    to_par_n, to_par_d);
            gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n,
                                        &set_par_d);
            gst_structure_free (tmp);

            /* Check if the adjusted PAR is accepted */
            if (set_par_n == to_par_n && set_par_d == to_par_d) {
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "height", G_TYPE_INT, set_h,
                                       "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d,
                                       NULL);
                goto done;
            }

            /* Otherwise scale the height to the new PAR and check if the
             * adjusted with is accepted. If all that fails we can't keep
             * the DAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d,
                                             set_par_n, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            h = (guint) gst_util_uint64_scale_int (w, den, num);
            gst_structure_fixate_field_nearest_int (outs, "height", h);
            if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                    set_par_n != set_par_d)
                gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                   set_par_n, set_par_d, NULL);

            goto done;
        } else if (gst_value_is_fixed (to_par)) {
            GstStructure *tmp;
            gint set_h, set_w, f_h, f_w;

            to_par_n = gst_value_get_fraction_numerator (to_par);
            to_par_d = gst_value_get_fraction_denominator (to_par);

            /* Calculate scale factor for the PAR change */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_n,
                                             to_par_d, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            /* Try to keep the input height (because of interlacing) */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", from_h);
            gst_structure_get_int (tmp, "height", &set_h);

            /* This might have failed but try to scale the width
             * to keep the DAR nonetheless */
            w = (guint) gst_util_uint64_scale_int (set_h, num, den);
            gst_structure_fixate_field_nearest_int (tmp, "width", w);
            gst_structure_get_int (tmp, "width", &set_w);
            gst_structure_free (tmp);

            /* We kept the DAR and the height is nearest to the original height */
            if (set_w == w) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, set_h, NULL);
                goto done;
            }

            f_h = set_h;
            f_w = set_w;

            /* If the former failed, try to keep the input width at least */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "width", from_w);
            gst_structure_get_int (tmp, "width", &set_w);

            /* This might have failed but try to scale the width
             * to keep the DAR nonetheless */
            h = (guint) gst_util_uint64_scale_int (set_w, den, num);
            gst_structure_fixate_field_nearest_int (tmp, "height", h);
            gst_structure_get_int (tmp, "height", &set_h);
            gst_structure_free (tmp);

            /* We kept the DAR and the width is nearest to the original width */
            if (set_h == h) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, set_h, NULL);
                goto done;
            }

            /* If all this failed, keep the height that was nearest to the orignal
             * height and the nearest possible width. This changes the DAR but
             * there's not much else to do here.
             */
            gst_structure_set (outs, "width", G_TYPE_INT, f_w, "height", G_TYPE_INT,
                               f_h, NULL);
            goto done;
        } else {
            GstStructure *tmp;
            gint set_h, set_w, set_par_n, set_par_d, tmp2;

            /* width, height and PAR are not fixed but passthrough is not possible */

            /* First try to keep the height and width as good as possible
             * and scale PAR */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", from_h);
            gst_structure_get_int (tmp, "height", &set_h);
            gst_structure_fixate_field_nearest_int (tmp, "width", from_w);
            gst_structure_get_int (tmp, "width", &set_w);

            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, set_w,
                                             &to_par_n, &to_par_d)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                gst_structure_free (tmp);
                goto done;
            }

            if (!gst_structure_has_field (tmp, "pixel-aspect-ratio"))
                gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par);
            gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio",
                    to_par_n, to_par_d);
            gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n,
                                        &set_par_d);
            gst_structure_free (tmp);

            if (set_par_n == to_par_n && set_par_d == to_par_d) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, set_h, NULL);

                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                       set_par_n, set_par_d, NULL);
                goto done;
            }

            /* Otherwise try to scale width to keep the DAR with the set
             * PAR and height */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d,
                                             set_par_n, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            w = (guint) gst_util_uint64_scale_int (set_h, num, den);
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "width", w);
            gst_structure_get_int (tmp, "width", &tmp2);
            gst_structure_free (tmp);

            if (tmp2 == w) {
                gst_structure_set (outs, "width", G_TYPE_INT, tmp2, "height",
                                   G_TYPE_INT, set_h, NULL);
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                       set_par_n, set_par_d, NULL);
                goto done;
            }

            /* ... or try the same with the height */
            h = (guint) gst_util_uint64_scale_int (set_w, den, num);
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", h);
            gst_structure_get_int (tmp, "height", &tmp2);
            gst_structure_free (tmp);

            if (tmp2 == h) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, tmp2, NULL);
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                       set_par_n, set_par_d, NULL);
                goto done;
            }

            /* If all fails we can't keep the DAR and take the nearest values
             * for everything from the first try */
            gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                               G_TYPE_INT, set_h, NULL);
            if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                    set_par_n != set_par_d)
                gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                   set_par_n, set_par_d, NULL);
        }
    }

done:
    GST_DEBUG_OBJECT (base, "fixated othercaps to %" GST_PTR_FORMAT, othercaps);

    if (from_par == &fpar)
        g_value_unset (&fpar);
    if (to_par == &tpar)
        g_value_unset (&tpar);

    return othercaps;
}
예제 #30
0
static GstCaps *
gst_shape_wipe_src_getcaps (GstPad * pad, GstCaps * filter)
{
  GstShapeWipe *self = GST_SHAPE_WIPE (gst_pad_get_parent (pad));
  GstCaps *templ, *ret, *tmp;

  if (gst_pad_has_current_caps (pad))
    return gst_pad_get_current_caps (pad);
  else if (gst_pad_has_current_caps (self->video_sinkpad))
    return gst_pad_get_current_caps (self->video_sinkpad);

  templ = gst_pad_get_pad_template_caps (self->video_sinkpad);
  tmp = gst_pad_peer_query_caps (self->video_sinkpad, NULL);
  if (tmp) {
    ret = gst_caps_intersect (tmp, templ);
    gst_caps_unref (templ);
    gst_caps_unref (tmp);
  } else {
    ret = templ;
  }

  GST_LOG_OBJECT (pad, "video sink accepted caps: %" GST_PTR_FORMAT, ret);

  if (gst_caps_is_empty (ret))
    goto done;

  tmp = gst_pad_peer_query_caps (pad, NULL);
  GST_LOG_OBJECT (pad, "peer accepted caps: %" GST_PTR_FORMAT, ret);
  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

  GST_LOG_OBJECT (pad, "intersection: %" GST_PTR_FORMAT, ret);

  if (gst_caps_is_empty (ret))
    goto done;

  if (self->vinfo.height && self->vinfo.width) {
    guint i, n;

    ret = gst_caps_make_writable (ret);
    n = gst_caps_get_size (ret);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (ret, i);

      gst_structure_set (s, "width", G_TYPE_INT, self->vinfo.width, "height",
          G_TYPE_INT, self->vinfo.height, NULL);
    }
  }

  tmp = gst_pad_peer_query_caps (self->mask_sinkpad, NULL);
  GST_LOG_OBJECT (pad, "mask sink accepted caps: %" GST_PTR_FORMAT, ret);
  if (tmp) {
    GstCaps *intersection, *tmp2;
    guint i, n;

    tmp2 = gst_pad_get_pad_template_caps (self->mask_sinkpad);
    intersection = gst_caps_intersect (tmp, tmp2);
    gst_caps_unref (tmp);
    gst_caps_unref (tmp2);

    tmp = gst_caps_make_writable (intersection);
    n = gst_caps_get_size (tmp);

    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (tmp, i);

      gst_structure_remove_fields (s, "format", "framerate", NULL);
      gst_structure_set_name (s, "video/x-raw");
    }

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

done:

  gst_object_unref (self);

  GST_LOG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);

  return ret;
}