static GstFlowReturn gst_vtdec_decode_buffer (GstVTDec * self, GstBuffer * buf) { GstVTApi *vt = self->ctx->vt; CMSampleBufferRef sbuf; VTStatus status; VTDecodeFrameFlags frame_flags = 0; GstFlowReturn ret = GST_FLOW_OK; sbuf = gst_vtdec_sample_buffer_from (self, buf); self->flush = FALSE; status = vt->VTDecompressionSessionDecodeFrame (self->session, sbuf, frame_flags, buf, NULL); if (status != 0) { GST_WARNING_OBJECT (self, "VTDecompressionSessionDecodeFrame returned %d", status); } status = vt->VTDecompressionSessionWaitForAsynchronousFrames (self->session); if (status != 0) { GST_WARNING_OBJECT (self, "VTDecompressionSessionWaitForAsynchronousFrames returned %d", status); } CFRelease (sbuf); gst_buffer_unref (buf); if (self->flush) { if (!gst_vtdec_negotiate_downstream (self)) { ret = GST_FLOW_NOT_NEGOTIATED; goto error; } g_queue_sort (self->cur_outbufs, (GCompareDataFunc) _sort_buffers, NULL); while (!g_queue_is_empty (self->cur_outbufs)) { buf = g_queue_pop_head (self->cur_outbufs); GST_LOG_OBJECT (self, "Pushing buffer with PTS:%" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (buf))); ret = gst_pad_push (self->srcpad, buf); if (ret != GST_FLOW_OK) { goto error; } } }; exit: return ret; error: { g_queue_free_full (self->cur_outbufs, (GDestroyNotify) gst_buffer_unref); self->cur_outbufs = g_queue_new (); goto exit; } }
static GstFlowReturn gst_vtdec_decode_buffer (GstVTDec * self, GstBuffer * buf) { GstVTApi *vt = self->ctx->vt; CMSampleBufferRef sbuf; VTStatus status; GstFlowReturn ret = GST_FLOW_OK; guint i; self->cur_inbuf = buf; sbuf = gst_vtdec_sample_buffer_from (self, buf); status = vt->VTDecompressionSessionDecodeFrame (self->session, sbuf, 0, 0, 0); if (status != 0) { GST_WARNING_OBJECT (self, "VTDecompressionSessionDecodeFrame returned %d", status); } status = vt->VTDecompressionSessionWaitForAsynchronousFrames (self->session); if (status != 0) { GST_WARNING_OBJECT (self, "VTDecompressionSessionWaitForAsynchronousFrames returned %d", status); } self->ctx->cm->FigSampleBufferRelease (sbuf); 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) { ret = gst_pad_push (self->srcpad, buf); } else { gst_buffer_unref (buf); } } g_ptr_array_set_size (self->cur_outbufs, 0); return ret; }