static GstFlowReturn
gst_inter_sub_src_create (GstBaseSrc * src, guint64 offset, guint size,
    GstBuffer ** buf)
{
  GstInterSubSrc *intersubsrc = GST_INTER_SUB_SRC (src);
  GstBuffer *buffer;

  GST_DEBUG_OBJECT (intersubsrc, "create");

  buffer = NULL;

  g_mutex_lock (&intersubsrc->surface->mutex);
  if (intersubsrc->surface->sub_buffer) {
    buffer = gst_buffer_ref (intersubsrc->surface->sub_buffer);
    //intersubsrc->surface->sub_buffer_count++;
    //if (intersubsrc->surface->sub_buffer_count >= 30) {
    gst_buffer_unref (intersubsrc->surface->sub_buffer);
    intersubsrc->surface->sub_buffer = NULL;
    //}
  }
  g_mutex_unlock (&intersubsrc->surface->mutex);

  if (buffer == NULL) {
    GstMapInfo map;

    buffer = gst_buffer_new_and_alloc (1);

    gst_buffer_map (buffer, &map, GST_MAP_WRITE);
    map.data[0] = 0;
    gst_buffer_unmap (buffer, &map);
  }

  buffer = gst_buffer_make_writable (buffer);

  /* FIXME: does this make sense? Rate is always 0 */
#if 0
  GST_BUFFER_TIMESTAMP (buffer) =
      gst_util_uint64_scale_int (GST_SECOND, intersubsrc->n_frames,
      intersubsrc->rate);
  GST_DEBUG_OBJECT (intersubsrc, "create ts %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
  GST_BUFFER_DURATION (buffer) =
      gst_util_uint64_scale_int (GST_SECOND, (intersubsrc->n_frames + 1),
      intersubsrc->rate) - GST_BUFFER_TIMESTAMP (buffer);
#endif
  GST_BUFFER_OFFSET (buffer) = intersubsrc->n_frames;
  GST_BUFFER_OFFSET_END (buffer) = -1;
  GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
  if (intersubsrc->n_frames == 0) {
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
  }
  intersubsrc->n_frames++;

  *buf = buffer;

  return GST_FLOW_OK;
}
Beispiel #2
0
/* With SPU LOCK */
static void
gst_dvd_spu_redraw_still (GstDVDSpu * dvdspu, gboolean force)
{
  /* If we have an active SPU command set and a reference frame, copy the
   * frame, redraw the SPU and store it as the pending frame for output */
  if (dvdspu->ref_frame) {
    gboolean redraw = (dvdspu->spu_state.flags & SPU_STATE_FORCED_DSP);
    redraw |= (dvdspu->spu_state.flags & SPU_STATE_FORCED_ONLY) == 0 &&
        (dvdspu->spu_state.flags & SPU_STATE_DISPLAY);

    if (redraw) {
      GstBuffer *buf = gst_buffer_ref (dvdspu->ref_frame);

      buf = gst_buffer_make_writable (buf);

      GST_LOG_OBJECT (dvdspu, "Redraw due to Still Frame with ref %p",
          dvdspu->ref_frame);
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
      GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
      GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;

      /* Render the SPU overlay onto the buffer */
      gstspu_render (dvdspu, buf);
      gst_buffer_replace (&dvdspu->pending_frame, buf);
      gst_buffer_unref (buf);
    } else if (force) {
      /* Simply output the reference frame */
      GstBuffer *buf = gst_buffer_ref (dvdspu->ref_frame);
      buf = gst_buffer_make_writable (buf);
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
      GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
      GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;

      GST_DEBUG_OBJECT (dvdspu, "Pushing reference frame at start of still");

      gst_buffer_replace (&dvdspu->pending_frame, buf);
      gst_buffer_unref (buf);
    } else {
      GST_LOG_OBJECT (dvdspu, "Redraw due to Still Frame skipped");
    }
  } else {
    GST_LOG_OBJECT (dvdspu, "Not redrawing still frame - no ref frame");
  }
}
Beispiel #3
0
static void udp_streaming (Encoder *encoder, GstBuffer *buffer)
{
        gsize buffer_size;
        gssize offset;
        GstFlowReturn ret;

        offset = 0;
        buffer_size = gst_buffer_get_size (buffer);
        while (buffer_size != 0) {
                if ((encoder->cache_size == 0) && (buffer_size < 1316)) {
                        encoder->cache_7x188 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_MEMORY, offset, buffer_size);
                        encoder->cache_size = buffer_size;
                        break;

                } else if (encoder->cache_size == 0) {
                        /* buffer_size >= 1316 */
                        encoder->cache_7x188 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_MEMORY, offset, 1316);
                        offset += 1316;
                        buffer_size -= 1316;

                } else if (encoder->cache_size + buffer_size >= 1316) {
                        gsize size;
                        gst_buffer_ref (buffer);
                        size = 1316 - encoder->cache_size;
                        encoder->cache_7x188 = gst_buffer_append_region (encoder->cache_7x188, buffer, offset, size);
                        offset += 1316 - encoder->cache_size;
                        buffer_size -= 1316 - encoder->cache_size;
                        encoder->cache_size = 0;

                } else {
                        /* encoder->cache_size + buffer_size < 1316 */
                        gst_buffer_ref (buffer);
                        encoder->cache_7x188 = gst_buffer_append_region (encoder->cache_7x188, buffer, offset, buffer_size);
                        encoder->cache_size += buffer_size;
                        break;
                }
                ret = gst_app_src_push_buffer ((GstAppSrc *)encoder->appsrc, encoder->cache_7x188);
                if (ret != GST_FLOW_OK) {
                        GST_ERROR ("appsrc push buffer failure, return %s.", gst_flow_get_name (ret));
                        gst_buffer_unref (encoder->cache_7x188);
                }
                encoder->cache_size = 0;
        }
}
Beispiel #4
0
static GstFlowReturn
gst_quarktv_transform (GstBaseTransform * trans, GstBuffer * in,
    GstBuffer * out)
{
  GstQuarkTV *filter = GST_QUARKTV (trans);
  gint area;
  guint32 *src, *dest;
  GstFlowReturn ret = GST_FLOW_OK;
  GstClockTime timestamp;
  GstBuffer **planetable;
  gint planes, current_plane;

  timestamp = GST_BUFFER_TIMESTAMP (in);
  timestamp =
      gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME, timestamp);

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

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

  if (G_UNLIKELY (filter->planetable == NULL))
    return GST_FLOW_WRONG_STATE;

  GST_OBJECT_LOCK (filter);
  area = filter->area;
  src = (guint32 *) GST_BUFFER_DATA (in);
  dest = (guint32 *) GST_BUFFER_DATA (out);
  planetable = filter->planetable;
  planes = filter->planes;
  current_plane = filter->current_plane;

  if (planetable[current_plane])
    gst_buffer_unref (planetable[current_plane]);
  planetable[current_plane] = gst_buffer_ref (in);

  /* For each pixel */
  while (--area) {
    GstBuffer *rand;

    /* pick a random buffer */
    rand = planetable[(current_plane + (fastrand () >> 24)) % planes];

    /* Copy the pixel from the random buffer to dest */
    dest[area] =
        (rand ? ((guint32 *) GST_BUFFER_DATA (rand))[area] : src[area]);
  }

  filter->current_plane--;
  if (filter->current_plane < 0)
    filter->current_plane = planes - 1;
  GST_OBJECT_UNLOCK (filter);

  return ret;
}
Beispiel #5
0
static gboolean
opus_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
{
  GstOpusDec *dec = GST_OPUS_DEC (gst_pad_get_parent (pad));
  gboolean ret = TRUE;
  GstStructure *s;
  const GValue *streamheader;

  s = gst_caps_get_structure (caps, 0);
  if ((streamheader = gst_structure_get_value (s, "streamheader")) &&
      G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY) &&
      gst_value_array_get_size (streamheader) >= 2) {
    const GValue *header;
    GstBuffer *buf;
    GstFlowReturn res = GST_FLOW_OK;

    header = gst_value_array_get_value (streamheader, 0);
    if (header && G_VALUE_HOLDS (header, GST_TYPE_BUFFER)) {
      buf = gst_value_get_buffer (header);
      res = opus_dec_chain_parse_header (dec, buf);
      if (res != GST_FLOW_OK)
        goto done;
      gst_buffer_replace (&dec->streamheader, buf);
    }
#if 0
    vorbiscomment = gst_value_array_get_value (streamheader, 1);
    if (vorbiscomment && G_VALUE_HOLDS (vorbiscomment, GST_TYPE_BUFFER)) {
      buf = gst_value_get_buffer (vorbiscomment);
      res = opus_dec_chain_parse_comments (dec, buf);
      if (res != GST_FLOW_OK)
        goto done;
      gst_buffer_replace (&dec->vorbiscomment, buf);
    }
#endif

    g_list_foreach (dec->extra_headers, (GFunc) gst_mini_object_unref, NULL);
    g_list_free (dec->extra_headers);
    dec->extra_headers = NULL;

    if (gst_value_array_get_size (streamheader) > 2) {
      gint i, n;

      n = gst_value_array_get_size (streamheader);
      for (i = 2; i < n; i++) {
        header = gst_value_array_get_value (streamheader, i);
        buf = gst_value_get_buffer (header);
        dec->extra_headers =
            g_list_prepend (dec->extra_headers, gst_buffer_ref (buf));
      }
    }
  }

done:
  gst_object_unref (dec);
  return ret;
}
static gboolean
gst_output_selector_switch (GstOutputSelector * osel)
{
  gboolean res = FALSE;
  GstEvent *ev = NULL;
  GstSegment *seg = NULL;
  gint64 start = 0, position = 0;

  /* Switch */
  GST_OBJECT_LOCK (GST_OBJECT (osel));
  GST_INFO_OBJECT (osel, "switching to pad %" GST_PTR_FORMAT,
      osel->pending_srcpad);
  if (gst_pad_is_linked (osel->pending_srcpad)) {
    osel->active_srcpad = osel->pending_srcpad;
    res = TRUE;
  }
  gst_object_unref (osel->pending_srcpad);
  osel->pending_srcpad = NULL;
  GST_OBJECT_UNLOCK (GST_OBJECT (osel));

  /* Send SEGMENT event and latest buffer if switching succeeded
   * and we already have a valid segment configured */
  if (res) {
    if (osel->segment.format != GST_FORMAT_UNDEFINED) {
      /* Send SEGMENT to the pad we are going to switch to */
      seg = &osel->segment;
      /* If resending then mark segment start and position accordingly */
      if (osel->resend_latest && osel->latest_buffer &&
          GST_BUFFER_TIMESTAMP_IS_VALID (osel->latest_buffer)) {
        start = position = GST_BUFFER_TIMESTAMP (osel->latest_buffer);
      } else {
        start = position = seg->position;
      }

      seg->start = start;
      seg->position = position;
      ev = gst_event_new_segment (seg);

      if (!gst_pad_push_event (osel->active_srcpad, ev)) {
        GST_WARNING_OBJECT (osel,
            "newsegment handling failed in %" GST_PTR_FORMAT,
            osel->active_srcpad);
      }
    }

    /* Resend latest buffer to newly switched pad */
    if (osel->resend_latest && osel->latest_buffer) {
      GST_INFO ("resending latest buffer");
      gst_pad_push (osel->active_srcpad, gst_buffer_ref (osel->latest_buffer));
    }
  } else {
    GST_WARNING_OBJECT (osel, "switch failed, pad not linked");
  }

  return res;
}
Beispiel #7
0
/* Emitted by vlcvideosink for every buffer,
 * Adds the buffer to the queue */
static void frame_handoff_cb( GstElement *p_ele, GstBuffer *p_buf,
        gpointer p_data )
{
    VLC_UNUSED( p_ele );
    decoder_t *p_dec = p_data;
    decoder_sys_t *p_sys = p_dec->p_sys;

    /* Push the buffer to the queue */
    gst_atomic_queue_push( p_sys->p_que, gst_buffer_ref( p_buf ) );
}
Beispiel #8
0
void
gst_vdp_video_buffer_add_reference (GstVdpVideoBuffer * buffer,
    GstVdpVideoBuffer * buf)
{
  g_assert (GST_IS_VDP_VIDEO_BUFFER (buffer));
  g_assert (GST_IS_VDP_VIDEO_BUFFER (buf));

  gst_buffer_ref (GST_BUFFER (buf));
  buffer->refs = g_slist_prepend (buffer->refs, buf);
}
Beispiel #9
0
QT_BEGIN_NAMESPACE

QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine)
    : QAbstractVideoBuffer(NoHandle)
    , m_buffer(buffer)
    , m_bytesPerLine(bytesPerLine)
    , m_mode(NotMapped)
{
    gst_buffer_ref(m_buffer);
}
Beispiel #10
0
static void
save_result (GstElement * sink, GstBuffer * buf, GstPad * pad, gpointer data)
{
  GstBuffer **p_buf = (GstBuffer **) data;

  *p_buf = gst_buffer_ref (buf);

  GST_DEBUG ("received converted buffer %p with caps %" GST_PTR_FORMAT,
      *p_buf, GST_BUFFER_CAPS (*p_buf));
}
Beispiel #11
0
static void
gst_video_rate_swap_prev (GstVideoRate * videorate, GstBuffer * buffer,
    gint64 time)
{
  GST_LOG_OBJECT (videorate, "swap_prev: storing buffer %p in prev", buffer);
  if (videorate->prevbuf)
    gst_buffer_unref (videorate->prevbuf);
  videorate->prevbuf = buffer != NULL ? gst_buffer_ref (buffer) : NULL;
  videorate->prev_ts = time;
}
Beispiel #12
0
static GstFlowReturn
gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{
  GstRTMPSink *sink = GST_RTMP_SINK (bsink);
  GstBuffer *reffed_buf = NULL;

  if (sink->first) {
    /* open the connection */
    if (!RTMP_IsConnected (sink->rtmp)) {
      if (!RTMP_Connect (sink->rtmp, NULL)
          || !RTMP_ConnectStream (sink->rtmp, 0)) {
        GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
            ("Could not connect to RTMP stream \"%s\" for writing", sink->uri));
        RTMP_Free (sink->rtmp);
        sink->rtmp = NULL;
        g_free (sink->rtmp_uri);
        sink->rtmp_uri = NULL;
        return GST_FLOW_ERROR;
      }
      GST_DEBUG_OBJECT (sink, "Opened connection to %s", sink->rtmp_uri);
    }

    /* FIXME: Parse the first buffer and see if it contains a header plus a packet instead
     * of just assuming it's only the header */
    GST_LOG_OBJECT (sink, "Caching first buffer of size %d for concatenation",
        GST_BUFFER_SIZE (buf));
    gst_buffer_replace (&sink->cache, buf);
    sink->first = FALSE;
    return GST_FLOW_OK;
  }

  if (sink->cache) {
    GST_LOG_OBJECT (sink, "Joining 2nd buffer of size %d to cached buf",
        GST_BUFFER_SIZE (buf));
    gst_buffer_ref (buf);
    reffed_buf = buf = gst_buffer_join (sink->cache, buf);
    sink->cache = NULL;
  }

  GST_LOG_OBJECT (sink, "Sending %d bytes to RTMP server",
      GST_BUFFER_SIZE (buf));

  if (!RTMP_Write (sink->rtmp,
          (char *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf))) {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Failed to write data"));
    if (reffed_buf)
      gst_buffer_unref (reffed_buf);
    return GST_FLOW_ERROR;
  }

  if (reffed_buf)
    gst_buffer_unref (reffed_buf);

  return GST_FLOW_OK;
}
static void
gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer)
{
  GstV4l2BufferPool *pool;
  gboolean resuscitated = FALSE;
  gint index;

  pool = buffer->pool;

  index = buffer->vbuffer.index;

  GST_LOG_OBJECT (pool->v4l2elem, "finalizing buffer %p %d", buffer, index);

  GST_V4L2_BUFFER_POOL_LOCK (pool);
  if (pool->running) {
    if (pool->requeuebuf) {
      if (!gst_v4l2_buffer_pool_qbuf (pool, buffer)) {
        GST_WARNING ("could not requeue buffer %p %d", buffer, index);
      } else {
        resuscitated = TRUE;
      }
    } else {
      resuscitated = TRUE;
      /* XXX double check this... I think it is ok to not synchronize this
       * w.r.t. destruction of the pool, since the buffer is still live and
       * the buffer holds a ref to the pool..
       */
      g_async_queue_push (pool->avail_buffers, buffer);
    }
  } else {
    GST_LOG_OBJECT (pool->v4l2elem, "the pool is shutting down");
  }

  if (resuscitated) {
    /* FIXME: check that the caps didn't change */
    GST_LOG_OBJECT (pool->v4l2elem, "reviving buffer %p, %d", buffer, index);
    gst_buffer_ref (GST_BUFFER (buffer));
    GST_BUFFER_SIZE (buffer) = 0;
    GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
    pool->buffers[index] = buffer;
  }

  GST_V4L2_BUFFER_POOL_UNLOCK (pool);

  if (!resuscitated) {
    GST_LOG_OBJECT (pool->v4l2elem,
        "buffer %p (data %p, len %u) not recovered, unmapping",
        buffer, GST_BUFFER_DATA (buffer), buffer->mmap_length);
    gst_mini_object_unref (GST_MINI_OBJECT (pool));
    v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), buffer->mmap_length);

    GST_MINI_OBJECT_CLASS (v4l2buffer_parent_class)->finalize (GST_MINI_OBJECT
        (buffer));
  }
}
void
gst_opus_header_create_caps_from_headers (GstCaps ** caps, GSList ** headers,
    GstBuffer * buf1, GstBuffer * buf2)
{
  int n_streams, family;
  gboolean multistream;
  GstMapInfo map;
  guint8 *data;

  g_return_if_fail (caps);
  g_return_if_fail (headers && !*headers);
  g_return_if_fail (gst_buffer_get_size (buf1) >= 19);

  gst_buffer_map (buf1, &map, GST_MAP_READ);
  data = map.data;

  /* work out the number of streams */
  family = data[18];
  if (family == 0) {
    n_streams = 1;
  } else {
    /* only included in the header for family > 0 */
    if (map.size >= 20)
      n_streams = data[19];
    else {
      g_warning ("family > 0 but header buffer size < 20");
      gst_buffer_unmap (buf1, &map);
      return;
    }
  }

  gst_buffer_unmap (buf1, &map);

  /* mark and put on caps */
  multistream = n_streams > 1;
  *caps = gst_caps_new_simple ("audio/x-opus",
      "multistream", G_TYPE_BOOLEAN, multistream, NULL);
  *caps = _gst_caps_set_buffer_array (*caps, "streamheader", buf1, buf2, NULL);

  *headers = g_slist_prepend (*headers, gst_buffer_ref (buf2));
  *headers = g_slist_prepend (*headers, gst_buffer_ref (buf1));
}
Beispiel #15
0
static void
fail_unless_result_gain (GstElement * element, gdouble expected_gain)
{
  GstBuffer *input_buf, *output_buf;
  gfloat input_sample, output_sample;
  gdouble gain, prop_gain;
  gboolean is_passthrough, expect_passthrough;
  gint i;

  fail_unless (g_list_length (buffers) == 0);

  input_sample = 1.0;
  input_buf = test_buffer_new (input_sample);

  /* We keep an extra reference to detect passthrough mode. */
  gst_buffer_ref (input_buf);
  /* Pushing steals a reference. */
  fail_unless (gst_pad_push (mysrcpad, input_buf) == GST_FLOW_OK);
  gst_buffer_unref (input_buf);

  /* The output buffer ends up on the global buffer list. */
  fail_unless (g_list_length (buffers) == 1);
  output_buf = buffers->data;
  fail_if (output_buf == NULL);

  buffers = g_list_remove (buffers, output_buf);
  ASSERT_BUFFER_REFCOUNT (output_buf, "output_buf", 1);
  fail_unless_equals_int (GST_BUFFER_SIZE (output_buf), 8 * sizeof (gfloat));

  output_sample = *((gfloat *) GST_BUFFER_DATA (output_buf));

  fail_if (output_sample == 0.0, "First output sample is zero");
  for (i = 1; i < 8; i++) {
    gfloat output = ((gfloat *) GST_BUFFER_DATA (output_buf))[i];

    fail_unless (output_sample == output, "Output samples not uniform");
  };

  gain = 20. * log10 (output_sample / input_sample);
  fail_unless (MATCH_GAIN (gain, expected_gain),
      "Applied gain is %.2f dB, expected %.2f dB", gain, expected_gain);
  g_object_get (element, "result-gain", &prop_gain, NULL);
  fail_unless (MATCH_GAIN (prop_gain, expected_gain),
      "Result gain is %.2f dB, expected %.2f dB", prop_gain, expected_gain);

  is_passthrough = (output_buf == input_buf);
  expect_passthrough = MATCH_GAIN (expected_gain, +0.00);
  fail_unless (is_passthrough == expect_passthrough,
      expect_passthrough
      ? "Expected operation in passthrough mode"
      : "Incorrect passthrough behaviour");

  gst_buffer_unref (output_buf);
}
Beispiel #16
0
static GstFlowReturn
gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
{
  GstFlacDec *dec;

  dec = GST_FLAC_DEC (audio_dec);

  /* drain remaining data? */
  if (G_UNLIKELY (buf == NULL)) {
    gst_flac_dec_flush (audio_dec, FALSE);
    return GST_FLOW_OK;
  }

  GST_LOG_OBJECT (dec, "frame: ts %" GST_TIME_FORMAT ", flags 0x%04x, "
      "%" G_GSIZE_FORMAT " bytes", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
      GST_BUFFER_FLAGS (buf), gst_buffer_get_size (buf));

  /* drop any in-stream headers, we've processed those in set_format already */
  if (G_UNLIKELY (!dec->got_headers)) {
    gboolean got_audio_frame;
    GstMapInfo map;

    /* check if this is a flac audio frame (rather than a header or junk) */
    gst_buffer_map (buf, &map, GST_MAP_READ);
    got_audio_frame =
        gst_flac_dec_scan_got_frame (dec, map.data, map.size, NULL);
    gst_buffer_unmap (buf, &map);

    if (!got_audio_frame) {
      GST_INFO_OBJECT (dec, "dropping in-stream header, %" G_GSIZE_FORMAT " "
          "bytes", map.size);
      gst_audio_decoder_finish_frame (audio_dec, NULL, 1);
      return GST_FLOW_OK;
    }

    GST_INFO_OBJECT (dec, "first audio frame, got all in-stream headers now");
    dec->got_headers = TRUE;
  }

  gst_adapter_push (dec->adapter, gst_buffer_ref (buf));
  buf = NULL;

  dec->last_flow = GST_FLOW_OK;

  /* framed - there should always be enough data to decode something */
  GST_LOG_OBJECT (dec, "%" G_GSIZE_FORMAT " bytes available",
      gst_adapter_available (dec->adapter));

  if (!FLAC__stream_decoder_process_single (dec->decoder)) {
    GST_INFO_OBJECT (dec, "process_single failed");
  }

  return dec->last_flow;
}
static GstFlowReturn
gst_video_filter_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
  GstFlowReturn res;
  GstVideoFilter *filter = GST_VIDEO_FILTER_CAST (trans);
  GstVideoFilterClass *fclass;

  if (G_UNLIKELY (!filter->negotiated))
    goto unknown_format;

  fclass = GST_VIDEO_FILTER_GET_CLASS (filter);
  if (fclass->transform_frame_ip) {
    GstVideoFrame frame;
    GstMapFlags flags;

    flags = GST_MAP_READ;

    if (!gst_base_transform_is_passthrough (trans))
      flags |= GST_MAP_WRITE;

    if (!gst_video_frame_map (&frame, &filter->in_info, buf, flags))
      goto invalid_buffer;

    /* GstVideoFrame has another reference, so the buffer looks unwriteable,
     * meaning that we can't attach any metas or anything to it. Other
     * map() functions like gst_buffer_map() don't get another reference
     * of the buffer and expect the buffer reference to be kept until
     * the buffer is unmapped again. */
    gst_buffer_unref (buf);
    res = fclass->transform_frame_ip (filter, &frame);
    gst_buffer_ref (buf);

    gst_video_frame_unmap (&frame);
  } else {
    GST_DEBUG_OBJECT (trans, "no transform_frame_ip vmethod");
    res = GST_FLOW_OK;
  }

  return res;

  /* ERRORS */
unknown_format:
  {
    GST_ELEMENT_ERROR (filter, CORE, NOT_IMPLEMENTED, (NULL),
        ("unknown format"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
invalid_buffer:
  {
    GST_ELEMENT_WARNING (filter, CORE, NOT_IMPLEMENTED, (NULL),
        ("invalid video buffer received"));
    return GST_FLOW_OK;
  }
}
Beispiel #18
0
GstBuffer *Resampler::eat (GstBuffer *in)
{
  if (m_sourceSR == m_targetSR)
  {
    gst_buffer_ref (in);
    return in;
  }

  writeToScratch (in);
  return produceResampledBuffer ();
}
Beispiel #19
0
static GstFlowReturn
gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{
  GstGLImageSink *glimage_sink = NULL;
  GstGLBuffer *gl_buffer = NULL;

  glimage_sink = GST_GLIMAGE_SINK (bsink);

  GST_INFO ("buffer size: %d", GST_BUFFER_SIZE (buf));

  //is gl
  if (glimage_sink->is_gl) {
    //increment gl buffer ref before storage
    gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf));
  }
  //is not gl
  else {
    //blocking call
    gl_buffer = gst_gl_buffer_new (glimage_sink->display,
        glimage_sink->width, glimage_sink->height);

    //blocking call
    gst_gl_display_do_upload (glimage_sink->display, gl_buffer->texture,
        glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf));

    //gl_buffer is created in this block, so the gl buffer is already referenced
  }

  if (glimage_sink->window_id != glimage_sink->new_window_id) {
    glimage_sink->window_id = glimage_sink->new_window_id;
    gst_gl_display_set_window_id (glimage_sink->display,
        glimage_sink->window_id);
  }
  //the buffer is cleared when an other comes in
  if (glimage_sink->stored_buffer) {
    gst_buffer_unref (GST_BUFFER_CAST (glimage_sink->stored_buffer));
    glimage_sink->stored_buffer = NULL;
  }
  //store current buffer
  glimage_sink->stored_buffer = gl_buffer;

  //redisplay opengl scene
  if (gl_buffer->texture &&
      gst_gl_display_redisplay (glimage_sink->display,
          gl_buffer->texture, gl_buffer->width, gl_buffer->height,
          glimage_sink->window_width, glimage_sink->window_height,
          glimage_sink->keep_aspect_ratio))
    return GST_FLOW_OK;
  else {
    GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
        GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL));
    return GST_FLOW_ERROR;
  }
}
Beispiel #20
0
QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine,
                QGstVideoBuffer::HandleType handleType,
                const QVariant &handle)
    : QAbstractVideoBuffer(handleType)
    , m_buffer(buffer)
    , m_bytesPerLine(bytesPerLine)
    , m_mode(NotMapped)
    , m_handle(handle)
{
    gst_buffer_ref(m_buffer);
}
static GstFlowReturn
gst_output_selector_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn res;
  GstOutputSelector *osel;
  GstClockTime position, duration;

  osel = GST_OUTPUT_SELECTOR (parent);

  /*
   * The _switch function might push a buffer if 'resend-latest' is true.
   *
   * Elements/Applications (e.g. camerabin) might use pad probes to
   * switch output-selector's active pad. If we simply switch and don't
   * recheck any pending pad switch the following codepath could end
   * up pushing a buffer on a non-active pad. This is bad.
   *
   * So we always should check the pending_srcpad before going further down
   * the chain and pushing the new buffer
   */
  while (osel->pending_srcpad) {
    /* Do the switch */
    gst_output_selector_switch (osel);
  }

  if (osel->latest_buffer) {
    gst_buffer_unref (osel->latest_buffer);
    osel->latest_buffer = NULL;
  }

  if (osel->resend_latest) {
    /* Keep reference to latest buffer to resend it after switch */
    osel->latest_buffer = gst_buffer_ref (buf);
  }

  /* Keep track of last stop and use it in SEGMENT start after
     switching to a new src pad */
  position = GST_BUFFER_TIMESTAMP (buf);
  if (GST_CLOCK_TIME_IS_VALID (position)) {
    duration = GST_BUFFER_DURATION (buf);
    if (GST_CLOCK_TIME_IS_VALID (duration)) {
      position += duration;
    }
    GST_LOG_OBJECT (osel, "setting last stop %" GST_TIME_FORMAT,
        GST_TIME_ARGS (position));
    osel->segment.position = position;
  }

  GST_LOG_OBJECT (osel, "pushing buffer to %" GST_PTR_FORMAT,
      osel->active_srcpad);
  res = gst_pad_push (osel->active_srcpad, buf);

  return res;
}
static GstFlowReturn
gst_inter_sub_src_create (GstBaseSrc * src, guint64 offset, guint size,
    GstBuffer ** buf)
{
  GstInterSubSrc *intersubsrc = GST_INTER_SUB_SRC (src);
  GstBuffer *buffer;

  GST_DEBUG_OBJECT (intersubsrc, "create");

  buffer = NULL;

  g_mutex_lock (intersubsrc->surface->mutex);
  if (intersubsrc->surface->sub_buffer) {
    buffer = gst_buffer_ref (intersubsrc->surface->sub_buffer);
    //intersubsrc->surface->sub_buffer_count++;
    //if (intersubsrc->surface->sub_buffer_count >= 30) {
    gst_buffer_unref (intersubsrc->surface->sub_buffer);
    intersubsrc->surface->sub_buffer = NULL;
    //}
  }
  g_mutex_unlock (intersubsrc->surface->mutex);

  if (buffer == NULL) {
    guint8 *data;

    buffer = gst_buffer_new_and_alloc (1);

    data = GST_BUFFER_DATA (buffer);
    data[0] = 0;
  }

  buffer = gst_buffer_make_metadata_writable (buffer);

  GST_BUFFER_TIMESTAMP (buffer) =
      gst_util_uint64_scale_int (GST_SECOND, intersubsrc->n_frames,
      intersubsrc->rate);
  GST_DEBUG_OBJECT (intersubsrc, "create ts %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
  GST_BUFFER_DURATION (buffer) =
      gst_util_uint64_scale_int (GST_SECOND, (intersubsrc->n_frames + 1),
      intersubsrc->rate) - GST_BUFFER_TIMESTAMP (buffer);
  GST_BUFFER_OFFSET (buffer) = intersubsrc->n_frames;
  GST_BUFFER_OFFSET_END (buffer) = -1;
  GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DISCONT);
  if (intersubsrc->n_frames == 0) {
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
  }
  gst_buffer_set_caps (buffer, GST_PAD_CAPS (GST_BASE_SRC_PAD (intersubsrc)));
  intersubsrc->n_frames++;

  *buf = buffer;

  return GST_FLOW_OK;
}
Beispiel #23
0
static GstFlowReturn
gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer)
{
  GstFlowReturn res = GST_FLOW_OK;
  GstAppSink *appsink = GST_APP_SINK (psink);
  gboolean emit;

  g_mutex_lock (appsink->priv->mutex);
  if (appsink->priv->flushing)
    goto flushing;

  GST_DEBUG_OBJECT (appsink, "pushing render buffer %p on queue (%d)",
      buffer, appsink->priv->queue->length);

  while (appsink->priv->max_buffers > 0 &&
      appsink->priv->queue->length >= appsink->priv->max_buffers) {
    if (appsink->priv->drop) {
      GstBuffer *buf;

      /* we need to drop the oldest buffer and try again */
      buf = g_queue_pop_head (appsink->priv->queue);
      GST_DEBUG_OBJECT (appsink, "dropping old buffer %p", buf);
      gst_buffer_unref (buf);
    } else {
      GST_DEBUG_OBJECT (appsink, "waiting for free space, length %d >= %d",
          appsink->priv->queue->length, appsink->priv->max_buffers);
      /* wait for a buffer to be removed or flush */
      g_cond_wait (appsink->priv->cond, appsink->priv->mutex);
      if (appsink->priv->flushing)
        goto flushing;
    }
  }
  /* we need to ref the buffer when pushing it in the queue */
  g_queue_push_tail (appsink->priv->queue, gst_buffer_ref (buffer));

  g_cond_signal (appsink->priv->cond);
  emit = appsink->priv->emit_signals;
  g_mutex_unlock (appsink->priv->mutex);

  if (appsink->priv->callbacks.new_buffer)
    res =
        appsink->priv->callbacks.new_buffer (appsink, appsink->priv->user_data);
  else if (emit)
    g_signal_emit (appsink, gst_app_sink_signals[SIGNAL_NEW_BUFFER], 0);

  return res;

flushing:
  {
    GST_DEBUG_OBJECT (appsink, "we are flushing");
    g_mutex_unlock (appsink->priv->mutex);
    return GST_FLOW_WRONG_STATE;
  }
}
/**
 * gst_vaapi_decoder_put_buffer:
 * @decoder: a #GstVaapiDecoder
 * @buf: a #GstBuffer
 *
 * Queues a #GstBuffer to the HW decoder. The decoder holds a
 * reference to @buf.
 *
 * Caller can notify an End-Of-Stream with @buf set to %NULL. However,
 * if an empty buffer is passed, i.e. a buffer with %NULL data pointer
 * or size equals to zero, then the function ignores this buffer and
 * returns %TRUE.
 *
 * Return value: %TRUE on success
 */
gboolean
gst_vaapi_decoder_put_buffer (GstVaapiDecoder * decoder, GstBuffer * buf)
{
  g_return_val_if_fail (decoder != NULL, FALSE);

  if (buf) {
    if (gst_buffer_get_size (buf) == 0)
      return TRUE;
    buf = gst_buffer_ref (buf);
  }
  return push_buffer (decoder, buf);
}
/**
 * gst_aggregator_pad_get_buffer:
 * @pad: the pad to get buffer from
 *
 * Returns: (transfer full): A reference to the buffer in @pad or
 * NULL if no buffer was queued. You should unref the buffer after
 * usage.
 */
GstBuffer *
gst_aggregator_pad_get_buffer (GstAggregatorPad * pad)
{
  GstBuffer *buffer = NULL;

  PAD_LOCK_EVENT (pad);
  if (pad->buffer)
    buffer = gst_buffer_ref (pad->buffer);
  PAD_UNLOCK_EVENT (pad);

  return buffer;
}
Beispiel #26
0
static GstFlowReturn
gst_identity_prepare_output_buffer (GstBaseTransform * trans,
    GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf)
{
  GstIdentity *identity = GST_IDENTITY (trans);

  /* only bother if we may have to alter metadata */
  if (identity->datarate > 0 || identity->single_segment) {
    if (gst_buffer_is_metadata_writable (in_buf))
      *out_buf = gst_buffer_ref (in_buf);
    else {
      /* make even less writable */
      gst_buffer_ref (in_buf);
      /* extra ref is dropped going through the official process */
      *out_buf = gst_buffer_make_metadata_writable (in_buf);
    }
  } else
    *out_buf = gst_buffer_ref (in_buf);

  return GST_FLOW_OK;
}
Beispiel #27
0
static GstFlowReturn
gst_rtp_opus_pay_handle_buffer (GstRTPBasePayload * basepayload,
    GstBuffer * buffer)
{
  GstBuffer *outbuf;

  outbuf = gst_rtp_buffer_new_allocate (0, 0, 0);
  outbuf = gst_buffer_append (outbuf, gst_buffer_ref (buffer));

  /* Push out */
  return gst_rtp_base_payload_push (basepayload, outbuf);
}
Beispiel #28
0
static GstFlowReturn
gst_eglglessink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
{
  GstEglGlesSink *eglglessink;

  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);

  eglglessink = GST_EGLGLESSINK (vsink);
  GST_DEBUG_OBJECT (eglglessink, "Got buffer: %p", buf);

  return gst_eglglessink_queue_buffer (eglglessink, gst_buffer_ref (buf));
}
Beispiel #29
0
/**
 * gst_adapter_get_buffer_fast:
 * @adapter:  a #GstAdapter
 * @nbytes: the number of bytes to get
 *
 * Returns a #GstBuffer containing the first @nbytes of the @adapter, but
 * does not flush them from the adapter. See gst_adapter_take_buffer_fast()
 * for details.
 *
 * Caller owns a reference to the returned buffer. gst_buffer_unref() after
 * usage.
 *
 * Free-function: gst_buffer_unref
 *
 * Returns: (transfer full) (nullable): a #GstBuffer containing the first
 *     @nbytes of the adapter, or %NULL if @nbytes bytes are not available.
 *     gst_buffer_unref() when no longer needed.
 *
 * Since: 1.6
 */
GstBuffer *
gst_adapter_get_buffer_fast (GstAdapter * adapter, gsize nbytes)
{
  GstBuffer *buffer = NULL;
  GstBuffer *cur;
  GSList *item;
  gsize skip;
  gsize left = nbytes;

  g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
  g_return_val_if_fail (nbytes > 0, NULL);

  GST_LOG_OBJECT (adapter, "getting buffer of %" G_GSIZE_FORMAT " bytes",
      nbytes);

  /* we don't have enough data, return NULL. This is unlikely
   * as one usually does an _available() first instead of grabbing a
   * random size. */
  if (G_UNLIKELY (nbytes > adapter->size))
    return NULL;

  skip = adapter->skip;
  cur = adapter->buflist->data;

  if (skip == 0 && gst_buffer_get_size (cur) == nbytes) {
    GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
        " as head buffer", nbytes);
    buffer = gst_buffer_ref (cur);
    goto done;
  }

  for (item = adapter->buflist; item && left > 0; item = item->next) {
    gsize size, cur_size;

    cur = item->data;
    cur_size = gst_buffer_get_size (cur);
    size = MIN (cur_size - skip, left);

    GST_LOG_OBJECT (adapter, "appending %" G_GSIZE_FORMAT " bytes"
        " via region copy", size);
    if (buffer)
      gst_buffer_copy_into (buffer, cur,
          GST_BUFFER_COPY_MEMORY | GST_BUFFER_COPY_META, skip, size);
    else
      buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, size);
    skip = 0;
    left -= size;
  }

done:

  return buffer;
}
GstFlowReturn AudioSourceProviderGStreamer::handleAudioBuffer(GstAppSink* sink)
{
    if (!m_client)
        return GST_FLOW_OK;

    // Pull a buffer from appsink and store it the appropriate buffer
    // list for the audio channel it represents.
    GRefPtr<GstSample> sample = adoptGRef(gst_app_sink_pull_sample(sink));
    if (!sample)
        return gst_app_sink_is_eos(sink) ? GST_FLOW_EOS : GST_FLOW_ERROR;

    GstBuffer* buffer = gst_sample_get_buffer(sample.get());
    if (!buffer)
        return GST_FLOW_ERROR;

    GstCaps* caps = gst_sample_get_caps(sample.get());
    if (!caps)
        return GST_FLOW_ERROR;

    GstAudioInfo info;
    gst_audio_info_from_caps(&info, caps);

    WTF::GMutexLocker<GMutex> lock(m_adapterMutex);

    // Check the first audio channel. The buffer is supposed to store
    // data of a single channel anyway.
    switch (GST_AUDIO_INFO_POSITION(&info, 0)) {
    case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT:
    case GST_AUDIO_CHANNEL_POSITION_MONO:
        gst_adapter_push(m_frontLeftAdapter, gst_buffer_ref(buffer));
        break;
    case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT:
        gst_adapter_push(m_frontRightAdapter, gst_buffer_ref(buffer));
        break;
    default:
        break;
    }

    return GST_FLOW_OK;
}