demux: provide full URL instead of access name (refs #18504)
[vlc.git] / modules / demux / dash / DASHManager.cpp
blob7670e61e572669c8c7667712d5a3c03b8fc108b7
1 /*****************************************************************************
2 * DASHManager.cpp
3 *****************************************************************************
4 * Copyright © 2010 - 2011 Klagenfurt University
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>
10 * This program is free software; you can redistribute it and/or modify it
11 * 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.
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.
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 Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <vlc_fixups.h>
30 #include <cinttypes>
32 #include "DASHManager.h"
33 #include "mpd/ProgramInformation.h"
34 #include "mpd/IsoffMainParser.h"
35 #include "xml/DOMParser.h"
36 #include "xml/Node.h"
37 #include "../adaptive/tools/Helper.h"
38 #include "../adaptive/http/HTTPConnectionManager.h"
39 #include <vlc_stream.h>
40 #include <vlc_demux.h>
41 #include <vlc_meta.h>
42 #include <vlc_block.h>
43 #include "../adaptive/tools/Retrieve.hpp"
45 #include <algorithm>
46 #include <ctime>
48 using namespace dash;
49 using namespace dash::mpd;
50 using namespace adaptive::logic;
52 DASHManager::DASHManager(demux_t *demux_,
53 AuthStorage *auth,
54 MPD *mpd,
55 AbstractStreamFactory *factory,
56 AbstractAdaptationLogic::LogicType type) :
57 PlaylistManager(demux_, auth, mpd, factory, type)
61 DASHManager::~DASHManager ()
65 void DASHManager::scheduleNextUpdate()
67 time_t now = time(NULL);
69 mtime_t minbuffer = 0;
70 std::vector<AbstractStream *>::const_iterator it;
71 for(it=streams.begin(); it!=streams.end(); ++it)
73 const AbstractStream *st = *it;
74 const mtime_t m = st->getMinAheadTime();
75 if(m > 0 && (m < minbuffer || minbuffer == 0))
76 minbuffer = m;
78 minbuffer /= 2;
80 if(playlist->minUpdatePeriod.Get() > minbuffer)
81 minbuffer = playlist->minUpdatePeriod.Get();
83 if(minbuffer < 5 * CLOCK_FREQ)
84 minbuffer = 5 * CLOCK_FREQ;
86 nextPlaylistupdate = now + minbuffer / CLOCK_FREQ;
88 msg_Dbg(p_demux, "Updated MPD, next update in %" PRId64 "s", (mtime_t) nextPlaylistupdate - now );
91 bool DASHManager::needsUpdate() const
93 if(nextPlaylistupdate && time(NULL) < nextPlaylistupdate)
94 return false;
96 return PlaylistManager::needsUpdate();
99 bool DASHManager::updatePlaylist()
101 /* do update */
102 if(nextPlaylistupdate)
104 std::string url(p_demux->psz_url);
106 block_t *p_block = Retrieve::HTTP(VLC_OBJECT(p_demux), authStorage, url);
107 if(!p_block)
108 return false;
110 stream_t *mpdstream = vlc_stream_MemoryNew(p_demux, p_block->p_buffer, p_block->i_buffer, true);
111 if(!mpdstream)
113 block_Release(p_block);
114 return false;
117 xml::DOMParser parser(mpdstream);
118 if(!parser.parse(true))
120 vlc_stream_Delete(mpdstream);
121 block_Release(p_block);
122 return false;
125 mtime_t minsegmentTime = 0;
126 std::vector<AbstractStream *>::iterator it;
127 for(it=streams.begin(); it!=streams.end(); it++)
129 mtime_t segmentTime = (*it)->getPlaybackTime();
130 if(!minsegmentTime || segmentTime < minsegmentTime)
131 minsegmentTime = segmentTime;
134 IsoffMainParser mpdparser(parser.getRootNode(), VLC_OBJECT(p_demux),
135 mpdstream, Helper::getDirectoryPath(url).append("/"));
136 MPD *newmpd = mpdparser.parse();
137 if(newmpd)
139 playlist->mergeWith(newmpd, minsegmentTime);
140 delete newmpd;
142 vlc_stream_Delete(mpdstream);
143 block_Release(p_block);
146 return true;
149 int DASHManager::doControl(int i_query, va_list args)
151 switch (i_query)
153 case DEMUX_GET_META:
155 MPD *mpd = dynamic_cast<MPD *>(playlist);
156 if(!mpd)
157 return VLC_EGENERIC;
159 if(!mpd->programInfo.Get())
160 break;
162 vlc_meta_t *p_meta = va_arg (args, vlc_meta_t *);
163 vlc_meta_t *meta = vlc_meta_New();
164 if (meta == NULL)
165 return VLC_EGENERIC;
167 if(!mpd->programInfo.Get()->getTitle().empty())
168 vlc_meta_SetTitle(meta, mpd->programInfo.Get()->getTitle().c_str());
170 if(!mpd->programInfo.Get()->getSource().empty())
171 vlc_meta_SetPublisher(meta, mpd->programInfo.Get()->getSource().c_str());
173 if(!mpd->programInfo.Get()->getCopyright().empty())
174 vlc_meta_SetCopyright(meta, mpd->programInfo.Get()->getCopyright().c_str());
176 if(!mpd->programInfo.Get()->getMoreInformationUrl().empty())
177 vlc_meta_SetURL(meta, mpd->programInfo.Get()->getMoreInformationUrl().c_str());
179 vlc_meta_Merge(p_meta, meta);
180 vlc_meta_Delete(meta);
181 break;
184 return PlaylistManager::doControl(i_query, args);
187 bool DASHManager::isDASH(xml::Node *root)
189 const std::string namespaces[] = {
190 "urn:mpeg:mpegB:schema:DASH:MPD:DIS2011",
191 "urn:mpeg:schema:dash:mpd:2011",
192 "urn:mpeg:DASH:schema:MPD:2011",
193 "urn:mpeg:mpegB:schema:DASH:MPD:DIS2011",
194 "urn:mpeg:schema:dash:mpd:2011",
195 "urn:mpeg:DASH:schema:MPD:2011",
198 if(root->getName() != "MPD")
199 return false;
201 std::string ns = root->getAttributeValue("xmlns");
202 for( size_t i=0; i<ARRAY_SIZE(namespaces); i++ )
204 if ( adaptive::Helper::ifind(ns, namespaces[i]) )
205 return true;
207 return false;
210 bool DASHManager::mimeMatched(const std::string &mime)
212 return (mime == "application/dash+xml");