diff --git a/sys/applemedia/vtdec.c b/sys/applemedia/vtdec.c index eb5d2f1ac3..22db2e8696 100644 --- a/sys/applemedia/vtdec.c +++ b/sys/applemedia/vtdec.c @@ -45,7 +45,7 @@ static VTDecompressionSessionRef gst_vtdec_create_session (GstVTDec * self, static void gst_vtdec_destroy_session (GstVTDec * self, VTDecompressionSessionRef * session); static GstFlowReturn gst_vtdec_decode_buffer (GstVTDec * self, GstBuffer * buf); -static void gst_vtdec_output_frame (void *data, gsize unk1, VTStatus result, +static void gst_vtdec_enqueue_frame (void *data, gsize unk1, VTStatus result, gsize unk2, CVBufferRef cvbuf); static CMSampleBufferRef gst_vtdec_sample_buffer_from (GstVTDec * self, @@ -358,7 +358,7 @@ gst_vtdec_create_session (GstVTDec * self, CMFormatDescriptionRef fmt_desc) gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferBytesPerRowAlignmentKey), 2 * self->negotiated_width); - callback.func = gst_vtdec_output_frame; + callback.func = gst_vtdec_enqueue_frame; callback.data = self; status = self->ctx->vt->VTDecompressionSessionCreate (NULL, fmt_desc, @@ -407,13 +407,20 @@ gst_vtdec_decode_buffer (GstVTDec * self, GstBuffer * buf) self->cur_inbuf = NULL; gst_buffer_unref (buf); + if (self->cur_outbufs->len > 0) { + if (!gst_vtdec_negotiate_downstream (self)) + ret = GST_FLOW_NOT_NEGOTIATED; + } + for (i = 0; i != self->cur_outbufs->len; i++) { GstBuffer *buf = g_ptr_array_index (self->cur_outbufs, i); - if (ret == GST_FLOW_OK) + if (ret == GST_FLOW_OK) { + gst_buffer_set_caps (buf, GST_PAD_CAPS (self->srcpad)); ret = gst_pad_push (self->srcpad, buf); - else + } else { gst_buffer_unref (buf); + } } g_ptr_array_set_size (self->cur_outbufs, 0); @@ -421,7 +428,7 @@ gst_vtdec_decode_buffer (GstVTDec * self, GstBuffer * buf) } static void -gst_vtdec_output_frame (void *data, gsize unk1, VTStatus result, gsize unk2, +gst_vtdec_enqueue_frame (void *data, gsize unk1, VTStatus result, gsize unk2, CVBufferRef cvbuf) { GstVTDec *self = GST_VTDEC_CAST (data); @@ -430,11 +437,7 @@ gst_vtdec_output_frame (void *data, gsize unk1, VTStatus result, gsize unk2, if (result != kVTSuccess) goto beach; - if (!gst_vtdec_negotiate_downstream (self)) - goto beach; - buf = gst_core_video_buffer_new (self->ctx, cvbuf); - gst_buffer_set_caps (buf, GST_PAD_CAPS (self->srcpad)); gst_buffer_copy_metadata (buf, self->cur_inbuf, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); diff --git a/sys/applemedia/vtenc.c b/sys/applemedia/vtenc.c index 43a16229e1..c7878482c3 100644 --- a/sys/applemedia/vtenc.c +++ b/sys/applemedia/vtenc.c @@ -77,7 +77,7 @@ static VTStatus gst_vtenc_session_configure_property_double (GstVTEnc * self, VTCompressionSessionRef session, CFStringRef name, gdouble value); static GstFlowReturn gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf); -static VTStatus gst_vtenc_output_buffer (void *data, int a2, int a3, int a4, +static VTStatus gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4, CMSampleBufferRef sbuf, int a6, int a7); static gboolean gst_vtenc_buffer_is_keyframe (GstVTEnc * self, CMSampleBufferRef sbuf); @@ -411,9 +411,7 @@ gst_vtenc_negotiate_downstream (GstVTEnc * self, CMSampleBufferRef sbuf) gst_buffer_unref (codec_data); } - GST_OBJECT_UNLOCK (self); result = gst_pad_set_caps (self->srcpad, caps); - GST_OBJECT_LOCK (self); gst_caps_unref (caps); @@ -502,7 +500,7 @@ gst_vtenc_create_session (GstVTEnc * self) gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferHeightKey), self->negotiated_height); - callback.func = gst_vtenc_output_buffer; + callback.func = gst_vtenc_enqueue_buffer; callback.data = self; status = vt->VTCompressionSessionCreate (NULL, @@ -770,13 +768,22 @@ gst_vtenc_encode_frame (GstVTEnc * self, GstBuffer * buf) self->cur_inbuf = NULL; gst_buffer_unref (buf); + if (self->cur_outbufs->len > 0) { + GstCoreMediaBuffer *cmbuf = + GST_CORE_MEDIA_BUFFER_CAST (g_ptr_array_index (self->cur_outbufs, 0)); + if (!gst_vtenc_negotiate_downstream (self, cmbuf->sample_buf)) + ret = GST_FLOW_NOT_NEGOTIATED; + } + for (i = 0; i != self->cur_outbufs->len; i++) { GstBuffer *buf = g_ptr_array_index (self->cur_outbufs, i); - if (ret == GST_FLOW_OK) + if (ret == GST_FLOW_OK) { + gst_buffer_set_caps (buf, GST_PAD_CAPS (self->srcpad)); ret = gst_pad_push (self->srcpad, buf); - else + } else { gst_buffer_unref (buf); + } } g_ptr_array_set_size (self->cur_outbufs, 0); @@ -792,7 +799,7 @@ cv_error: } static VTStatus -gst_vtenc_output_buffer (void *data, int a2, int a3, int a4, +gst_vtenc_enqueue_buffer (void *data, int a2, int a3, int a4, CMSampleBufferRef sbuf, int a6, int a7) { GstVTEnc *self = data; @@ -812,11 +819,7 @@ gst_vtenc_output_buffer (void *data, int a2, int a3, int a4, } self->expect_keyframe = FALSE; - if (!gst_vtenc_negotiate_downstream (self, sbuf)) - goto beach; - buf = gst_core_media_buffer_new (self->ctx, sbuf); - gst_buffer_set_caps (buf, GST_PAD_CAPS (self->srcpad)); gst_buffer_copy_metadata (buf, self->cur_inbuf, GST_BUFFER_COPY_TIMESTAMPS); if (is_keyframe) { GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);