Merge remote-tracking branch 'origin/master' into 0.11
[platform/upstream/gst-plugins-good.git] / gst / rtp / gstrtpchannels.c
1 /* GStreamer
2  * Copyright (C) <2008> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "gstrtpchannels.h"
24
25 /* 
26  * RTP channel positions as discussed in RFC 3551 and also RFC 3555
27  *
28  * We can't really represent the described channel positions in GStreamer but we
29  * implement a (very rough) approximation here.
30  */
31
32 static gboolean
33 check_channels (const GstRTPChannelOrder * order,
34     const GstAudioChannelPosition * pos)
35 {
36   gint i;
37   gboolean res = TRUE;
38
39   for (i = 0; i < order->channels; i++) {
40     if (order->pos[i] != pos[i]) {
41       res = FALSE;
42       break;
43     }
44   }
45   return res;
46 }
47
48 /**
49  * gst_rtp_channels_get_by_pos:
50  * @channels: the amount of channels
51  * @pos: a channel layout
52  *
53  * Return a description of the channel layout.
54  *
55  * Returns: a #GstRTPChannelOrder with the channel information or NULL when @pos
56  * is not a valid layout.
57  */
58 const GstRTPChannelOrder *
59 gst_rtp_channels_get_by_pos (gint channels, const GstAudioChannelPosition * pos)
60 {
61   gint i;
62   const GstRTPChannelOrder *res = NULL;
63
64   g_return_val_if_fail (pos != NULL, NULL);
65
66   for (i = 0; channel_orders[i].pos; i++) {
67     if (channel_orders[i].channels != channels)
68       continue;
69
70     if (check_channels (&channel_orders[i], pos)) {
71       res = &channel_orders[i];
72       break;
73     }
74   }
75   return res;
76 }
77
78 /**
79  * gst_rtp_channels_create_default:
80  * @channels: the amount of channels
81  * @order: a channel order
82  *
83  * Get the channel order info the @order and @channels.
84  *
85  * Returns: a #GstRTPChannelOrder with the channel information or NULL when
86  * @order is not a know layout for @channels.
87  */
88 const GstRTPChannelOrder *
89 gst_rtp_channels_get_by_order (gint channels, const gchar * order)
90 {
91   gint i;
92   const GstRTPChannelOrder *res = NULL;
93
94   for (i = 0; channel_orders[i].pos; i++) {
95     if (channel_orders[i].channels != channels)
96       continue;
97
98     /* no name but channels match, continue */
99     if (!channel_orders[i].name || !order) {
100       res = &channel_orders[i];
101       break;
102     }
103
104     /* compare names */
105     if (g_ascii_strcasecmp (channel_orders[i].name, order)) {
106       res = &channel_orders[i];
107       break;
108     }
109   }
110   return res;
111 }
112
113 /**
114  * gst_rtp_channels_get_by_index:
115  * @channels: the amount of channels
116  * @idx: the channel index to retrieve
117  *
118  * Get the allowed channel order descriptions for @channels. @idx can be used to
119  * retrieve the desired index.
120  *
121  * Returns: a #GstRTPChannelOrder at @idx, NULL when there are no valid channel
122  * orders.
123  */
124 const GstRTPChannelOrder *
125 gst_rtp_channels_get_by_index (gint channels, guint idx)
126 {
127   gint i;
128   const GstRTPChannelOrder *res = NULL;
129
130   for (i = 0; channel_orders[i].pos; i++) {
131     if (channel_orders[i].channels != channels)
132       continue;
133
134     if (idx == 0) {
135       res = &channel_orders[i];
136       break;
137     }
138     idx--;
139   }
140   return res;
141 }
142
143
144 /**
145  * gst_rtp_channels_create_default:
146  * @channels: the amount of channels
147  *
148  * Create a default none channel mapping for @channels.
149  *
150  * Returns: a #GstAudioChannelPosition with all the channel position info set to
151  * #GST_AUDIO_CHANNEL_POSITION_NONE.
152  */
153 GstAudioChannelPosition *
154 gst_rtp_channels_create_default (gint channels)
155 {
156   gint i;
157   GstAudioChannelPosition *posn;
158
159   g_return_val_if_fail (channels > 0, NULL);
160
161   posn = g_new (GstAudioChannelPosition, channels);
162
163   for (i = 0; i < channels; i++)
164     posn[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
165
166   return posn;
167 }