/**
 *  fill FarsightCodec fields based on payloader capabilities
 *  TODO: optimise using quarks
 */
static gboolean
extract_field_data (GQuark field_id,
                    const GValue *value,
                    gpointer user_data)
{
  /* TODO : This can be called several times from different rtp caps for the
   * same codec, it would be good to make sure any duplicate values are the
   * same, if not then we have several rtp elements that are giving different
   * caps information, therefore they need to be fixed */

  FsCodec *codec = (FsCodec *) user_data;
  GType type = G_VALUE_TYPE (value);
  const gchar *field_name = g_quark_to_string (field_id);
  const gchar *tmp;

  if (0 == strcmp (field_name, "media"))
  {
    if (type != G_TYPE_STRING)
    {
      return FALSE;
    }
    tmp = g_value_get_string (value);
    if (strcmp (tmp, "audio") == 0)
    {
      codec->media_type = FS_MEDIA_TYPE_AUDIO;
    }
    else if (strcmp (tmp, "video") == 0)
    {
      codec->media_type = FS_MEDIA_TYPE_VIDEO;
    }

  }
  else if (0 == strcmp (field_name, "payload"))
  {
    if (type == GST_TYPE_INT_RANGE)
    {
      if (gst_value_get_int_range_min (value) < 96 ||
          gst_value_get_int_range_max (value) > 255)
      {
        return FALSE;
      }
    }
    else if (type == G_TYPE_INT)
    {
      int id;
      id = g_value_get_int (value);
      if (id > 96)
      {
        /* Dynamic id that was explicitelly set ?? shouldn't happen */
        return FALSE;
      }
      codec->id = id;
    }
    else
    {
      return FALSE;
    }
  }
  else if (0 == strcmp (field_name, "clock-rate"))
  {
    if (type == GST_TYPE_INT_RANGE)
    {
      /* set to 0, this should be checked by the optional parameters code later
       * in Farsight */
      codec->clock_rate = 0;
      return TRUE;
    }
    else if (type != G_TYPE_INT)
    {
      return FALSE;
    }
    codec->clock_rate = g_value_get_int (value);
  }
  else if (0 == strcmp (field_name, "ssrc") ||
      0 == strcmp (field_name, "clock-base") ||
      0 == strcmp (field_name, "seqnum-base"))
  {
    // ignore these fields for now
    ;
  }
  else if (0 == strcmp (field_name, "encoding-name"))
  {
    if (type != G_TYPE_STRING)
    {
      return FALSE;
    }
    if (!codec->encoding_name)
    {
      codec->encoding_name = g_value_dup_string (value);
    }
  }
  else if (0 == strcmp (field_name, "encoding-params"))
  {
    if (type != G_TYPE_STRING)
    {
      return FALSE;
    }
    codec->channels = (guint) g_ascii_strtoull (
                                       g_value_get_string (value), NULL, 10);
  }
  else
  {
    if (type == G_TYPE_STRING)
      fs_codec_add_optional_parameter (codec, field_name,
          g_value_get_string (value));
  }

  return TRUE;
}
Ejemplo n.º 2
0
static VALUE
int_range_get_max(VALUE self)
{
    return INT2NUM(gst_value_get_int_range_max(RVAL2GOBJ(self)));
}
static gboolean
gst_video_crop_transform_dimension_value (const GValue * src_val,
    gint delta, GValue * dest_val, GstPadDirection direction, gboolean dynamic)
{
  gboolean ret = TRUE;

  if (G_VALUE_HOLDS_INT (src_val)) {
    gint ival = g_value_get_int (src_val);
    ival = gst_video_crop_transform_dimension (ival, delta);

    if (dynamic) {
      if (direction == GST_PAD_SRC) {
        if (ival == G_MAXINT) {
          g_value_init (dest_val, G_TYPE_INT);
          g_value_set_int (dest_val, ival);
        } else {
          g_value_init (dest_val, GST_TYPE_INT_RANGE);
          gst_value_set_int_range (dest_val, ival, G_MAXINT);
        }
      } else {
        if (ival == 1) {
          g_value_init (dest_val, G_TYPE_INT);
          g_value_set_int (dest_val, ival);
        } else {
          g_value_init (dest_val, GST_TYPE_INT_RANGE);
          gst_value_set_int_range (dest_val, 1, ival);
        }
      }
    } else {
      g_value_init (dest_val, G_TYPE_INT);
      g_value_set_int (dest_val, ival);
    }
  } else if (GST_VALUE_HOLDS_INT_RANGE (src_val)) {
    gint min = gst_value_get_int_range_min (src_val);
    gint max = gst_value_get_int_range_max (src_val);

    min = gst_video_crop_transform_dimension (min, delta);
    max = gst_video_crop_transform_dimension (max, delta);

    if (dynamic) {
      if (direction == GST_PAD_SRC)
        max = G_MAXINT;
      else
        min = 1;
    }

    if (min == max) {
      g_value_init (dest_val, G_TYPE_INT);
      g_value_set_int (dest_val, min);
    } else {
      g_value_init (dest_val, GST_TYPE_INT_RANGE);
      gst_value_set_int_range (dest_val, min, max);
    }
  } else if (GST_VALUE_HOLDS_LIST (src_val)) {
    gint i;

    g_value_init (dest_val, GST_TYPE_LIST);

    for (i = 0; i < gst_value_list_get_size (src_val); ++i) {
      const GValue *list_val;
      GValue newval = { 0, };

      list_val = gst_value_list_get_value (src_val, i);
      if (gst_video_crop_transform_dimension_value (list_val, delta, &newval,
              direction, dynamic))
        gst_value_list_append_value (dest_val, &newval);
      g_value_unset (&newval);
    }

    if (gst_value_list_get_size (dest_val) == 0) {
      g_value_unset (dest_val);
      ret = FALSE;
    }
  } else {
    ret = FALSE;
  }

  return ret;
}
Ejemplo n.º 4
0
// TODO: gets formats for cameras, when a format return a range it gets
// in steps /2 and *2 from min to max, for format7 it should be free to get any size
static void
get_supported_video_formats (ofGstDevice &webcam_device, GstCaps &caps)
{
    int i;
    int num_structures;

    num_structures = gst_caps_get_size (&caps);
    for (i = 0; i < num_structures; i++)
    {
        GstStructure *structure;
        const GValue *width, *height;
        structure = gst_caps_get_structure (&caps, i);

        width  = gst_structure_get_value (structure, "width");
        height = gst_structure_get_value (structure, "height");

        if (G_VALUE_HOLDS_INT (width))
        {
            ofGstVideoFormat * video_format = new ofGstVideoFormat;

            video_format->mimetype = g_strdup (gst_structure_get_name (structure));
            gst_structure_get_int (structure, "width", &(video_format->width));
            gst_structure_get_int (structure, "height", &(video_format->height));
            add_video_format(webcam_device, video_format, *structure);
        }
        else if (GST_VALUE_HOLDS_INT_RANGE (width))
        {
            int min_width, max_width, min_height, max_height;
            int cur_width, cur_height;

            min_width  = gst_value_get_int_range_min (width);
            max_width  = gst_value_get_int_range_max (width);
            min_height = gst_value_get_int_range_min (height);
            max_height = gst_value_get_int_range_max (height);

            cur_width  = min_width;
            cur_height = min_height;
            /* Gstreamer will sometimes give us a range with min_xxx == max_xxx,
             we use <= here (and not below) to make this work */
            while (cur_width <= max_width && cur_height <= max_height)
            {
                ofGstVideoFormat * video_format = new ofGstVideoFormat;

                video_format->mimetype = g_strdup (gst_structure_get_name (structure));
                video_format->width    = cur_width;
                video_format->height   = cur_height;
                add_video_format(webcam_device, video_format, *structure);
                cur_width  *= 2;
                cur_height *= 2;
            }

            cur_width  = max_width;
            cur_height = max_height;
            while (cur_width > min_width && cur_height > min_height)
            {
                ofGstVideoFormat * video_format = new ofGstVideoFormat;

                video_format->mimetype = g_strdup (gst_structure_get_name (structure));
                video_format->width    = cur_width;
                video_format->height   = cur_height;
                add_video_format(webcam_device, video_format, *structure);
                cur_width  /= 2;
                cur_height /= 2;
            }
        }
        else
        {
            g_critical ("GValue type %s, cannot be handled for resolution width", G_VALUE_TYPE_NAME (width));
        }
    }

    /* Sort the format array (so that it will show sorted in the resolution
    selection GUI), and rebuild the hashtable (as that will be invalid after
    the sorting) */
    sort (webcam_device.video_formats.begin(), webcam_device.video_formats.end(), resolution_compare);
    g_hash_table_remove_all (webcam_device.supported_resolutions);
    for (i = 0; i < webcam_device.num_video_formats; i++) {
        ofGstVideoFormat * format = webcam_device.video_formats[i];

        g_hash_table_insert (webcam_device.supported_resolutions,
                             g_strdup_printf ("%ix%i", format->width,
                                              format->height),
                             GINT_TO_POINTER(i + 1));
    }
}
Ejemplo n.º 5
0
/**
 * update_aspect_filter:
 * @self: camerasrc object
 * @new_caps: new caps of next buffers arriving to view finder sink element
 *
 * Updates aspect ratio capsfilter to maintain aspect ratio, if we need to
 * scale frames for showing them in view finder.
 */
static void
update_aspect_filter (GstWrapperCameraBinSrc * self, GstCaps * new_caps)
{
  // XXX why not instead add a preserve-aspect-ratio property to videoscale?
#if 0
  if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_SCALE) {
    GstCaps *sink_caps, *ar_caps;
    GstStructure *st;
    gint in_w = 0, in_h = 0, sink_w = 0, sink_h = 0, target_w = 0, target_h = 0;
    gdouble ratio_w, ratio_h;
    GstPad *sink_pad;
    const GValue *range;

    sink_pad = gst_element_get_static_pad (camera->view_sink, "sink");

    if (sink_pad) {
      sink_caps = gst_pad_get_caps (sink_pad);
      gst_object_unref (sink_pad);
      if (sink_caps) {
        if (!gst_caps_is_any (sink_caps)) {
          GST_DEBUG_OBJECT (camera, "sink element caps %" GST_PTR_FORMAT,
              sink_caps);
          /* Get maximum resolution that view finder sink accepts */
          st = gst_caps_get_structure (sink_caps, 0);
          if (gst_structure_has_field_typed (st, "width", GST_TYPE_INT_RANGE)) {
            range = gst_structure_get_value (st, "width");
            sink_w = gst_value_get_int_range_max (range);
          }
          if (gst_structure_has_field_typed (st, "height", GST_TYPE_INT_RANGE)) {
            range = gst_structure_get_value (st, "height");
            sink_h = gst_value_get_int_range_max (range);
          }
          GST_DEBUG_OBJECT (camera, "sink element accepts max %dx%d", sink_w,
              sink_h);

          /* Get incoming frames' resolution */
          if (sink_h && sink_w) {
            st = gst_caps_get_structure (new_caps, 0);
            gst_structure_get_int (st, "width", &in_w);
            gst_structure_get_int (st, "height", &in_h);
            GST_DEBUG_OBJECT (camera, "new caps with %dx%d", in_w, in_h);
          }
        }
        gst_caps_unref (sink_caps);
      }
    }

    /* If we get bigger frames than view finder sink accepts, then we scale.
       If we scale we need to adjust aspect ratio capsfilter caps in order
       to maintain aspect ratio while scaling. */
    if (in_w && in_h && (in_w > sink_w || in_h > sink_h)) {
      ratio_w = (gdouble) sink_w / in_w;
      ratio_h = (gdouble) sink_h / in_h;

      if (ratio_w < ratio_h) {
        target_w = sink_w;
        target_h = (gint) (ratio_w * in_h);
      } else {
        target_w = (gint) (ratio_h * in_w);
        target_h = sink_h;
      }

      GST_DEBUG_OBJECT (camera, "setting %dx%d filter to maintain aspect ratio",
          target_w, target_h);
      ar_caps = gst_caps_copy (new_caps);
      gst_caps_set_simple (ar_caps, "width", G_TYPE_INT, target_w, "height",
          G_TYPE_INT, target_h, NULL);
    } else {
      GST_DEBUG_OBJECT (camera, "no scaling");
      ar_caps = new_caps;
    }

    GST_DEBUG_OBJECT (camera, "aspect ratio filter caps %" GST_PTR_FORMAT,
        ar_caps);
    g_object_set (G_OBJECT (camera->aspect_filter), "caps", ar_caps, NULL);
    if (ar_caps != new_caps)
      gst_caps_unref (ar_caps);
  }
#endif
}
Ejemplo n.º 6
0
void test_simplify()
{
  GstStructure *s1, *s2;
  gboolean did_simplify;
  GstCaps *caps;

  caps = gst_caps_from_string (non_simple_caps_string);
  fail_unless (caps != NULL,
      "gst_caps_from_string (non_simple_caps_string) failed");

  did_simplify = gst_caps_do_simplify (caps);
  fail_unless (did_simplify == TRUE,
      "gst_caps_do_simplify() should have worked");

  /* check simplified caps, should be:
   *
   * video/x-raw-rgb, bpp=(int)8, depth=(int)8, endianness=(int)1234,
   *     framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ],
   *     height=(int)[ 16, 4096 ];
   * video/x-raw-yuv, format=(fourcc){ YV12, YUY2, I420 },
   *     width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],
   *     framerate=(fraction)[ 1/100, 100 ]
   */
  fail_unless (gst_caps_get_size (caps) == 2);
  s1 = gst_caps_get_structure (caps, 0);
  s2 = gst_caps_get_structure (caps, 1);
  fail_unless (s1 != NULL);
  fail_unless (s2 != NULL);

  if (!gst_structure_has_name (s1, "video/x-raw-rgb")) {
    GstStructure *tmp;

    tmp = s1;
    s1 = s2;
    s2 = tmp;
  }

  fail_unless (gst_structure_has_name (s1, "video/x-raw-rgb"));
  {
    const GValue *framerate_value;
    const GValue *width_value;
    const GValue *height_value;
    const GValue *val_fps;
    GValue test_fps = { 0, };
    gint bpp, depth, endianness;
    gint min_width, max_width;
    gint min_height, max_height;

    fail_unless (gst_structure_get_int (s1, "bpp", &bpp));
    fail_unless (bpp == 8);

    fail_unless (gst_structure_get_int (s1, "depth", &depth));
    fail_unless (depth == 8);

    fail_unless (gst_structure_get_int (s1, "endianness", &endianness));
    fail_unless (endianness == G_LITTLE_ENDIAN);

    g_value_init (&test_fps, GST_TYPE_FRACTION);
    framerate_value = gst_structure_get_value (s1, "framerate");
    fail_unless (framerate_value != NULL);
    fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));

    val_fps = gst_value_get_fraction_range_min (framerate_value);
    gst_value_set_fraction (&test_fps, 1, 100);
    fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);

    val_fps = gst_value_get_fraction_range_max (framerate_value);
    gst_value_set_fraction (&test_fps, 100, 1);
    fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);

    g_value_unset (&test_fps);

    width_value = gst_structure_get_value (s1, "width");
    fail_unless (width_value != NULL);
    fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value));
    min_width = gst_value_get_int_range_min (width_value);
    max_width = gst_value_get_int_range_max (width_value);
    fail_unless (min_width == 16 && max_width == 4096);

    height_value = gst_structure_get_value (s1, "height");
    fail_unless (height_value != NULL);
    fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value));
    min_height = gst_value_get_int_range_min (height_value);
    max_height = gst_value_get_int_range_max (height_value);
    fail_unless (min_height == 16 && max_height == 4096);
  }

  fail_unless (gst_structure_has_name (s2, "video/x-raw-yuv"));
  {
    const GValue *framerate_value;
    const GValue *format_value;
    const GValue *width_value;
    const GValue *height_value;
    const GValue *val_fps;
    GValue test_fps = { 0, };
    gint min_width, max_width;
    gint min_height, max_height;

    format_value = gst_structure_get_value (s2, "format");
    fail_unless (format_value != NULL);
    fail_unless (GST_VALUE_HOLDS_LIST (format_value));
    fail_unless (gst_value_list_get_size (format_value) == 3);
    fail_unless (check_fourcc_list (format_value) == TRUE);

    g_value_init (&test_fps, GST_TYPE_FRACTION);
    framerate_value = gst_structure_get_value (s2, "framerate");
    fail_unless (framerate_value != NULL);
    fail_unless (GST_VALUE_HOLDS_FRACTION_RANGE (framerate_value));

    val_fps = gst_value_get_fraction_range_min (framerate_value);
    gst_value_set_fraction (&test_fps, 1, 100);
    fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);

    val_fps = gst_value_get_fraction_range_max (framerate_value);
    gst_value_set_fraction (&test_fps, 100, 1);
    fail_unless (gst_value_compare (&test_fps, val_fps) == GST_VALUE_EQUAL);

    g_value_unset (&test_fps);

    width_value = gst_structure_get_value (s2, "width");
    fail_unless (width_value != NULL);
    fail_unless (GST_VALUE_HOLDS_INT_RANGE (width_value));
    min_width = gst_value_get_int_range_min (width_value);
    max_width = gst_value_get_int_range_max (width_value);
    fail_unless (min_width == 16 && max_width == 4096);

    height_value = gst_structure_get_value (s2, "height");
    fail_unless (height_value != NULL);
    fail_unless (GST_VALUE_HOLDS_INT_RANGE (height_value));
    min_height = gst_value_get_int_range_min (height_value);
    max_height = gst_value_get_int_range_max (height_value);
    fail_unless (min_height == 16 && max_height == 4096);
  }

  gst_caps_unref (caps);
}