예제 #1
0
static void
setup (void)
{
  GstTagSetter *setter;
  gchar *desc_str;
  GstCaps *filter_caps;
  GstBus *bus;
  gint i;

  GST_INFO ("init");

  main_loop = g_main_loop_new (NULL, TRUE);

  camera = gst_check_setup_element ("camerabin");

  setup_camerabin_elements (camera);

  g_signal_connect (camera, "image-done", G_CALLBACK (capture_done), main_loop);

  bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
  gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop);
  gst_bus_set_sync_handler (bus, bus_sync_callback, main_loop);
  gst_object_unref (bus);

  filter_caps = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420");
  g_object_set (G_OBJECT (camera), "filter-caps", filter_caps, NULL);
  gst_caps_unref (filter_caps);

  /* force a low framerate here to not timeout the tests because of the
   * encoders */
  g_signal_emit_by_name (camera, "set-video-resolution-fps", 320, 240, 5, 1,
      NULL);

  /* Set some default tags */
  setter = GST_TAG_SETTER (camera);
  desc_str = g_strdup_printf ("Created by %s", g_get_real_name ());

  gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
      GST_TAG_DESCRIPTION, desc_str, NULL);
  g_free (desc_str);

  if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
      GST_STATE_CHANGE_FAILURE) {
    GST_WARNING ("setting camerabin to PLAYING failed");
    gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL);
    gst_object_unref (camera);
    camera = NULL;
  }

  /* create the taglists */
  for (i = 0; i < TAGLISTS_COUNT; i++) {
    taglists[i] = gst_tag_list_new_full (GST_TAG_ARTIST, "test-artist",
        GST_TAG_GEO_LOCATION_LONGITUDE, g_random_double_range (-180, 180),
        GST_TAG_GEO_LOCATION_LATITUDE, g_random_double_range (-90, 90),
        GST_TAG_GEO_LOCATION_ELEVATION, g_random_double_range (0, 3000), NULL);
  }

  GST_INFO ("init finished");
}
예제 #2
0
static GstFlowReturn
gst_multipart_demux_chain (GstPad * pad, GstBuffer * buf)
{
    GstMultipartDemux *multipart;
    GstAdapter *adapter;
    GstClockTime timestamp;
    gint size = 1;
    GstFlowReturn res;

    multipart = GST_MULTIPART_DEMUX (gst_pad_get_parent (pad));
    adapter = multipart->adapter;

    res = GST_FLOW_OK;

    timestamp = GST_BUFFER_TIMESTAMP (buf);

    if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
        gst_adapter_clear (adapter);
    }
    gst_adapter_push (adapter, buf);

    while (gst_adapter_available (adapter) > 0) {
        GstMultipartPad *srcpad;
        GstBuffer *outbuf;
        gboolean created;
        gint datalen;

        if (G_UNLIKELY (!multipart->header_completed)) {
            if ((size = multipart_parse_header (multipart)) < 0) {
                goto nodata;
            } else {
                gst_adapter_flush (adapter, size);
                multipart->header_completed = TRUE;
            }
        }
        if ((size = multipart_find_boundary (multipart, &datalen)) < 0) {
            goto nodata;
        }

        /* Invalidate header info */
        multipart->header_completed = FALSE;
        multipart->content_length = -1;

        if (G_UNLIKELY (datalen <= 0)) {
            GST_DEBUG_OBJECT (multipart, "skipping empty content.");
            gst_adapter_flush (adapter, size - datalen);
        } else {
            srcpad =
                gst_multipart_find_pad_by_mime (multipart,
                                                multipart->mime_type, &created);
            outbuf = gst_adapter_take_buffer (adapter, datalen);
            gst_adapter_flush (adapter, size - datalen);

            gst_buffer_set_caps (outbuf, GST_PAD_CAPS (srcpad->pad));
            if (created) {
                GstTagList *tags;

                /* Push new segment, first buffer has 0 timestamp */
                gst_pad_push_event (srcpad->pad,
                                    gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));

                tags =
                    gst_tag_list_new_full (GST_TAG_CONTAINER_FORMAT, "Multipart", NULL);
                gst_pad_push_event (srcpad->pad, gst_event_new_tag (tags));

                GST_BUFFER_TIMESTAMP (outbuf) = 0;
            } else {
                GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
            }
            GST_DEBUG_OBJECT (multipart,
                              "pushing buffer with timestamp %" GST_TIME_FORMAT,
                              GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
            GST_DEBUG_OBJECT (multipart, "buffer has caps %" GST_PTR_FORMAT,
                              GST_BUFFER_CAPS (outbuf));
            res = gst_pad_push (srcpad->pad, outbuf);
            res = gst_multipart_combine_flows (multipart, srcpad, res);
            if (res != GST_FLOW_OK)
                break;
        }
    }

nodata:
    gst_object_unref (multipart);

    if (G_UNLIKELY (size == MULTIPART_DATA_ERROR))
        return GST_FLOW_ERROR;
    if (G_UNLIKELY (size == MULTIPART_DATA_EOS))
        return GST_FLOW_UNEXPECTED;

    return res;
}
예제 #3
0
static gboolean
mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse,
    GstBuffer * buf)
{
  MPEGSeqHdr new_hdr;
  guint8 *cur, *end;

  cur = GST_BUFFER_DATA (buf);
  end = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf);

  memset (&new_hdr, 0, sizeof (MPEGSeqHdr));

  if (G_UNLIKELY (!mpeg_util_parse_sequence_hdr (&new_hdr, cur, end)))
    return FALSE;

  if (new_hdr.width < 16 || new_hdr.width > 4096 ||
      new_hdr.height < 16 || new_hdr.height > 4096) {
    GST_WARNING_OBJECT (mpegvideoparse, "Width/height out of valid range "
        "[16, 4096]");
    return FALSE;
  }

  if (memcmp (&mpegvideoparse->seq_hdr, &new_hdr, sizeof (MPEGSeqHdr)) != 0) {
    GstCaps *caps;
    GstBuffer *seq_buf;
    /*
     * Profile indication - 1 => High, 2 => Spatially Scalable,
     *                      3 => SNR Scalable, 4 => Main, 5 => Simple
     * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1
     */
    const gchar *profiles[] = { "high", "spatial", "snr", "main", "simple" };
    /*
     * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low,
     *                    except in the case of profile = 0
     */
    const gchar *levels[] = { "high", "high-1440", "main", "low" };

    /* Store the entire sequence header + sequence header extension
       for output as codec_data */
    seq_buf = gst_buffer_copy (buf);
    gst_buffer_replace (&mpegvideoparse->seq_hdr_buf, seq_buf);
    gst_buffer_unref (seq_buf);

    caps = gst_caps_new_simple ("video/mpeg",
        "systemstream", G_TYPE_BOOLEAN, FALSE,
        "parsed", G_TYPE_BOOLEAN, TRUE,
        "mpegversion", G_TYPE_INT, new_hdr.mpeg_version,
        "width", G_TYPE_INT, new_hdr.width,
        "height", G_TYPE_INT, new_hdr.height,
        "framerate", GST_TYPE_FRACTION, new_hdr.fps_n, new_hdr.fps_d,
        "pixel-aspect-ratio", GST_TYPE_FRACTION, new_hdr.par_w, new_hdr.par_h,
        "interlaced", G_TYPE_BOOLEAN, !new_hdr.progressive,
        "codec_data", GST_TYPE_BUFFER, seq_buf, NULL);

    if (new_hdr.mpeg_version == 2) {
      const gchar *profile = NULL, *level = NULL;

      if (new_hdr.profile > 0 && new_hdr.profile < 6)
        profile = profiles[new_hdr.profile - 1];

      if ((new_hdr.level > 3) && (new_hdr.level < 11) &&
          (new_hdr.level % 2 == 0))
        level = levels[(new_hdr.level >> 1) - 1];

      if (new_hdr.profile == 8) {
        /* Non-hierarchical profile */
        switch (new_hdr.level) {
          case 2:
            level = levels[0];
          case 5:
            level = levels[2];
            profile = "4:2:2";
            break;
          case 10:
            level = levels[0];
          case 11:
            level = levels[1];
          case 13:
            level = levels[2];
          case 14:
            level = levels[3];
            profile = "multiview";
            break;
          default:
            break;
        }
      }

      if (profile)
        gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
      else
        GST_DEBUG ("Invalid profile - %u", new_hdr.profile);

      if (level)
        gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
      else
        GST_DEBUG ("Invalid level - %u", new_hdr.level);
    }

    GST_DEBUG ("New mpegvideoparse caps: %" GST_PTR_FORMAT, caps);
    if (!gst_pad_set_caps (mpegvideoparse->srcpad, caps)) {
      gst_caps_unref (caps);
      return FALSE;
    }
    gst_caps_unref (caps);

    if (new_hdr.bitrate > 0) {
      GstTagList *taglist;

      taglist = gst_tag_list_new_full (GST_TAG_BITRATE, new_hdr.bitrate, NULL);
      gst_element_found_tags_for_pad (GST_ELEMENT_CAST (mpegvideoparse),
          mpegvideoparse->srcpad, taglist);
    }

    /* And update the new_hdr into our stored version */
    mpegvideoparse->seq_hdr = new_hdr;
  }