summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOle André Vadla Ravnås <oravnas@cisco.com>2010-12-10 00:58:58 +0100
committerOle André Vadla Ravnås <oravnas@cisco.com>2010-12-10 04:07:05 +0100
commitf3d8e3920dfc4126a8c98e4e376b8f2fb21d560c (patch)
tree9549136f487a8317ff5de21eb68429ed70593061
parentf7e5878c9e4c905ffab0de443ac92715db500cb6 (diff)
applemedia: only enqueue buffers in the VideoToolbox callbacks
These callbacks may fire from any thread, hence we should only enqueue buffers and let the streaming thread take care of the rest as soon as the blocking encode or decode operation has finished.
-rw-r--r--sys/applemedia/vtdec.c21
-rw-r--r--sys/applemedia/vtenc.c25
2 files changed, 26 insertions, 20 deletions
diff --git a/sys/applemedia/vtdec.c b/sys/applemedia/vtdec.c
index eb5d2f1ac..22db2e869 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 43a16229e..c7878482c 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);