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; }
/* 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"); } }
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; } }
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; }
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; }
/* 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 ) ); }
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); }
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); }
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)); }
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; }
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)); }
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); }
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; } }
GstBuffer *Resampler::eat (GstBuffer *in) { if (m_sourceSR == m_targetSR) { gst_buffer_ref (in); return in; } writeToScratch (in); return produceResampledBuffer (); }
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; } }
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; }
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; }
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; }
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); }
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)); }
/** * 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; }