Пример #1
0
static void
gst_vtdec_enqueue_frame (void *data1, void *data2, VTStatus result,
    VTDecodeInfoFlags info, CVBufferRef cvbuf, CMTime pts, CMTime duration)
{
  GstVTDec *self = GST_VTDEC_CAST (data1);
  GstBuffer *src_buf = GST_BUFFER (data2);
  GstBuffer *buf;

  if (result != kVTSuccess) {
    GST_ERROR_OBJECT (self, "Error decoding frame %d", result);
    goto beach;
  }

  if (kVTDecodeInfo_FrameDropped & info) {
    GST_WARNING_OBJECT (self, "Frame dropped");
    goto beach;
  }

  buf = gst_core_video_buffer_new (cvbuf, &self->vinfo);
  gst_buffer_copy_into (buf, src_buf, GST_BUFFER_COPY_METADATA, 0, -1);
  GST_BUFFER_PTS (buf) = pts.value;
  GST_BUFFER_DURATION (buf) = duration.value;

  g_queue_push_head (self->cur_outbufs, buf);
  if (GST_BUFFER_PTS (src_buf) <= GST_BUFFER_DTS (src_buf)) {
    GST_LOG_OBJECT (self, "Flushing interal queue of buffers");
    self->flush = TRUE;
  } else {
    GST_LOG_OBJECT (self, "Queuing buffer");
  }

beach:
  return;
}
Пример #2
0
static void
gst_vtdec_enqueue_frame (void *data, gsize unk1, VTStatus result, gsize unk2,
    CVBufferRef cvbuf)
{
  GstVTDec *self = GST_VTDEC_CAST (data);
  GstBuffer *buf;

  if (result != kVTSuccess)
    goto beach;

  buf = gst_core_video_buffer_new (self->ctx, cvbuf, &self->vinfo);
  gst_buffer_copy_into (buf, self->cur_inbuf, GST_BUFFER_COPY_METADATA, 0, -1);

  g_ptr_array_add (self->cur_outbufs, buf);

beach:
  return;
}
Пример #3
0
static GstStateChangeReturn
gst_vtdec_change_state (GstElement * element, GstStateChange transition)
{
  GstVTDec *self = GST_VTDEC_CAST (element);
  GError *error = NULL;
  GstStateChangeReturn ret;

  if (transition == GST_STATE_CHANGE_NULL_TO_READY) {
    self->ctx = gst_core_media_ctx_new (GST_API_CORE_VIDEO | GST_API_CORE_MEDIA
        | GST_API_VIDEO_TOOLBOX, &error);
    if (error != NULL)
      goto api_error;

    self->cur_outbufs = g_ptr_array_new ();
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  if (transition == GST_STATE_CHANGE_READY_TO_NULL) {
    gst_vtdec_destroy_session (self, &self->session);

    self->ctx->cm->FigFormatDescriptionRelease (self->fmt_desc);
    self->fmt_desc = NULL;

    gst_video_info_init (&self->vinfo);

    g_ptr_array_free (self->cur_outbufs, TRUE);
    self->cur_outbufs = NULL;

    g_object_unref (self->ctx);
    self->ctx = NULL;
  }

  return ret;

api_error:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, FAILED, ("API error"),
        ("%s", error->message));
    g_clear_error (&error);
    return GST_STATE_CHANGE_FAILURE;
  }
}
Пример #4
0
static GstFlowReturn
gst_vtdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstVTDec *self = GST_VTDEC_CAST (parent);

  if (!gst_vtdec_is_negotiated (self))
    goto not_negotiated;

  if (self->session == NULL)
    goto pending_caps;

  return gst_vtdec_decode_buffer (self, buf);

not_negotiated:
  GST_DEBUG_OBJECT (self, "chain called while not negotiated");
  gst_buffer_unref (buf);
  return GST_FLOW_NOT_NEGOTIATED;

pending_caps:
  gst_buffer_unref (buf);
  GST_DEBUG_OBJECT (self, "dropped buffer %p (waiting for complete caps)", buf);
  return GST_FLOW_OK;
}
Пример #5
0
static gboolean
gst_vtdec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstVTDec *self = GST_VTDEC_CAST (parent);
  gboolean forward = TRUE;
  gboolean res = TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_vtdec_sink_setcaps (self, caps);
    }
    default:
      break;
  }

  if (forward)
    res = gst_pad_event_default (pad, parent, event);
  return res;
}