1a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/* 2a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 3a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * BlueZ - Bluetooth protocol stack for Linux 4a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 59184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org> 6a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 7a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 8a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * This library is free software; you can redistribute it and/or 9a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * modify it under the terms of the GNU Lesser General Public 10a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * License as published by the Free Software Foundation; either 11a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * version 2.1 of the License, or (at your option) any later version. 12a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 13a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * This library is distributed in the hope that it will be useful, 14a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * but WITHOUT ANY WARRANTY; without even the implied warranty of 15a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * Lesser General Public License for more details. 17a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 18a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * You should have received a copy of the GNU Lesser General Public 19a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * License along with this library; if not, write to the Free Software 20a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 22a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz */ 23a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 24a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#ifdef HAVE_CONFIG_H 25a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <config.h> 26a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#endif 27a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 28e20bd41482accdcd76d46111cccebb2cea46bf8cMarcel Holtmann#include "gstpragma.h" 29a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "gstrtpsbcpay.h" 30a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <math.h> 31a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <string.h> 32a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 33a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define RTP_SBC_PAYLOAD_HEADER_SIZE 1 34a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define DEFAULT_MIN_FRAMES 0 35a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define RTP_SBC_HEADER_TOTAL (12 + RTP_SBC_PAYLOAD_HEADER_SIZE) 36a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 37a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#if __BYTE_ORDER == __LITTLE_ENDIAN 38a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 39a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct rtp_payload { 40cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 frame_count:4; 41cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 rfa0:1; 42cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_last_fragment:1; 43cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_first_fragment:1; 44cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_fragmented:1; 45a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} __attribute__ ((packed)); 46a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 47a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#elif __BYTE_ORDER == __BIG_ENDIAN 48a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 49a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct rtp_payload { 50cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_fragmented:1; 51cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_first_fragment:1; 52cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_last_fragment:1; 53cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 rfa0:1; 54cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 frame_count:4; 55a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} __attribute__ ((packed)); 56a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 57a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#else 58a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#error "Unknown byte order" 59a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#endif 60a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 61a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzenum { 62a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz PROP_0, 63a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz PROP_MIN_FRAMES 64a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}; 65a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 66a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGST_DEBUG_CATEGORY_STATIC(gst_rtp_sbc_pay_debug); 67a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define GST_CAT_DEFAULT gst_rtp_sbc_pay_debug 68a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 69a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGST_BOILERPLATE(GstRtpSBCPay, gst_rtp_sbc_pay, GstBaseRTPPayload, 70a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_TYPE_BASE_RTP_PAYLOAD); 71a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 72a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic const GstElementDetails gst_rtp_sbc_pay_details = 73a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_ELEMENT_DETAILS("RTP packet payloader", 74a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Codec/Payloader/Network", 75a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Payload SBC audio as RTP packets", 76a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Thiago Sousa Santos " 77a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "<thiagoss@lcc.ufcg.edu.br>"); 78a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 79a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstStaticPadTemplate gst_rtp_sbc_pay_sink_factory = 80a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, 813ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz GST_STATIC_CAPS("audio/x-sbc, " 82a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "rate = (int) { 16000, 32000, 44100, 48000 }, " 83a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "channels = (int) [ 1, 2 ], " 8441387ca1ae954c4b8ea99e8e4e1646198af254a7Luiz Augusto von Dentz "mode = (string) { \"mono\", \"dual\", \"stereo\", \"joint\" }, " 85a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "blocks = (int) { 4, 8, 12, 16 }, " 86a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "subbands = (int) { 4, 8 }, " 8741387ca1ae954c4b8ea99e8e4e1646198af254a7Luiz Augusto von Dentz "allocation = (string) { \"snr\", \"loudness\" }, " 8841387ca1ae954c4b8ea99e8e4e1646198af254a7Luiz Augusto von Dentz "bitpool = (int) [ 2, 64 ]") 89a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz ); 90a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 91a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstStaticPadTemplate gst_rtp_sbc_pay_src_factory = 92a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS, 933ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz GST_STATIC_CAPS( 943ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "application/x-rtp, " 953ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "media = (string) \"audio\"," 963ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " 973ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "clock-rate = (int) { 16000, 32000, 44100, 48000 }," 983ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "encoding-name = (string) \"SBC\"") 99a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz ); 100a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 101cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_set_property(GObject *object, guint prop_id, 102cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg const GValue *value, GParamSpec *pspec); 103cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_get_property(GObject *object, guint prop_id, 104cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GValue *value, GParamSpec *pspec); 105a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 106a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gint gst_rtp_sbc_pay_get_frame_len(gint subbands, gint channels, 107cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg gint blocks, gint bitpool, const gchar *channel_mode) 108a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 109a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint len; 110a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint join; 111a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 112a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz len = 4 + (4 * subbands * channels)/8; 113a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 114a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (strcmp(channel_mode, "mono") == 0 || 115a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz strcmp(channel_mode, "dual") == 0) 116cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg len += ((blocks * channels * bitpool) + 7) / 8; 117a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz else { 118a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz join = strcmp(channel_mode, "joint") == 0 ? 1 : 0; 119cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg len += ((join * subbands + blocks * bitpool) + 7) / 8; 120a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 121a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 122a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return len; 123a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 124a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 125a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_rtp_sbc_pay_set_caps(GstBaseRTPPayload *payload, 126a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstCaps *caps) 127a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 128a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 129a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint rate, subbands, channels, blocks, bitpool; 130a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint frame_len; 131cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg const gchar *channel_mode; 132a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstStructure *structure; 133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay = GST_RTP_SBC_PAY(payload); 135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz structure = gst_caps_get_structure(caps, 0); 137a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "rate", &rate)) 138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 139a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "channels", &channels)) 140a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "blocks", &blocks)) 142a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 143a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "bitpool", &bitpool)) 144a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 145a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "subbands", &subbands)) 146a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 147a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 148a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz channel_mode = gst_structure_get_string(structure, "mode"); 149a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!channel_mode) 150a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 151a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 152a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz frame_len = gst_rtp_sbc_pay_get_frame_len(subbands, channels, blocks, 153a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz bitpool, channel_mode); 154a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 155a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay->frame_length = frame_len; 156a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 157cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg gst_basertppayload_set_options(payload, "audio", TRUE, "SBC", rate); 158a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 159a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_DEBUG_OBJECT(payload, "calculated frame length: %d ", frame_len); 160a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 161cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg return gst_basertppayload_set_outcaps(payload, NULL); 162a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_rtp_sbc_pay_flush_buffers(GstRtpSBCPay *sbcpay) 165a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 166a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint available; 167a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint max_payload; 168cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GstBuffer *outbuf; 169a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint8 *payload_data; 170449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz guint frame_count; 171449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz guint payload_length; 172a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz struct rtp_payload *payload; 173a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 174a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (sbcpay->frame_length == 0) { 175a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_ERROR_OBJECT(sbcpay, "Frame length is 0"); 176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return GST_FLOW_ERROR; 177a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 179a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz available = gst_adapter_available(sbcpay->adapter); 180a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 181a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz max_payload = gst_rtp_buffer_calc_payload_len( 182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_BASE_RTP_PAYLOAD_MTU(sbcpay) - RTP_SBC_PAYLOAD_HEADER_SIZE, 183a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 0, 0); 184a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 185a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz max_payload = MIN(max_payload, available); 186449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz frame_count = max_payload / sbcpay->frame_length; 187449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz payload_length = frame_count * sbcpay->frame_length; 1887ae45c5a353a3e6a32044263cb1a367f237e6505Luiz Augusto von Dentz if (payload_length == 0) /* Nothing to send */ 1897ae45c5a353a3e6a32044263cb1a367f237e6505Luiz Augusto von Dentz return GST_FLOW_OK; 190a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 191449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz outbuf = gst_rtp_buffer_new_allocate(payload_length + 192a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0); 193a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 194a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_buffer_set_payload_type(outbuf, 195a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_BASE_RTP_PAYLOAD_PT(sbcpay)); 196a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 197a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_data = gst_rtp_buffer_get_payload(outbuf); 198cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg payload = (struct rtp_payload *) payload_data; 199a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz memset(payload, 0, sizeof(struct rtp_payload)); 200449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz payload->frame_count = frame_count; 201a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 202744fbe08ac5950a96cfbe193fcc2f664c26acf61Luiz Augusto von Dentz gst_adapter_copy(sbcpay->adapter, payload_data + 20393f2cfda49d36c29a089012fd7e9df0bcaa8682eLuiz Augusto von Dentz RTP_SBC_PAYLOAD_HEADER_SIZE, 0, payload_length); 204744fbe08ac5950a96cfbe193fcc2f664c26acf61Luiz Augusto von Dentz gst_adapter_flush(sbcpay->adapter, payload_length); 205a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 2061f9f22f64d5e7c66c6e2d20452f6e5918d0020fbLuiz Augusto von Dentz GST_BUFFER_TIMESTAMP(outbuf) = sbcpay->timestamp; 207cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GST_DEBUG_OBJECT(sbcpay, "Pushing %d bytes", payload_length); 208a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 2091f9f22f64d5e7c66c6e2d20452f6e5918d0020fbLuiz Augusto von Dentz return gst_basertppayload_push(GST_BASE_RTP_PAYLOAD(sbcpay), outbuf); 210a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 211a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 212a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_rtp_sbc_pay_handle_buffer(GstBaseRTPPayload *payload, 213a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstBuffer *buffer) 214a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 215a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 216a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint available; 217a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 2183ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz /* FIXME check for negotiation */ 2193ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz 220a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay = GST_RTP_SBC_PAY(payload); 221a8b3b548ec9870df10709a839ed4c07e6d8eb76dLuiz Augusto von Dentz sbcpay->timestamp = GST_BUFFER_TIMESTAMP(buffer); 222a8b3b548ec9870df10709a839ed4c07e6d8eb76dLuiz Augusto von Dentz 2237ae45c5a353a3e6a32044263cb1a367f237e6505Luiz Augusto von Dentz gst_adapter_push(sbcpay->adapter, buffer); 224a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 225a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz available = gst_adapter_available(sbcpay->adapter); 226a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (available + RTP_SBC_HEADER_TOTAL >= 2270260a8613bd992b596dfa0f2b69ecfbba33c9bcaMarcel Holtmann GST_BASE_RTP_PAYLOAD_MTU(sbcpay) || 2280260a8613bd992b596dfa0f2b69ecfbba33c9bcaMarcel Holtmann (available > 2290260a8613bd992b596dfa0f2b69ecfbba33c9bcaMarcel Holtmann (sbcpay->min_frames * sbcpay->frame_length))) 230a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return gst_rtp_sbc_pay_flush_buffers(sbcpay); 231a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 232a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return GST_FLOW_OK; 233a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 234a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 235a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_rtp_sbc_pay_handle_event(GstPad *pad, 236a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstEvent *event) 237a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 238a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay = GST_RTP_SBC_PAY(GST_PAD_PARENT(pad)); 239a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 240a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz switch (GST_EVENT_TYPE(event)) { 241a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz case GST_EVENT_EOS: 242a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_flush_buffers(sbcpay); 243a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 244a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz default: 245a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 246a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 247a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 248a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 249a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 250a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 251a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_base_init(gpointer g_class) 252a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 253a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); 254a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 255a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_element_class_add_pad_template(element_class, 256a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_static_pad_template_get(&gst_rtp_sbc_pay_sink_factory)); 257a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_element_class_add_pad_template(element_class, 258a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_static_pad_template_get(&gst_rtp_sbc_pay_src_factory)); 259a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 260a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_element_class_set_details(element_class, &gst_rtp_sbc_pay_details); 261a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 262a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 263a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_finalize(GObject *object) 264a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 265a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay = GST_RTP_SBC_PAY(object); 266cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg g_object_unref(sbcpay->adapter); 267a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 268cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object)); 269a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 270a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 271a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_class_init(GstRtpSBCPayClass *klass) 272a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 273a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GObjectClass *gobject_class; 274a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstBaseRTPPayloadClass *payload_class = 275a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_BASE_RTP_PAYLOAD_CLASS(klass); 276a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 277a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class = G_OBJECT_CLASS(klass); 278a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz parent_class = g_type_class_peek_parent(klass); 279a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 280a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_rtp_sbc_pay_finalize); 281a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class->set_property = GST_DEBUG_FUNCPTR( 282a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_set_property); 283a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class->get_property = GST_DEBUG_FUNCPTR( 284a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_get_property); 285a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 286a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_class->set_caps = GST_DEBUG_FUNCPTR(gst_rtp_sbc_pay_set_caps); 287a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_class->handle_buffer = GST_DEBUG_FUNCPTR( 288a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_handle_buffer); 289a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_class->handle_event = GST_DEBUG_FUNCPTR( 290a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_handle_event); 291a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 292a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz /* properties */ 293cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg g_object_class_install_property(G_OBJECT_CLASS(klass), 294a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz PROP_MIN_FRAMES, 295cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg g_param_spec_int("min-frames", "minimum frame number", 296a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Minimum quantity of frames to send in one packet " 297a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "(-1 for maximum allowed by the mtu)", 298a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz -1, G_MAXINT, DEFAULT_MIN_FRAMES, G_PARAM_READWRITE)); 299a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 300a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_DEBUG_CATEGORY_INIT(gst_rtp_sbc_pay_debug, "rtpsbcpay", 0, 301a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "RTP SBC payloader"); 302a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 303a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 304cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_set_property(GObject *object, guint prop_id, 305cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg const GValue *value, GParamSpec *pspec) 306a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 307a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 308a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 309cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg sbcpay = GST_RTP_SBC_PAY(object); 310a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 311a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz switch (prop_id) { 312a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz case PROP_MIN_FRAMES: 313a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay->min_frames = g_value_get_int(value); 314a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 315a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz default: 316cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 317a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 318a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 319a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 320a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 321cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_get_property(GObject *object, guint prop_id, 322cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GValue *value, GParamSpec *pspec) 323a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 324a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 325a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 326cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg sbcpay = GST_RTP_SBC_PAY(object); 327a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 328a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz switch (prop_id) { 329a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz case PROP_MIN_FRAMES: 330a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz g_value_set_int(value, sbcpay->min_frames); 331a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 332a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz default: 333cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 334a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 335a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 336a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 337a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 338a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_init(GstRtpSBCPay *self, GstRtpSBCPayClass *klass) 339a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 340a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz self->adapter = gst_adapter_new(); 341a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz self->frame_length = 0; 3421f9f22f64d5e7c66c6e2d20452f6e5918d0020fbLuiz Augusto von Dentz self->timestamp = 0; 343a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 344a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz self->min_frames = DEFAULT_MIN_FRAMES; 345a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 346a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 347cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberggboolean gst_rtp_sbc_pay_plugin_init(GstPlugin *plugin) 348a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 349cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg return gst_element_register(plugin, "rtpsbcpay", GST_RANK_NONE, 350cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GST_TYPE_RTP_SBC_PAY); 351a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 352a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 353