static gboolean gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf) { gboolean result; 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_pad_get_pad_template_caps (self->srcpad); caps = gst_caps_make_writable (caps); 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; gpointer codec_data; gsize codec_data_size; GstBuffer *codec_data_buf; fmt = CMSampleBufferGetFormatDescription (sbuf); atoms = CMFormatDescriptionGetExtension (fmt, kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms); avccKey = CFStringCreateWithCString (NULL, "avcC", kCFStringEncodingUTF8); avcc = CFDictionaryGetValue (atoms, avccKey); CFRelease (avccKey); codec_data_size = CFDataGetLength (avcc); codec_data = g_malloc (codec_data_size); CFDataGetBytes (avcc, CFRangeMake (0, codec_data_size), codec_data); codec_data_buf = gst_buffer_new_wrapped (codec_data, codec_data_size); gst_structure_set (s, "codec_data", GST_TYPE_BUFFER, codec_data_buf, NULL); gst_buffer_unref (codec_data_buf); } result = gst_pad_push_event (self->srcpad, gst_event_new_caps (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; }
OSStatus CMPVideoFormatDescriptionCopyExtradata(CFAllocatorRef allocator, CMVideoFormatDescriptionRef formatDescription, CFDataRef *outExtradata) { const FourCharCode mediaSubType = CMFormatDescriptionGetMediaSubType(formatDescription); if(mediaSubType == kCMVideoCodecType_MPEG4Video || mediaSubType == kCMVideoCodecType_H264) { CFDictionaryRef atoms = CMFormatDescriptionGetExtension(formatDescription, kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms); CFDataRef extradata = CFDictionaryGetValue(atoms, CFSTR("avcC")); if(extradata == nil) { return CMPParameterError; } *outExtradata = CFDataCreateCopy(allocator, extradata); return noErr; } else { *outExtradata = NULL; return noErr; } }