static gboolean gst_rtp_base_payload_audio_sink_event (GstRTPBasePayload * basep, GstEvent * event) { GstRTPBaseAudioPayload *payload; gboolean res = FALSE; payload = GST_RTP_BASE_AUDIO_PAYLOAD (basep); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: /* flush remaining bytes in the adapter */ gst_rtp_base_audio_payload_flush (payload, -1, -1); break; case GST_EVENT_FLUSH_STOP: gst_adapter_clear (payload->priv->adapter); break; default: break; } /* let parent handle the remainder of the event */ res = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (basep, event); return res; }
static GstStateChangeReturn gst_rtp_base_payload_audio_change_state (GstElement * element, GstStateChange transition) { GstRTPBaseAudioPayload *rtpbasepayload; GstStateChangeReturn ret; rtpbasepayload = GST_RTP_BASE_AUDIO_PAYLOAD (element); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: rtpbasepayload->priv->cached_mtu = -1; rtpbasepayload->priv->last_rtptime = -1; rtpbasepayload->priv->last_timestamp = -1; break; default: break; } ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_adapter_clear (rtpbasepayload->priv->adapter); break; default: break; } return ret; }
static void gst_rtp_L16_pay_init (GstRtpL16Pay * rtpL16pay) { GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpL16pay); /* tell rtpbaseaudiopayload that this is a sample based codec */ gst_rtp_base_audio_payload_set_sample_based (rtpbaseaudiopayload); }
static gboolean gst_rtp_L16_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) { GstRtpL16Pay *rtpL16pay; gboolean res; gchar *params; GstAudioInfo *info; const GstRTPChannelOrder *order; GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (basepayload); rtpL16pay = GST_RTP_L16_PAY (basepayload); info = &rtpL16pay->info; gst_audio_info_init (info); if (!gst_audio_info_from_caps (info, caps)) goto invalid_caps; order = gst_rtp_channels_get_by_pos (info->channels, info->position); rtpL16pay->order = order; gst_rtp_base_payload_set_options (basepayload, "audio", TRUE, "L16", info->rate); params = g_strdup_printf ("%d", info->channels); if (!order && info->channels > 2) { GST_ELEMENT_WARNING (rtpL16pay, STREAM, DECODE, (NULL), ("Unknown channel order for %d channels", info->channels)); } if (order && order->name) { res = gst_rtp_base_payload_set_outcaps (basepayload, "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT, info->channels, "channel-order", G_TYPE_STRING, order->name, NULL); } else { res = gst_rtp_base_payload_set_outcaps (basepayload, "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT, info->channels, NULL); } g_free (params); /* octet-per-sample is 2 * channels for L16 */ gst_rtp_base_audio_payload_set_sample_options (rtpbaseaudiopayload, 2 * info->channels); return res; /* ERRORS */ invalid_caps: { GST_DEBUG_OBJECT (rtpL16pay, "invalid caps"); return FALSE; } }
static void gst_rtp_base_audio_payload_finalize (GObject * object) { GstRTPBaseAudioPayload *payload; payload = GST_RTP_BASE_AUDIO_PAYLOAD (object); g_object_unref (payload->priv->adapter); GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); }
static void gst_rtp_bv_pay_init (GstRTPBVPay * rtpbvpay) { GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpbvpay); rtpbvpay->mode = -1; /* tell rtpbaseaudiopayload that this is a frame based codec */ gst_rtp_base_audio_payload_set_frame_based (rtpbaseaudiopayload); }
static void gst_rtp_g722_pay_init (GstRtpG722Pay * rtpg722pay) { GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpg722pay); GST_RTP_BASE_PAYLOAD (rtpg722pay)->pt = GST_RTP_PAYLOAD_G722; /* tell rtpbaseaudiopayload that this is a sample based codec */ gst_rtp_base_audio_payload_set_sample_based (rtpbaseaudiopayload); }
static void gst_rtp_pcmu_pay_init (GstRtpPcmuPay * rtppcmupay) { GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtppcmupay); GST_RTP_BASE_PAYLOAD (rtppcmupay)->clock_rate = 8000; /* tell rtpbaseaudiopayload that this is a sample based codec */ gst_rtp_base_audio_payload_set_sample_based (rtpbaseaudiopayload); /* octet-per-sample is 1 for PCM */ gst_rtp_base_audio_payload_set_sample_options (rtpbaseaudiopayload, 1); }
static void gst_rtp_siren_pay_init (GstRTPSirenPay * rtpsirenpay) { GstRTPBasePayload *rtpbasepayload; GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbasepayload = GST_RTP_BASE_PAYLOAD (rtpsirenpay); rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpsirenpay); /* we don't set the payload type, it should be set by the application using * the pt property or the default 96 will be used */ rtpbasepayload->clock_rate = 16000; /* tell rtpbaseaudiopayload that this is a frame based codec */ gst_rtp_base_audio_payload_set_frame_based (rtpbaseaudiopayload); }
static void gst_rtp_base_audio_payload_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstRTPBaseAudioPayload *payload; payload = GST_RTP_BASE_AUDIO_PAYLOAD (object); switch (prop_id) { case PROP_BUFFER_LIST: g_value_set_boolean (value, payload->priv->buffer_list); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean gst_rtp_siren_pay_setcaps (GstRTPBasePayload * rtpbasepayload, GstCaps * caps) { GstRTPSirenPay *rtpsirenpay; GstRTPBaseAudioPayload *rtpbaseaudiopayload; gint dct_length; GstStructure *structure; const char *payload_name; rtpsirenpay = GST_RTP_SIREN_PAY (rtpbasepayload); rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpbasepayload); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "dct-length", &dct_length); if (dct_length != 320) goto wrong_dct; payload_name = gst_structure_get_name (structure); if (g_ascii_strcasecmp ("audio/x-siren", payload_name)) goto wrong_caps; gst_rtp_base_payload_set_options (rtpbasepayload, "audio", TRUE, "SIREN", 16000); /* set options for this frame based audio codec */ gst_rtp_base_audio_payload_set_frame_options (rtpbaseaudiopayload, 20, 40); return gst_rtp_base_payload_set_outcaps (rtpbasepayload, NULL); /* ERRORS */ wrong_dct: { GST_ERROR_OBJECT (rtpsirenpay, "dct-length must be 320, received %d", dct_length); return FALSE; } wrong_caps: { GST_ERROR_OBJECT (rtpsirenpay, "expected audio/x-siren, received %s", payload_name); return FALSE; } }
static gboolean gst_rtp_bv_pay_sink_setcaps (GstRTPBasePayload * rtpbasepayload, GstCaps * caps) { GstRTPBVPay *rtpbvpay; GstRTPBaseAudioPayload *rtpbaseaudiopayload; gint mode; GstStructure *structure; const char *payload_name; rtpbvpay = GST_RTP_BV_PAY (rtpbasepayload); rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpbasepayload); structure = gst_caps_get_structure (caps, 0); payload_name = gst_structure_get_name (structure); if (g_ascii_strcasecmp ("audio/x-bv", payload_name)) goto wrong_caps; if (!gst_structure_get_int (structure, "mode", &mode)) goto no_mode; if (mode != 16 && mode != 32) goto wrong_mode; if (mode == 16) { gst_rtp_base_payload_set_options (rtpbasepayload, "audio", TRUE, "BV16", 8000); rtpbasepayload->clock_rate = 8000; } else { gst_rtp_base_payload_set_options (rtpbasepayload, "audio", TRUE, "BV32", 16000); rtpbasepayload->clock_rate = 16000; } /* set options for this frame based audio codec */ gst_rtp_base_audio_payload_set_frame_options (rtpbaseaudiopayload, mode, mode == 16 ? 10 : 20); if (mode != rtpbvpay->mode && rtpbvpay->mode != -1) goto mode_changed; rtpbvpay->mode = mode; return TRUE; /* ERRORS */ wrong_caps: { GST_ERROR_OBJECT (rtpbvpay, "expected audio/x-bv, received %s", payload_name); return FALSE; } no_mode: { GST_ERROR_OBJECT (rtpbvpay, "did not receive a mode"); return FALSE; } wrong_mode: { GST_ERROR_OBJECT (rtpbvpay, "mode must be 16 or 32, received %d", mode); return FALSE; } mode_changed: { GST_ERROR_OBJECT (rtpbvpay, "Mode has changed from %d to %d! " "Mode cannot change while streaming", rtpbvpay->mode, mode); return FALSE; } }
static gboolean gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) { GstRtpG722Pay *rtpg722pay; GstStructure *structure; gint rate, channels, clock_rate; gboolean res; gchar *params; #if 0 GstAudioChannelPosition *pos; const GstRTPChannelOrder *order; #endif GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (basepayload); rtpg722pay = GST_RTP_G722_PAY (basepayload); structure = gst_caps_get_structure (caps, 0); /* first parse input caps */ if (!gst_structure_get_int (structure, "rate", &rate)) goto no_rate; if (!gst_structure_get_int (structure, "channels", &channels)) goto no_channels; /* FIXME: Do something with the channel positions */ #if 0 /* get the channel order */ pos = gst_audio_get_channel_positions (structure); if (pos) order = gst_rtp_channels_get_by_pos (channels, pos); else order = NULL; #endif /* Clock rate is always 8000 Hz for G722 according to * RFC 3551 although the sampling rate is 16000 Hz */ clock_rate = 8000; gst_rtp_base_payload_set_options (basepayload, "audio", basepayload->pt != GST_RTP_PAYLOAD_G722, "G722", clock_rate); params = g_strdup_printf ("%d", channels); #if 0 if (!order && channels > 2) { GST_ELEMENT_WARNING (rtpg722pay, STREAM, DECODE, (NULL), ("Unknown channel order for %d channels", channels)); } if (order && order->name) { res = gst_rtp_base_payload_set_outcaps (basepayload, "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT, channels, "channel-order", G_TYPE_STRING, order->name, NULL); } else { #endif res = gst_rtp_base_payload_set_outcaps (basepayload, "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT, channels, NULL); #if 0 } #endif g_free (params); #if 0 g_free (pos); #endif rtpg722pay->rate = rate; rtpg722pay->channels = channels; /* bits-per-sample is 4 * channels for G722, but as the RTP clock runs at * half speed (8 instead of 16 khz), pretend it's 8 bits per sample * channels. */ gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload, 8 * rtpg722pay->channels); return res; /* ERRORS */ no_rate: { GST_DEBUG_OBJECT (rtpg722pay, "no rate given"); return FALSE; } no_channels: { GST_DEBUG_OBJECT (rtpg722pay, "no channels given"); return FALSE; } }
static gboolean gst_rtp_ilbc_pay_sink_setcaps (GstRTPBasePayload * rtpbasepayload, GstCaps * caps) { GstRTPILBCPay *rtpilbcpay; GstRTPBaseAudioPayload *rtpbaseaudiopayload; gboolean ret; gint mode; gchar *mode_str; GstStructure *structure; const char *payload_name; rtpilbcpay = GST_RTP_ILBC_PAY (rtpbasepayload); rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpbasepayload); structure = gst_caps_get_structure (caps, 0); payload_name = gst_structure_get_name (structure); if (g_ascii_strcasecmp ("audio/x-iLBC", payload_name)) goto wrong_caps; if (!gst_structure_get_int (structure, "mode", &mode)) goto no_mode; if (mode != 20 && mode != 30) goto wrong_mode; gst_rtp_base_payload_set_options (rtpbasepayload, "audio", TRUE, "ILBC", 8000); /* set options for this frame based audio codec */ gst_rtp_base_audio_payload_set_frame_options (rtpbaseaudiopayload, mode, mode == 30 ? 50 : 38); mode_str = g_strdup_printf ("%d", mode); ret = gst_rtp_base_payload_set_outcaps (rtpbasepayload, "mode", G_TYPE_STRING, mode_str, NULL); g_free (mode_str); if (mode != rtpilbcpay->mode && rtpilbcpay->mode != -1) goto mode_changed; rtpilbcpay->mode = mode; return ret; /* ERRORS */ wrong_caps: { GST_ERROR_OBJECT (rtpilbcpay, "expected audio/x-iLBC, received %s", payload_name); return FALSE; } no_mode: { GST_ERROR_OBJECT (rtpilbcpay, "did not receive a mode"); return FALSE; } wrong_mode: { GST_ERROR_OBJECT (rtpilbcpay, "mode must be 20 or 30, received %d", mode); return FALSE; } mode_changed: { GST_ERROR_OBJECT (rtpilbcpay, "Mode has changed from %d to %d! " "Mode cannot change while streaming", rtpilbcpay->mode, mode); return FALSE; } }