Skip to content

Commit

Permalink
ETag / Modified conditioned manifest updates
Browse files Browse the repository at this point in the history
  • Loading branch information
peak3d committed Aug 31, 2017
1 parent ffcb528 commit 5df3ba1
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 27 deletions.
5 changes: 3 additions & 2 deletions src/common/AdaptiveTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ namespace adaptive

void AdaptiveTree::SetFragmentDuration(const AdaptationSet* adp, const Representation* rep, size_t pos, uint64_t timestamp, uint32_t fragmentDuration, uint32_t movie_timescale)
{
if (!has_timeshift_buffer_ || (rep->flags_ & AdaptiveTree::Representation::URLSEGMENTS) != 0)
if (!has_timeshift_buffer_ || !update_parameter_.empty() ||
(rep->flags_ & AdaptiveTree::Representation::URLSEGMENTS) != 0)
return;

//Get a modifiable adaptationset
Expand Down Expand Up @@ -213,7 +214,7 @@ namespace adaptive
}
}
}
else if (manifestUpdateParam == "ETAG")
else if (manifestUpdateParam == "etag")
{
update_parameter_ = manifestUpdateParam;
}
Expand Down
4 changes: 2 additions & 2 deletions src/common/AdaptiveTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ namespace adaptive
std::string language_;
std::string mimeType_;
std::string base_url_;
std::string id;
std::string id_, group_;
std::string codecs_;
std::vector<Representation*> repesentations_;
SPINCACHE<uint32_t> segment_durations_;
Expand Down Expand Up @@ -269,7 +269,7 @@ namespace adaptive
std::vector<Period*> periods_;
std::string manifest_url_, base_url_, base_domain_, update_parameter_;
std::string::size_type update_parameter_pos_;
std::string etag_;
std::string etag_, last_modified_;

/* XML Parsing*/
XML_Parser parser_;
Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ bool adaptive::AdaptiveTree::download(const char* url, const std::map<std::strin
while ((nbRead = file.Read(buf, CHUNKSIZE)) > 0 && ~nbRead && write_data(buf, nbRead));

etag_ = file.GetProperty(ADDON_FILE_PROPERTY_RESPONSE_HEADER, "etag");
last_modified_ = file.GetProperty(ADDON_FILE_PROPERTY_RESPONSE_HEADER, "last-modified");

//download_speed_ = file.GetFileDownloadSpeed();

Expand Down
74 changes: 51 additions & 23 deletions src/parser/DASHTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,9 @@ start(void *data, const char *el, const char **attr)
: stricmp((const char*)*(attr + 1), "text") == 0 ? DASHTree::SUBTITLE
: DASHTree::NOTYPE;
else if (strcmp((const char*)*attr, "id") == 0)
dash->current_adaptationset_->id = (const char*)*(attr + 1);
dash->current_adaptationset_->id_ = (const char*)*(attr + 1);
else if (strcmp((const char*)*attr, "group") == 0)
dash->current_adaptationset_->group_ = (const char*)*(attr + 1);
else if (strcmp((const char*)*attr, "lang") == 0)
dash->current_adaptationset_->language_ = ltranslate((const char*)*(attr + 1));
else if (strcmp((const char*)*attr, "mimeType") == 0)
Expand Down Expand Up @@ -1389,7 +1391,7 @@ void DASHTree::RefreshSegments(Representation *rep, const Segment *seg)
{
last_update_time_ = now;

std::string replaced(update_parameter_);
std::string replaced;
unsigned int nextStartNumber(rep->startNumber_ + rep->segments_.size());

if (~update_parameter_pos_)
Expand All @@ -1408,12 +1410,17 @@ void DASHTree::RefreshSegments(Representation *rep, const Segment *seg)
DASHTree updateTree;
updateTree.manifest_headers_ = manifest_headers_;
if (!~update_parameter_pos_)
updateTree.manifest_headers_["If-None-Match"] = etag_;
{
updateTree.manifest_headers_["If-None-Match"] = "\"" + etag_ + "\"";
if (!last_modified_.empty())
updateTree.manifest_headers_["If-Modified-Since"] = last_modified_;
}

bool someInserted(false);
if (updateTree.open(manifest_url_ + replaced, ""))
{
etag_ = updateTree.etag_;
last_modified_ = updateTree.last_modified_;

std::vector<Period*>::const_iterator bpd(periods_.begin()), epd(periods_.end());
for (std::vector<Period*>::const_iterator bp(updateTree.periods_.begin()), ep(updateTree.periods_.end()); bp != ep && bpd != epd; ++bp, ++bpd)
Expand All @@ -1422,41 +1429,62 @@ void DASHTree::RefreshSegments(Representation *rep, const Segment *seg)
{
//Locate adaptationset
std::vector<AdaptationSet*>::const_iterator bad((*bpd)->adaptationSets_.begin()), ead((*bpd)->adaptationSets_.end());
for (; bad != ead && (*bad)->id != (*ba)->id; ++bad);
for (; bad != ead && ((*bad)->id_ != (*ba)->id_ || (*bad)->group_ != (*ba)->group_); ++bad);
if (bad != ead)
{
for (std::vector<Representation*>::iterator br((*ba)->repesentations_.begin()), er((*ba)->repesentations_.end()); br != er; ++br)
{
//Youtube returns last smallest number in case the requested data is not available
if ((*br)->startNumber_ < nextStartNumber)
if (~update_parameter_pos_ && (*br)->startNumber_ < nextStartNumber)
continue;

//Locate representation
std::vector<Representation*>::const_iterator brd((*bad)->repesentations_.begin()), erd((*bad)->repesentations_.end());
for (; brd != erd && (*brd)->id != (*br)->id; ++brd);
if (brd != erd && !(*br)->segments_.empty())
{
//Here we go -> Insert new segments
uint64_t ptsOffset = (*brd)->nextPts_ - (*br)->segments_[0]->startPTS_;
unsigned int repFreeSegments(freeSegments);
std::vector<Segment>::iterator bs((*br)->segments_.data.begin()), es((*br)->segments_.data.end());
for (; bs != es && repFreeSegments; ++bs)
if (~update_parameter_pos_) // partitial update
{
//Here we go -> Insert new segments
uint64_t ptsOffset = (*brd)->nextPts_ - (*br)->segments_[0]->startPTS_;
unsigned int repFreeSegments(freeSegments);
std::vector<Segment>::iterator bs((*br)->segments_.data.begin()), es((*br)->segments_.data.end());
for (; bs != es && repFreeSegments; ++bs)
{
Log(LOGLEVEL_DEBUG, "DASH Update: insert repid: %s url: %s", (*br)->id.c_str(), bs->url);
if ((*brd)->flags_ & Representation::URLSEGMENTS)
delete[](*brd)->segments_[0]->url;
bs->startPTS_ += ptsOffset;
(*brd)->segments_.insert(*bs);
if ((*brd)->flags_ & Representation::URLSEGMENTS)
bs->url = nullptr;
++(*brd)->startNumber_;
--repFreeSegments;
someInserted = true;
}
if (bs == es)
(*brd)->nextPts_ += (*br)->nextPts_;
else
(*brd)->nextPts_ += bs->startPTS_;
}
else //Full update, be careful with startnumbers!
{
Log(LOGLEVEL_DEBUG, "DASH Update: insert repid: %s url: %s", (*br)->id.c_str(), bs->url);
if ((*brd)->flags_ & Representation::URLSEGMENTS)
delete[](*brd)->segments_[0]->url;
bs->startPTS_ += ptsOffset;
(*brd)->segments_.insert(*bs);
if ((*brd)->flags_ & Representation::URLSEGMENTS)
bs->url = nullptr;
++(*brd)->startNumber_;
--repFreeSegments;
(*br)->segments_.swap((*brd)->newSegments_);
(*brd)->newStartNumber_ = (*brd)->startNumber_;
if (!(*brd)->newSegments_.empty())
{
uint64_t searchPts = (*brd)->newSegments_[0]->startPTS_;
for (const auto &s : (*brd)->segments_.data)
{
if (s.startPTS_ >= searchPts)
break;
++(*brd)->newStartNumber_;
}
}
Log(LOGLEVEL_DEBUG, "DASH Full update: repid: %s current_start:%u, new_start:%u",
(*br)->id.c_str(), (*brd)->startNumber_, (*brd)->newStartNumber_);
someInserted = true;
}
if (bs == es)
(*brd)->nextPts_ += (*br)->nextPts_;
else
(*brd)->nextPts_ += bs->startPTS_;
}
}
}
Expand Down

0 comments on commit 5df3ba1

Please sign in to comment.