static GstBuffer * gst_wavenc_create_header_buf (GstWavEnc * wavenc, guint audio_data_size) { struct wave_header wave; GstBuffer *buf; GstMapInfo map; guint8 *header; buf = gst_buffer_new_and_alloc (WAV_HEADER_LEN); gst_buffer_map (buf, &map, GST_MAP_WRITE); header = map.data; memset (header, 0, WAV_HEADER_LEN); wave.common.wChannels = wavenc->channels; wave.common.wBitsPerSample = wavenc->width; wave.common.dwSamplesPerSec = wavenc->rate; /* Fill out our wav-header with some information */ memcpy (wave.riff.id, "RIFF", 4); wave.riff.len = audio_data_size + WAV_HEADER_LEN - 8; memcpy (wave.riff.wav_id, "WAVE", 4); memcpy (wave.format.id, "fmt ", 4); wave.format.len = 16; wave.common.wFormatTag = wavenc->format; wave.common.wBlockAlign = (wavenc->width / 8) * wave.common.wChannels; wave.common.dwAvgBytesPerSec = wave.common.wBlockAlign * wave.common.dwSamplesPerSec; memcpy (wave.data.id, "data", 4); wave.data.len = audio_data_size; memcpy (header, (char *) wave.riff.id, 4); GST_WRITE_UINT32_LE (header + 4, wave.riff.len); memcpy (header + 8, (char *) wave.riff.wav_id, 4); memcpy (header + 12, (char *) wave.format.id, 4); GST_WRITE_UINT32_LE (header + 16, wave.format.len); GST_WRITE_UINT16_LE (header + 20, wave.common.wFormatTag); GST_WRITE_UINT16_LE (header + 22, wave.common.wChannels); GST_WRITE_UINT32_LE (header + 24, wave.common.dwSamplesPerSec); GST_WRITE_UINT32_LE (header + 28, wave.common.dwAvgBytesPerSec); GST_WRITE_UINT16_LE (header + 32, wave.common.wBlockAlign); GST_WRITE_UINT16_LE (header + 34, wave.common.wBitsPerSample); memcpy (header + 36, (char *) wave.data.id, 4); GST_WRITE_UINT32_LE (header + 40, wave.data.len); gst_buffer_unmap (buf, &map); return buf; }
static void gst_mim_enc_create_tcp_header (GstMimEnc * mimenc, guint8 * p, guint32 payload_size, GstClockTime ts, gboolean keyframe, gboolean paused) { p[0] = 24; p[1] = paused ? 1 : 0; GST_WRITE_UINT16_LE (p + 2, mimenc->width); GST_WRITE_UINT16_LE (p + 4, mimenc->height); GST_WRITE_UINT16_LE (p + 6, keyframe ? 1 : 0); GST_WRITE_UINT32_LE (p + 8, payload_size); GST_WRITE_UINT32_LE (p + 12, paused ? 0 : GST_MAKE_FOURCC ('M', 'L', '2', '0')); GST_WRITE_UINT32_LE (p + 16, 0); GST_WRITE_UINT32_LE (p + 20, ts / GST_MSECOND); }
static GstFlowReturn mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer, GstCaps * caps, MXFMetadataTimelineTrack * track, MXFMetadataSourceClip * component, gpointer mapping_data, GstBuffer ** outbuf) { guint i, j, nsamples; const guint8 *indata; guint8 *outdata; MXFD10AudioMappingData *data = mapping_data; g_return_val_if_fail (data != NULL, GST_FLOW_ERROR); g_return_val_if_fail (data->channels != 0 && data->width != 0, GST_FLOW_ERROR); /* SMPTE 386M 5.3.1 */ if (key->u[12] != 0x06 || key->u[13] != 0x01 || key->u[14] != 0x10) { GST_ERROR ("Invalid D10 sound essence element"); return GST_FLOW_ERROR; } /* Now transform raw AES3 into raw audio, see SMPTE 331M */ if ((GST_BUFFER_SIZE (buffer) - 4) % 32 != 0) { GST_ERROR ("Invalid D10 sound essence buffer size"); return GST_FLOW_ERROR; } nsamples = ((GST_BUFFER_SIZE (buffer) - 4) / 4) / 8; *outbuf = gst_buffer_new_and_alloc (nsamples * data->width * data->channels); gst_buffer_copy_metadata (*outbuf, buffer, GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS); indata = GST_BUFFER_DATA (buffer); outdata = GST_BUFFER_DATA (*outbuf); /* Skip 32 bit header */ indata += 4; for (i = 0; i < nsamples; i++) { for (j = 0; j < data->channels; j++) { guint32 in = GST_READ_UINT32_LE (indata); /* Remove first 4 and last 4 bits as they only * contain status data. Shift the 24 bit samples * to the correct width afterwards. */ if (data->width == 2) { in = (in >> 12) & 0xffff; GST_WRITE_UINT16_LE (outdata, in); } else if (data->width == 3) { in = (in >> 4) & 0xffffff; GST_WRITE_UINT24_LE (outdata, in); }
static void fill_bmp_header(guint8 *image_data, guint image_width, guint image_height) { guint dib_image_row_size = ((DIB_BITS_PER_PIXEL * image_width + 31) / 32) * 4; guint dib_image_size = dib_image_row_size * image_height; guint8 *data = image_data; *data = 'B'; data++; *data = 'M'; data++; GST_WRITE_UINT32_LE(data, (BMP_HEADER_SIZE + dib_image_size)); data += 4; GST_WRITE_UINT16_LE(data, BMP_RESERVED); data += 2; GST_WRITE_UINT16_LE(data, BMP_RESERVED); data += 2; GST_WRITE_UINT32_LE(data, BMP_HEADER_SIZE); data += 4; GST_WRITE_UINT32_LE(data, DIB_HEADER_SIZE); data += 4; GST_WRITE_UINT32_LE(data, image_width); data += 4; GST_WRITE_UINT32_LE(data, image_height); data += 4; GST_WRITE_UINT16_LE(data, DIB_COLOR_PLANES); data += 2; GST_WRITE_UINT16_LE(data, DIB_BITS_PER_PIXEL); data += 2; GST_WRITE_UINT32_LE(data, DIB_COMPRESSION); data += 4; GST_WRITE_UINT32_LE(data, dib_image_size); data += 4; GST_WRITE_UINT32_LE(data, DIB_HORIZONTAL_RESOLUTION); data += 4; GST_WRITE_UINT32_LE(data, DIB_VERTICAL_RESOLUTION); data += 4; GST_WRITE_UINT32_LE(data, DIB_COLORS_IN_PALETTE); data += 4; GST_WRITE_UINT32_LE(data, DIB_IMPORTANT_COLORS); data += 4; }
/* create a CMML ident header buffer */ static GstFlowReturn gst_cmml_enc_new_ident_header (GstCmmlEnc * enc, GstBuffer ** buffer) { guint8 ident_header[CMML_IDENT_HEADER_SIZE]; guint8 *wptr = ident_header; memcpy (wptr, "CMML\0\0\0\0", 8); wptr += 8; GST_WRITE_UINT16_LE (wptr, enc->major); wptr += 2; GST_WRITE_UINT16_LE (wptr, enc->minor); wptr += 2; GST_WRITE_UINT64_LE (wptr, enc->granulerate_n); wptr += 8; GST_WRITE_UINT64_LE (wptr, enc->granulerate_d); wptr += 8; *wptr = enc->granuleshift; return gst_cmml_enc_new_buffer (enc, (guchar *) & ident_header, CMML_IDENT_HEADER_SIZE, buffer); }
static GstBuffer * gst_mimenc_create_tcp_header (GstMimEnc * mimenc, guint32 payload_size, GstClockTime timestamp, gboolean keyframe, gboolean paused) { // 24 bytes GstBuffer *buf_header = gst_buffer_new_and_alloc (24); guchar *p = (guchar *) GST_BUFFER_DATA (buf_header); GST_BUFFER_TIMESTAMP (buf_header) = timestamp; p[0] = 24; p[1] = paused ? 1 : 0; GST_WRITE_UINT16_LE (p + 2, mimenc->width); GST_WRITE_UINT16_LE (p + 4, mimenc->height); GST_WRITE_UINT16_LE (p + 6, keyframe ? 1 : 0); GST_WRITE_UINT32_LE (p + 8, payload_size); GST_WRITE_UINT32_LE (p + 12, paused ? 0 : GST_MAKE_FOURCC ('M', 'L', '2', '0')); GST_WRITE_UINT32_LE (p + 16, 0); GST_WRITE_UINT32_LE (p + 20, timestamp / GST_MSECOND); return buf_header; }
static void gst_exif_writer_write_short_tag (GstExifWriter * writer, guint16 tag, guint16 value) { guint32 offset = 0; if (writer->byte_order == G_LITTLE_ENDIAN) { GST_WRITE_UINT16_LE ((guint8 *) & offset, value); } else { GST_WRITE_UINT16_BE ((guint8 *) & offset, value); } gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_SHORT, 1, offset, TRUE); }
/* Correctly format samples with width!=depth for the wav format, i.e. * have the data in the highest depth bits and all others zero */ static void gst_wavenc_format_samples (GstBuffer * buf, guint width, guint depth) { guint8 *data = GST_BUFFER_DATA (buf); guint nsamples = (GST_BUFFER_SIZE (buf) * 8) / width; guint32 tmp; for (; nsamples; nsamples--) { switch (width) { case 8: tmp = *data; *data = *data << (width - depth); data += 1; break; case 16: tmp = GST_READ_UINT16_LE (data); tmp = tmp << (width - depth); GST_WRITE_UINT16_LE (data, tmp); data += 2; break; case 24: tmp = READ24_FROM_LE (data); tmp = tmp << (width - depth); WRITE24_TO_LE (data, tmp); data += 3; break; case 32: tmp = GST_READ_UINT32_LE (data); tmp = tmp << (width - depth); GST_WRITE_UINT32_LE (data, tmp); data += 4; break; } } }
static gboolean gst_real_video_dec_setcaps (GstPad * pad, GstCaps * caps) { GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad)); GstStructure *s = gst_caps_get_structure (caps, 0); gint version, res, width, height, format, subformat; gint framerate_num, framerate_denom; gchar data[36]; gboolean bres; const GValue *v; if (!gst_structure_get_int (s, "rmversion", &version) || !gst_structure_get_int (s, "width", (gint *) & width) || !gst_structure_get_int (s, "height", (gint *) & height) || !gst_structure_get_int (s, "format", &format) || !gst_structure_get_int (s, "subformat", &subformat) || !gst_structure_get_fraction (s, "framerate", &framerate_num, &framerate_denom)) goto missing_keys; GST_LOG_OBJECT (dec, "Setting version to %d", version); close_library (dec, &dec->lib); if (!open_library (dec, version, &dec->lib)) goto open_failed; /* Initialize REAL driver. */ GST_WRITE_UINT16_LE (data + 0, 11); GST_WRITE_UINT16_LE (data + 2, width); GST_WRITE_UINT16_LE (data + 4, height); GST_WRITE_UINT16_LE (data + 6, 0); GST_WRITE_UINT32_LE (data + 8, 0); GST_WRITE_UINT32_LE (data + 12, subformat); GST_WRITE_UINT32_LE (data + 16, 1); GST_WRITE_UINT32_LE (data + 20, format); if ((res = dec->lib.Init (&data, &dec->lib.context))) goto could_not_initialize; if ((v = gst_structure_get_value (s, "codec_data"))) { GstBuffer *buf; guint32 *msgdata; guint i; guint8 *bufdata; guint bufsize; struct { guint32 type; guint32 msg; gpointer data; guint32 extra[6]; } msg; buf = g_value_peek_pointer (v); bufdata = GST_BUFFER_DATA (buf); bufsize = GST_BUFFER_SIZE (buf); /* skip format and subformat */ bufdata += 8; bufsize -= 8; GST_LOG_OBJECT (dec, "Creating custom message of length %d", bufsize); msgdata = g_new0 (guint32, bufsize + 2); if (!msgdata) goto could_not_allocate; msg.type = 0x24; msg.msg = 1 + ((subformat >> 16) & 7); msg.data = msgdata; for (i = 0; i < 6; i++) msg.extra[i] = 0; msgdata[0] = width; msgdata[1] = height; for (i = 0; i < bufsize; i++) msgdata[i + 2] = 4 * (guint32) bufdata[i]; res = dec->lib.Message (&msg, dec->lib.context); g_free (msgdata); if (res) goto could_not_send_message; }
static GstFlowReturn gst_opus_parse_parse_frame (GstBaseParse * base, GstBaseParseFrame * frame) { guint64 duration; GstOpusParse *parse; gboolean is_idheader, is_commentheader; GstMapInfo map; GstAudioClippingMeta *cmeta = gst_buffer_get_audio_clipping_meta (frame->buffer); parse = GST_OPUS_PARSE (base); g_assert (!cmeta || cmeta->format == GST_FORMAT_DEFAULT); is_idheader = gst_opus_header_is_id_header (frame->buffer); is_commentheader = gst_opus_header_is_comment_header (frame->buffer); if (!parse->got_headers || !parse->header_sent) { GstCaps *caps; /* Opus streams can decode to 1 or 2 channels, so use the header value if we have one, or 2 otherwise */ if (is_idheader) { gst_buffer_replace (&parse->id_header, frame->buffer); GST_DEBUG_OBJECT (parse, "Found ID header, keeping"); return GST_BASE_PARSE_FLOW_DROPPED; } else if (is_commentheader) { gst_buffer_replace (&parse->comment_header, frame->buffer); GST_DEBUG_OBJECT (parse, "Found comment header, keeping"); return GST_BASE_PARSE_FLOW_DROPPED; } parse->got_headers = TRUE; if (cmeta && cmeta->start) { parse->pre_skip += cmeta->start; gst_buffer_map (frame->buffer, &map, GST_MAP_READ); duration = packet_duration_opus (map.data, map.size); gst_buffer_unmap (frame->buffer, &map); /* Queue frame for later once we know all initial padding */ if (duration == cmeta->start) { frame->flags |= GST_BASE_PARSE_FRAME_FLAG_QUEUE; } } if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_QUEUE)) { if (FALSE && parse->id_header && parse->comment_header) { guint16 pre_skip; gst_buffer_map (parse->id_header, &map, GST_MAP_READWRITE); pre_skip = GST_READ_UINT16_LE (map.data + 10); if (pre_skip != parse->pre_skip) { GST_DEBUG_OBJECT (parse, "Fixing up pre-skip %u -> %" G_GUINT64_FORMAT, pre_skip, parse->pre_skip); GST_WRITE_UINT16_LE (map.data + 10, parse->pre_skip); } gst_buffer_unmap (parse->id_header, &map); caps = gst_codec_utils_opus_create_caps_from_header (parse->id_header, parse->comment_header); } else { GstCaps *sink_caps; guint32 sample_rate = 48000; guint8 n_channels, n_streams, n_stereo_streams, channel_mapping_family; guint8 channel_mapping[256]; GstBuffer *id_header; sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse)); if (!sink_caps || !gst_codec_utils_opus_parse_caps (sink_caps, &sample_rate, &n_channels, &channel_mapping_family, &n_streams, &n_stereo_streams, channel_mapping)) { GST_INFO_OBJECT (parse, "No headers and no caps, blindly setting up canonical stereo"); n_channels = 2; n_streams = 1; n_stereo_streams = 1; channel_mapping_family = 0; channel_mapping[0] = 0; channel_mapping[1] = 1; } if (sink_caps) gst_caps_unref (sink_caps); id_header = gst_codec_utils_opus_create_header (sample_rate, n_channels, channel_mapping_family, n_streams, n_stereo_streams, channel_mapping, parse->pre_skip, 0); caps = gst_codec_utils_opus_create_caps_from_header (id_header, NULL); gst_buffer_unref (id_header); } gst_buffer_replace (&parse->id_header, NULL); gst_buffer_replace (&parse->comment_header, NULL); gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps); gst_caps_unref (caps); parse->header_sent = TRUE; } } GST_BUFFER_TIMESTAMP (frame->buffer) = parse->next_ts; gst_buffer_map (frame->buffer, &map, GST_MAP_READ); duration = packet_duration_opus (map.data, map.size); gst_buffer_unmap (frame->buffer, &map); parse->next_ts += duration; GST_BUFFER_DURATION (frame->buffer) = duration; GST_BUFFER_OFFSET_END (frame->buffer) = gst_util_uint64_scale (parse->next_ts, 48000, GST_SECOND); GST_BUFFER_OFFSET (frame->buffer) = parse->next_ts; return GST_FLOW_OK; }
gint mve_compress_audio (guint8 * dest, const guint8 * src, guint16 len, guint8 channels) { gint16 prev[2], s; gint delta, real_res; gint cur_chan; guint8 v; for (cur_chan = 0; cur_chan < channels; ++cur_chan) { prev[cur_chan] = GST_READ_UINT16_LE (src); GST_WRITE_UINT16_LE (dest, prev[cur_chan]); src += 2; dest += 2; len -= 2; } cur_chan = 0; while (len > 0) { s = GST_READ_UINT16_LE (src); src += 2; delta = s - prev[cur_chan]; if (delta >= 0) v = mve_enc_delta (delta); else v = 256 - mve_enc_delta (-delta); real_res = dec_table[v] + prev[cur_chan]; if (real_res < -32768 || real_res > 32767) { /* correct overflow */ /* GST_DEBUG ("co:%d + %d = %d -> new v:%d, dec_table:%d will be %d", prev[cur_chan], dec_table[v], real_res, v, dec_table[v], prev[cur_chan]+dec_table[v]); */ if (s > 0) { if (real_res > 32767) --v; } else { if (real_res < -32768) ++v; } real_res = dec_table[v] + prev[cur_chan]; } if (G_UNLIKELY (abs (real_res - s) > 32767)) { GST_ERROR ("sign loss left unfixed in audio stream, deviation:%d", real_res - s); return -1; } *dest++ = v; --len; /* use previous output instead of input. That way output will not go too far from input. */ prev[cur_chan] += dec_table[v]; cur_chan = channels - 1 - cur_chan; } return 0; }
static GstFlowReturn gst_rtp_asf_pay_handle_packet (GstRtpAsfPay * rtpasfpay, GstBuffer * buffer) { GstBaseRTPPayload *rtppay; GstAsfPacketInfo *packetinfo; guint8 flags; guint8 *data; guint32 packet_util_size; guint32 packet_offset; guint32 size_left; GstFlowReturn ret = GST_FLOW_OK; rtppay = GST_BASE_RTP_PAYLOAD (rtpasfpay); packetinfo = &rtpasfpay->packetinfo; if (!gst_asf_parse_packet (buffer, packetinfo, TRUE, rtpasfpay->asfinfo.packet_size)) { GST_ERROR_OBJECT (rtpasfpay, "Error while parsing asf packet"); gst_buffer_unref (buffer); return GST_FLOW_ERROR; } if (packetinfo->packet_size == 0) packetinfo->packet_size = rtpasfpay->asfinfo.packet_size; GST_LOG_OBJECT (rtpasfpay, "Packet size: %" G_GUINT32_FORMAT ", padding: %" G_GUINT32_FORMAT, packetinfo->packet_size, packetinfo->padding); /* update padding field to 0 */ if (packetinfo->padding > 0) { GstAsfPacketInfo info; /* find padding field offset */ guint offset = packetinfo->err_cor_len + 2 + gst_asf_get_var_size_field_len (packetinfo->packet_field_type) + gst_asf_get_var_size_field_len (packetinfo->seq_field_type); buffer = gst_buffer_make_writable (buffer); switch (packetinfo->padd_field_type) { case ASF_FIELD_TYPE_DWORD: GST_WRITE_UINT32_LE (&(GST_BUFFER_DATA (buffer)[offset]), 0); break; case ASF_FIELD_TYPE_WORD: GST_WRITE_UINT16_LE (&(GST_BUFFER_DATA (buffer)[offset]), 0); break; case ASF_FIELD_TYPE_BYTE: GST_BUFFER_DATA (buffer)[offset] = 0; break; case ASF_FIELD_TYPE_NONE: default: break; } gst_asf_parse_packet (buffer, &info, FALSE, 0); } if (packetinfo->padding != 0) packet_util_size = rtpasfpay->asfinfo.packet_size - packetinfo->padding; else packet_util_size = packetinfo->packet_size; packet_offset = 0; while (packet_util_size > 0) { /* Even if we don't fill completely an output buffer we * push it when we add an fragment. Because it seems that * it is not possible to determine where a asf packet * fragment ends inside a rtp packet payload. * This flag tells us to push the packet. */ gboolean force_push = FALSE; /* we have no output buffer pending, create one */ if (rtpasfpay->current == NULL) { GST_LOG_OBJECT (rtpasfpay, "Creating new output buffer"); rtpasfpay->current = gst_rtp_buffer_new_allocate_len (GST_BASE_RTP_PAYLOAD_MTU (rtpasfpay), 0, 0); rtpasfpay->cur_off = gst_rtp_buffer_get_header_len (rtpasfpay->current); rtpasfpay->has_ts = FALSE; rtpasfpay->marker = FALSE; } data = GST_BUFFER_DATA (rtpasfpay->current) + rtpasfpay->cur_off; size_left = GST_BUFFER_SIZE (rtpasfpay->current) - rtpasfpay->cur_off; GST_DEBUG_OBJECT (rtpasfpay, "Input buffer bytes consumed: %" G_GUINT32_FORMAT "/%" G_GUINT32_FORMAT, packet_offset, GST_BUFFER_SIZE (buffer)); GST_DEBUG_OBJECT (rtpasfpay, "Output rtpbuffer status"); GST_DEBUG_OBJECT (rtpasfpay, "Current offset: %" G_GUINT32_FORMAT, rtpasfpay->cur_off); GST_DEBUG_OBJECT (rtpasfpay, "Size left: %" G_GUINT32_FORMAT, size_left); GST_DEBUG_OBJECT (rtpasfpay, "Has ts: %s", rtpasfpay->has_ts ? "yes" : "no"); if (rtpasfpay->has_ts) { GST_DEBUG_OBJECT (rtpasfpay, "Ts: %" G_GUINT32_FORMAT, rtpasfpay->ts); } flags = 0; if (packetinfo->has_keyframe) { flags = flags | 0x80; } flags = flags | 0x20; /* Relative timestamp is present */ if (!rtpasfpay->has_ts) { /* this is the first asf packet, its send time is the * rtp packet timestamp */ rtpasfpay->has_ts = TRUE; rtpasfpay->ts = packetinfo->send_time; } if (GST_BUFFER_SIZE (rtpasfpay->current) - rtpasfpay->cur_off >= packet_util_size + 8) { /* enough space for the rest of the packet */ if (packet_offset == 0) { flags = flags | 0x40; GST_WRITE_UINT24_BE (data + 1, packet_util_size); } else { GST_WRITE_UINT24_BE (data + 1, packet_offset); force_push = TRUE; } data[0] = flags; GST_WRITE_UINT32_BE (data + 4, (gint32) (packetinfo->send_time) - (gint32) rtpasfpay->ts); memcpy (data + 8, GST_BUFFER_DATA (buffer) + packet_offset, packet_util_size); /* updating status variables */ rtpasfpay->cur_off += 8 + packet_util_size; size_left -= packet_util_size + 8; packet_offset += packet_util_size; packet_util_size = 0; rtpasfpay->marker = TRUE; } else { /* fragment packet */ data[0] = flags; GST_WRITE_UINT24_BE (data + 1, packet_offset); GST_WRITE_UINT32_BE (data + 4, (gint32) (packetinfo->send_time) - (gint32) rtpasfpay->ts); memcpy (data + 8, GST_BUFFER_DATA (buffer) + packet_offset, size_left - 8); /* updating status variables */ rtpasfpay->cur_off += size_left; packet_offset += size_left - 8; packet_util_size -= size_left - 8; size_left = 0; force_push = TRUE; } /* there is not enough room for any more buffers */ if (force_push || size_left <= 8) { if (size_left != 0) { /* trim remaining bytes not used */ GstBuffer *aux = gst_buffer_create_sub (rtpasfpay->current, 0, GST_BUFFER_SIZE (rtpasfpay->current) - size_left); gst_buffer_unref (rtpasfpay->current); rtpasfpay->current = aux; } gst_rtp_buffer_set_ssrc (rtpasfpay->current, rtppay->current_ssrc); gst_rtp_buffer_set_marker (rtpasfpay->current, rtpasfpay->marker); gst_rtp_buffer_set_payload_type (rtpasfpay->current, GST_BASE_RTP_PAYLOAD_PT (rtppay)); gst_rtp_buffer_set_seq (rtpasfpay->current, rtppay->seqnum + 1); gst_rtp_buffer_set_timestamp (rtpasfpay->current, packetinfo->send_time); GST_BUFFER_TIMESTAMP (rtpasfpay->current) = GST_BUFFER_TIMESTAMP (buffer); gst_buffer_set_caps (rtpasfpay->current, GST_PAD_CAPS (GST_BASE_RTP_PAYLOAD_SRCPAD (rtppay))); rtppay->seqnum++; rtppay->timestamp = packetinfo->send_time; GST_DEBUG_OBJECT (rtpasfpay, "Pushing rtp buffer"); ret = gst_pad_push (GST_BASE_RTP_PAYLOAD_SRCPAD (rtppay), rtpasfpay->current); rtpasfpay->current = NULL; if (ret != GST_FLOW_OK) { gst_buffer_unref (buffer); return ret; } } } gst_buffer_unref (buffer); return ret; }