1 /*****************************************************************************
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 *****************************************************************************/
29 #include <vlc_fixups.h>
32 #include "DASHManager.h"
33 #include "mpd/ProgramInformation.h"
34 #include "mpd/IsoffMainParser.h"
35 #include "xml/DOMParser.h"
37 #include "../adaptive/tools/Helper.h"
38 #include "../adaptive/http/HTTPConnectionManager.h"
39 #include <vlc_stream.h>
40 #include <vlc_demux.h>
42 #include <vlc_block.h>
43 #include "../adaptive/tools/Retrieve.hpp"
49 using namespace dash::mpd
;
50 using namespace adaptive::logic
;
52 DASHManager::DASHManager(demux_t
*demux_
,
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))
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
)
96 return PlaylistManager::needsUpdate();
99 bool DASHManager::updatePlaylist()
102 if(nextPlaylistupdate
)
104 std::string
url(p_demux
->psz_url
);
106 block_t
*p_block
= Retrieve::HTTP(VLC_OBJECT(p_demux
), authStorage
, url
);
110 stream_t
*mpdstream
= vlc_stream_MemoryNew(p_demux
, p_block
->p_buffer
, p_block
->i_buffer
, true);
113 block_Release(p_block
);
117 xml::DOMParser
parser(mpdstream
);
118 if(!parser
.parse(true))
120 vlc_stream_Delete(mpdstream
);
121 block_Release(p_block
);
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();
139 playlist
->mergeWith(newmpd
, minsegmentTime
);
142 vlc_stream_Delete(mpdstream
);
143 block_Release(p_block
);
149 int DASHManager::doControl(int i_query
, va_list args
)
155 MPD
*mpd
= dynamic_cast<MPD
*>(playlist
);
159 if(!mpd
->programInfo
.Get())
162 vlc_meta_t
*p_meta
= va_arg (args
, vlc_meta_t
*);
163 vlc_meta_t
*meta
= vlc_meta_New();
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
);
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")
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
]) )
210 bool DASHManager::mimeMatched(const std::string
&mime
)
212 return (mime
== "application/dash+xml");