static void gst_rtp_ulpfec_dec_start (GstRtpUlpFecDec * self, GstBufferList * buflist, guint8 fec_pt, guint16 lost_seq) { guint fec_packets = 0; gsize i; g_assert (NULL == self->info_media); g_assert (0 == self->info_fec->len); g_assert (0 == self->info_arr->len); g_array_set_size (self->info_arr, gst_buffer_list_length (buflist)); for (i = 0; i < gst_buffer_list_length (buflist) && !self->lost_packet_from_storage; ++i) { GstBuffer *buffer = gst_buffer_list_get (buflist, i); RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (self, i); if (!rtp_ulpfec_map_info_map (gst_buffer_ref (buffer), info)) g_assert_not_reached (); if (fec_pt == gst_rtp_buffer_get_payload_type (&info->rtp)) { GST_DEBUG_RTP_PACKET (self, "rtp header (fec)", &info->rtp); ++fec_packets; if (rtp_ulpfec_buffer_is_valid (&info->rtp)) { GST_DEBUG_FEC_PACKET (self, &info->rtp); g_ptr_array_add (self->info_fec, GUINT_TO_POINTER (i)); } } else { GST_LOG_RTP_PACKET (self, "rtp header (incoming)", &info->rtp); if (lost_seq == gst_rtp_buffer_get_seq (&info->rtp)) { GST_DEBUG_OBJECT (self, "Received lost packet from from the storage"); g_list_free (self->info_media); self->info_media = NULL; self->lost_packet_from_storage = TRUE; } self->info_media = g_list_insert_sorted_with_data (self->info_media, GUINT_TO_POINTER (i), _compare_fec_map_info, self); } } if (!self->lost_packet_from_storage) { self->fec_packets_received += fec_packets; self->fec_packets_rejected += fec_packets - self->info_fec->len; } }
static GstFlowReturn gst_hls_sink_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list) { guint i, len; GstBuffer *buffer; GstFlowReturn ret; GstHlsSink *sink = GST_HLS_SINK_CAST (parent); if (sink->target_duration == 0 || sink->waiting_fku) return gst_proxy_pad_chain_list_default (pad, parent, list); GST_DEBUG_OBJECT (pad, "chaining each group in list as a merged buffer"); len = gst_buffer_list_length (list); ret = GST_FLOW_OK; for (i = 0; i < len; i++) { buffer = gst_buffer_list_get (list, i); if (!sink->waiting_fku) gst_hls_sink_check_schedule_next_key_unit (sink, buffer); ret = gst_pad_chain (pad, gst_buffer_ref (buffer)); if (ret != GST_FLOW_OK) break; } gst_buffer_list_unref (list); return ret; }
static GstBufferList * create_buffer_list (void) { guint len; GstBuffer *buffer; mylist = gst_buffer_list_new (); fail_if (mylist == NULL); mycaps = gst_caps_from_string ("application/x-gst-check"); fail_if (mycaps == NULL); len = gst_buffer_list_length (mylist); fail_if (len != 0); buffer = gst_buffer_new_and_alloc (sizeof (gint)); gst_buffer_fill (buffer, 0, &values[0], sizeof (gint)); gst_buffer_list_add (mylist, buffer); buffer = gst_buffer_new_and_alloc (sizeof (gint)); gst_buffer_fill (buffer, 0, &values[1], sizeof (gint)); gst_buffer_list_add (mylist, buffer); buffer = gst_buffer_new_and_alloc (sizeof (gint)); gst_buffer_fill (buffer, 0, &values[2], sizeof (gint)); gst_buffer_list_add (mylist, buffer); gst_pad_set_caps (mysrcpad, mycaps); gst_caps_unref (mycaps); return mylist; }
static void copyGstreamerBuffersToAudioChannel(GstBufferList* buffers, AudioChannel* audioChannel) { #ifdef GST_API_VERSION_1 gsize offset = 0; for (unsigned i = 0; i < gst_buffer_list_length(buffers); i++) { GstBuffer* buffer = gst_buffer_list_get(buffers, i); if (!buffer) continue; GstMapInfo info; gst_buffer_map(buffer, &info, GST_MAP_READ); memcpy(audioChannel->mutableData() + offset, reinterpret_cast<float*>(info.data), info.size); offset += info.size / sizeof(float); gst_buffer_unmap(buffer, &info); } #else GstBufferListIterator* iter = gst_buffer_list_iterate(buffers); gst_buffer_list_iterator_next_group(iter); GstBuffer* buffer = gst_buffer_list_iterator_merge_group(iter); if (buffer) { memcpy(audioChannel->mutableData(), reinterpret_cast<float*>(GST_BUFFER_DATA(buffer)), GST_BUFFER_SIZE(buffer)); gst_buffer_unref(buffer); } gst_buffer_list_iterator_free(iter); #endif }
/* * Chain list function for testing buffer lists */ static GstFlowReturn rtp_pipeline_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list) { guint i, len; fail_if (!list); /* * Count the size of the payload in the buffer list. */ len = gst_buffer_list_length (list); /* Loop through all groups */ for (i = 0; i < len; i++) { GstBuffer *paybuf; GstMemory *mem; gint size; paybuf = gst_buffer_list_get (list, i); /* only count real data which is expected in last memory block */ fail_unless (gst_buffer_n_memory (paybuf) > 1); mem = gst_buffer_get_memory_range (paybuf, gst_buffer_n_memory (paybuf) - 1, 1); size = gst_memory_get_sizes (mem, NULL, NULL); gst_memory_unref (mem); chain_list_bytes_received += size; } gst_buffer_list_unref (list); return GST_FLOW_OK; }
static GstFlowReturn gst_rtp_base_audio_payload_push_buffer (GstRTPBaseAudioPayload * baseaudiopayload, GstBuffer * buffer, GstClockTime timestamp) { GstRTPBasePayload *basepayload; GstRTPBaseAudioPayloadPrivate *priv; GstBuffer *outbuf; guint payload_len; GstFlowReturn ret; priv = baseaudiopayload->priv; basepayload = GST_RTP_BASE_PAYLOAD (baseaudiopayload); payload_len = gst_buffer_get_size (buffer); GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT, payload_len, GST_TIME_ARGS (timestamp)); /* create just the RTP header buffer */ outbuf = gst_rtp_base_payload_allocate_output_buffer (basepayload, 0, 0, 0); /* set metadata */ gst_rtp_base_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len, timestamp); if (priv->buffer_list) { GstBufferList *list; guint i, len; list = gst_buffer_list_new (); len = gst_buffer_list_length (list); for (i = 0; i < len; i++) { /* FIXME */ g_warning ("bufferlist not implemented"); gst_buffer_list_add (list, outbuf); gst_buffer_list_add (list, buffer); } GST_DEBUG_OBJECT (baseaudiopayload, "Pushing list %p", list); ret = gst_rtp_base_payload_push_list (basepayload, list); } else { CopyMetaData data; /* copy payload */ data.pay = baseaudiopayload; data.outbuf = outbuf; gst_buffer_foreach_meta (buffer, foreach_metadata, &data); outbuf = gst_buffer_append (outbuf, buffer); GST_DEBUG_OBJECT (baseaudiopayload, "Pushing buffer %p", outbuf); ret = gst_rtp_base_payload_push (basepayload, outbuf); } return ret; }
static void copyGstreamerBuffersToAudioChannel(GstBufferList* buffers, AudioChannel* audioChannel) { float* destination = audioChannel->mutableData(); unsigned bufferCount = gst_buffer_list_length(buffers); for (unsigned i = 0; i < bufferCount; ++i) { GstBuffer* buffer = gst_buffer_list_get(buffers, i); ASSERT(buffer); gsize bufferSize = gst_buffer_get_size(buffer); gst_buffer_extract(buffer, 0, destination, bufferSize); destination += bufferSize / sizeof(float); } }
static GstFlowReturn mpegpsmux_push_gop_list (MpegPsMux * mux) { GstFlowReturn flow; g_assert (mux->gop_list != NULL); GST_DEBUG_OBJECT (mux, "Sending pending GOP of %u buffers", gst_buffer_list_length (mux->gop_list)); flow = gst_pad_push_list (mux->srcpad, mux->gop_list); mux->gop_list = NULL; return flow; }
static GstFlowReturn gst_file_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list) { GstFlowReturn flow; GstBuffer **buffers; GstFileSink *sink; guint8 *mem_nums; guint total_mems; guint i, num_buffers; gboolean sync_after = FALSE; sink = GST_FILE_SINK_CAST (bsink); num_buffers = gst_buffer_list_length (buffer_list); if (num_buffers == 0) goto no_data; /* extract buffers from list and count memories */ buffers = g_newa (GstBuffer *, num_buffers); mem_nums = g_newa (guint8, num_buffers); for (i = 0, total_mems = 0; i < num_buffers; ++i) { buffers[i] = gst_buffer_list_get (buffer_list, i); mem_nums[i] = gst_buffer_n_memory (buffers[i]); total_mems += mem_nums[i]; if (GST_BUFFER_FLAG_IS_SET (buffers[i], GST_BUFFER_FLAG_SYNC_AFTER)) sync_after = TRUE; } flow = gst_file_sink_render_buffers (sink, buffers, num_buffers, mem_nums, total_mems); if (flow == GST_FLOW_OK && sync_after) { if (fflush (sink->file) || fsync (fileno (sink->file))) { GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (_("Error while writing to file \"%s\"."), sink->filename), ("%s", g_strerror (errno))); flow = GST_FLOW_ERROR; } } return flow; no_data: { GST_LOG_OBJECT (sink, "empty buffer list"); return GST_FLOW_OK; } }
static GstFlowReturn sink_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list) { GstDtlsDec *self = GST_DTLS_DEC (parent); GstFlowReturn ret = GST_FLOW_OK; GstPad *other_pad; list = gst_buffer_list_make_writable (list); gst_buffer_list_foreach (list, process_buffer_from_list, self); if (gst_buffer_list_length (list) == 0) { GST_DEBUG_OBJECT (self, "Not produced any buffers"); gst_buffer_list_unref (list); return GST_FLOW_OK; } g_mutex_lock (&self->src_mutex); other_pad = self->src; if (other_pad) gst_object_ref (other_pad); g_mutex_unlock (&self->src_mutex); if (other_pad) { GST_LOG_OBJECT (self, "decoded buffer list with length %u, pushing", gst_buffer_list_length (list)); ret = gst_pad_push_list (other_pad, list); gst_object_unref (other_pad); } else { GST_LOG_OBJECT (self, "dropped buffer list with length %d, not linked", gst_buffer_list_length (list)); gst_buffer_list_unref (list); } return ret; }
/* * Render function for testing udpsink with buffer lists */ static GstFlowReturn udpsink_render_list (GstBaseSink * sink, GstBufferList * list) { guint i, num; num = gst_buffer_list_length (list); for (i = 0; i < num; ++i) { GstBuffer *buf = gst_buffer_list_get (list, i); gsize size = gst_buffer_get_size (buf); GST_DEBUG ("rendered %" G_GSIZE_FORMAT " bytes", size); render_list_bytes_received += size; } return GST_FLOW_OK; }
/** * @brief Handle list of buffers. * * GstBaseSink method implementation. */ static GstFlowReturn gst_tensor_sink2_render_list (GstBaseSink * sink, GstBufferList * buffer_list) { GstTensorSink2 *self; GstBuffer *buffer; guint i; guint num_buffers; self = GST_TENSOR_SINK2 (sink); num_buffers = gst_buffer_list_length (buffer_list); for (i = 0; i < num_buffers; i++) { buffer = gst_buffer_list_get (buffer_list, i); gst_tensor_sink2_render_buffer (self, buffer); } return GST_FLOW_OK; }
static GstFlowReturn gst_rtp_base_depayload_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list) { GstRTPBaseDepayloadClass *bclass; GstRTPBaseDepayload *basedepay; GstFlowReturn flow_ret; GstBuffer *buffer; guint i, len; basedepay = GST_RTP_BASE_DEPAYLOAD_CAST (parent); bclass = GST_RTP_BASE_DEPAYLOAD_GET_CLASS (basedepay); flow_ret = GST_FLOW_OK; /* chain each buffer in list individually */ len = gst_buffer_list_length (list); if (len == 0) goto done; for (i = 0; i < len; i++) { buffer = gst_buffer_list_get (list, i); /* handle_buffer takes ownership of input buffer */ /* FIXME: add a way to steal buffers from list as we will unref it anyway */ gst_buffer_ref (buffer); /* Should we fix up any missing timestamps for list buffers here * (e.g. set to first or previous timestamp in list) or just assume * the's a jitterbuffer that will have done that for us? */ flow_ret = gst_rtp_base_depayload_handle_buffer (basedepay, bclass, buffer); if (flow_ret != GST_FLOW_OK) break; } done: gst_buffer_list_unref (list); return flow_ret; }
static GstFlowReturn gst_fd_sink_render_list (GstBaseSink * bsink, GstBufferList * buffer_list) { GstFlowReturn flow; GstBuffer **buffers; GstFdSink *sink; guint8 *mem_nums; guint total_mems; guint i, num_buffers; sink = GST_FD_SINK_CAST (bsink); num_buffers = gst_buffer_list_length (buffer_list); if (num_buffers == 0) goto no_data; /* extract buffers from list and count memories */ buffers = g_newa (GstBuffer *, num_buffers); mem_nums = g_newa (guint8, num_buffers); for (i = 0, total_mems = 0; i < num_buffers; ++i) { buffers[i] = gst_buffer_list_get (buffer_list, i); mem_nums[i] = gst_buffer_n_memory (buffers[i]); total_mems += mem_nums[i]; } flow = gst_fd_sink_render_buffers (sink, buffers, num_buffers, mem_nums, total_mems); return flow; no_data: { GST_LOG_OBJECT (sink, "empty buffer list"); return GST_FLOW_OK; } }
static GstFlowReturn gst_rtp_vraw_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) { GstRtpVRawPay *rtpvrawpay; GstFlowReturn ret = GST_FLOW_OK; gfloat packets_per_packline; guint pgroups_per_packet; guint packlines_per_list, buffers_per_list; guint lines_delay; /* after how many packed lines we push out a buffer list */ guint last_line; /* last pack line number we pushed out a buffer list */ guint line, offset; guint8 *p0, *yp, *up, *vp; guint ystride, uvstride; guint xinc, yinc; guint pgroup; guint mtu; guint width, height; gint field, fields; GstVideoFormat format; GstVideoFrame frame; gint interlaced; gboolean use_buffer_lists; GstBufferList *list = NULL; GstRTPBuffer rtp = { NULL, }; rtpvrawpay = GST_RTP_VRAW_PAY (payload); gst_video_frame_map (&frame, &rtpvrawpay->vinfo, buffer, GST_MAP_READ); GST_LOG_OBJECT (rtpvrawpay, "new frame of %" G_GSIZE_FORMAT " bytes", gst_buffer_get_size (buffer)); /* get pointer and strides of the planes */ p0 = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0); yp = GST_VIDEO_FRAME_COMP_DATA (&frame, 0); up = GST_VIDEO_FRAME_COMP_DATA (&frame, 1); vp = GST_VIDEO_FRAME_COMP_DATA (&frame, 2); ystride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 0); uvstride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 1); mtu = GST_RTP_BASE_PAYLOAD_MTU (payload); /* amount of bytes for one pixel */ pgroup = rtpvrawpay->pgroup; width = GST_VIDEO_INFO_WIDTH (&rtpvrawpay->vinfo); height = GST_VIDEO_INFO_HEIGHT (&rtpvrawpay->vinfo); interlaced = GST_VIDEO_INFO_IS_INTERLACED (&rtpvrawpay->vinfo); format = GST_VIDEO_INFO_FORMAT (&rtpvrawpay->vinfo); yinc = rtpvrawpay->yinc; xinc = rtpvrawpay->xinc; /* after how many packed lines we push out a buffer list */ lines_delay = GST_ROUND_UP_4 (height / rtpvrawpay->chunks_per_frame); /* calculate how many buffers we expect to store in a single buffer list */ pgroups_per_packet = (mtu - (12 + 14)) / pgroup; packets_per_packline = width / (xinc * pgroups_per_packet * 1.0); packlines_per_list = height / (yinc * rtpvrawpay->chunks_per_frame); buffers_per_list = packlines_per_list * packets_per_packline; buffers_per_list = GST_ROUND_UP_8 (buffers_per_list); use_buffer_lists = (rtpvrawpay->chunks_per_frame < (height / yinc)); fields = 1 + interlaced; /* start with line 0, offset 0 */ for (field = 0; field < fields; field++) { line = field; offset = 0; last_line = 0; if (use_buffer_lists) list = gst_buffer_list_new_sized (buffers_per_list); /* write all lines */ while (line < height) { guint left, pack_line; GstBuffer *out; guint8 *outdata, *headers; gboolean next_line, complete = FALSE; guint length, cont, pixels; /* get the max allowed payload length size, we try to fill the complete MTU */ left = gst_rtp_buffer_calc_payload_len (mtu, 0, 0); out = gst_rtp_buffer_new_allocate (left, 0, 0); if (field == 0) { GST_BUFFER_PTS (out) = GST_BUFFER_PTS (buffer); } else { GST_BUFFER_PTS (out) = GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer) / 2; } gst_rtp_buffer_map (out, GST_MAP_WRITE, &rtp); outdata = gst_rtp_buffer_get_payload (&rtp); GST_LOG_OBJECT (rtpvrawpay, "created buffer of size %u for MTU %u", left, mtu); /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Extended Sequence Number | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |F| Line No |C| Offset | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Length |F| Line No | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |C| Offset | . * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ . * . . * . Two (partial) lines of video data . * . . * +---------------------------------------------------------------+ */ /* need 2 bytes for the extended sequence number */ *outdata++ = 0; *outdata++ = 0; left -= 2; /* the headers start here */ headers = outdata; /* make sure we can fit at least *one* header and pixel */ if (!(left > (6 + pgroup))) { gst_rtp_buffer_unmap (&rtp); gst_buffer_unref (out); goto too_small; } /* while we can fit at least one header and one pixel */ while (left > (6 + pgroup)) { /* we need a 6 bytes header */ left -= 6; /* get how may bytes we need for the remaining pixels */ pixels = width - offset; length = (pixels * pgroup) / xinc; if (left >= length) { /* pixels and header fit completely, we will write them and skip to the * next line. */ next_line = TRUE; } else { /* line does not fit completely, see how many pixels fit */ pixels = (left / pgroup) * xinc; length = (pixels * pgroup) / xinc; next_line = FALSE; } GST_LOG_OBJECT (rtpvrawpay, "filling %u bytes in %u pixels", length, pixels); left -= length; /* write length */ *outdata++ = (length >> 8) & 0xff; *outdata++ = length & 0xff; /* write line no */ *outdata++ = ((line >> 8) & 0x7f) | ((field << 7) & 0x80); *outdata++ = line & 0xff; if (next_line) { /* go to next line we do this here to make the check below easier */ line += yinc; } /* calculate continuation marker */ cont = (left > (6 + pgroup) && line < height) ? 0x80 : 0x00; /* write offset and continuation marker */ *outdata++ = ((offset >> 8) & 0x7f) | cont; *outdata++ = offset & 0xff; if (next_line) { /* reset offset */ offset = 0; GST_LOG_OBJECT (rtpvrawpay, "go to next line %u", line); } else { offset += pixels; GST_LOG_OBJECT (rtpvrawpay, "next offset %u", offset); } if (!cont) break; } GST_LOG_OBJECT (rtpvrawpay, "consumed %u bytes", (guint) (outdata - headers)); /* second pass, read headers and write the data */ while (TRUE) { guint offs, lin; /* read length and cont */ length = (headers[0] << 8) | headers[1]; lin = ((headers[2] & 0x7f) << 8) | headers[3]; offs = ((headers[4] & 0x7f) << 8) | headers[5]; cont = headers[4] & 0x80; pixels = length / pgroup; headers += 6; GST_LOG_OBJECT (payload, "writing length %u, line %u, offset %u, cont %d", length, lin, offs, cont); switch (format) { case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_UYVY: case GST_VIDEO_FORMAT_UYVP: offs /= xinc; memcpy (outdata, p0 + (lin * ystride) + (offs * pgroup), length); outdata += length; break; case GST_VIDEO_FORMAT_AYUV: { gint i; guint8 *datap; datap = p0 + (lin * ystride) + (offs * 4); for (i = 0; i < pixels; i++) { *outdata++ = datap[2]; *outdata++ = datap[1]; *outdata++ = datap[3]; datap += 4; } break; } case GST_VIDEO_FORMAT_I420: { gint i; guint uvoff; guint8 *yd1p, *yd2p, *udp, *vdp; yd1p = yp + (lin * ystride) + (offs); yd2p = yd1p + ystride; uvoff = (lin / yinc * uvstride) + (offs / xinc); udp = up + uvoff; vdp = vp + uvoff; for (i = 0; i < pixels; i++) { *outdata++ = *yd1p++; *outdata++ = *yd1p++; *outdata++ = *yd2p++; *outdata++ = *yd2p++; *outdata++ = *udp++; *outdata++ = *vdp++; } break; } case GST_VIDEO_FORMAT_Y41B: { gint i; guint uvoff; guint8 *ydp, *udp, *vdp; ydp = yp + (lin * ystride) + offs; uvoff = (lin / yinc * uvstride) + (offs / xinc); udp = up + uvoff; vdp = vp + uvoff; for (i = 0; i < pixels; i++) { *outdata++ = *udp++; *outdata++ = *ydp++; *outdata++ = *ydp++; *outdata++ = *vdp++; *outdata++ = *ydp++; *outdata++ = *ydp++; } break; } default: gst_rtp_buffer_unmap (&rtp); gst_buffer_unref (out); goto unknown_sampling; } if (!cont) break; } if (line >= height) { GST_LOG_OBJECT (rtpvrawpay, "field/frame complete, set marker"); gst_rtp_buffer_set_marker (&rtp, TRUE); complete = TRUE; } gst_rtp_buffer_unmap (&rtp); if (left > 0) { GST_LOG_OBJECT (rtpvrawpay, "we have %u bytes left", left); gst_buffer_resize (out, 0, gst_buffer_get_size (out) - left); } /* Now either push out the buffer directly */ if (!use_buffer_lists) { ret = gst_rtp_base_payload_push (payload, out); continue; } /* or add the buffer to buffer list ... */ gst_buffer_list_add (list, out); /* .. and check if we need to push out the list */ pack_line = (line - field) / fields; if (complete || (pack_line > last_line && pack_line % lines_delay == 0)) { GST_LOG_OBJECT (rtpvrawpay, "pushing list of %u buffers up to pack " "line %u", gst_buffer_list_length (list), pack_line); ret = gst_rtp_base_payload_push_list (payload, list); list = NULL; if (!complete) list = gst_buffer_list_new_sized (buffers_per_list); last_line = pack_line; } } } gst_video_frame_unmap (&frame); gst_buffer_unref (buffer); return ret; /* ERRORS */ unknown_sampling: { GST_ELEMENT_ERROR (payload, STREAM, FORMAT, (NULL), ("unimplemented sampling")); gst_video_frame_unmap (&frame); gst_buffer_unref (buffer); return GST_FLOW_NOT_SUPPORTED; } too_small: { GST_ELEMENT_ERROR (payload, RESOURCE, NO_SPACE_LEFT, (NULL), ("not enough space to send at least one pixel")); gst_video_frame_unmap (&frame); gst_buffer_unref (buffer); return GST_FLOW_NOT_SUPPORTED; } }
uint BufferList::length() const { return gst_buffer_list_length(object<GstBufferList>()); }
static GstFlowReturn gst_rtp_base_audio_payload_push_buffer (GstRTPBaseAudioPayload * baseaudiopayload, GstBuffer * buffer, GstClockTime timestamp) { GstRTPBasePayload *basepayload; GstRTPBaseAudioPayloadPrivate *priv; GstBuffer *outbuf; guint8 *payload; guint payload_len; GstFlowReturn ret; priv = baseaudiopayload->priv; basepayload = GST_RTP_BASE_PAYLOAD (baseaudiopayload); payload_len = gst_buffer_get_size (buffer); GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT, payload_len, GST_TIME_ARGS (timestamp)); if (priv->buffer_list) { /* create just the RTP header buffer */ outbuf = gst_rtp_buffer_new_allocate (0, 0, 0); } else { /* create buffer to hold the payload */ outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0); } /* set metadata */ gst_rtp_base_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len, timestamp); if (priv->buffer_list) { GstBufferList *list; guint i, len; list = gst_buffer_list_new (); len = gst_buffer_list_length (list); for (i = 0; i < len; i++) { /* FIXME */ g_warning ("bufferlist not implemented"); gst_buffer_list_add (list, outbuf); gst_buffer_list_add (list, buffer); } GST_DEBUG_OBJECT (baseaudiopayload, "Pushing list %p", list); ret = gst_rtp_base_payload_push_list (basepayload, list); } else { GstRTPBuffer rtp = { NULL }; /* copy payload */ gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp); payload = gst_rtp_buffer_get_payload (&rtp); gst_buffer_extract (buffer, 0, payload, payload_len); gst_rtp_buffer_unmap (&rtp); gst_buffer_unref (buffer); GST_DEBUG_OBJECT (baseaudiopayload, "Pushing buffer %p", outbuf); ret = gst_rtp_base_payload_push (basepayload, outbuf); } return ret; }