Commit ed2fe051 authored by Francois Cartegnie's avatar Francois Cartegnie

demux: adaptative: restart on seek

parent f801e7d7
......@@ -54,7 +54,7 @@ void SegmentTracker::resetCounter()
prevRepresentation = NULL;
}
Chunk * SegmentTracker::getNextChunk(StreamType type)
Chunk * SegmentTracker::getNextChunk(StreamType type, bool switch_allowed)
{
BaseRepresentation *rep;
ISegment *segment;
......@@ -62,7 +62,8 @@ Chunk * SegmentTracker::getNextChunk(StreamType type)
if(!currentPeriod)
return NULL;
if(prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE)
if( !switch_allowed ||
(prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) )
rep = prevRepresentation;
else
rep = logic->getCurrentRepresentation(type, currentPeriod);
......@@ -97,7 +98,7 @@ Chunk * SegmentTracker::getNextChunk(StreamType type)
{
currentPeriod = playlist->getNextPeriod(currentPeriod);
resetCounter();
return getNextChunk(type);
return getNextChunk(type, switch_allowed);
}
Chunk *chunk = segment->toChunk(count, rep);
......
......@@ -58,7 +58,7 @@ namespace adaptative
void setAdaptationLogic(AbstractAdaptationLogic *);
void resetCounter();
Chunk* getNextChunk(StreamType);
Chunk* getNextChunk(StreamType, bool);
bool setPosition(mtime_t, bool, bool);
mtime_t getSegmentStart() const;
void pruneFromCurrent();
......
......@@ -127,7 +127,7 @@ Chunk * Stream::getChunk()
{
if (currentChunk == NULL)
{
currentChunk = segmentTracker->getNextChunk(type);
currentChunk = segmentTracker->getNextChunk(type, output->switchAllowed());
if (currentChunk == NULL)
eof = true;
}
......@@ -280,6 +280,7 @@ BaseStreamOutput::BaseStreamOutput(demux_t *demux, const std::string &name) :
{
this->name = name;
seekable = true;
restarting = false;
demuxstream = NULL;
fakeesout = new es_out_t;
......@@ -295,7 +296,8 @@ BaseStreamOutput::BaseStreamOutput(demux_t *demux, const std::string &name) :
fakeesout->pf_send = esOutSend;
fakeesout->p_sys = (es_out_sys_t*) this;
if(!restart())
demuxstream = stream_DemuxNew(realdemux, name.c_str(), fakeesout);
if(!demuxstream)
throw VLC_EGENERIC;
}
......@@ -303,14 +305,14 @@ BaseStreamOutput::~BaseStreamOutput()
{
if (demuxstream)
stream_Delete(demuxstream);
delete fakeesout;
vlc_mutex_destroy(&lock);
/* shouldn't be any */
std::list<Demuxed *>::const_iterator it;
for(it=queues.begin(); it!=queues.end();++it)
delete *it;
delete fakeesout;
vlc_mutex_destroy(&lock);
}
int BaseStreamOutput::esCount() const
......@@ -325,7 +327,8 @@ void BaseStreamOutput::pushBlock(block_t *block)
bool BaseStreamOutput::seekAble() const
{
return (demuxstream && seekable);
bool b_canswitch = switchAllowed();
return (demuxstream && seekable && b_canswitch);
}
void BaseStreamOutput::setPosition(mtime_t nztime)
......@@ -353,6 +356,7 @@ bool BaseStreamOutput::restart()
return false;
vlc_mutex_lock(&lock);
restarting = true;
stream_t *olddemuxstream = demuxstream;
demuxstream = newdemuxstream;
vlc_mutex_unlock(&lock);
......@@ -365,7 +369,16 @@ bool BaseStreamOutput::restart()
bool BaseStreamOutput::reinitsOnSeek() const
{
return false;
return true;
}
bool BaseStreamOutput::switchAllowed() const
{
bool b_allowed;
vlc_mutex_lock(const_cast<vlc_mutex_t *>(&lock));
b_allowed = !restarting;
vlc_mutex_unlock(const_cast<vlc_mutex_t *>(&lock));
return b_allowed;
}
void BaseStreamOutput::sendToDecoder(mtime_t nzdeadline)
......@@ -395,15 +408,18 @@ void BaseStreamOutput::sendToDecoderUnlocked(mtime_t nzdeadline)
}
}
BaseStreamOutput::Demuxed::Demuxed()
BaseStreamOutput::Demuxed::Demuxed(es_out_id_t *id, const es_format_t *fmt)
{
p_queue = NULL;
pp_queue_last = &p_queue;
es_id = NULL;
es_id = id;
es_format_Init(&fmtcpy, UNKNOWN_ES, 0);
es_format_Copy(&fmtcpy, fmt);
}
BaseStreamOutput::Demuxed::~Demuxed()
{
es_format_Clean(&fmtcpy);
drop();
}
......@@ -418,18 +434,52 @@ void BaseStreamOutput::Demuxed::drop()
es_out_id_t * BaseStreamOutput::esOutAdd(es_out_t *fakees, const es_format_t *p_fmt)
{
BaseStreamOutput *me = (BaseStreamOutput *) fakees->p_sys;
es_out_id_t *p_es = me->realdemux->out->pf_add(me->realdemux->out, p_fmt);
es_out_id_t *p_es = NULL;
vlc_mutex_lock(&me->lock);
std::list<Demuxed *>::iterator it;
bool b_hasestorecyle = false;
for(it=me->queues.begin(); it!=me->queues.end();++it)
{
Demuxed *pair = *it;
b_hasestorecyle |= pair->recycle;
if( p_es )
continue;
if( me->restarting )
{
/* If we're recycling from same format */
if( es_format_IsSimilar(p_fmt, &pair->fmtcpy) &&
p_fmt->i_extra == pair->fmtcpy.i_extra &&
!memcmp(p_fmt->p_extra, pair->fmtcpy.p_extra, p_fmt->i_extra) )
{
msg_Err(me->realdemux, "using recycled");
pair->recycle = false;
p_es = pair->es_id;
}
}
}
if(!b_hasestorecyle)
{
me->restarting = false;
}
if(!p_es)
{
p_es = me->realdemux->out->pf_add(me->realdemux->out, p_fmt);
if(p_es)
{
vlc_mutex_lock(&me->lock);
Demuxed *pair = new (std::nothrow) Demuxed();
Demuxed *pair = new (std::nothrow) Demuxed(p_es, p_fmt);
if(pair)
{
pair->es_id = p_es;
me->queues.push_back(pair);
}
vlc_mutex_unlock(&me->lock);
}
vlc_mutex_unlock(&me->lock);
return p_es;
}
......@@ -461,13 +511,27 @@ void BaseStreamOutput::esOutDel(es_out_t *fakees, es_out_id_t *p_es)
if((*it)->es_id == p_es)
{
me->sendToDecoderUnlocked(INT64_MAX - VLC_TS_0);
break;
}
}
if(it != me->queues.end())
{
if(me->restarting)
{
(*it)->recycle = true;
}
else
{
delete *it;
me->queues.erase(it);
break;
}
}
vlc_mutex_unlock(&me->lock);
if(!me->restarting)
me->realdemux->out->pf_del(me->realdemux->out, p_es);
vlc_mutex_unlock(&me->lock);
}
int BaseStreamOutput::esOutControl(es_out_t *fakees, int i_query, va_list args)
......@@ -484,6 +548,17 @@ int BaseStreamOutput::esOutControl(es_out_t *fakees, int i_query, va_list args)
me->pcr = (int64_t)va_arg( args, int64_t );
return VLC_SUCCESS;
}
else if( i_query == ES_OUT_GET_ES_STATE )
{
va_arg( args, es_out_id_t * );
bool *pb = va_arg( args, bool * );
*pb = true;
return VLC_SUCCESS;
}
else if( me->restarting )
{
return VLC_EGENERIC;
}
return me->realdemux->out->pf_control(me->realdemux->out, i_query, args);
}
......
......@@ -27,6 +27,7 @@
#include <string>
#include <list>
#include <vlc_common.h>
#include <vlc_es.h>
#include "StreamsType.hpp"
namespace adaptative
......@@ -100,6 +101,7 @@ namespace adaptative
virtual void setPosition(mtime_t) = 0;
virtual void sendToDecoder(mtime_t) = 0;
virtual bool reinitsOnSeek() const = 0;
virtual bool switchAllowed() const = 0;
protected:
demux_t *realdemux;
......@@ -130,12 +132,14 @@ namespace adaptative
virtual void setPosition(mtime_t); /* reimpl */
virtual void sendToDecoder(mtime_t); /* reimpl */
virtual bool reinitsOnSeek() const; /* reimpl */
virtual bool switchAllowed() const; /* reimpl */
protected:
es_out_t *fakeesout; /* to intercept/proxy what is sent from demuxstream */
stream_t *demuxstream;
bool seekable;
std::string name;
bool restarting;
private:
static es_out_id_t *esOutAdd(es_out_t *, const es_format_t *);
......@@ -147,12 +151,14 @@ namespace adaptative
class Demuxed
{
friend class BaseStreamOutput;
Demuxed();
Demuxed(es_out_id_t *, const es_format_t *);
~Demuxed();
void drop();
es_out_id_t *es_id;
block_t *p_queue;
block_t **pp_queue_last;
bool recycle;
es_format_t fmtcpy;
};
std::list<Demuxed *> queues;
vlc_mutex_t lock;
......
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