gstrtpsbcpay.c revision 0260a8613bd992b596dfa0f2b69ecfbba33c9bca
1a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/* 2a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 3a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * BlueZ - Bluetooth protocol stack for Linux 4a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz * 5fb333f1c88df9c50529a390297565a6627bcf7adMarcel Holtmann * Copyright (C) 2004-2009 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 28a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "gstrtpsbcpay.h" 29a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <math.h> 30a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <string.h> 31a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 32a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define RTP_SBC_PAYLOAD_HEADER_SIZE 1 33a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define DEFAULT_MIN_FRAMES 0 34a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define RTP_SBC_HEADER_TOTAL (12 + RTP_SBC_PAYLOAD_HEADER_SIZE) 35a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 36a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#if __BYTE_ORDER == __LITTLE_ENDIAN 37a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 38a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct rtp_payload { 39cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 frame_count:4; 40cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 rfa0:1; 41cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_last_fragment:1; 42cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_first_fragment:1; 43cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_fragmented:1; 44a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} __attribute__ ((packed)); 45a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 46a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#elif __BYTE_ORDER == __BIG_ENDIAN 47a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 48a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct rtp_payload { 49cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_fragmented:1; 50cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_first_fragment:1; 51cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 is_last_fragment:1; 52cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 rfa0:1; 53cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg guint8 frame_count:4; 54a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} __attribute__ ((packed)); 55a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 56a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#else 57a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#error "Unknown byte order" 58a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#endif 59a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 60a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzenum { 61a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz PROP_0, 62a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz PROP_MIN_FRAMES 63a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}; 64a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 65a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGST_DEBUG_CATEGORY_STATIC(gst_rtp_sbc_pay_debug); 66a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define GST_CAT_DEFAULT gst_rtp_sbc_pay_debug 67a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 68a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGST_BOILERPLATE(GstRtpSBCPay, gst_rtp_sbc_pay, GstBaseRTPPayload, 69a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_TYPE_BASE_RTP_PAYLOAD); 70a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 71a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic const GstElementDetails gst_rtp_sbc_pay_details = 72a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_ELEMENT_DETAILS("RTP packet payloader", 73a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Codec/Payloader/Network", 74a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Payload SBC audio as RTP packets", 75a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Thiago Sousa Santos " 76a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "<thiagoss@lcc.ufcg.edu.br>"); 77a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 78a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstStaticPadTemplate gst_rtp_sbc_pay_sink_factory = 79a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS, 803ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz GST_STATIC_CAPS("audio/x-sbc, " 81a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "rate = (int) { 16000, 32000, 44100, 48000 }, " 82a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "channels = (int) [ 1, 2 ], " 8341387ca1ae954c4b8ea99e8e4e1646198af254a7Luiz Augusto von Dentz "mode = (string) { \"mono\", \"dual\", \"stereo\", \"joint\" }, " 84a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "blocks = (int) { 4, 8, 12, 16 }, " 85a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "subbands = (int) { 4, 8 }, " 8641387ca1ae954c4b8ea99e8e4e1646198af254a7Luiz Augusto von Dentz "allocation = (string) { \"snr\", \"loudness\" }, " 8741387ca1ae954c4b8ea99e8e4e1646198af254a7Luiz Augusto von Dentz "bitpool = (int) [ 2, 64 ]") 88a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz ); 89a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 90a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstStaticPadTemplate gst_rtp_sbc_pay_src_factory = 91a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS, 923ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz GST_STATIC_CAPS( 933ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "application/x-rtp, " 943ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "media = (string) \"audio\"," 953ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " 963ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "clock-rate = (int) { 16000, 32000, 44100, 48000 }," 973ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz "encoding-name = (string) \"SBC\"") 98a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz ); 99a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 100cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_set_property(GObject *object, guint prop_id, 101cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg const GValue *value, GParamSpec *pspec); 102cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_get_property(GObject *object, guint prop_id, 103cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GValue *value, GParamSpec *pspec); 104a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 105a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gint gst_rtp_sbc_pay_get_frame_len(gint subbands, gint channels, 106cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg gint blocks, gint bitpool, const gchar *channel_mode) 107a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 108a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint len; 109a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint join; 110a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 111a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz len = 4 + (4 * subbands * channels)/8; 112a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 113a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (strcmp(channel_mode, "mono") == 0 || 114a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz strcmp(channel_mode, "dual") == 0) 115cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg len += ((blocks * channels * bitpool) + 7) / 8; 116a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz else { 117a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz join = strcmp(channel_mode, "joint") == 0 ? 1 : 0; 118cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg len += ((join * subbands + blocks * bitpool) + 7) / 8; 119a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 120a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 121a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return len; 122a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 123a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 124a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_rtp_sbc_pay_set_caps(GstBaseRTPPayload *payload, 125a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstCaps *caps) 126a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 127a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 128a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint rate, subbands, channels, blocks, bitpool; 129a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gint frame_len; 130cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg const gchar *channel_mode; 131a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstStructure *structure; 132a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay = GST_RTP_SBC_PAY(payload); 134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz structure = gst_caps_get_structure(caps, 0); 136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "rate", &rate)) 137a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "channels", &channels)) 139a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 140a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "blocks", &blocks)) 141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 142a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "bitpool", &bitpool)) 143a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 144a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!gst_structure_get_int(structure, "subbands", &subbands)) 145a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 146a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 147a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz channel_mode = gst_structure_get_string(structure, "mode"); 148a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (!channel_mode) 149a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 150a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 151a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz frame_len = gst_rtp_sbc_pay_get_frame_len(subbands, channels, blocks, 152a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz bitpool, channel_mode); 153a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 154a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay->frame_length = frame_len; 155a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 156cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg gst_basertppayload_set_options(payload, "audio", TRUE, "SBC", rate); 157a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 158a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_DEBUG_OBJECT(payload, "calculated frame length: %d ", frame_len); 159a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 160cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg return gst_basertppayload_set_outcaps(payload, NULL); 161a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 162a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_rtp_sbc_pay_flush_buffers(GstRtpSBCPay *sbcpay) 164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 165a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint available; 166a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint max_payload; 167cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GstBuffer *outbuf; 168a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint8 *payload_data; 169449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz guint frame_count; 170449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz guint payload_length; 171a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz struct rtp_payload *payload; 172a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 173a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (sbcpay->frame_length == 0) { 174a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_ERROR_OBJECT(sbcpay, "Frame length is 0"); 175a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return GST_FLOW_ERROR; 176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 177a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz available = gst_adapter_available(sbcpay->adapter); 179a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 180a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz max_payload = gst_rtp_buffer_calc_payload_len( 181a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_BASE_RTP_PAYLOAD_MTU(sbcpay) - RTP_SBC_PAYLOAD_HEADER_SIZE, 182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 0, 0); 183a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 184a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz max_payload = MIN(max_payload, available); 185449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz frame_count = max_payload / sbcpay->frame_length; 186449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz payload_length = frame_count * sbcpay->frame_length; 1877ae45c5a353a3e6a32044263cb1a367f237e6505Luiz Augusto von Dentz if (payload_length == 0) /* Nothing to send */ 1887ae45c5a353a3e6a32044263cb1a367f237e6505Luiz Augusto von Dentz return GST_FLOW_OK; 189a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 190449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz outbuf = gst_rtp_buffer_new_allocate(payload_length + 191a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz RTP_SBC_PAYLOAD_HEADER_SIZE, 0, 0); 192a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 193a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_buffer_set_payload_type(outbuf, 194a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_BASE_RTP_PAYLOAD_PT(sbcpay)); 195a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 196a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_data = gst_rtp_buffer_get_payload(outbuf); 197cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg payload = (struct rtp_payload *) payload_data; 198a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz memset(payload, 0, sizeof(struct rtp_payload)); 199449c9728f515a3b1263f6961c608328b3ad582a9Luiz Augusto von Dentz payload->frame_count = frame_count; 200a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 201744fbe08ac5950a96cfbe193fcc2f664c26acf61Luiz Augusto von Dentz gst_adapter_copy(sbcpay->adapter, payload_data + 20293f2cfda49d36c29a089012fd7e9df0bcaa8682eLuiz Augusto von Dentz RTP_SBC_PAYLOAD_HEADER_SIZE, 0, payload_length); 203744fbe08ac5950a96cfbe193fcc2f664c26acf61Luiz Augusto von Dentz gst_adapter_flush(sbcpay->adapter, payload_length); 204a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 2051f9f22f64d5e7c66c6e2d20452f6e5918d0020fbLuiz Augusto von Dentz GST_BUFFER_TIMESTAMP(outbuf) = sbcpay->timestamp; 206cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GST_DEBUG_OBJECT(sbcpay, "Pushing %d bytes", payload_length); 207a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 2081f9f22f64d5e7c66c6e2d20452f6e5918d0020fbLuiz Augusto von Dentz return gst_basertppayload_push(GST_BASE_RTP_PAYLOAD(sbcpay), outbuf); 209a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 210a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 211a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_rtp_sbc_pay_handle_buffer(GstBaseRTPPayload *payload, 212a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstBuffer *buffer) 213a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 214a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 215a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz guint available; 216a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 2173ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz /* FIXME check for negotiation */ 2183ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz 219a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay = GST_RTP_SBC_PAY(payload); 220a8b3b548ec9870df10709a839ed4c07e6d8eb76dLuiz Augusto von Dentz sbcpay->timestamp = GST_BUFFER_TIMESTAMP(buffer); 221a8b3b548ec9870df10709a839ed4c07e6d8eb76dLuiz Augusto von Dentz 2227ae45c5a353a3e6a32044263cb1a367f237e6505Luiz Augusto von Dentz gst_adapter_push(sbcpay->adapter, buffer); 223a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 224a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz available = gst_adapter_available(sbcpay->adapter); 225a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz if (available + RTP_SBC_HEADER_TOTAL >= 2260260a8613bd992b596dfa0f2b69ecfbba33c9bcaMarcel Holtmann GST_BASE_RTP_PAYLOAD_MTU(sbcpay) || 2270260a8613bd992b596dfa0f2b69ecfbba33c9bcaMarcel Holtmann (available > 2280260a8613bd992b596dfa0f2b69ecfbba33c9bcaMarcel Holtmann (sbcpay->min_frames * sbcpay->frame_length))) 229a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return gst_rtp_sbc_pay_flush_buffers(sbcpay); 230a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 231a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return GST_FLOW_OK; 232a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 233a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 234a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_rtp_sbc_pay_handle_event(GstPad *pad, 235a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstEvent *event) 236a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 237a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay = GST_RTP_SBC_PAY(GST_PAD_PARENT(pad)); 238a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 239a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz switch (GST_EVENT_TYPE(event)) { 240a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz case GST_EVENT_EOS: 241a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_flush_buffers(sbcpay); 242a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 243a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz default: 244a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 245a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 246a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 247a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz return FALSE; 248a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 249a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 250a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_base_init(gpointer g_class) 251a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 252a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstElementClass *element_class = GST_ELEMENT_CLASS(g_class); 253a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 254a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_element_class_add_pad_template(element_class, 255a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_static_pad_template_get(&gst_rtp_sbc_pay_sink_factory)); 256a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_element_class_add_pad_template(element_class, 257a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_static_pad_template_get(&gst_rtp_sbc_pay_src_factory)); 258a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 259a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_element_class_set_details(element_class, &gst_rtp_sbc_pay_details); 260a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 261a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 262a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_finalize(GObject *object) 263a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 264a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay = GST_RTP_SBC_PAY(object); 265cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg g_object_unref(sbcpay->adapter); 266a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 267cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GST_CALL_PARENT(G_OBJECT_CLASS, finalize, (object)); 268a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 269a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 270a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_class_init(GstRtpSBCPayClass *klass) 271a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 272a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GObjectClass *gobject_class; 273a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstBaseRTPPayloadClass *payload_class = 274a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_BASE_RTP_PAYLOAD_CLASS(klass); 275a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 276a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class = G_OBJECT_CLASS(klass); 277a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz parent_class = g_type_class_peek_parent(klass); 278a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 279a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class->finalize = GST_DEBUG_FUNCPTR(gst_rtp_sbc_pay_finalize); 280a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class->set_property = GST_DEBUG_FUNCPTR( 281a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_set_property); 282a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gobject_class->get_property = GST_DEBUG_FUNCPTR( 283a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_get_property); 284a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 285a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_class->set_caps = GST_DEBUG_FUNCPTR(gst_rtp_sbc_pay_set_caps); 286a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_class->handle_buffer = GST_DEBUG_FUNCPTR( 287a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_handle_buffer); 288a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz payload_class->handle_event = GST_DEBUG_FUNCPTR( 289a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz gst_rtp_sbc_pay_handle_event); 290a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 291a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz /* properties */ 292cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg g_object_class_install_property(G_OBJECT_CLASS(klass), 293a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz PROP_MIN_FRAMES, 294cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg g_param_spec_int("min-frames", "minimum frame number", 295a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "Minimum quantity of frames to send in one packet " 296a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "(-1 for maximum allowed by the mtu)", 297a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz -1, G_MAXINT, DEFAULT_MIN_FRAMES, G_PARAM_READWRITE)); 298a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 299a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GST_DEBUG_CATEGORY_INIT(gst_rtp_sbc_pay_debug, "rtpsbcpay", 0, 300a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz "RTP SBC payloader"); 301a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 302a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 303cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_set_property(GObject *object, guint prop_id, 304cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg const GValue *value, GParamSpec *pspec) 305a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 306a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 307a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 308cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg sbcpay = GST_RTP_SBC_PAY(object); 309a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 310a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz switch (prop_id) { 311a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz case PROP_MIN_FRAMES: 312a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz sbcpay->min_frames = g_value_get_int(value); 313a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 314a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz default: 315cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 316a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 317a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 318a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 319a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 320cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedbergstatic void gst_rtp_sbc_pay_get_property(GObject *object, guint prop_id, 321cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GValue *value, GParamSpec *pspec) 322a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 323a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz GstRtpSBCPay *sbcpay; 324a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 325cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg sbcpay = GST_RTP_SBC_PAY(object); 326a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 327a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz switch (prop_id) { 328a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz case PROP_MIN_FRAMES: 329a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz g_value_set_int(value, sbcpay->min_frames); 330a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 331a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz default: 332cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); 333a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz break; 334a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz } 335a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 336a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 337a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_rtp_sbc_pay_init(GstRtpSBCPay *self, GstRtpSBCPayClass *klass) 338a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 339a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz self->adapter = gst_adapter_new(); 340a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz self->frame_length = 0; 3411f9f22f64d5e7c66c6e2d20452f6e5918d0020fbLuiz Augusto von Dentz self->timestamp = 0; 342a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 343a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz self->min_frames = DEFAULT_MIN_FRAMES; 344a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 345a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 346cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberggboolean gst_rtp_sbc_pay_plugin_init(GstPlugin *plugin) 347a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{ 348cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg return gst_element_register(plugin, "rtpsbcpay", GST_RANK_NONE, 349cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg GST_TYPE_RTP_SBC_PAY); 350a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz} 351a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz 352