Esempio n. 1
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;
}