Exemplo n.º 1
0
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;
  }
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
static VTCompressionSessionRef
gst_vtenc_create_session (GstVTEnc * self)
{
  VTCompressionSessionRef session = NULL;
  GstCVApi *cv = self->ctx->cv;
  GstVTApi *vt = self->ctx->vt;
  CFMutableDictionaryRef pb_attrs;
  VTCompressionOutputCallback callback;
  VTStatus status;

  pb_attrs = CFDictionaryCreateMutable (NULL, 0, &kCFTypeDictionaryKeyCallBacks,
      &kCFTypeDictionaryValueCallBacks);
  gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferPixelFormatTypeKey),
      kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
  gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferWidthKey),
      self->negotiated_width);
  gst_vtutil_dict_set_i32 (pb_attrs, *(cv->kCVPixelBufferHeightKey),
      self->negotiated_height);

  callback.func = gst_vtenc_enqueue_buffer;
  callback.data = self;

  status = vt->VTCompressionSessionCreate (NULL,
      self->negotiated_width, self->negotiated_height,
      self->details->format_id, 0, pb_attrs, 0, callback, &session);
  GST_INFO_OBJECT (self, "VTCompressionSessionCreate for %d x %d => %d",
      self->negotiated_width, self->negotiated_height, status);
  if (status != kVTSuccess)
    goto beach;

  if (self->dump_properties) {
    gst_vtenc_session_dump_properties (self, session);

    self->dump_properties = FALSE;
  }

  gst_vtenc_session_configure_usage (self, session, gst_vtenc_get_usage (self));

  gst_vtenc_session_configure_expected_framerate (self, session,
      (gdouble) self->negotiated_fps_n / (gdouble) self->negotiated_fps_d);
  gst_vtenc_session_configure_expected_duration (self, session,
      (gdouble) self->negotiated_fps_d / (gdouble) self->negotiated_fps_n);

  status = vt->VTCompressionSessionSetProperty (session,
      *(vt->kVTCompressionPropertyKey_ProfileLevel),
      *(vt->kVTProfileLevel_H264_Baseline_3_0));
  GST_DEBUG_OBJECT (self, "kVTCompressionPropertyKey_ProfileLevel => %d",
      status);

  status = vt->VTCompressionSessionSetProperty (session,
      *(vt->kVTCompressionPropertyKey_AllowTemporalCompression),
      kCFBooleanTrue);
  GST_DEBUG_OBJECT (self,
      "kVTCompressionPropertyKey_AllowTemporalCompression => %d", status);

  gst_vtenc_session_configure_max_keyframe_interval (self, session, 0);
  gst_vtenc_session_configure_max_keyframe_interval_duration (self, session,
      G_MAXDOUBLE);

  gst_vtenc_session_configure_bitrate (self, session,
      gst_vtenc_get_bitrate (self));

beach:
  CFRelease (pb_attrs);

  return session;
}