]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - plugins/elements/gsthttpsrc.c
.cvsignore for gst/elements/, also testig loginfo script
[glsdk/gstreamer0-10.git] / plugins / elements / gsthttpsrc.c
1 /* Gnome-Streamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
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  */
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
24 #include <gsthttpsrc.h>
27 GstElementDetails gst_httpsrc_details = {
28   "HTTP Source",
29   "Source/Network",
30   "Read data from an HTTP stream",
31   VERSION,
32   "Erik Walthinsen <omega@cse.ogi.edu>",
33   "(C) 1999",
34 };
37 static void gst_httpsrc_push(GstSrc *src);
38 static gboolean gst_httpsrc_open_url(GstHttpSrc *src);
39 static void gst_httpsrc_close_url(GstHttpSrc *src);
40 static gboolean gst_httpsrc_change_state(GstElement *element,
41                                          GstElementState state);
44 /* HttpSrc signals and args */
45 enum {
46   /* FILL ME */
47   LAST_SIGNAL
48 };
50 enum {
51   ARG_0,
52   ARG_LOCATION,
53   ARG_BYTESPERREAD,
54   ARG_OFFSET
55 };
58 static void gst_httpsrc_class_init(GstHttpSrcClass *klass);
59 static void gst_httpsrc_init(GstHttpSrc *httpsrc);
60 static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id);
61 static void gst_httpsrc_get_arg(GtkObject *object,GtkArg *arg,guint id);
64 static GstSrcClass *parent_class = NULL;
65 static guint gst_httpsrc_signals[LAST_SIGNAL] = { 0 };
67 GtkType
68 gst_httpsrc_get_type(void) {
69   static GtkType httpsrc_type = 0;
71   if (!httpsrc_type) {
72     static const GtkTypeInfo httpsrc_info = {
73       "GstHttpSrc",
74       sizeof(GstHttpSrc),
75       sizeof(GstHttpSrcClass),
76       (GtkClassInitFunc)gst_httpsrc_class_init,
77       (GtkObjectInitFunc)gst_httpsrc_init,
78       (GtkArgSetFunc)gst_httpsrc_set_arg,
79       (GtkArgGetFunc)gst_httpsrc_get_arg,
80       (GtkClassInitFunc)NULL,
81     };
82     httpsrc_type = gtk_type_unique(GST_TYPE_SRC,&httpsrc_info);
83   }
84   return httpsrc_type;
85 }
87 static void
88 gst_httpsrc_class_init(GstHttpSrcClass *klass) {
89   GtkObjectClass *gtkobject_class;
90   GstElementClass *gstelement_class;
91   GstSrcClass *gstsrc_class;
93   gtkobject_class = (GtkObjectClass*)klass;
94   gstelement_class = (GstElementClass*)klass;
95   gstsrc_class = (GstSrcClass*)klass;
97   parent_class = gtk_type_class(GST_TYPE_SRC);
100   gtk_object_add_arg_type("GstHttpSrc::location", GTK_TYPE_STRING,
101                           GTK_ARG_READWRITE, ARG_LOCATION);
102   gtk_object_add_arg_type("GstHttpSrc::bytesperread", GTK_TYPE_INT,
103                           GTK_ARG_READWRITE, ARG_BYTESPERREAD);
105   gtkobject_class->set_arg = gst_httpsrc_set_arg;
106   gtkobject_class->get_arg = gst_httpsrc_get_arg;
108   gstelement_class->change_state = gst_httpsrc_change_state;
110   gstsrc_class->push = gst_httpsrc_push;
111   gstsrc_class->push_region = NULL;
114 static void gst_httpsrc_init(GstHttpSrc *httpsrc) {
115   httpsrc->srcpad = gst_pad_new("src",GST_PAD_SRC);
116   gst_element_add_pad(GST_ELEMENT(httpsrc),httpsrc->srcpad);
118   httpsrc->url = NULL;
119   httpsrc->request = NULL;
120   httpsrc->fd = 0;
121   httpsrc->curoffset = 0;
122   httpsrc->bytes_per_read = 4096;
125 static void gst_httpsrc_push(GstSrc *src) {
126   GstHttpSrc *httpsrc;
127   GstBuffer *buf;
128   glong readbytes;
130   g_return_if_fail(src != NULL);
131   g_return_if_fail(GST_IS_HTTPSRC(src));
132 //  g_return_if_fail(GST_FLAG_IS_SET(src,GST_));
133   httpsrc = GST_HTTPSRC(src);
135   buf = gst_buffer_new();
136   GST_BUFFER_DATA(buf) = (gpointer)malloc(httpsrc->bytes_per_read);
137   readbytes = read(httpsrc->fd,GST_BUFFER_DATA(buf),httpsrc->bytes_per_read);
138   if (readbytes == 0) {
139     gst_src_signal_eos(GST_SRC(httpsrc));
140     return;
141   }
143   if (readbytes < httpsrc->bytes_per_read) {
144     // FIXME: set the buffer's EOF bit here
145   }
146   GST_BUFFER_OFFSET(buf) = httpsrc->curoffset;
147   GST_BUFFER_SIZE(buf) = readbytes;
148   httpsrc->curoffset += readbytes;
150   gst_pad_push(httpsrc->srcpad,buf);
153 static gboolean gst_httpsrc_open_url(GstHttpSrc *httpsrc) {
154   gint status;
156   g_return_if_fail(httpsrc != NULL);
157   g_return_if_fail(GST_IS_HTTPSRC(httpsrc));
158   g_return_if_fail(httpsrc->url != NULL);
160   httpsrc->request = ghttp_request_new();
161   ghttp_set_uri(httpsrc->request,httpsrc->url);
162   ghttp_set_sync(httpsrc->request,ghttp_async);
163   ghttp_set_header(httpsrc->request,"User-Agent","GstHttpSrc");
164   ghttp_prepare(httpsrc->request);
166   /* process everything up to the actual data stream */
167   /* FIXME: should be in preroll, but hey */
168   status = 0;
169   while ((ghttp_get_status(httpsrc->request).proc != ghttp_proc_response)
170          && (status >= 0)) {
171     status = ghttp_process(httpsrc->request);
172   }
174   /* get the fd so we can read data ourselves */
175   httpsrc->fd = ghttp_get_socket(httpsrc->request);
176   return TRUE;
179 /* unmap and close the file */
180 static void gst_httpsrc_close_url(GstHttpSrc *src) {  
181   g_return_if_fail(src->fd > 0);
182  
183   close(src->fd);
184   src->fd = 0;
187 static void gst_httpsrc_set_arg(GtkObject *object,GtkArg *arg,guint id) {
188   GstHttpSrc *src;
190   /* it's not null if we got it, but it might not be ours */
191   g_return_if_fail(GST_IS_HTTPSRC(object));
192   src = GST_HTTPSRC(object);
194   switch(id) {
195     case ARG_LOCATION:
196       /* the element must be stopped in order to do this */
197       g_return_if_fail(!GST_FLAG_IS_SET(src,GST_STATE_RUNNING));
199       if (src->url) g_free(src->url);
200       /* clear the url if we get a NULL (is that possible?) */
201       if (GTK_VALUE_STRING(*arg) == NULL) {
202         src->url = NULL;
203         gst_element_set_state(GST_ELEMENT(object),~GST_STATE_COMPLETE);
204       /* otherwise set the new url */
205       } else {
206         src->url = g_strdup(GTK_VALUE_STRING(*arg));
207         gst_element_set_state(GST_ELEMENT(object),GST_STATE_COMPLETE);
208       }
209       break;
210     case ARG_BYTESPERREAD:
211       src->bytes_per_read = GTK_VALUE_INT(*arg);
212       break;
213     default:
214       break;
215   }
218 static void gst_httpsrc_get_arg(GtkObject *object,GtkArg *arg,guint id) {
219   GstHttpSrc *httpsrc;
221   /* it's not null if we got it, but it might not be ours */
222   g_return_if_fail(GST_IS_HTTPSRC(object));
223   httpsrc = GST_HTTPSRC(object);
224                           
225   switch (id) {
226     case ARG_LOCATION:
227       GTK_VALUE_STRING(*arg) = httpsrc->url;
228       break;
229     case ARG_BYTESPERREAD:
230       GTK_VALUE_INT(*arg) = httpsrc->bytes_per_read;
231       break;
232     default:
233       arg->type = GTK_TYPE_INVALID;
234       break;
235   }
238 static gboolean gst_httpsrc_change_state(GstElement *element,
239                                          GstElementState state) {
240   g_return_if_fail(GST_IS_HTTPSRC(element));
242   switch (state) {
243     case GST_STATE_RUNNING:
244       if (!gst_httpsrc_open_url(GST_HTTPSRC(element)))
245         return FALSE;
246       break;  
247     case ~GST_STATE_RUNNING:
248       gst_httpsrc_close_url(GST_HTTPSRC(element));
249       break;
250     default:   
251       break;
252   }
253  
254   if (GST_ELEMENT_CLASS(parent_class)->change_state)
255     return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
256   return TRUE;