Esempio n. 1
0
static GstFlowReturn
gst_mio_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf)
{
  GstMIOVideoSrc *self = GST_MIO_VIDEO_SRC_CAST (pushsrc);
  GstCMApi *cm = self->ctx->cm;
  CMFormatDescriptionRef format;

  FRAME_QUEUE_LOCK (self);
  while (self->running && g_queue_is_empty (self->queue))
    FRAME_QUEUE_WAIT (self);
  *buf = g_queue_pop_tail (self->queue);
  FRAME_QUEUE_UNLOCK (self);

  if (G_UNLIKELY (!self->running))
    goto shutting_down;

  format = cm->CMSampleBufferGetFormatDescription
      (GST_CORE_MEDIA_BUFFER (*buf)->sample_buf);
  if (self->prev_format != NULL &&
      !cm->CMFormatDescriptionEqual (format, self->prev_format)) {
    goto unexpected_format;
  }
  cm->FigFormatDescriptionRelease (self->prev_format);
  self->prev_format = cm->FigFormatDescriptionRetain (format);

  if (self->prev_offset == GST_BUFFER_OFFSET_NONE ||
      GST_BUFFER_OFFSET (*buf) - self->prev_offset != 1) {
    GST_BUFFER_FLAG_SET (*buf, GST_BUFFER_FLAG_DISCONT);
  }
  self->prev_offset = GST_BUFFER_OFFSET (*buf);

  return GST_FLOW_OK;

  /* ERRORS */
shutting_down:
  {
    if (*buf != NULL) {
      gst_buffer_unref (*buf);
      *buf = NULL;
    }

    return GST_FLOW_FLUSHING;
  }
unexpected_format:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, READ,
        ("capture format changed unexpectedly"),
        ("another application likely reconfigured the device"));

    if (*buf != NULL) {
      gst_buffer_unref (*buf);
      *buf = NULL;
    }

    return GST_FLOW_ERROR;
  }
}
Esempio n. 2
0
static gboolean
gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf)
{
  gboolean result;
  GstCMApi *cm = self->ctx->cm;
  GstCaps *caps;
  GstStructure *s;

  if (self->caps_width == self->negotiated_width &&
      self->caps_height == self->negotiated_height &&
      self->caps_fps_n == self->negotiated_fps_n &&
      self->caps_fps_d == self->negotiated_fps_d) {
    return TRUE;
  }

  caps = gst_caps_copy (gst_pad_get_pad_template_caps (self->srcpad));
  s = gst_caps_get_structure (caps, 0);
  gst_structure_set (s,
      "width", G_TYPE_INT, self->negotiated_width,
      "height", G_TYPE_INT, self->negotiated_height,
      "framerate", GST_TYPE_FRACTION,
      self->negotiated_fps_n, self->negotiated_fps_d, NULL);

  if (self->details->format_id == kVTFormatH264) {
    CMFormatDescriptionRef fmt;
    CFDictionaryRef atoms;
    CFStringRef avccKey;
    CFDataRef avcc;
    GstBuffer *codec_data;

    fmt = cm->CMSampleBufferGetFormatDescription (sbuf);
    atoms = cm->CMFormatDescriptionGetExtension (fmt,
        *(cm->kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms));
    avccKey = CFStringCreateWithCString (NULL, "avcC", kCFStringEncodingUTF8);
    avcc = CFDictionaryGetValue (atoms, avccKey);
    CFRelease (avccKey);
    codec_data = gst_buffer_new_and_alloc (CFDataGetLength (avcc));
    CFDataGetBytes (avcc, CFRangeMake (0, CFDataGetLength (avcc)),
        GST_BUFFER_DATA (codec_data));

    gst_structure_set (s, "codec_data", GST_TYPE_BUFFER, codec_data, NULL);

    gst_buffer_unref (codec_data);
  }

  result = gst_pad_set_caps (self->srcpad, caps);

  gst_caps_unref (caps);

  self->caps_width = self->negotiated_width;
  self->caps_height = self->negotiated_height;
  self->caps_fps_n = self->negotiated_fps_n;
  self->caps_fps_d = self->negotiated_fps_d;

  return result;
}