Commit db1c4aa7 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen Committed by Jean-Baptiste Kempf

dash: Adding an implementation for UrlTemplate

Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent d3086fea
...@@ -55,9 +55,9 @@ DASHManager::~DASHManager () ...@@ -55,9 +55,9 @@ DASHManager::~DASHManager ()
delete this->mpdManager; delete this->mpdManager;
} }
int DASHManager::read (void *p_buffer, size_t len) int DASHManager::read( void *p_buffer, size_t len )
{ {
if(this->currentChunk == NULL) if ( this->currentChunk == NULL )
{ {
try try
{ {
...@@ -70,19 +70,19 @@ int DASHManager::read (void *p_buffer, size_t len) ...@@ -70,19 +70,19 @@ int DASHManager::read (void *p_buffer, size_t len)
} }
} }
int ret = this->conManager->read(this->currentChunk, p_buffer, len); int ret = this->conManager->read( this->currentChunk, p_buffer, len );
if ( ret == 0 )
if(ret <= 0)
{ {
this->currentChunk = NULL; this->currentChunk = NULL;
return this->read(p_buffer, len); return this->read(p_buffer, len );
} }
return ret; return ret;
} }
int DASHManager::peek (const uint8_t **pp_peek, size_t i_peek)
int DASHManager::peek( const uint8_t **pp_peek, size_t i_peek )
{ {
if(this->currentChunk == NULL) if ( this->currentChunk == NULL )
{ {
try try
{ {
...@@ -94,7 +94,7 @@ int DASHManager::peek (const uint8_t **pp_peek, size_t i_peek) ...@@ -94,7 +94,7 @@ int DASHManager::peek (const uint8_t **pp_peek, size_t i_peek)
} }
} }
int ret = this->conManager->peek(this->currentChunk, pp_peek, i_peek); int ret = this->conManager->peek( this->currentChunk, pp_peek, i_peek );
return ret; return ret;
} }
......
...@@ -43,8 +43,8 @@ namespace dash ...@@ -43,8 +43,8 @@ namespace dash
logic::IAdaptationLogic::LogicType type ); logic::IAdaptationLogic::LogicType type );
virtual ~DASHManager (); virtual ~DASHManager ();
int read (void *p_buffer, size_t len); int read( void *p_buffer, size_t len );
int peek (const uint8_t **pp_peek, size_t i_peek); int peek( const uint8_t **pp_peek, size_t i_peek );
const mpd::IMPDManager* getMpdManager() const; const mpd::IMPDManager* getMpdManager() const;
private: private:
......
...@@ -49,6 +49,8 @@ SOURCES_stream_filter_dash = \ ...@@ -49,6 +49,8 @@ SOURCES_stream_filter_dash = \
mpd/SegmentInfoCommon.h \ mpd/SegmentInfoCommon.h \
mpd/SegmentInfoDefault.cpp \ mpd/SegmentInfoDefault.cpp \
mpd/SegmentInfoDefault.h \ mpd/SegmentInfoDefault.h \
mpd/SegmentTemplate.cpp \
mpd/SegmentTemplate.h \
mpd/SegmentTimeline.cpp \ mpd/SegmentTimeline.cpp \
mpd/SegmentTimeline.h \ mpd/SegmentTimeline.h \
mpd/TrickModeType.cpp \ mpd/TrickModeType.cpp \
......
...@@ -45,7 +45,6 @@ namespace dash ...@@ -45,7 +45,6 @@ namespace dash
AbstractAdaptationLogic (dash::mpd::IMPDManager *mpdManager); AbstractAdaptationLogic (dash::mpd::IMPDManager *mpdManager);
virtual ~AbstractAdaptationLogic (); virtual ~AbstractAdaptationLogic ();
virtual dash::http::Chunk* getNextChunk () throw(dash::exception::EOFException) = 0;
virtual void downloadRateChanged (long bpsAvg, long bpsLastChunk); virtual void downloadRateChanged (long bpsAvg, long bpsLastChunk);
long getBpsAvg (); long getBpsAvg ();
......
...@@ -31,7 +31,8 @@ using namespace dash::logic; ...@@ -31,7 +31,8 @@ using namespace dash::logic;
using namespace dash::xml; using namespace dash::xml;
using namespace dash::mpd; using namespace dash::mpd;
IAdaptationLogic* AdaptationLogicFactory::create (IAdaptationLogic::LogicType logic, IMPDManager *mpdManager) IAdaptationLogic* AdaptationLogicFactory::create ( IAdaptationLogic::LogicType logic,
IMPDManager *mpdManager )
{ {
switch(logic) switch(logic)
{ {
......
...@@ -43,7 +43,7 @@ AlwaysBestAdaptationLogic::~AlwaysBestAdaptationLogic () ...@@ -43,7 +43,7 @@ AlwaysBestAdaptationLogic::~AlwaysBestAdaptationLogic ()
{ {
} }
Chunk* AlwaysBestAdaptationLogic::getNextChunk () throw(EOFException) Chunk* AlwaysBestAdaptationLogic::getNextChunk() throw(EOFException)
{ {
if(this->schedule.size() == 0) if(this->schedule.size() == 0)
throw EOFException(); throw EOFException();
...@@ -75,7 +75,7 @@ void AlwaysBestAdaptationLogic::initSchedule () ...@@ -75,7 +75,7 @@ void AlwaysBestAdaptationLogic::initSchedule ()
if(best != NULL) if(best != NULL)
{ {
std::vector<const Segment *> segments = this->mpdManager->getSegments(best); std::vector<Segment *> segments = this->mpdManager->getSegments(best);
for(size_t j = 0; j < segments.size(); j++) for(size_t j = 0; j < segments.size(); j++)
{ {
this->schedule.push_back(segments.at(j)); this->schedule.push_back(segments.at(j));
......
...@@ -45,10 +45,10 @@ namespace dash ...@@ -45,10 +45,10 @@ namespace dash
AlwaysBestAdaptationLogic (dash::mpd::IMPDManager *mpdManager); AlwaysBestAdaptationLogic (dash::mpd::IMPDManager *mpdManager);
virtual ~AlwaysBestAdaptationLogic (); virtual ~AlwaysBestAdaptationLogic ();
dash::http::Chunk* getNextChunk () throw(dash::exception::EOFException); dash::http::Chunk* getNextChunk() throw(dash::exception::EOFException);
private: private:
std::vector<const mpd::Segment *> schedule; std::vector<mpd::Segment *> schedule;
dash::mpd::IMPDManager *mpdManager; dash::mpd::IMPDManager *mpdManager;
size_t count; size_t count;
......
...@@ -42,10 +42,10 @@ namespace dash ...@@ -42,10 +42,10 @@ namespace dash
Default, Default,
AlwaysBest, AlwaysBest,
AlwaysLowest, AlwaysLowest,
RateBased, RateBased
}; };
virtual dash::http::Chunk* getNextChunk() throw(dash::exception::EOFException) = 0; virtual dash::http::Chunk* getNextChunk() throw(dash::exception::EOFException) = 0;
}; };
} }
......
...@@ -41,7 +41,7 @@ namespace dash ...@@ -41,7 +41,7 @@ namespace dash
NullAdaptationLogic (dash::mpd::IMPDManager *mpdManager) : AbstractAdaptationLogic(mpdManager) {} NullAdaptationLogic (dash::mpd::IMPDManager *mpdManager) : AbstractAdaptationLogic(mpdManager) {}
virtual ~NullAdaptationLogic() {} virtual ~NullAdaptationLogic() {}
dash::http::Chunk* getNextChunk () throw(dash::exception::EOFException) { throw dash::exception::EOFException(); } dash::http::Chunk* getNextChunk() throw(dash::exception::EOFException) { throw dash::exception::EOFException(); }
}; };
} }
} }
......
...@@ -41,7 +41,7 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic (IMPDManager *mpdManager) : ...@@ -41,7 +41,7 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic (IMPDManager *mpdManager) :
{ {
} }
Chunk* RateBasedAdaptationLogic::getNextChunk () throw(EOFException) Chunk* RateBasedAdaptationLogic::getNextChunk() throw(EOFException)
{ {
if(this->mpdManager == NULL) if(this->mpdManager == NULL)
throw EOFException(); throw EOFException();
...@@ -53,12 +53,12 @@ Chunk* RateBasedAdaptationLogic::getNextChunk () throw(EOFException) ...@@ -53,12 +53,12 @@ Chunk* RateBasedAdaptationLogic::getNextChunk () throw(EOFException)
Representation *rep = this->mpdManager->getRepresentation(this->currentPeriod, bitrate); Representation *rep = this->mpdManager->getRepresentation(this->currentPeriod, bitrate);
if(rep == NULL) if ( rep == NULL )
throw EOFException(); throw EOFException();
std::vector<const Segment *> segments = this->mpdManager->getSegments(rep); std::vector<Segment *> segments = this->mpdManager->getSegments(rep);
if(this->count == segments.size()) if ( this->count == segments.size() )
{ {
this->currentPeriod = this->mpdManager->getNextPeriod(this->currentPeriod); this->currentPeriod = this->mpdManager->getNextPeriod(this->currentPeriod);
this->count = 0; this->count = 0;
...@@ -67,9 +67,13 @@ Chunk* RateBasedAdaptationLogic::getNextChunk () throw(EOFException) ...@@ -67,9 +67,13 @@ Chunk* RateBasedAdaptationLogic::getNextChunk () throw(EOFException)
if ( segments.size() > this->count ) if ( segments.size() > this->count )
{ {
Segment *seg = segments.at( this->count );
Chunk *chunk = new Chunk; Chunk *chunk = new Chunk;
chunk->setUrl( segments.at( this->count )->getSourceUrl() ); chunk->setUrl( seg->getSourceUrl() );
this->count++; //In case of UrlTemplate, we must stay on the same segment.
if ( seg->isSingleShot() == true )
this->count++;
seg->done();
return chunk; return chunk;
} }
return NULL; return NULL;
......
...@@ -41,7 +41,7 @@ namespace dash ...@@ -41,7 +41,7 @@ namespace dash
public: public:
RateBasedAdaptationLogic (dash::mpd::IMPDManager *mpdManager); RateBasedAdaptationLogic (dash::mpd::IMPDManager *mpdManager);
dash::http::Chunk* getNextChunk () throw(dash::exception::EOFException); dash::http::Chunk* getNextChunk() throw(dash::exception::EOFException);
private: private:
dash::mpd::IMPDManager *mpdManager; dash::mpd::IMPDManager *mpdManager;
......
...@@ -153,7 +153,7 @@ static int Read (stream_t *p_stream, void *p_buffer, unsigned int i_ ...@@ -153,7 +153,7 @@ static int Read (stream_t *p_stream, void *p_buffer, unsigned int i_
dash::DASHManager *p_dashManager = p_sys->p_dashManager; dash::DASHManager *p_dashManager = p_sys->p_dashManager;
int i_ret = 0; int i_ret = 0;
i_ret = p_dashManager->read(p_buffer, i_len); i_ret = p_dashManager->read(p_buffer, i_len );
if (i_ret < 0) if (i_ret < 0)
{ {
...@@ -173,13 +173,15 @@ static int Read (stream_t *p_stream, void *p_buffer, unsigned int i_ ...@@ -173,13 +173,15 @@ static int Read (stream_t *p_stream, void *p_buffer, unsigned int i_
return i_ret; return i_ret;
} }
static int Peek (stream_t *p_stream, const uint8_t **pp_peek, unsigned int i_peek) static int Peek (stream_t *p_stream, const uint8_t **pp_peek, unsigned int i_peek)
{ {
stream_sys_t *p_sys = (stream_sys_t *) p_stream->p_sys; stream_sys_t *p_sys = (stream_sys_t *) p_stream->p_sys;
dash::DASHManager *p_dashManager = p_sys->p_dashManager; dash::DASHManager *p_dashManager = p_sys->p_dashManager;
return p_dashManager->peek(pp_peek, i_peek); return p_dashManager->peek( pp_peek, i_peek );
} }
static int Control (stream_t *p_stream, int i_query, va_list args) static int Control (stream_t *p_stream, int i_query, va_list args)
{ {
stream_sys_t *p_sys = p_stream->p_sys; stream_sys_t *p_sys = p_stream->p_sys;
......
...@@ -34,6 +34,7 @@ HTTPConnection::HTTPConnection (const std::string& url, stream_t *stream) ...@@ -34,6 +34,7 @@ HTTPConnection::HTTPConnection (const std::string& url, stream_t *stream)
this->url = url; this->url = url;
this->stream = stream; this->stream = stream;
} }
HTTPConnection::~HTTPConnection () HTTPConnection::~HTTPConnection ()
{ {
...@@ -66,6 +67,7 @@ void HTTPConnection::parseURL () ...@@ -66,6 +67,7 @@ void HTTPConnection::parseURL ()
this->request = "GET " + this->path + " HTTP/1.1\r\n" + this->request = "GET " + this->path + " HTTP/1.1\r\n" +
"Host: " + this->hostname + "\r\nConnection: close\r\n\r\n"; "Host: " + this->hostname + "\r\nConnection: close\r\n\r\n";
} }
bool HTTPConnection::init() bool HTTPConnection::init()
{ {
this->urlStream = stream_UrlNew( this->stream, this->url.c_str() ); this->urlStream = stream_UrlNew( this->stream, this->url.c_str() );
......
...@@ -46,9 +46,10 @@ HTTPConnectionManager::~HTTPConnectionManager () ...@@ -46,9 +46,10 @@ HTTPConnectionManager::~HTTPConnectionManager ()
this->closeAllConnections(); this->closeAllConnections();
} }
bool HTTPConnectionManager::closeConnection (IHTTPConnection *con) bool HTTPConnectionManager::closeConnection( IHTTPConnection *con )
{ {
for(std::vector<HTTPConnection *>::iterator it = this->connections.begin(); it != this->connections.end(); ++it) for(std::vector<HTTPConnection *>::iterator it = this->connections.begin();
it != this->connections.end(); ++it)
{ {
if(*it == con) if(*it == con)
{ {
...@@ -60,7 +61,8 @@ bool HTTPConnectionManager::closeConnection (IHTTPConnec ...@@ -60,7 +61,8 @@ bool HTTPConnectionManager::closeConnection (IHTTPConnec
} }
return false; return false;
} }
bool HTTPConnectionManager::closeConnection (Chunk *chunk)
bool HTTPConnectionManager::closeConnection( Chunk *chunk )
{ {
HTTPConnection *con = this->chunkMap[chunk]; HTTPConnection *con = this->chunkMap[chunk];
bool ret = this->closeConnection(con); bool ret = this->closeConnection(con);
...@@ -68,6 +70,7 @@ bool HTTPConnectionManager::closeConnection (Chunk *chun ...@@ -68,6 +70,7 @@ bool HTTPConnectionManager::closeConnection (Chunk *chun
delete(chunk); delete(chunk);
return ret; return ret;
} }
void HTTPConnectionManager::closeAllConnections () void HTTPConnectionManager::closeAllConnections ()
{ {
for(std::vector<HTTPConnection *>::iterator it = this->connections.begin(); it != this->connections.end(); ++it) for(std::vector<HTTPConnection *>::iterator it = this->connections.begin(); it != this->connections.end(); ++it)
...@@ -103,7 +106,6 @@ int HTTPConnectionManager::read( Chunk *chunk, void *p_buffer, s ...@@ -103,7 +106,6 @@ int HTTPConnectionManager::read( Chunk *chunk, void *p_buffer, s
int ret = this->chunkMap[chunk]->read(p_buffer, len); int ret = this->chunkMap[chunk]->read(p_buffer, len);
mtime_t end = mdate(); mtime_t end = mdate();
std::cout << "ret: " << ret << std::endl;
if( ret <= 0 ) if( ret <= 0 )
this->closeConnection( chunk ); this->closeConnection( chunk );
else else
......
...@@ -40,11 +40,11 @@ BasicCMManager::~BasicCMManager () ...@@ -40,11 +40,11 @@ BasicCMManager::~BasicCMManager ()
delete this->mpd; delete this->mpd;
} }
std::vector<const Segment*> BasicCMManager::getSegments( Representation *rep ) std::vector<Segment*> BasicCMManager::getSegments( Representation *rep )
{ {
std::vector<const Segment *> retSegments; std::vector<Segment *> retSegments;
SegmentInfo* info = rep->getSegmentInfo(); SegmentInfo* info = rep->getSegmentInfo();
const Segment* initSegment = info->getInitialisationSegment(); Segment* initSegment = info->getInitialisationSegment();
if ( initSegment ) if ( initSegment )
retSegments.push_back( initSegment ); retSegments.push_back( initSegment );
......
...@@ -51,7 +51,7 @@ namespace dash ...@@ -51,7 +51,7 @@ namespace dash
Period* getFirstPeriod(); Period* getFirstPeriod();
Period* getNextPeriod( Period *period ); Period* getNextPeriod( Period *period );
Representation* getBestRepresentation( Period *period ); Representation* getBestRepresentation( Period *period );
std::vector<const Segment *> getSegments( Representation *rep ); std::vector<Segment *> getSegments( Representation *rep );
Representation* getRepresentation( Period *period, int bitrate ); Representation* getRepresentation( Period *period, int bitrate );
const MPD* getMPD() const; const MPD* getMPD() const;
......
...@@ -521,7 +521,7 @@ bool BasicCMParser::resolveUrlTemplates( std::string &url, bool &containRunti ...@@ -521,7 +521,7 @@ bool BasicCMParser::resolveUrlTemplates( std::string &url, bool &containRunti
} }
else else
{ {
std::cout << "Unhandled token " << token << std::endl; std::cerr << "Unhandled token " << token << std::endl;
return false; return false;
} }
} }
......
...@@ -31,7 +31,7 @@ namespace dash ...@@ -31,7 +31,7 @@ namespace dash
virtual Period* getFirstPeriod () = 0; virtual Period* getFirstPeriod () = 0;
virtual Period* getNextPeriod (Period *period) = 0; virtual Period* getNextPeriod (Period *period) = 0;
virtual Representation* getBestRepresentation (Period *period) = 0; virtual Representation* getBestRepresentation (Period *period) = 0;
virtual std::vector<const Segment *> getSegments (Representation *rep) = 0; virtual std::vector<Segment *> getSegments(Representation *rep ) = 0;
virtual Representation* getRepresentation (Period *period, int bitrate) = 0; virtual Representation* getRepresentation (Period *period, int bitrate) = 0;
virtual const MPD* getMPD () const = 0; virtual const MPD* getMPD () const = 0;
virtual ~IMPDManager(){} virtual ~IMPDManager(){}
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
using namespace dash::mpd; using namespace dash::mpd;
const std::string& Segment::getSourceUrl () const std::string Segment::getSourceUrl() const
{ {
return this->sourceUrl; return this->sourceUrl;
} }
...@@ -39,3 +39,13 @@ void Segment::setSourceUrl( const std::string &url ) ...@@ -39,3 +39,13 @@ void Segment::setSourceUrl( const std::string &url )
if ( url.empty() == false ) if ( url.empty() == false )
this->sourceUrl = url; this->sourceUrl = url;
} }
bool Segment::isSingleShot() const
{
return true;
}
void Segment::done()
{
//Only used for a SegmentTemplate.
}
...@@ -35,10 +35,17 @@ namespace dash ...@@ -35,10 +35,17 @@ namespace dash
{ {
public: public:
virtual ~Segment(){} virtual ~Segment(){}
const std::string& getSourceUrl() const; virtual std::string getSourceUrl() const;
void setSourceUrl( const std::string &url ); virtual void setSourceUrl( const std::string &url );
/**
* @return true if the segment should be dropped after being read.
* That is basically true when using an Url, and false
* when using an UrlTemplate
*/
virtual bool isSingleShot() const;
virtual void done();
private: protected:
std::string sourceUrl; std::string sourceUrl;
}; };
} }
......
...@@ -64,12 +64,12 @@ void SegmentInfoCommon::setStartIndex(int startIndex) ...@@ -64,12 +64,12 @@ void SegmentInfoCommon::setStartIndex(int startIndex)
this->startIndex = startIndex; this->startIndex = startIndex;
} }
const Segment* SegmentInfoCommon::getInitialisationSegment() const Segment* SegmentInfoCommon::getInitialisationSegment() const
{ {
return this->initialisationSegment; return this->initialisationSegment;
} }
void SegmentInfoCommon::setInitialisationSegment(const Segment *seg) void SegmentInfoCommon::setInitialisationSegment(Segment *seg)
{ {
if ( seg != NULL ) if ( seg != NULL )
this->initialisationSegment = seg; this->initialisationSegment = seg;
......
...@@ -44,8 +44,8 @@ namespace dash ...@@ -44,8 +44,8 @@ namespace dash
void setDuration( time_t duration ); void setDuration( time_t duration );
int getStartIndex() const; int getStartIndex() const;
void setStartIndex( int startIndex ); void setStartIndex( int startIndex );
const Segment* getInitialisationSegment() const; Segment* getInitialisationSegment() const;
void setInitialisationSegment( const Segment* seg ); void setInitialisationSegment( Segment* seg );
const std::list<std::string>& getBaseURL() const; const std::list<std::string>& getBaseURL() const;
void appendBaseURL( const std::string& url ); void appendBaseURL( const std::string& url );
const SegmentTimeline* getSegmentTimeline() const; const SegmentTimeline* getSegmentTimeline() const;
...@@ -54,7 +54,7 @@ namespace dash ...@@ -54,7 +54,7 @@ namespace dash
private: private:
time_t duration; time_t duration;
int startIndex; int startIndex;
const Segment* initialisationSegment; Segment* initialisationSegment;
std::list<std::string> baseURLs; std::list<std::string> baseURLs;
const SegmentTimeline* segmentTimeline; const SegmentTimeline* segmentTimeline;
}; };
......
/*****************************************************************************
* SegmentTemplate.cpp: Implement the UrlTemplate element.
*****************************************************************************
* Copyright (C) 1998-2007 VLC authors and VideoLAN
* $Id$
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "SegmentTemplate.h"
#include "SegmentTimeline.h"
#include "Representation.h"
#include "Group.h"
#include "SegmentInfoDefault.h"
#include <cassert>
#include <cstring>
#include <iostream>
#include <sstream>
using namespace dash::mpd;
SegmentTemplate::SegmentTemplate( bool containRuntimeIdentifier,
Representation* representation ) :
containRuntimeIdentifier( containRuntimeIdentifier ),
representation( representation ),
beginTime( std::string::npos ),
beginIndex( std::string::npos ),
currentSegmentIndex( 0 )
{
}
std::string SegmentTemplate::getSourceUrl() const
{
std::string res = this->sourceUrl;
if ( this->containRuntimeIdentifier == false )
return Segment::getSourceUrl();
if ( this->beginIndex != std::string::npos )
std::cerr << "Unhandled identifier \"$Index$\"" << std::endl;
if ( this->beginTime != std::string::npos )
{
//FIXME: This should use the current representation SegmentInfo
//which "inherits" the SegmentInfoDefault values.
if ( this->representation->getParentGroup()->getSegmentInfoDefault() != NULL &&
this->representation->getParentGroup()->getSegmentInfoDefault()->getSegmentTimeline() != NULL )
{
const SegmentTimeline::Element *el = this->representation->getParentGroup()->
getSegmentInfoDefault()->getSegmentTimeline()->getElement( this->currentSegmentIndex );
if ( el != NULL )
{
std::ostringstream oss;
oss << el->t;
res.replace( this->beginTime, strlen("$Time$"), oss.str() );
}
}
}
return res;
}
void SegmentTemplate::setSourceUrl( const std::string &url )
{
if ( this->containRuntimeIdentifier == true )
{
this->beginTime = url.find( "$Time$" );
this->beginIndex = url.find( "$Index$" );
}
Segment::setSourceUrl( url );
}
bool SegmentTemplate::isSingleShot() const
{
return false;
}
void SegmentTemplate::done()
{
this->currentSegmentIndex++;
}
/*****************************************************************************
* SegmentTemplate.cpp: Implement the UrlTemplate element.
*****************************************************************************
* Copyright (C) 1998-2007 VLC authors and VideoLAN
* $Id$
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef SEGMENTTEMPLATE_H
#define SEGMENTTEMPLATE_H
#include "mpd/Segment.h"
namespace dash
{
namespace mpd
{
class Representation;
class SegmentTemplate : public Segment
{
public:
SegmentTemplate( bool containRuntimeIdentifier, Representation *rep );
virtual std::string getSourceUrl() const;
virtual void setSourceUrl( const std::string & url );
virtual bool isSingleShot() const;
virtual void done();
private:
bool containRuntimeIdentifier;
Representation* representation;
size_t beginTime;
size_t beginIndex;
int currentSegmentIndex;
};
}
}
#endif // SEGMENTTEMPLATE_H
...@@ -52,28 +52,33 @@ void dash::mpd::SegmentTimeline::setTimescale(int timescale) ...@@ -52,28 +52,33 @@ void dash::mpd::SegmentTimeline::setTimescale(int timescale)
void dash::mpd::SegmentTimeline::addElement(dash::mpd::SegmentTimeline::Element *e) void dash::mpd::SegmentTimeline::addElement(dash::mpd::SegmentTimeline::Element *e)
{ {
this->elements.push_back( e ); int64_t offset = 0;
for ( int i = 0; i <= e->r; ++i )
{
this->elements.push_back( e );
if ( i < e->r )
{
e = new SegmentTimeline::Element( *e );
offset += e->d;
e->t += offset;
}
}
} }
const SegmentTimeline::Element* SegmentTimeline::getElement( mtime_t dts ) const const SegmentTimeline::Element* SegmentTimeline::getElement( unsigned int index ) const
{ {
if ( this->elements.size() == 0 ) if ( this->elements.size() <= index )
return NULL; return NULL;
int64_t targetT = dts * this->timescale / 1000000;
targetT -= this->elements.front()->t;
std::list<Element*>::const_iterator it = this->elements.begin(); std::list<Element*>::const_iterator it = this->elements.begin();
std::list<Element*>::const_iterator end = this->elements.end(); std::list<Element*>::const_iterator end = this->elements.end();
const Element* res = NULL; unsigned int i = 0;
while ( it != end ) while ( it != end )
{ {
if ( (*it)->t > targetT ) if ( i == index )
return res; return *it;
res = *it;
++it; ++it;
++i;
} }
std::cerr << "No more element to be used." << std::endl;
return NULL; return NULL;
} }
...@@ -81,3 +86,10 @@ dash::mpd::SegmentTimeline::Element::Element() : ...@@ -81,3 +86,10 @@ dash::mpd::SegmentTimeline::Element::Element() :
r( 0 ) r( 0 )
{ {
} }
SegmentTimeline::Element::Element(const SegmentTimeline::Element &e) :
t( e.t ),
d( e.d ),
r( 0 )
{
}
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <list> #include <list>
#include <stdint.h> #include <stdint.h>
#include <vlc_common.h>
namespace dash namespace dash
{ {
...@@ -39,6 +38,7 @@ namespace dash ...@@ -39,6 +38,7 @@ namespace dash
struct Element struct Element
{ {
Element(); Element();
Element( const Element& e );
int64_t t; int64_t t;
int64_t d; int64_t d;
int r; int r;
...@@ -48,7 +48,7 @@ namespace dash ...@@ -48,7 +48,7 @@ namespace dash
int getTimescale() const; int getTimescale() const;
void setTimescale( int timescale ); void setTimescale( int timescale );
void addElement( Element* e ); void addElement( Element* e );
const Element* getElement( mtime_t dts ) const; const Element* getElement( unsigned int index ) const;
private: private:
int timescale; int timescale;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment