Commit e017b611 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: adaptative: refactor into playlistmanager

parent 7b2c07c6
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "logic/RateBasedAdaptationLogic.h" #include "logic/RateBasedAdaptationLogic.h"
#include "logic/AlwaysLowestAdaptationLogic.hpp" #include "logic/AlwaysLowestAdaptationLogic.hpp"
#include <vlc_stream.h> #include <vlc_stream.h>
#include <vlc_demux.h>
#include <ctime> #include <ctime>
...@@ -40,16 +41,17 @@ using namespace adaptative::http; ...@@ -40,16 +41,17 @@ using namespace adaptative::http;
using namespace adaptative::logic; using namespace adaptative::logic;
using namespace adaptative; using namespace adaptative;
PlaylistManager::PlaylistManager( AbstractPlaylist *pl, PlaylistManager::PlaylistManager( demux_t *p_demux_,
AbstractPlaylist *pl,
AbstractStreamOutputFactory *factory, AbstractStreamOutputFactory *factory,
AbstractAdaptationLogic::LogicType type, AbstractAdaptationLogic::LogicType type ) :
stream_t *stream) :
conManager ( NULL ), conManager ( NULL ),
logicType ( type ), logicType ( type ),
playlist ( pl ), playlist ( pl ),
streamOutputFactory( factory ), streamOutputFactory( factory ),
stream ( stream ), p_demux ( p_demux_ ),
nextPlaylistupdate ( 0 ) nextPlaylistupdate ( 0 ),
i_nzpcr ( 0 )
{ {
currentPeriod = playlist->getFirstPeriod(); currentPeriod = playlist->getFirstPeriod();
} }
...@@ -110,14 +112,12 @@ bool PlaylistManager::setupPeriod() ...@@ -110,14 +112,12 @@ bool PlaylistManager::setupPeriod()
return true; return true;
} }
bool PlaylistManager::start(demux_t *demux_) bool PlaylistManager::start()
{ {
p_demux = demux_;
if(!setupPeriod()) if(!setupPeriod())
return false; return false;
conManager = new (std::nothrow) HTTPConnectionManager(VLC_OBJECT(stream)); conManager = new (std::nothrow) HTTPConnectionManager(VLC_OBJECT(p_demux->s));
if(!conManager) if(!conManager)
return false; return false;
...@@ -261,6 +261,124 @@ bool PlaylistManager::updatePlaylist() ...@@ -261,6 +261,124 @@ bool PlaylistManager::updatePlaylist()
return true; return true;
} }
#define DEMUX_INCREMENT (CLOCK_FREQ / 20)
int PlaylistManager::demux_callback(demux_t *p_demux)
{
PlaylistManager *manager = reinterpret_cast<PlaylistManager *>(p_demux->p_sys);
return manager->doDemux(DEMUX_INCREMENT);
}
int PlaylistManager::doDemux(int64_t increment)
{
if(i_nzpcr == VLC_TS_INVALID)
{
if( Stream::status_eof == demux(i_nzpcr + increment, false) )
{
return VLC_DEMUXER_EOF;
}
i_nzpcr = getFirstDTS();
if(i_nzpcr == VLC_TS_INVALID)
i_nzpcr = getPCR();
}
Stream::status status = demux(i_nzpcr + increment, true);
switch(status)
{
case Stream::status_eof:
return VLC_DEMUXER_EOF;
case Stream::status_buffering:
break;
case Stream::status_eop:
i_nzpcr = VLC_TS_INVALID;
es_out_Control(p_demux->out, ES_OUT_RESET_PCR);
break;
case Stream::status_demuxed:
if( i_nzpcr != VLC_TS_INVALID )
{
i_nzpcr += increment;
int group = getGroup();
es_out_Control(p_demux->out, ES_OUT_SET_GROUP_PCR, group, VLC_TS_0 + i_nzpcr);
}
break;
}
if( !updatePlaylist() )
msg_Warn(p_demux, "Can't update MPD");
return VLC_DEMUXER_SUCCESS;
}
int PlaylistManager::control_callback(demux_t *p_demux, int i_query, va_list args)
{
PlaylistManager *manager = reinterpret_cast<PlaylistManager *>(p_demux->p_sys);
return manager->doControl(i_query, args);
}
int PlaylistManager::doControl(int i_query, va_list args)
{
switch (i_query)
{
case DEMUX_CAN_SEEK:
*(va_arg (args, bool *)) = seekAble();
break;
case DEMUX_CAN_CONTROL_PACE:
*(va_arg (args, bool *)) = true;
break;
case DEMUX_CAN_PAUSE:
*(va_arg (args, bool *)) = playlist->isLive();
break;
case DEMUX_GET_TIME:
*(va_arg (args, int64_t *)) = i_nzpcr;
break;
case DEMUX_GET_LENGTH:
*(va_arg (args, int64_t *)) = getDuration();
break;
case DEMUX_GET_POSITION:
if(!getDuration())
return VLC_EGENERIC;
*(va_arg (args, double *)) = (double) i_nzpcr
/ getDuration();
break;
case DEMUX_SET_POSITION:
{
int64_t time = getDuration() * va_arg(args, double);
if(playlist->isLive() ||
!getDuration() ||
!setPosition(time))
return VLC_EGENERIC;
i_nzpcr = VLC_TS_INVALID;
break;
}
case DEMUX_SET_TIME:
{
int64_t time = va_arg(args, int64_t);
if(playlist->isLive() ||
!setPosition(time))
return VLC_EGENERIC;
i_nzpcr = VLC_TS_INVALID;
break;
}
case DEMUX_GET_PTS_DELAY:
*va_arg (args, int64_t *) = INT64_C(1000) *
var_InheritInteger(p_demux, "network-caching");
break;
default:
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::LogicType type) AbstractAdaptationLogic *PlaylistManager::createLogic(AbstractAdaptationLogic::LogicType type)
{ {
switch(type) switch(type)
......
...@@ -49,13 +49,12 @@ namespace adaptative ...@@ -49,13 +49,12 @@ namespace adaptative
class PlaylistManager class PlaylistManager
{ {
public: public:
PlaylistManager( AbstractPlaylist *, PlaylistManager( demux_t *, AbstractPlaylist *,
AbstractStreamOutputFactory *, AbstractStreamOutputFactory *,
AbstractAdaptationLogic::LogicType type, AbstractAdaptationLogic::LogicType type );
stream_t *stream);
virtual ~PlaylistManager (); virtual ~PlaylistManager ();
bool start(demux_t *); bool start();
Stream::status demux(mtime_t, bool); Stream::status demux(mtime_t, bool);
mtime_t getDuration() const; mtime_t getDuration() const;
...@@ -67,7 +66,15 @@ namespace adaptative ...@@ -67,7 +66,15 @@ namespace adaptative
bool seekAble() const; bool seekAble() const;
virtual bool updatePlaylist(); virtual bool updatePlaylist();
/* static callbacks */
static int control_callback(demux_t *, int, va_list);
static int demux_callback(demux_t *);
protected: protected:
/* Demux calls */
virtual int doControl(int, va_list);
virtual int doDemux(int64_t);
bool setupPeriod(); bool setupPeriod();
void unsetPeriod(); void unsetPeriod();
/* local factories */ /* local factories */
...@@ -77,10 +84,10 @@ namespace adaptative ...@@ -77,10 +84,10 @@ namespace adaptative
AbstractAdaptationLogic::LogicType logicType; AbstractAdaptationLogic::LogicType logicType;
AbstractPlaylist *playlist; AbstractPlaylist *playlist;
AbstractStreamOutputFactory *streamOutputFactory; AbstractStreamOutputFactory *streamOutputFactory;
stream_t *stream;
demux_t *p_demux; demux_t *p_demux;
std::vector<Stream *> streams; std::vector<Stream *> streams;
mtime_t nextPlaylistupdate; mtime_t nextPlaylistupdate;
mtime_t i_nzpcr;
BasePeriod *currentPeriod; BasePeriod *currentPeriod;
}; };
......
...@@ -31,9 +31,12 @@ ...@@ -31,9 +31,12 @@
#include "DASHManager.h" #include "DASHManager.h"
#include "DASHStreamFormat.hpp" #include "DASHStreamFormat.hpp"
#include "mpd/MPDFactory.h" #include "mpd/MPDFactory.h"
#include "mpd/ProgramInformation.h"
#include "xml/DOMParser.h" #include "xml/DOMParser.h"
#include "../adaptative/logic/RateBasedAdaptationLogic.h" #include "../adaptative/logic/RateBasedAdaptationLogic.h"
#include <vlc_stream.h> #include <vlc_stream.h>
#include <vlc_demux.h>
#include <vlc_meta.h>
#include "../adaptative/tools/Retrieve.hpp" #include "../adaptative/tools/Retrieve.hpp"
#include <algorithm> #include <algorithm>
...@@ -58,10 +61,10 @@ AbstractStreamOutput *DASHStreamOutputFactory::create(demux_t *demux, const Stre ...@@ -58,10 +61,10 @@ AbstractStreamOutput *DASHStreamOutputFactory::create(demux_t *demux, const Stre
return NULL; return NULL;
} }
DASHManager::DASHManager(MPD *mpd, DASHManager::DASHManager(demux_t *demux_, MPD *mpd,
AbstractStreamOutputFactory *factory, AbstractStreamOutputFactory *factory,
AbstractAdaptationLogic::LogicType type, stream_t *stream) : AbstractAdaptationLogic::LogicType type) :
PlaylistManager(mpd, factory, type, stream) PlaylistManager(demux_, mpd, factory, type)
{ {
} }
...@@ -81,16 +84,16 @@ bool DASHManager::updatePlaylist() ...@@ -81,16 +84,16 @@ bool DASHManager::updatePlaylist()
/* do update */ /* do update */
if(nextPlaylistupdate) if(nextPlaylistupdate)
{ {
std::string url(stream->psz_access); std::string url(p_demux->s->psz_access);
url.append("://"); url.append("://");
url.append(stream->psz_path); url.append(p_demux->s->psz_path);
uint8_t *p_data = NULL; uint8_t *p_data = NULL;
size_t i_data = Retrieve::HTTP(VLC_OBJECT(stream), url, (void**) &p_data); size_t i_data = Retrieve::HTTP(VLC_OBJECT(p_demux->s), url, (void**) &p_data);
if(!p_data) if(!p_data)
return false; return false;
stream_t *mpdstream = stream_MemoryNew(stream, p_data, i_data, false); stream_t *mpdstream = stream_MemoryNew(p_demux->s, p_data, i_data, false);
if(!mpdstream) if(!mpdstream)
{ {
free(p_data); free(p_data);
...@@ -139,26 +142,64 @@ bool DASHManager::updatePlaylist() ...@@ -139,26 +142,64 @@ bool DASHManager::updatePlaylist()
nextPlaylistupdate = now + (maxinterval - mininterval) / (2 * CLOCK_FREQ); nextPlaylistupdate = now + (maxinterval - mininterval) / (2 * CLOCK_FREQ);
msg_Dbg(stream, "Updated MPD, next update in %" PRId64 "s (%" PRId64 "..%" PRId64 ")", msg_Dbg(p_demux, "Updated MPD, next update in %" PRId64 "s (%" PRId64 "..%" PRId64 ")",
nextPlaylistupdate - now, mininterval, maxinterval ); nextPlaylistupdate - now, mininterval, maxinterval );
return true; return true;
} }
int DASHManager::doControl(int i_query, va_list args)
{
switch (i_query)
{
case DEMUX_GET_META:
{
MPD *mpd = dynamic_cast<MPD *>(playlist);
if(!mpd)
return VLC_EGENERIC;
if(!mpd->programInfo.Get())
break;
vlc_meta_t *p_meta = (vlc_meta_t *) va_arg (args, vlc_meta_t*);
vlc_meta_t *meta = vlc_meta_New();
if (meta == NULL)
return VLC_EGENERIC;
if(!mpd->programInfo.Get()->getTitle().empty())
vlc_meta_SetTitle(meta, mpd->programInfo.Get()->getTitle().c_str());
if(!mpd->programInfo.Get()->getSource().empty())
vlc_meta_SetPublisher(meta, mpd->programInfo.Get()->getSource().c_str());
if(!mpd->programInfo.Get()->getCopyright().empty())
vlc_meta_SetCopyright(meta, mpd->programInfo.Get()->getCopyright().c_str());
if(!mpd->programInfo.Get()->getMoreInformationUrl().empty())
vlc_meta_SetURL(meta, mpd->programInfo.Get()->getMoreInformationUrl().c_str());
vlc_meta_Merge(p_meta, meta);
vlc_meta_Delete(meta);
break;
}
}
return PlaylistManager::doControl(i_query, args);
}
AbstractAdaptationLogic *DASHManager::createLogic(AbstractAdaptationLogic::LogicType type) AbstractAdaptationLogic *DASHManager::createLogic(AbstractAdaptationLogic::LogicType type)
{ {
switch(type) switch(type)
{ {
case AbstractAdaptationLogic::FixedRate: case AbstractAdaptationLogic::FixedRate:
{ {
size_t bps = var_InheritInteger(stream, "dash-prefbw") * 8192; size_t bps = var_InheritInteger(p_demux, "dash-prefbw") * 8192;
return new (std::nothrow) FixedRateAdaptationLogic(bps); return new (std::nothrow) FixedRateAdaptationLogic(bps);
} }
case AbstractAdaptationLogic::Default: case AbstractAdaptationLogic::Default:
case AbstractAdaptationLogic::RateBased: case AbstractAdaptationLogic::RateBased:
{ {
int width = var_InheritInteger(stream, "dash-prefwidth"); int width = var_InheritInteger(p_demux, "dash-prefwidth");
int height = var_InheritInteger(stream, "dash-prefheight"); int height = var_InheritInteger(p_demux, "dash-prefheight");
return new (std::nothrow) RateBasedAdaptationLogic(width, height); return new (std::nothrow) RateBasedAdaptationLogic(width, height);
} }
default: default:
......
...@@ -42,14 +42,16 @@ namespace dash ...@@ -42,14 +42,16 @@ namespace dash
class DASHManager : public PlaylistManager class DASHManager : public PlaylistManager
{ {
public: public:
DASHManager( mpd::MPD *mpd, DASHManager( demux_t *, mpd::MPD *mpd,
AbstractStreamOutputFactory *, AbstractStreamOutputFactory *,
logic::AbstractAdaptationLogic::LogicType type, logic::AbstractAdaptationLogic::LogicType type);
stream_t *stream);
virtual ~DASHManager (); virtual ~DASHManager ();
virtual bool updatePlaylist(); //reimpl virtual bool updatePlaylist(); //reimpl
virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType); //reimpl virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType); //reimpl
protected:
virtual int doControl(int, va_list); /* reimpl */
}; };
} }
......
...@@ -35,14 +35,10 @@ ...@@ -35,14 +35,10 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_demux.h> #include <vlc_demux.h>
#include <vlc_meta.h>
#include <errno.h>
#include "xml/DOMParser.h" #include "xml/DOMParser.h"
#include "mpd/MPDFactory.h" #include "mpd/MPDFactory.h"
#include "mpd/Period.h" #include "mpd/Period.h"
#include "mpd/ProgramInformation.h"
#include "DASHManager.h" #include "DASHManager.h"
using namespace adaptative::logic; using namespace adaptative::logic;
...@@ -96,15 +92,6 @@ vlc_module_end () ...@@ -96,15 +92,6 @@ vlc_module_end ()
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
struct demux_sys_t
{
dash::DASHManager *p_dashManager;
dash::mpd::MPD *p_mpd;
mtime_t i_nzpcr;
};
static int Demux( demux_t * );
static int Control (demux_t *p_demux, int i_query, va_list args);
/***************************************************************************** /*****************************************************************************
* Open: * Open:
...@@ -140,30 +127,21 @@ static int Open(vlc_object_t *p_obj) ...@@ -140,30 +127,21 @@ static int Open(vlc_object_t *p_obj)
return VLC_EGENERIC; return VLC_EGENERIC;
} }
demux_sys_t *p_sys = (demux_sys_t *) malloc(sizeof(demux_sys_t));
if (unlikely(p_sys == NULL))
return VLC_ENOMEM;
p_sys->p_mpd = mpd;
int logic = var_InheritInteger( p_obj, "dash-logic" ); int logic = var_InheritInteger( p_obj, "dash-logic" );
DASHManager*p_dashManager = new DASHManager(p_sys->p_mpd, DASHManager *p_dashManager = new (std::nothrow) DASHManager(p_demux, mpd,
new (std::nothrow) DASHStreamOutputFactory, new (std::nothrow) DASHStreamOutputFactory,
static_cast<AbstractAdaptationLogic::LogicType>(logic), static_cast<AbstractAdaptationLogic::LogicType>(logic));
p_demux->s);
BasePeriod *period = mpd->getFirstPeriod(); BasePeriod *period = mpd->getFirstPeriod();
if(period && !p_dashManager->start(p_demux)) if(period && !p_dashManager->start())
{ {
delete p_dashManager; delete p_dashManager;
free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_sys->p_dashManager = p_dashManager;
p_demux->p_sys = p_sys;
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
p_sys->i_nzpcr = 0; p_demux->p_sys = reinterpret_cast<demux_sys_t *>(p_dashManager);
p_demux->pf_demux = p_dashManager->demux_callback;
p_demux->pf_control = p_dashManager->control_callback;
msg_Dbg(p_obj,"opening mpd file (%s)", p_demux->s->psz_path); msg_Dbg(p_obj,"opening mpd file (%s)", p_demux->s->psz_path);
...@@ -174,151 +152,9 @@ static int Open(vlc_object_t *p_obj) ...@@ -174,151 +152,9 @@ static int Open(vlc_object_t *p_obj)
*****************************************************************************/ *****************************************************************************/
static void Close(vlc_object_t *p_obj) static void Close(vlc_object_t *p_obj)
{ {
demux_t *p_demux = (demux_t*) p_obj; demux_t *p_demux = (demux_t*) p_obj;
demux_sys_t *p_sys = (demux_sys_t *) p_demux->p_sys; PlaylistManager *p_manager = reinterpret_cast<PlaylistManager *>(p_demux->p_sys);
DASHManager *p_dashManager = p_sys->p_dashManager;
delete p_dashManager;
free(p_sys);
}
/*****************************************************************************
* Callbacks:
*****************************************************************************/
#define DEMUX_INCREMENT (CLOCK_FREQ / 20)
static int Demux(demux_t *p_demux)
{
demux_sys_t *p_sys = p_demux->p_sys;
if(p_sys->i_nzpcr == VLC_TS_INVALID)
{
if( Stream::status_eof ==
p_sys->p_dashManager->demux(p_sys->i_nzpcr + DEMUX_INCREMENT, false) )
{
return VLC_DEMUXER_EOF;
}
p_sys->i_nzpcr = p_sys->p_dashManager->getFirstDTS();
if(p_sys->i_nzpcr == VLC_TS_INVALID)
p_sys->i_nzpcr = p_sys->p_dashManager->getPCR();
}
Stream::status status =
p_sys->p_dashManager->demux(p_sys->i_nzpcr + DEMUX_INCREMENT, true);
switch(status)
{
case Stream::status_eof:
return VLC_DEMUXER_EOF;
case Stream::status_buffering:
break;
case Stream::status_eop:
p_sys->i_nzpcr = VLC_TS_INVALID;
es_out_Control(p_demux->out, ES_OUT_RESET_PCR);
break;
case Stream::status_demuxed:
if( p_sys->i_nzpcr != VLC_TS_INVALID )
{
p_sys->i_nzpcr += DEMUX_INCREMENT;
int group = p_sys->p_dashManager->getGroup();
es_out_Control(p_demux->out, ES_OUT_SET_GROUP_PCR, group, VLC_TS_0 + p_sys->i_nzpcr);
}
break;
}
if( !p_sys->p_dashManager->updatePlaylist() )
msg_Warn(p_demux, "Can't update MPD");
return VLC_DEMUXER_SUCCESS; delete p_manager;
} }
static int Control (demux_t *p_demux, int i_query, va_list args)
{
demux_sys_t *p_sys = p_demux->p_sys;
switch (i_query)
{
case DEMUX_CAN_SEEK:
*(va_arg (args, bool *)) = p_sys->p_dashManager->seekAble();
break;
case DEMUX_CAN_CONTROL_PACE:
*(va_arg (args, bool *)) = true;
break;
case DEMUX_CAN_PAUSE:
*(va_arg (args, bool *)) = p_sys->p_mpd->isLive();
break;
case DEMUX_GET_TIME:
*(va_arg (args, int64_t *)) = p_sys->i_nzpcr;
break;
case DEMUX_GET_LENGTH:
*(va_arg (args, int64_t *)) = p_sys->p_dashManager->getDuration();
break;
case DEMUX_GET_POSITION:
if(!p_sys->p_dashManager->getDuration())
return VLC_EGENERIC;
*(va_arg (args, double *)) = (double) p_sys->i_nzpcr
/ p_sys->p_dashManager->getDuration();
break;
case DEMUX_SET_POSITION:
{
int64_t time = p_sys->p_dashManager->getDuration() * va_arg(args, double);
if(p_sys->p_mpd->isLive() ||
!p_sys->p_dashManager->getDuration() ||
!p_sys->p_dashManager->setPosition(time))
return VLC_EGENERIC;
p_sys->i_nzpcr = VLC_TS_INVALID;
break;
}
case DEMUX_SET_TIME:
{
int64_t time = va_arg(args, int64_t);
if(p_sys->p_mpd->isLive() ||
!p_sys->p_dashManager->setPosition(time))
return VLC_EGENERIC;
p_sys->i_nzpcr = VLC_TS_INVALID;
break;
}
case DEMUX_GET_PTS_DELAY:
*va_arg (args, int64_t *) = INT64_C(1000) *
var_InheritInteger(p_demux, "network-caching");
break;
case DEMUX_GET_META:
{
if(!p_sys->p_mpd->programInfo.Get())
break;
vlc_meta_t *p_meta = (vlc_meta_t *) va_arg (args, vlc_meta_t*);
vlc_meta_t *meta = vlc_meta_New();
if (meta == NULL)
return VLC_EGENERIC;
if(!p_sys->p_mpd->programInfo.Get()->getTitle().empty())
vlc_meta_SetTitle(meta, p_sys->p_mpd->programInfo.Get()->getTitle().c_str());
if(!p_sys->p_mpd->programInfo.Get()->getSource().empty())
vlc_meta_SetPublisher(meta, p_sys->p_mpd->programInfo.Get()->getSource().c_str());
if(!p_sys->p_mpd->programInfo.Get()->getCopyright().empty())
vlc_meta_SetCopyright(meta, p_sys->p_mpd->programInfo.Get()->getCopyright().c_str());
if(!p_sys->p_mpd->programInfo.Get()->getMoreInformationUrl().empty())
vlc_meta_SetURL(meta, p_sys->p_mpd->programInfo.Get()->getMoreInformationUrl().c_str());
vlc_meta_Merge(p_meta, meta);
vlc_meta_Delete(meta);
break;
}
default:
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "../adaptative/tools/Retrieve.hpp" #include "../adaptative/tools/Retrieve.hpp"
#include "playlist/Parser.hpp" #include "playlist/Parser.hpp"
#include <vlc_stream.h> #include <vlc_stream.h>
#include <vlc_demux.h>
#include <time.h> #include <time.h>
using namespace adaptative; using namespace adaptative;
...@@ -34,10 +35,10 @@ using namespace adaptative::logic; ...@@ -34,10 +35,10 @@ using namespace adaptative::logic;
using namespace hls; using namespace hls;
using namespace hls::playlist; using namespace hls::playlist;
HLSManager::HLSManager(M3U8 *playlist, HLSManager::HLSManager(demux_t *demux_, M3U8 *playlist,
AbstractStreamOutputFactory *factory, AbstractStreamOutputFactory *factory,
AbstractAdaptationLogic::LogicType type, stream_t *stream) : AbstractAdaptationLogic::LogicType type) :
PlaylistManager(playlist, factory, type, stream) PlaylistManager(demux_, playlist, factory, type)
{ {
} }
...@@ -51,14 +52,14 @@ AbstractAdaptationLogic *HLSManager::createLogic(AbstractAdaptationLogic::LogicT ...@@ -51,14 +52,14 @@ AbstractAdaptationLogic *HLSManager::createLogic(AbstractAdaptationLogic::LogicT
{ {
case AbstractAdaptationLogic::FixedRate: case AbstractAdaptationLogic::FixedRate:
{ {
size_t bps = var_InheritInteger(stream, "hls-prefbw") * 8192; size_t bps = var_InheritInteger(p_demux, "hls-prefbw") * 8192;
return new (std::nothrow) FixedRateAdaptationLogic(bps); return new (std::nothrow) FixedRateAdaptationLogic(bps);
} }
case AbstractAdaptationLogic::Default: case AbstractAdaptationLogic::Default:
case AbstractAdaptationLogic::RateBased: case AbstractAdaptationLogic::RateBased:
{ {
int width = var_InheritInteger(stream, "hls-prefwidth"); int width = var_InheritInteger(p_demux, "hls-prefwidth");
int height = var_InheritInteger(stream, "hls-prefheight"); int height = var_InheritInteger(p_demux, "hls-prefheight");
return new (std::nothrow) RateBasedAdaptationLogic(width, height); return new (std::nothrow) RateBasedAdaptationLogic(width, height);
} }
default: default:
...@@ -80,16 +81,16 @@ bool HLSManager::updatePlaylist() ...@@ -80,16 +81,16 @@ bool HLSManager::updatePlaylist()
/* do update */ /* do update */
if(nextPlaylistupdate) if(nextPlaylistupdate)
{ {
std::string url(stream->psz_access); std::string url(p_demux->s->psz_access);
url.append("://"); url.append("://");
url.append(stream->psz_path); url.append(p_demux->s->psz_path);
uint8_t *p_data = NULL; uint8_t *p_data = NULL;
size_t i_data = Retrieve::HTTP(VLC_OBJECT(stream), url, (void**) &p_data); size_t i_data = Retrieve::HTTP(VLC_OBJECT(p_demux->s), url, (void**) &p_data);
if(!p_data) if(!p_data)
return false; return false;
stream_t *updatestream = stream_MemoryNew(stream, p_data, i_data, false); stream_t *updatestream = stream_MemoryNew(p_demux->s, p_data, i_data, false);
if(!updatestream) if(!updatestream)
{ {
free(p_data); free(p_data);
...@@ -140,7 +141,7 @@ bool HLSManager::updatePlaylist() ...@@ -140,7 +141,7 @@ bool HLSManager::updatePlaylist()
nextPlaylistupdate = now + (mininterval + maxinterval) / (2 * CLOCK_FREQ); nextPlaylistupdate = now + (mininterval + maxinterval) / (2 * CLOCK_FREQ);
msg_Dbg(stream, "Updated playlist, next update in %" PRId64 "s " msg_Dbg(p_demux, "Updated playlist, next update in %" PRId64 "s "
"%" PRId64 " %" PRId64, nextPlaylistupdate - now, mininterval, "%" PRId64 " %" PRId64, nextPlaylistupdate - now, mininterval,
maxinterval); maxinterval);
......
...@@ -31,10 +31,9 @@ namespace hls ...@@ -31,10 +31,9 @@ namespace hls
class HLSManager : public PlaylistManager class HLSManager : public PlaylistManager
{ {
public: public:
HLSManager( playlist::M3U8 *, HLSManager( demux_t *, playlist::M3U8 *,
AbstractStreamOutputFactory *, AbstractStreamOutputFactory *,
logic::AbstractAdaptationLogic::LogicType type, logic::AbstractAdaptationLogic::LogicType type );
stream_t *stream );
virtual ~HLSManager(); virtual ~HLSManager();
virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType); virtual AbstractAdaptationLogic *createLogic(AbstractAdaptationLogic::LogicType);
virtual bool updatePlaylist(); virtual bool updatePlaylist();
......
...@@ -31,9 +31,6 @@ ...@@ -31,9 +31,6 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_demux.h> #include <vlc_demux.h>
#include <vlc_meta.h>
#include <errno.h>
#include "../adaptative/logic/AbstractAdaptationLogic.h" #include "../adaptative/logic/AbstractAdaptationLogic.h"
#include "HLSManager.hpp" #include "HLSManager.hpp"
...@@ -93,15 +90,6 @@ vlc_module_end () ...@@ -93,15 +90,6 @@ vlc_module_end ()
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
struct demux_sys_t
{
adaptative::PlaylistManager *p_manager;
hls::playlist::M3U8 *p_playlist;
mtime_t i_nzpcr;
};
static int Demux( demux_t * );
static int Control (demux_t *p_demux, int i_query, va_list args);
/***************************************************************************** /*****************************************************************************
* Open: * Open:
...@@ -169,39 +157,28 @@ static int Open(vlc_object_t *p_obj) ...@@ -169,39 +157,28 @@ static int Open(vlc_object_t *p_obj)
if(!isHTTPLiveStreaming(p_demux->s)) if(!isHTTPLiveStreaming(p_demux->s))
return VLC_EGENERIC; return VLC_EGENERIC;
demux_sys_t *p_sys = (demux_sys_t *) malloc(sizeof(demux_sys_t));
if (unlikely(p_sys == NULL))
return VLC_ENOMEM;
Parser parser(p_demux->s); Parser parser(p_demux->s);
p_sys->p_playlist = parser.parse(std::string()); M3U8 *p_playlist = parser.parse(std::string());
if(!p_sys->p_playlist) if(!p_playlist)
{
free(p_sys);
return VLC_EGENERIC; return VLC_EGENERIC;
}
int logic = var_InheritInteger(p_obj, "hls-logic"); int logic = var_InheritInteger(p_obj, "hls-logic");
HLSManager *p_manager = HLSManager *p_manager =
new (std::nothrow) HLSManager(p_sys->p_playlist, new (std::nothrow) HLSManager(p_demux, p_playlist,
new (std::nothrow) HLSStreamOutputFactory, new (std::nothrow) HLSStreamOutputFactory,
static_cast<AbstractAdaptationLogic::LogicType>(logic), static_cast<AbstractAdaptationLogic::LogicType>(logic));
p_demux->s);
BasePeriod *period = p_sys->p_playlist->getFirstPeriod(); BasePeriod *period = p_playlist->getFirstPeriod();
if(period && !p_manager->start(p_demux)) if(period && !p_manager->start())
{ {
delete p_manager; delete p_manager;
free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_sys->p_manager = p_manager;
p_demux->p_sys = p_sys;
p_demux->pf_demux = Demux;
p_demux->pf_control = Control;
p_sys->i_nzpcr = VLC_TS_INVALID; p_demux->p_sys = reinterpret_cast<demux_sys_t *>(p_manager);
p_demux->pf_demux = p_manager->demux_callback;
p_demux->pf_control = p_manager->control_callback;
msg_Dbg(p_obj,"opening mpd file (%s)", p_demux->s->psz_path); msg_Dbg(p_obj,"opening mpd file (%s)", p_demux->s->psz_path);
...@@ -212,122 +189,8 @@ static int Open(vlc_object_t *p_obj) ...@@ -212,122 +189,8 @@ static int Open(vlc_object_t *p_obj)
*****************************************************************************/ *****************************************************************************/
static void Close(vlc_object_t *p_obj) static void Close(vlc_object_t *p_obj)
{ {
demux_t *p_demux = (demux_t*) p_obj; demux_t *p_demux = (demux_t*) p_obj;
demux_sys_t *p_sys = (demux_sys_t *) p_demux->p_sys; PlaylistManager *p_manager = reinterpret_cast<PlaylistManager *>(p_demux->p_sys);
delete p_sys->p_manager;
free(p_sys);
}
/*****************************************************************************
* Callbacks:
*****************************************************************************/
#define DEMUX_INCREMENT (CLOCK_FREQ / 20)
static int Demux(demux_t *p_demux)
{
demux_sys_t *p_sys = p_demux->p_sys;
if(p_sys->i_nzpcr == VLC_TS_INVALID)
{
if( Stream::status_eof ==
p_sys->p_manager->demux(p_sys->i_nzpcr + DEMUX_INCREMENT, false) )
{
return VLC_DEMUXER_EOF;
}
p_sys->i_nzpcr = p_sys->p_manager->getFirstDTS();
if(p_sys->i_nzpcr == VLC_TS_INVALID)
p_sys->i_nzpcr = p_sys->p_manager->getPCR();
}
Stream::status status =
p_sys->p_manager->demux(p_sys->i_nzpcr + DEMUX_INCREMENT, true);
switch(status)
{
case Stream::status_eof:
return VLC_DEMUXER_EOF;
case Stream::status_buffering:
break;
case Stream::status_eop:
p_sys->i_nzpcr = VLC_TS_INVALID;
es_out_Control(p_demux->out, ES_OUT_RESET_PCR);
break;
case Stream::status_demuxed:
if( p_sys->i_nzpcr != VLC_TS_INVALID )
{
p_sys->i_nzpcr += DEMUX_INCREMENT;
int group = p_sys->p_manager->getGroup();
es_out_Control(p_demux->out, ES_OUT_SET_GROUP_PCR, group, VLC_TS_0 + p_sys->i_nzpcr);
}
break;
}
if( !p_sys->p_manager->updatePlaylist() )
msg_Warn(p_demux, "Can't update playlist");
return VLC_DEMUXER_SUCCESS; delete p_manager;
}
static int Control (demux_t *p_demux, int i_query, va_list args)
{
demux_sys_t *p_sys = p_demux->p_sys;
switch (i_query)
{
case DEMUX_CAN_SEEK:
*(va_arg (args, bool *)) = p_sys->p_manager->seekAble();
break;
case DEMUX_CAN_CONTROL_PACE:
*(va_arg (args, bool *)) = true;
break;
case DEMUX_CAN_PAUSE:
*(va_arg (args, bool *)) = p_sys->p_playlist->isLive();
break;
case DEMUX_GET_TIME:
*(va_arg (args, int64_t *)) = p_sys->i_nzpcr;
break;
case DEMUX_GET_LENGTH:
*(va_arg (args, int64_t *)) = p_sys->p_manager->getDuration();
break;
case DEMUX_GET_POSITION:
if(!p_sys->p_manager->getDuration())
return VLC_EGENERIC;
*(va_arg (args, double *)) = (double) p_sys->i_nzpcr
/ p_sys->p_manager->getDuration();
break;
case DEMUX_SET_POSITION:
{
int64_t time = p_sys->p_manager->getDuration() * va_arg(args, double);
if(p_sys->p_playlist->isLive() ||
!p_sys->p_manager->getDuration() ||
!p_sys->p_manager->setPosition(time))
return VLC_EGENERIC;
p_sys->i_nzpcr = VLC_TS_INVALID;
break;
}
case DEMUX_SET_TIME:
{
int64_t time = va_arg(args, int64_t);
if(p_sys->p_playlist->isLive() ||
!p_sys->p_manager->setPosition(time))
return VLC_EGENERIC;
p_sys->i_nzpcr = VLC_TS_INVALID;
break;
}
case DEMUX_GET_PTS_DELAY:
*va_arg (args, int64_t *) = INT64_C(1000) *
var_InheritInteger(p_demux, "network-caching");
break;
default:
return VLC_EGENERIC;
}
return VLC_SUCCESS;
} }
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