Esempio n. 1
0
static GstFlowReturn
gst_frei0r_filter_transform (GstBaseTransform * trans, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstFrei0rFilter *self = GST_FREI0R_FILTER (trans);
  GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (trans);
  gdouble time;

  if (G_UNLIKELY (self->width <= 0 || self->height <= 0))
    return GST_FLOW_NOT_NEGOTIATED;

  if (G_UNLIKELY (!self->f0r_instance)) {
    self->f0r_instance =
        gst_frei0r_instance_construct (klass->ftable, klass->properties,
        klass->n_properties, self->property_cache, self->width, self->height);
    if (G_UNLIKELY (!self->f0r_instance))
      return GST_FLOW_ERROR;
  }

  time = ((gdouble) GST_BUFFER_TIMESTAMP (inbuf)) / GST_SECOND;

  if (klass->ftable->update2)
    klass->ftable->update2 (self->f0r_instance, time,
        (const guint32 *) GST_BUFFER_DATA (inbuf), NULL, NULL,
        (guint32 *) GST_BUFFER_DATA (outbuf));
  else
    klass->ftable->update (self->f0r_instance, time,
        (const guint32 *) GST_BUFFER_DATA (inbuf),
        (guint32 *) GST_BUFFER_DATA (outbuf));

  return GST_FLOW_OK;
}
Esempio n. 2
0
static GstFlowReturn
gst_frei0r_mixer_collected (GstCollectPads * pads, GstFrei0rMixer * self)
{
  GstBuffer *inbuf0 = NULL, *inbuf1 = NULL, *inbuf2 = NULL;
  GstBuffer *outbuf = NULL;
  GstFlowReturn ret = GST_FLOW_OK;
  GSList *l;
  GstFrei0rMixerClass *klass = GST_FREI0R_MIXER_GET_CLASS (self);
  GstClockTime timestamp;
  gdouble time;
  GstSegment *segment = NULL;
  GstAllocationParams alloc_params = { 0, 31, 0, 0 };
  GstMapInfo outmap, inmap0, inmap1, inmap2;

  if (G_UNLIKELY (self->info.width <= 0 || self->info.height <= 0))
    return GST_FLOW_NOT_NEGOTIATED;

  if (G_UNLIKELY (!self->f0r_instance)) {
    self->f0r_instance = gst_frei0r_instance_construct (klass->ftable,
        klass->properties, klass->n_properties, self->property_cache,
        self->info.width, self->info.height);
    if (G_UNLIKELY (!self->f0r_instance))
      return GST_FLOW_ERROR;
  }

  if (self->segment_event) {
    gst_pad_push_event (self->src, self->segment_event);
    self->segment_event = NULL;
  }

  /* FIXME Request an allocator and/or pool */
  outbuf = gst_buffer_new_allocate (NULL, self->info.size, &alloc_params);

  for (l = pads->data; l; l = l->next) {
    GstCollectData *cdata = l->data;

    if (cdata->pad == self->sink0) {
      inbuf0 = gst_collect_pads_pop (pads, cdata);
      segment = &cdata->segment;
    } else if (cdata->pad == self->sink1) {
      inbuf1 = gst_collect_pads_pop (pads, cdata);
    } else if (cdata->pad == self->sink2) {
      inbuf2 = gst_collect_pads_pop (pads, cdata);
    }
  }

  if (!inbuf0 || !inbuf1 || (!inbuf2 && self->sink2))
    goto eos;

  gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
  gst_buffer_map (inbuf0, &inmap0, GST_MAP_READ);
  gst_buffer_map (inbuf1, &inmap1, GST_MAP_READ);
  if (inbuf2)
    gst_buffer_map (inbuf2, &inmap2, GST_MAP_READ);

  g_assert (segment != NULL);
  timestamp = GST_BUFFER_PTS (inbuf0);
  timestamp = gst_segment_to_stream_time (segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (timestamp))
    gst_object_sync_values (GST_OBJECT (self), timestamp);

  gst_buffer_copy_into (outbuf, inbuf0,
      GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
  time = ((gdouble) GST_BUFFER_PTS (outbuf)) / GST_SECOND;

  GST_OBJECT_LOCK (self);
  klass->ftable->update2 (self->f0r_instance, time,
      (const guint32 *) inmap0.data, (const guint32 *) inmap1.data,
      (inbuf2) ? (const guint32 *) inmap2.data : NULL, (guint32 *) outmap.data);
  GST_OBJECT_UNLOCK (self);

  gst_buffer_unmap (outbuf, &outmap);
  gst_buffer_unref (inbuf0);
  gst_buffer_unmap (inbuf0, &inmap0);
  gst_buffer_unref (inbuf1);
  gst_buffer_unmap (inbuf1, &inmap1);
  if (inbuf2) {
    gst_buffer_unmap (inbuf2, &inmap2);
    gst_buffer_unref (inbuf2);
  }

  ret = gst_pad_push (self->src, outbuf);

  return ret;

eos:
  {
    GST_DEBUG_OBJECT (self, "no data available, must be EOS");
    gst_buffer_unref (outbuf);

    if (inbuf0)
      gst_buffer_unref (inbuf0);
    if (inbuf1)
      gst_buffer_unref (inbuf1);
    if (inbuf2)
      gst_buffer_unref (inbuf2);

    gst_pad_push_event (self->src, gst_event_new_eos ());
    return GST_FLOW_EOS;
  }
}
Esempio n. 3
0
static GstFlowReturn
gst_frei0r_mixer_collected (GstCollectPads * pads, GstFrei0rMixer * self)
{
  GstBuffer *inbuf0 = NULL, *inbuf1 = NULL, *inbuf2 = NULL;
  GstBuffer *outbuf = NULL;
  GstFlowReturn ret = GST_FLOW_OK;
  GSList *l;
  GstFrei0rMixerClass *klass = GST_FREI0R_MIXER_GET_CLASS (self);
  GstClockTime timestamp;
  gdouble time;
  GstSegment *segment = NULL;

  if (G_UNLIKELY (self->width <= 0 || self->height <= 0))
    return GST_FLOW_NOT_NEGOTIATED;

  if (G_UNLIKELY (!self->f0r_instance)) {
    self->f0r_instance =
        gst_frei0r_instance_construct (klass->ftable, klass->properties,
        klass->n_properties, self->property_cache, self->width, self->height);
    if (G_UNLIKELY (!self->f0r_instance))
      return GST_FLOW_ERROR;
  }

  if (self->newseg_event) {
    gst_pad_push_event (self->src, self->newseg_event);
    self->newseg_event = NULL;
  }

  if ((ret =
          gst_pad_alloc_buffer_and_set_caps (self->src, GST_BUFFER_OFFSET_NONE,
              gst_video_format_get_size (self->fmt, self->width, self->height),
              GST_PAD_CAPS (self->src), &outbuf)) != GST_FLOW_OK)
    return ret;

  for (l = pads->data; l; l = l->next) {
    GstCollectData *cdata = l->data;

    if (cdata->pad == self->sink0) {
      inbuf0 = gst_collect_pads_pop (pads, cdata);
      segment = &cdata->segment;
    } else if (cdata->pad == self->sink1) {
      inbuf1 = gst_collect_pads_pop (pads, cdata);
    } else if (cdata->pad == self->sink2) {
      inbuf2 = gst_collect_pads_pop (pads, cdata);
    }
  }

  if (!inbuf0 || !inbuf1 || (!inbuf2 && self->sink2))
    goto eos;

  g_assert (segment != NULL);
  timestamp = GST_BUFFER_TIMESTAMP (inbuf0);
  timestamp = gst_segment_to_stream_time (segment, GST_FORMAT_TIME, timestamp);

  GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT,
      GST_TIME_ARGS (timestamp));

  if (GST_CLOCK_TIME_IS_VALID (timestamp))
    gst_object_sync_values (G_OBJECT (self), timestamp);

  gst_buffer_copy_metadata (outbuf, inbuf0,
      GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
  time = ((gdouble) GST_BUFFER_TIMESTAMP (outbuf)) / GST_SECOND;

  GST_OBJECT_LOCK (self);
  klass->ftable->update2 (self->f0r_instance, time,
      (const guint32 *) GST_BUFFER_DATA (inbuf0),
      (const guint32 *) GST_BUFFER_DATA (inbuf1),
      (inbuf2) ? (const guint32 *) GST_BUFFER_DATA (inbuf2) : NULL,
      (guint32 *) GST_BUFFER_DATA (outbuf));
  GST_OBJECT_UNLOCK (self);

  gst_buffer_unref (inbuf0);
  gst_buffer_unref (inbuf1);
  if (inbuf2)
    gst_buffer_unref (inbuf2);

  ret = gst_pad_push (self->src, outbuf);

  return ret;

eos:
  {
    GST_DEBUG_OBJECT (self, "no data available, must be EOS");
    gst_buffer_unref (outbuf);

    if (inbuf0)
      gst_buffer_unref (inbuf0);
    if (inbuf1)
      gst_buffer_unref (inbuf1);
    if (inbuf2)
      gst_buffer_unref (inbuf2);

    gst_pad_push_event (self->src, gst_event_new_eos ());
    return GST_FLOW_UNEXPECTED;
  }
}