2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
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.
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.
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.
20 #include "rtsp-media.h"
22 G_DEFINE_TYPE (GstRTSPMedia, gst_rtsp_media, G_TYPE_OBJECT);
24 static void gst_rtsp_media_finalize (GObject * obj);
27 gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
29 GObjectClass *gobject_class;
31 gobject_class = G_OBJECT_CLASS (klass);
33 gobject_class->finalize = gst_rtsp_media_finalize;
37 gst_rtsp_media_init (GstRTSPMedia * media)
39 media->streams = g_array_new (FALSE, TRUE, sizeof (GstRTSPMediaStream *));
43 gst_rtsp_media_stream_free (GstRTSPMediaStream *stream)
48 gst_rtsp_media_finalize (GObject * obj)
53 media = GST_RTSP_MEDIA (obj);
55 g_free (media->location);
56 gst_rtsp_url_free (media->url);
58 for (i = 0; i < media->streams->len; i++) {
59 GstRTSPMediaStream *stream;
61 stream = g_array_index (media->streams, GstRTSPMediaStream *, i);
63 gst_rtsp_media_stream_free (stream);
65 g_array_free (media->streams, TRUE);
67 G_OBJECT_CLASS (gst_rtsp_media_parent_class)->finalize (obj);
72 * @location: the URL of the media
74 * Create a new #GstRTSPMedia instance.
76 * Returns: a new #GstRTSPMedia object or %NULL when location did not contain a
77 * valid or understood URL.
80 gst_rtsp_media_new (const gchar *location)
87 if (gst_rtsp_url_parse (location, &url) != GST_RTSP_OK)
90 result = g_object_new (GST_TYPE_RTSP_MEDIA, NULL);
91 result->location = g_strdup (location);
104 caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPMediaStream * stream)
107 gst_caps_unref (stream->caps);
108 if ((stream->caps = GST_PAD_CAPS (pad)))
109 gst_caps_ref (stream->caps);
113 * gst_rtsp_media_prepare:
114 * @media: a #GstRTSPMedia
115 * @bin: the parent bin to create the elements in.
117 * Prepare the media object so that it creates its streams. Implementations
118 * should crate the needed gstreamer elements and add them to @bin. No state
119 * changes should be performed on them yet.
121 * One or more GstRTSPMediaStream objects should be added to @media with the
122 * srcpad member set to a source pad that produces buffer of type
125 * Returns: %TRUE if the media could be prepared.
128 gst_rtsp_media_prepare (GstRTSPMedia *media, GstBin *bin)
130 GstRTSPMediaStream *stream;
131 GstElement *pay, *element;
135 /* if we're already prepared we must exit */
136 g_return_val_if_fail (media->prepared == FALSE, FALSE);
138 g_print ("%s\n", media->url->abspath);
140 if (g_str_has_prefix (media->url->abspath, "/camera")) {
142 element = gst_parse_launch ("( "
143 "v4l2src ! video/x-raw-yuv,width=352,height=288,framerate=15/1 ! "
144 "queue ! videorate ! ffmpegcolorspace ! "
145 "x264enc bitrate=300 ! rtph264pay name=pay0 pt=96 "
146 "alsasrc ! audio/x-raw-int,rate=8000 ! queue ! "
147 "amrnbenc ! rtpamrpay name=pay1 pt=97 "
150 else if (g_str_has_prefix (media->url->abspath, "/h264")) {
152 element = gst_parse_launch ("( uridecodebin "
153 "uri=file:///home/cschalle/Videos/mi2.avi ! "
154 "x264enc bitrate=300 ! rtph264pay name=pay0 )", NULL);
156 else if (g_str_has_prefix (media->url->abspath, "/theora")) {
157 /* transcode theora */
158 element = gst_parse_launch ("( uridecodebin "
159 "uri=file:///home/wim/data/mi2.avi ! "
160 "theoraenc ! rtptheorapay name=pay0 )", NULL);
162 else if (g_str_has_prefix (media->url->abspath, "/macpclinux")) {
164 element = gst_parse_launch ("( filesrc "
165 "location=/home/cschalle/Videos/mac_pc_linux_2.ogg ! oggdemux name=d ! "
166 "queue ! theoraparse ! rtptheorapay name=pay0 "
167 "d. ! queue ! vorbisparse ! rtpvorbispay name=pay1 )", NULL);
169 else if (g_str_has_prefix (media->url->abspath, "/rtspproxy")) {
170 /* proxy RTSP transcode */
171 element = gst_parse_launch ("( uridecodebin "
172 "uri=rtsp://ia300135.us.archive.org:554/0/items/uncovered_interviews/uncovered_interviews_3_256kb.mp4 ! "
173 "x264enc bitrate=1800 ! rtph264pay name=pay0 )", NULL);
175 else if (g_str_has_prefix (media->url->abspath, "/httpproxy")) {
176 /* proxy HTTP transcode */
177 element = gst_parse_launch ("( uridecodebin "
178 "uri=http://movies.apple.com/movies/fox/maxpayne/maxpayne-tlre_h480.mov name=d "
179 "d. ! queue ! x264enc bitrate=1800 ! rtph264pay name=pay0 pt=96 "
180 "d. ! queue ! faac ! rtpmp4gpay name=pay1 pt=97 )", NULL);
185 gst_bin_add (bin, element);
190 name = g_strdup_printf ("pay%d", i);
192 if (!(pay = gst_bin_get_by_name (GST_BIN (element), name))) {
197 /* create the stream */
198 stream = g_new0 (GstRTSPMediaStream, 1);
199 stream->media = media;
200 stream->element = element;
201 stream->payloader = pay;
202 stream->idx = media->streams->len;
204 pad = gst_element_get_static_pad (pay, "src");
206 stream->srcpad = gst_ghost_pad_new (name, pad);
207 gst_element_add_pad (stream->element, stream->srcpad);
209 stream->caps_sig = g_signal_connect (pad, "notify::caps", (GCallback) caps_notify, stream);
210 gst_object_unref (pad);
213 g_array_append_val (media->streams, stream);
214 gst_object_unref (pay);
219 media->prepared = TRUE;
225 * gst_rtsp_media_n_streams:
226 * @media: a #GstRTSPMedia
228 * Get the number of streams in this media.
230 * Returns: The number of streams.
233 gst_rtsp_media_n_streams (GstRTSPMedia *media)
235 g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), 0);
236 g_return_val_if_fail (media->prepared, 0);
238 return media->streams->len;
242 * gst_rtsp_media_get_stream:
243 * @media: a #GstRTSPMedia
244 * @idx: the stream index
246 * Retrieve the stream with index @idx from @media.
248 * Returns: the #GstRTSPMediaStream at index @idx.
251 gst_rtsp_media_get_stream (GstRTSPMedia *media, guint idx)
253 GstRTSPMediaStream *res;
255 g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
256 g_return_val_if_fail (media->prepared, 0);
257 g_return_val_if_fail (idx < media->streams->len, NULL);
259 res = g_array_index (media->streams, GstRTSPMediaStream *, idx);