• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) <2005> 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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23 
24 #include <gst/rtp/gstrtpbuffer.h>
25 #include <gst/audio/audio.h>
26 
27 #include <string.h>
28 #include "gstrtpelements.h"
29 #include "gstrtpmpadepay.h"
30 #include "gstrtputils.h"
31 
32 GST_DEBUG_CATEGORY_STATIC (rtpmpadepay_debug);
33 #define GST_CAT_DEFAULT (rtpmpadepay_debug)
34 
35 static GstStaticPadTemplate gst_rtp_mpa_depay_src_template =
36 GST_STATIC_PAD_TEMPLATE ("src",
37     GST_PAD_SRC,
38     GST_PAD_ALWAYS,
39     GST_STATIC_CAPS ("audio/mpeg, " "mpegversion = (int) 1")
40     );
41 
42 static GstStaticPadTemplate gst_rtp_mpa_depay_sink_template =
43     GST_STATIC_PAD_TEMPLATE ("sink",
44     GST_PAD_SINK,
45     GST_PAD_ALWAYS,
46     GST_STATIC_CAPS ("application/x-rtp, "
47         "media = (string) \"audio\", "
48         "payload = (int) " GST_RTP_PAYLOAD_MPA_STRING ", "
49         "clock-rate = (int) 90000 ;"
50         "application/x-rtp, "
51         "media = (string) \"audio\", "
52         "encoding-name = (string) \"MPA\", clock-rate = (int) [1, MAX]")
53     );
54 
55 #define gst_rtp_mpa_depay_parent_class parent_class
56 G_DEFINE_TYPE (GstRtpMPADepay, gst_rtp_mpa_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);
57 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (rtpmpadepay, "rtpmpadepay",
58     GST_RANK_SECONDARY, GST_TYPE_RTP_MPA_DEPAY, rtp_element_init (plugin));
59 
60 static gboolean gst_rtp_mpa_depay_setcaps (GstRTPBaseDepayload * depayload,
61     GstCaps * caps);
62 static GstBuffer *gst_rtp_mpa_depay_process (GstRTPBaseDepayload * depayload,
63     GstRTPBuffer * rtp);
64 
65 static void
gst_rtp_mpa_depay_class_init(GstRtpMPADepayClass * klass)66 gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass)
67 {
68   GstElementClass *gstelement_class;
69   GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
70 
71   GST_DEBUG_CATEGORY_INIT (rtpmpadepay_debug, "rtpmpadepay", 0,
72       "MPEG Audio RTP Depayloader");
73 
74   gstelement_class = (GstElementClass *) klass;
75   gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
76 
77   gst_element_class_add_static_pad_template (gstelement_class,
78       &gst_rtp_mpa_depay_src_template);
79   gst_element_class_add_static_pad_template (gstelement_class,
80       &gst_rtp_mpa_depay_sink_template);
81 
82   gst_element_class_set_static_metadata (gstelement_class,
83       "RTP MPEG audio depayloader", "Codec/Depayloader/Network/RTP",
84       "Extracts MPEG audio from RTP packets (RFC 2038)",
85       "Wim Taymans <wim.taymans@gmail.com>");
86 
87   gstrtpbasedepayload_class->set_caps = gst_rtp_mpa_depay_setcaps;
88   gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_mpa_depay_process;
89 }
90 
91 static void
gst_rtp_mpa_depay_init(GstRtpMPADepay * rtpmpadepay)92 gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay)
93 {
94 }
95 
96 static gboolean
gst_rtp_mpa_depay_setcaps(GstRTPBaseDepayload * depayload,GstCaps * caps)97 gst_rtp_mpa_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
98 {
99   GstStructure *structure;
100   GstCaps *outcaps;
101   gint clock_rate;
102   gboolean res;
103 
104   structure = gst_caps_get_structure (caps, 0);
105 
106   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
107     clock_rate = 90000;
108   depayload->clock_rate = clock_rate;
109 
110   outcaps =
111       gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1, NULL);
112   res = gst_pad_set_caps (depayload->srcpad, outcaps);
113   gst_caps_unref (outcaps);
114 
115   return res;
116 }
117 
118 static GstBuffer *
gst_rtp_mpa_depay_process(GstRTPBaseDepayload * depayload,GstRTPBuffer * rtp)119 gst_rtp_mpa_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
120 {
121   GstRtpMPADepay *rtpmpadepay;
122   GstBuffer *outbuf;
123   gint payload_len;
124 #if 0
125   guint8 *payload;
126   guint16 frag_offset;
127 #endif
128   gboolean marker;
129 
130   rtpmpadepay = GST_RTP_MPA_DEPAY (depayload);
131 
132   payload_len = gst_rtp_buffer_get_payload_len (rtp);
133 
134   if (payload_len <= 4)
135     goto empty_packet;
136 
137 #if 0
138   payload = gst_rtp_buffer_get_payload (&rtp);
139   /* strip off header
140    *
141    *  0                   1                   2                   3
142    *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
143    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144    * |             MBZ               |          Frag_offset          |
145    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146    */
147   frag_offset = (payload[2] << 8) | payload[3];
148 #endif
149 
150   /* subbuffer skipping the 4 header bytes */
151   outbuf = gst_rtp_buffer_get_payload_subbuffer (rtp, 4, -1);
152   marker = gst_rtp_buffer_get_marker (rtp);
153 
154   if (marker) {
155     /* mark start of talkspurt with RESYNC */
156     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_RESYNC);
157   }
158   GST_DEBUG_OBJECT (rtpmpadepay,
159       "gst_rtp_mpa_depay_chain: pushing buffer of size %" G_GSIZE_FORMAT "",
160       gst_buffer_get_size (outbuf));
161 
162   if (outbuf) {
163     gst_rtp_drop_non_audio_meta (rtpmpadepay, outbuf);
164   }
165 
166   /* FIXME, we can push half mpeg frames when they are split over multiple
167    * RTP packets */
168   return outbuf;
169 
170   /* ERRORS */
171 empty_packet:
172   {
173     GST_ELEMENT_WARNING (rtpmpadepay, STREAM, DECODE,
174         ("Empty Payload."), (NULL));
175     return NULL;
176   }
177 }
178