diff --git a/gst/rtp/gstrtpL16depay.c b/gst/rtp/gstrtpL16depay.c index ca9f3c05d5..f1bed59399 100644 --- a/gst/rtp/gstrtpL16depay.c +++ b/gst/rtp/gstrtpL16depay.c @@ -25,7 +25,6 @@ #include #include -#include #include "gstrtpL16depay.h" #include "gstrtpchannels.h" @@ -39,6 +38,7 @@ GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw, " "format = (string) S16_BE, " + "layout = (string) interleaved, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]") ); @@ -131,6 +131,7 @@ gst_rtp_L16_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) gboolean res; const gchar *channel_order; const GstRTPChannelOrder *order; + GstAudioInfo *info; rtpL16depay = GST_RTP_L16_DEPAY (depayload); @@ -171,32 +172,32 @@ gst_rtp_L16_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) } depayload->clock_rate = clock_rate; - rtpL16depay->rate = clock_rate; - rtpL16depay->channels = channels; - srccaps = gst_caps_new_simple ("audio/x-raw", - "format", G_TYPE_STRING, "S16_BE", - "rate", G_TYPE_INT, clock_rate, "channels", G_TYPE_INT, channels, NULL); + info = &rtpL16depay->info; + gst_audio_info_init (info); + info->finfo = gst_audio_format_get_info (GST_AUDIO_FORMAT_S16BE); + info->rate = clock_rate; + info->channels = channels; + info->bpf = (info->finfo->width / 8) * channels; /* add channel positions */ channel_order = gst_structure_get_string (structure, "channel-order"); order = gst_rtp_channels_get_by_order (channels, channel_order); + rtpL16depay->order = order; if (order) { - gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), - order->pos); + memcpy (info->position, order->pos, + sizeof (GstAudioChannelPosition) * channels); + gst_audio_channel_positions_to_valid_order (info->position, info->channels); } else { - GstAudioChannelPosition *pos; - GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE, (NULL), ("Unknown channel order '%s' for %d channels", GST_STR_NULL (channel_order), channels)); /* create default NONE layout */ - pos = gst_rtp_channels_create_default (channels); - gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), pos); - g_free (pos); + gst_rtp_channels_create_default (channels, info->position); } + srccaps = gst_audio_info_to_caps (info); res = gst_pad_set_caps (depayload->srcpad, srccaps); gst_caps_unref (srccaps); @@ -237,6 +238,14 @@ gst_rtp_L16_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf) GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); } + outbuf = gst_buffer_make_writable (outbuf); + if (rtpL16depay->order && + !gst_audio_buffer_reorder_channels (outbuf, + rtpL16depay->info.finfo->format, rtpL16depay->info.channels, + rtpL16depay->info.position, rtpL16depay->order->pos)) { + goto reorder_failed; + } + gst_rtp_buffer_unmap (&rtp); return outbuf; @@ -249,6 +258,13 @@ empty_packet: gst_rtp_buffer_unmap (&rtp); return NULL; } +reorder_failed: + { + GST_ELEMENT_ERROR (rtpL16depay, STREAM, DECODE, + ("Channel reordering failed."), (NULL)); + gst_rtp_buffer_unmap (&rtp); + return NULL; + } } gboolean diff --git a/gst/rtp/gstrtpL16depay.h b/gst/rtp/gstrtpL16depay.h index 0fd9506434..b5b7c93766 100644 --- a/gst/rtp/gstrtpL16depay.h +++ b/gst/rtp/gstrtpL16depay.h @@ -22,6 +22,9 @@ #include #include +#include + +#include "gstrtpchannels.h" G_BEGIN_DECLS @@ -45,8 +48,8 @@ struct _GstRtpL16Depay { GstRTPBaseDepayload depayload; - guint rate; - guint channels; + GstAudioInfo info; + const GstRTPChannelOrder *order; }; /* Standard definition defining a class for this element. */ diff --git a/gst/rtp/gstrtpL16pay.c b/gst/rtp/gstrtpL16pay.c index cf5a647af0..af98ba9e3e 100644 --- a/gst/rtp/gstrtpL16pay.c +++ b/gst/rtp/gstrtpL16pay.c @@ -24,7 +24,6 @@ #include #include -#include #include #include "gstrtpL16pay.h" @@ -39,6 +38,7 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw, " "format = (string) S16_BE, " + "layout = (string) interleaved, " "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]") ); @@ -68,6 +68,9 @@ static gboolean gst_rtp_L16_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps); static GstCaps *gst_rtp_L16_pay_getcaps (GstRTPBasePayload * rtppayload, GstPad * pad, GstCaps * filter); +static GstFlowReturn +gst_rtp_L16_pay_handle_buffer (GstRTPBasePayload * basepayload, + GstBuffer * buffer); #define gst_rtp_L16_pay_parent_class parent_class G_DEFINE_TYPE (GstRtpL16Pay, gst_rtp_L16_pay, GST_TYPE_RTP_BASE_AUDIO_PAYLOAD); @@ -83,6 +86,7 @@ gst_rtp_L16_pay_class_init (GstRtpL16PayClass * klass) gstrtpbasepayload_class->set_caps = gst_rtp_L16_pay_setcaps; gstrtpbasepayload_class->get_caps = gst_rtp_L16_pay_getcaps; + gstrtpbasepayload_class->handle_buffer = gst_rtp_L16_pay_handle_buffer; gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&gst_rtp_L16_pay_src_template)); @@ -113,72 +117,54 @@ static gboolean gst_rtp_L16_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) { GstRtpL16Pay *rtpL16pay; - GstStructure *structure; - gint channels, rate; gboolean res; gchar *params; - GstAudioChannelPosition *pos; + GstAudioInfo *info; const GstRTPChannelOrder *order; GstRTPBaseAudioPayload *rtpbaseaudiopayload; rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (basepayload); rtpL16pay = GST_RTP_L16_PAY (basepayload); - structure = gst_caps_get_structure (caps, 0); + info = &rtpL16pay->info; + gst_audio_info_init (info); + if (!gst_audio_info_from_caps (info, caps)) + goto invalid_caps; - /* first parse input caps */ - if (!gst_structure_get_int (structure, "rate", &rate)) - goto no_rate; + order = gst_rtp_channels_get_by_pos (info->channels, info->position); + rtpL16pay->order = order; - if (!gst_structure_get_int (structure, "channels", &channels)) - goto no_channels; + gst_rtp_base_payload_set_options (basepayload, "audio", TRUE, "L16", + info->rate); + params = g_strdup_printf ("%d", info->channels); - /* 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; - - gst_rtp_base_payload_set_options (basepayload, "audio", TRUE, "L16", rate); - params = g_strdup_printf ("%d", channels); - - if (!order && channels > 2) { + if (!order && info->channels > 2) { GST_ELEMENT_WARNING (rtpL16pay, STREAM, DECODE, - (NULL), ("Unknown channel order for %d channels", channels)); + (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, - channels, "channel-order", G_TYPE_STRING, order->name, NULL); + 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, - channels, NULL); + info->channels, NULL); } g_free (params); - g_free (pos); - - rtpL16pay->rate = rate; - rtpL16pay->channels = channels; /* octet-per-sample is 2 * channels for L16 */ gst_rtp_base_audio_payload_set_sample_options (rtpbaseaudiopayload, - 2 * rtpL16pay->channels); + 2 * info->channels); return res; /* ERRORS */ -no_rate: +invalid_caps: { - GST_DEBUG_OBJECT (rtpL16pay, "no rate given"); - return FALSE; - } -no_channels: - { - GST_DEBUG_OBJECT (rtpL16pay, "no channels given"); + GST_DEBUG_OBJECT (rtpL16pay, "invalid caps"); return FALSE; } } @@ -232,6 +218,26 @@ gst_rtp_L16_pay_getcaps (GstRTPBasePayload * rtppayload, GstPad * pad, return caps; } +static GstFlowReturn +gst_rtp_L16_pay_handle_buffer (GstRTPBasePayload * basepayload, + GstBuffer * buffer) +{ + GstRtpL16Pay *rtpL16pay; + + rtpL16pay = GST_RTP_L16_PAY (basepayload); + buffer = gst_buffer_make_writable (buffer); + + if (rtpL16pay->order && + !gst_audio_buffer_reorder_channels (buffer, rtpL16pay->info.finfo->format, + rtpL16pay->info.channels, rtpL16pay->info.position, + rtpL16pay->order->pos)) { + return GST_FLOW_ERROR; + } + + return GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->handle_buffer (basepayload, + buffer); +} + gboolean gst_rtp_L16_pay_plugin_init (GstPlugin * plugin) { diff --git a/gst/rtp/gstrtpL16pay.h b/gst/rtp/gstrtpL16pay.h index b24138e0f9..515a512d93 100644 --- a/gst/rtp/gstrtpL16pay.h +++ b/gst/rtp/gstrtpL16pay.h @@ -23,6 +23,8 @@ #include #include +#include "gstrtpchannels.h" + G_BEGIN_DECLS #define GST_TYPE_RTP_L16_PAY \ @@ -43,8 +45,8 @@ struct _GstRtpL16Pay { GstRTPBaseAudioPayload payload; - gint rate; - gint channels; + GstAudioInfo info; + const GstRTPChannelOrder *order; }; struct _GstRtpL16PayClass diff --git a/gst/rtp/gstrtpchannels.c b/gst/rtp/gstrtpchannels.c index 2ce428035c..2c56ec22a5 100644 --- a/gst/rtp/gstrtpchannels.c +++ b/gst/rtp/gstrtpchannels.c @@ -33,14 +33,16 @@ static gboolean check_channels (const GstRTPChannelOrder * order, const GstAudioChannelPosition * pos) { - gint i; + gint i, j; gboolean res = TRUE; for (i = 0; i < order->channels; i++) { - if (order->pos[i] != pos[i]) { - res = FALSE; - break; + for (j = 0; j < order->channels; j++) { + if (order->pos[j] == pos[i]) + break; } + if (j == order->channels) + return FALSE; } return res; } @@ -150,18 +152,13 @@ gst_rtp_channels_get_by_index (gint channels, guint idx) * Returns: a #GstAudioChannelPosition with all the channel position info set to * #GST_AUDIO_CHANNEL_POSITION_NONE. */ -GstAudioChannelPosition * -gst_rtp_channels_create_default (gint channels) +void +gst_rtp_channels_create_default (gint channels, GstAudioChannelPosition * posn) { gint i; - GstAudioChannelPosition *posn; - g_return_val_if_fail (channels > 0, NULL); - - posn = g_new (GstAudioChannelPosition, channels); + g_return_if_fail (channels > 0); for (i = 0; i < channels; i++) posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE; - - return posn; } diff --git a/gst/rtp/gstrtpchannels.h b/gst/rtp/gstrtpchannels.h index b99a200eee..0a1b3a5de5 100644 --- a/gst/rtp/gstrtpchannels.h +++ b/gst/rtp/gstrtpchannels.h @@ -21,7 +21,9 @@ #include #include -#include + +#ifndef __GST_RTP_CHANNELS_H__ +#define __GST_RTP_CHANNELS_H__ typedef struct { @@ -41,14 +43,14 @@ static const GstAudioChannelPosition pos_4_2[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE + GST_AUDIO_CHANNEL_POSITION_LFE1 }; static const GstAudioChannelPosition pos_4_3[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE + GST_AUDIO_CHANNEL_POSITION_LFE1 }; static const GstAudioChannelPosition pos_5_1[] = { @@ -65,14 +67,14 @@ static const GstAudioChannelPosition pos_6_1[] = { GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE + GST_AUDIO_CHANNEL_POSITION_LFE1 }; static const GstAudioChannelPosition pos_6_2[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT }; @@ -81,7 +83,7 @@ static const GstAudioChannelPosition pos_8_1[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, @@ -92,7 +94,7 @@ static const GstAudioChannelPosition pos_8_2[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, @@ -103,7 +105,7 @@ static const GstAudioChannelPosition pos_8_3[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, - GST_AUDIO_CHANNEL_POSITION_LFE, + GST_AUDIO_CHANNEL_POSITION_LFE1, GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, @@ -111,7 +113,7 @@ static const GstAudioChannelPosition pos_8_3[] = { }; static const GstAudioChannelPosition pos_def_1[] = { - GST_AUDIO_CHANNEL_POSITION_FRONT_MONO + GST_AUDIO_CHANNEL_POSITION_MONO }; static const GstAudioChannelPosition pos_def_2[] = { @@ -129,7 +131,7 @@ static const GstAudioChannelPosition pos_def_4[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, - GST_AUDIO_CHANNEL_POSITION_LFE + GST_AUDIO_CHANNEL_POSITION_LFE1 }; static const GstAudioChannelPosition pos_def_5[] = { @@ -146,7 +148,7 @@ static const GstAudioChannelPosition pos_def_6[] = { GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, - GST_AUDIO_CHANNEL_POSITION_LFE + GST_AUDIO_CHANNEL_POSITION_LFE1 }; static const GstRTPChannelOrder channel_orders[] = @@ -183,4 +185,6 @@ const GstRTPChannelOrder * gst_rtp_channels_get_by_order (gint channels, const gchar *order); const GstRTPChannelOrder * gst_rtp_channels_get_by_index (gint channels, guint idx); -GstAudioChannelPosition * gst_rtp_channels_create_default (gint channels); +void gst_rtp_channels_create_default (gint channels, GstAudioChannelPosition *pos); + +#endif /* __GST_RTP_CHANNELS_H__ */ diff --git a/gst/rtp/gstrtpg722depay.c b/gst/rtp/gstrtpg722depay.c index b3c66e33f9..e197e4deb9 100644 --- a/gst/rtp/gstrtpg722depay.c +++ b/gst/rtp/gstrtpg722depay.c @@ -25,7 +25,6 @@ #include #include -#include #include "gstrtpg722depay.h" #include "gstrtpchannels.h" @@ -127,8 +126,10 @@ gst_rtp_g722_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) gint channels; GstCaps *srccaps; gboolean res; +#if 0 const gchar *channel_order; const GstRTPChannelOrder *order; +#endif rtpg722depay = GST_RTP_G722_DEPAY (depayload); @@ -179,6 +180,8 @@ gst_rtp_g722_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) srccaps = gst_caps_new_simple ("audio/G722", "rate", G_TYPE_INT, samplerate, "channels", G_TYPE_INT, channels, NULL); + /* FIXME: Do something with the channel order */ +#if 0 /* add channel positions */ channel_order = gst_structure_get_string (structure, "channel-order"); @@ -197,6 +200,7 @@ gst_rtp_g722_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), pos); g_free (pos); } +#endif res = gst_pad_set_caps (depayload->srcpad, srccaps); gst_caps_unref (srccaps); diff --git a/gst/rtp/gstrtpg722pay.c b/gst/rtp/gstrtpg722pay.c index a565f38d01..986b84c4a8 100644 --- a/gst/rtp/gstrtpg722pay.c +++ b/gst/rtp/gstrtpg722pay.c @@ -24,7 +24,6 @@ #include #include -#include #include #include "gstrtpg722pay.h" @@ -105,8 +104,10 @@ gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) 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); @@ -121,12 +122,15 @@ gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) 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 */ @@ -136,6 +140,7 @@ gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) 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)); @@ -146,13 +151,18 @@ gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) "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; diff --git a/gst/rtp/gstrtpvrawpay.c b/gst/rtp/gstrtpvrawpay.c index a463ef868b..214a30714f 100644 --- a/gst/rtp/gstrtpvrawpay.c +++ b/gst/rtp/gstrtpvrawpay.c @@ -271,7 +271,7 @@ gst_rtp_vraw_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer) width = GST_VIDEO_INFO_WIDTH (&rtpvrawpay->vinfo); height = GST_VIDEO_INFO_HEIGHT (&rtpvrawpay->vinfo); - interlaced = !!(rtpvrawpay->vinfo.flags & GST_VIDEO_FLAG_INTERLACED); + interlaced = ! !(rtpvrawpay->vinfo.flags & GST_VIDEO_FLAG_INTERLACED); /* start with line 0, offset 0 */ for (field = 0; field < 1 + interlaced; field++) {