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; } }
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; }