]> git.sesse.net Git - vlc/blob - modules/stream_filter/dash/dash.cpp
dash: include <config.h> in all cpp files
[vlc] / modules / stream_filter / dash / dash.cpp
1 /*****************************************************************************
2  * dash.cpp: DASH module
3  *****************************************************************************
4  * Copyright © 2010 - 2011 Klagenfurt University
5  *
6  * Created on: Aug 10, 2010
7  * Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
8  *          Christian Timmerer  <christian.timmerer@itec.uni-klu.ac.at>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published
12  * by the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34
35 #include <errno.h>
36
37 #include "DASHManager.h"
38 #include "xml/DOMParser.h"
39 #include "http/HTTPConnectionManager.h"
40 #include "adaptationlogic/IAdaptationLogic.h"
41 #include "mpd/BasicCMParser.h"
42
43 #define SEEK 0
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 static int  Open    (vlc_object_t *);
49 static void Close   (vlc_object_t *);
50
51 vlc_module_begin ()
52         set_shortname( N_("DASH"))
53         set_description( N_("Dynamic Adaptive Streaming over HTTP") )
54         set_capability( "stream_filter", 19 )
55         set_category( CAT_INPUT )
56         set_subcategory( SUBCAT_INPUT_STREAM_FILTER )
57         set_callbacks( Open, Close )
58 vlc_module_end ()
59
60 /*****************************************************************************
61  * Local prototypes
62  *****************************************************************************/
63 struct stream_sys_t
64 {
65         dash::DASHManager                   *p_dashManager;
66         dash::http::HTTPConnectionManager   *p_conManager;
67         dash::mpd::MPD                      *p_mpd;
68         int                                 position;
69         bool                                isLive;
70 };
71
72 static int  Read            (stream_t *p_stream, void *p_buffer, unsigned int i_len);
73 static int  Peek            (stream_t *p_stream, const uint8_t **pp_peek, unsigned int i_peek);
74 static int  Control         (stream_t *p_stream, int i_query, va_list args);
75
76 /*****************************************************************************
77  * Open:
78  *****************************************************************************/
79 static int Open(vlc_object_t *p_obj)
80 {
81     stream_t *p_stream = (stream_t*) p_obj;
82
83     if(!dash::xml::DOMParser::isDash(p_stream->p_source))
84         return VLC_EGENERIC;
85
86     //Build a XML tree
87     dash::xml::DOMParser        parser(p_stream->p_source);
88     if( !parser.parse() )
89     {
90         msg_Dbg( p_stream, "Could not parse mpd file." );
91         return VLC_EGENERIC;
92     }
93     //Begin the actual MPD parsing:
94     dash::mpd::BasicCMParser    mpdParser( parser.getRootNode(), p_stream->p_source );
95     if ( mpdParser.parse() == false || mpdParser.getMPD() == NULL )
96     {
97         msg_Err( p_obj, "MPD file parsing failed." );
98         return VLC_EGENERIC;
99     }
100
101     stream_sys_t        *p_sys = (stream_sys_t *) malloc(sizeof(stream_sys_t));
102     if (unlikely(p_sys == NULL))
103         return VLC_ENOMEM;
104
105     p_sys->p_mpd = mpdParser.getMPD();
106     dash::http::HTTPConnectionManager *p_conManager =
107                               new dash::http::HTTPConnectionManager( p_stream );
108     dash::DASHManager*p_dashManager =
109             new dash::DASHManager( p_conManager, p_sys->p_mpd,
110                                    dash::logic::IAdaptationLogic::RateBased );
111
112     if ( p_dashManager->getMpdManager() == NULL ||
113          p_dashManager->getMpdManager()->getMPD() == NULL ||
114          p_dashManager->getAdaptionLogic() == NULL )
115     {
116         delete p_conManager;
117         delete p_dashManager;
118         free( p_sys );
119         return VLC_EGENERIC;
120     }
121     p_sys->p_dashManager    = p_dashManager;
122     p_sys->p_conManager     = p_conManager;
123     p_sys->position         = 0;
124     p_sys->isLive           = p_dashManager->getMpdManager()->getMPD()->isLive();
125     p_stream->p_sys         = p_sys;
126     p_stream->pf_read       = Read;
127     p_stream->pf_peek       = Peek;
128     p_stream->pf_control    = Control;
129
130     msg_Dbg(p_obj,"opening mpd file (%s)", p_stream->psz_path);
131
132     return VLC_SUCCESS;
133 }
134 /*****************************************************************************
135  * Close:
136  *****************************************************************************/
137 static void Close(vlc_object_t *p_obj)
138 {
139     stream_t                            *p_stream       = (stream_t*) p_obj;
140     stream_sys_t                        *p_sys          = (stream_sys_t *) p_stream->p_sys;
141     dash::DASHManager                   *p_dashManager  = p_sys->p_dashManager;
142     dash::http::HTTPConnectionManager   *p_conManager   = p_sys->p_conManager;
143
144     delete(p_conManager);
145     delete(p_dashManager);
146     free(p_sys);
147 }
148 /*****************************************************************************
149  * Callbacks:
150  *****************************************************************************/
151 static int  Read            (stream_t *p_stream, void *p_buffer, unsigned int i_len)
152 {
153     stream_sys_t        *p_sys          = (stream_sys_t *) p_stream->p_sys;
154     dash::DASHManager   *p_dashManager  = p_sys->p_dashManager;
155     int                 i_ret           = 0;
156
157     i_ret = p_dashManager->read(p_buffer, i_len );
158
159     if (i_ret < 0)
160     {
161         switch (errno)
162         {
163             case EINTR:
164             case EAGAIN:
165                 break;
166             default:
167                 msg_Dbg(p_stream, "DASH Read: failed to read (%m)");
168                 return 0;
169         }
170         return 0;
171     }
172
173     p_sys->position += i_ret;
174
175     return i_ret;
176 }
177
178 static int  Peek            (stream_t *p_stream, const uint8_t **pp_peek, unsigned int i_peek)
179 {
180     stream_sys_t        *p_sys          = (stream_sys_t *) p_stream->p_sys;
181     dash::DASHManager   *p_dashManager  = p_sys->p_dashManager;
182
183     return p_dashManager->peek( pp_peek, i_peek );
184 }
185
186 static int  Control         (stream_t *p_stream, int i_query, va_list args)
187 {
188     stream_sys_t *p_sys = p_stream->p_sys;
189
190     switch (i_query)
191     {
192         case STREAM_CAN_SEEK:
193         case STREAM_CAN_FASTSEEK:
194             /*TODO Support Seek */
195             *(va_arg (args, bool *)) = SEEK;
196             break;
197         case STREAM_GET_POSITION:
198             *(va_arg (args, uint64_t *)) = p_sys->position;
199             break;
200         case STREAM_SET_POSITION:
201             return VLC_EGENERIC;
202         case STREAM_GET_SIZE:
203             if(p_sys->isLive)
204                 *(va_arg (args, uint64_t *)) = 0;
205             break;
206         default:
207             return VLC_EGENERIC;
208     }
209     return VLC_SUCCESS;
210 }