Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
76bbbcfc
Commit
76bbbcfc
authored
Sep 21, 2015
by
Francois Cartegnie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
demux: hls: move updates to local playlists with lazy loading
parent
f8af0beb
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
96 additions
and
113 deletions
+96
-113
modules/demux/adaptative/PlaylistManager.cpp
modules/demux/adaptative/PlaylistManager.cpp
+5
-2
modules/demux/adaptative/SegmentTracker.cpp
modules/demux/adaptative/SegmentTracker.cpp
+9
-2
modules/demux/adaptative/SegmentTracker.hpp
modules/demux/adaptative/SegmentTracker.hpp
+1
-0
modules/demux/adaptative/Streams.cpp
modules/demux/adaptative/Streams.cpp
+6
-0
modules/demux/adaptative/Streams.hpp
modules/demux/adaptative/Streams.hpp
+1
-0
modules/demux/adaptative/playlist/BaseRepresentation.cpp
modules/demux/adaptative/playlist/BaseRepresentation.cpp
+5
-0
modules/demux/adaptative/playlist/BaseRepresentation.h
modules/demux/adaptative/playlist/BaseRepresentation.h
+2
-1
modules/demux/adaptative/playlist/SegmentInformation.cpp
modules/demux/adaptative/playlist/SegmentInformation.cpp
+1
-1
modules/demux/adaptative/playlist/SegmentInformation.hpp
modules/demux/adaptative/playlist/SegmentInformation.hpp
+2
-2
modules/demux/hls/HLSManager.cpp
modules/demux/hls/HLSManager.cpp
+0
-83
modules/demux/hls/HLSManager.hpp
modules/demux/hls/HLSManager.hpp
+0
-1
modules/demux/hls/playlist/Parser.cpp
modules/demux/hls/playlist/Parser.cpp
+4
-5
modules/demux/hls/playlist/Parser.hpp
modules/demux/hls/playlist/Parser.hpp
+1
-1
modules/demux/hls/playlist/Representation.cpp
modules/demux/hls/playlist/Representation.cpp
+53
-13
modules/demux/hls/playlist/Representation.hpp
modules/demux/hls/playlist/Representation.hpp
+6
-2
No files found.
modules/demux/adaptative/PlaylistManager.cpp
View file @
76bbbcfc
...
...
@@ -269,6 +269,10 @@ bool PlaylistManager::seekAble() const
bool
PlaylistManager
::
updatePlaylist
()
{
std
::
vector
<
Stream
*>::
const_iterator
it
;
for
(
it
=
streams
.
begin
();
it
!=
streams
.
end
();
++
it
)
(
*
it
)
->
runUpdates
();
return
true
;
}
...
...
@@ -313,8 +317,7 @@ int PlaylistManager::doDemux(int64_t increment)
break
;
}
if
(
!
updatePlaylist
()
)
msg_Warn
(
p_demux
,
"Can't update MPD"
);
updatePlaylist
();
return
VLC_DEMUXER_SUCCESS
;
}
...
...
modules/demux/adaptative/SegmentTracker.cpp
View file @
76bbbcfc
...
...
@@ -85,8 +85,9 @@ SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed)
initializing
=
true
;
}
/* Ensure content is loaded */
rep
->
runLocalUpdates
();
/* Ensure ephemere content is updated/loaded */
if
(
rep
->
needsUpdate
())
updateSelected
();
/* If we're starting, set the first segment number to download */
if
(
!
sequence_set
)
...
...
@@ -168,3 +169,9 @@ void SegmentTracker::pruneFromCurrent()
if
(
playlist
->
isLive
()
&&
sequence_set
)
playlist
->
pruneBySegmentNumber
(
count
);
}
void
SegmentTracker
::
updateSelected
()
{
if
(
prevRepresentation
)
prevRepresentation
->
runLocalUpdates
(
getSegmentStart
(),
count
);
}
modules/demux/adaptative/SegmentTracker.hpp
View file @
76bbbcfc
...
...
@@ -56,6 +56,7 @@ namespace adaptative
bool
setPosition
(
mtime_t
,
bool
,
bool
);
mtime_t
getSegmentStart
()
const
;
void
pruneFromCurrent
();
void
updateSelected
();
private:
bool
initializing
;
...
...
modules/demux/adaptative/Streams.cpp
View file @
76bbbcfc
...
...
@@ -313,3 +313,9 @@ void Stream::prune()
{
segmentTracker
->
pruneFromCurrent
();
}
void
Stream
::
runUpdates
()
{
if
(
!
isDisabled
())
segmentTracker
->
updateSelected
();
}
modules/demux/adaptative/Streams.hpp
View file @
76bbbcfc
...
...
@@ -83,6 +83,7 @@ namespace adaptative
bool
setPosition
(
mtime_t
,
bool
);
mtime_t
getPosition
()
const
;
void
prune
();
void
runUpdates
();
private:
SegmentChunk
*
getChunk
();
...
...
modules/demux/adaptative/playlist/BaseRepresentation.cpp
View file @
76bbbcfc
...
...
@@ -71,6 +71,11 @@ void BaseRepresentation::addCodec(const std::string &codec)
codecs
.
push_back
(
codec
);
}
bool
BaseRepresentation
::
needsUpdate
()
const
{
return
false
;
}
void
BaseRepresentation
::
debug
(
vlc_object_t
*
obj
,
int
indent
)
const
{
std
::
string
text
(
indent
,
' '
);
...
...
modules/demux/adaptative/playlist/BaseRepresentation.h
View file @
76bbbcfc
...
...
@@ -58,8 +58,9 @@ namespace adaptative
void
setBandwidth
(
uint64_t
bandwidth
);
const
std
::
list
<
std
::
string
>
&
getCodecs
()
const
;
void
addCodec
(
const
std
::
string
&
);
virtual
bool
needsUpdate
()
const
;
v
oid
debug
(
vlc_object_t
*
,
int
=
0
)
const
;
v
irtual
void
debug
(
vlc_object_t
*
,
int
=
0
)
const
;
/* for segment templates */
virtual
std
::
string
contextualize
(
size_t
,
const
std
::
string
&
,
...
...
modules/demux/adaptative/playlist/SegmentInformation.cpp
View file @
76bbbcfc
...
...
@@ -328,7 +328,7 @@ void SegmentInformation::pruneBySegmentNumber(uint64_t num)
childs
.
at
(
i
)
->
pruneBySegmentNumber
(
num
);
}
void
SegmentInformation
::
runLocalUpdates
()
void
SegmentInformation
::
runLocalUpdates
(
mtime_t
,
uint64_t
)
{
}
...
...
modules/demux/adaptative/playlist/SegmentInformation.hpp
View file @
76bbbcfc
...
...
@@ -81,10 +81,10 @@ namespace adaptative
ISegment
*
getSegment
(
SegmentInfoType
,
uint64_t
=
0
)
const
;
bool
getSegmentNumberByTime
(
mtime_t
,
uint64_t
*
)
const
;
mtime_t
getPlaybackTimeBySegmentNumber
(
uint64_t
)
const
;
void
getDurationsRange
(
mtime_t
*
,
mtime_t
*
)
const
;
v
irtual
v
oid
getDurationsRange
(
mtime_t
*
,
mtime_t
*
)
const
;
virtual
void
mergeWith
(
SegmentInformation
*
,
mtime_t
);
virtual
void
pruneBySegmentNumber
(
uint64_t
);
virtual
void
runLocalUpdates
();
virtual
void
runLocalUpdates
(
mtime_t
,
uint64_t
);
protected:
std
::
size_t
getAllSegments
(
std
::
vector
<
ISegment
*>
&
)
const
;
...
...
modules/demux/hls/HLSManager.cpp
View file @
76bbbcfc
...
...
@@ -122,86 +122,3 @@ AbstractAdaptationLogic *HLSManager::createLogic(AbstractAdaptationLogic::LogicT
return
PlaylistManager
::
createLogic
(
type
);
}
}
bool
HLSManager
::
updatePlaylist
()
{
if
(
!
playlist
->
isLive
()
||
!
playlist
->
minUpdatePeriod
.
Get
())
return
true
;
time_t
now
=
time
(
NULL
);
if
(
nextPlaylistupdate
&&
now
<
nextPlaylistupdate
)
return
true
;
M3U8
*
updatedplaylist
=
NULL
;
/* do update */
if
(
nextPlaylistupdate
)
{
std
::
string
url
(
p_demux
->
psz_access
);
url
.
append
(
"://"
);
url
.
append
(
p_demux
->
psz_location
);
uint8_t
*
p_data
=
NULL
;
size_t
i_data
=
Retrieve
::
HTTP
(
VLC_OBJECT
(
p_demux
->
s
),
url
,
(
void
**
)
&
p_data
);
if
(
!
p_data
)
return
false
;
stream_t
*
updatestream
=
stream_MemoryNew
(
p_demux
->
s
,
p_data
,
i_data
,
false
);
if
(
!
updatestream
)
{
free
(
p_data
);
nextPlaylistupdate
=
now
+
playlist
->
minUpdatePeriod
.
Get
()
/
CLOCK_FREQ
;
return
false
;
}
M3U8Parser
parser
;
updatedplaylist
=
parser
.
parse
(
updatestream
,
url
);
if
(
!
updatedplaylist
)
{
stream_Delete
(
updatestream
);
nextPlaylistupdate
=
now
+
playlist
->
minUpdatePeriod
.
Get
()
/
CLOCK_FREQ
;
return
false
;
}
stream_Delete
(
updatestream
);
}
/* Compute new MPD update time */
mtime_t
mininterval
=
0
;
mtime_t
maxinterval
=
0
;
if
(
updatedplaylist
)
{
updatedplaylist
->
getPlaylistDurationsRange
(
&
mininterval
,
&
maxinterval
);
playlist
->
mergeWith
(
updatedplaylist
);
playlist
->
debug
();
delete
updatedplaylist
;
/* pruning */
std
::
vector
<
Stream
*>::
iterator
it
;
for
(
it
=
streams
.
begin
();
it
!=
streams
.
end
();
++
it
)
{
(
*
it
)
->
prune
();
}
}
else
{
playlist
->
getPlaylistDurationsRange
(
&
mininterval
,
&
maxinterval
);
}
if
(
playlist
->
minUpdatePeriod
.
Get
()
>
mininterval
)
mininterval
=
playlist
->
minUpdatePeriod
.
Get
();
if
(
mininterval
<
5
*
CLOCK_FREQ
)
mininterval
=
5
*
CLOCK_FREQ
;
if
(
maxinterval
<
mininterval
)
maxinterval
=
mininterval
;
nextPlaylistupdate
=
now
+
(
mininterval
+
(
maxinterval
-
mininterval
)
/
2
)
/
CLOCK_FREQ
;
msg_Dbg
(
p_demux
,
"Updated playlist, next update in %"
PRId64
"s (""%"
PRId64
"..%"
PRId64
")"
,
nextPlaylistupdate
-
now
,
mininterval
/
CLOCK_FREQ
,
maxinterval
/
CLOCK_FREQ
);
return
true
;
}
modules/demux/hls/HLSManager.hpp
View file @
76bbbcfc
...
...
@@ -36,7 +36,6 @@ namespace hls
logic
::
AbstractAdaptationLogic
::
LogicType
type
);
virtual
~
HLSManager
();
virtual
AbstractAdaptationLogic
*
createLogic
(
AbstractAdaptationLogic
::
LogicType
);
virtual
bool
updatePlaylist
();
static
bool
isHTTPLiveStreaming
(
stream_t
*
);
};
...
...
modules/demux/hls/playlist/Parser.cpp
View file @
76bbbcfc
...
...
@@ -148,7 +148,7 @@ void M3U8Parser::createAndFillRepresentation(vlc_object_t *p_obj, BaseAdaptation
}
}
bool
M3U8Parser
::
loa
dSegmentsFromPlaylistURI
(
vlc_object_t
*
p_obj
,
Representation
*
rep
)
bool
M3U8Parser
::
appen
dSegmentsFromPlaylistURI
(
vlc_object_t
*
p_obj
,
Representation
*
rep
)
{
void
*
p_data
;
const
size_t
i_data
=
Retrieve
::
HTTP
(
p_obj
,
rep
->
getPlaylistUrl
().
toString
(),
&
p_data
);
...
...
@@ -172,9 +172,9 @@ bool M3U8Parser::loadSegmentsFromPlaylistURI(vlc_object_t *p_obj, Representation
void
M3U8Parser
::
parseSegments
(
vlc_object_t
*
p_obj
,
Representation
*
rep
,
const
std
::
list
<
Tag
*>
&
tagslist
)
{
SegmentList
*
segmentList
=
new
(
std
::
nothrow
)
SegmentList
(
rep
);
rep
->
setSegmentList
(
segmentList
);
rep
->
timescale
.
Set
(
100
);
rep
->
b_loaded
=
true
;
stime_t
totalduration
=
0
;
stime_t
nzStartTime
=
0
;
...
...
@@ -308,8 +308,9 @@ void M3U8Parser::parseSegments(vlc_object_t *p_obj, Representation *rep, const s
{
rep
->
getPlaylist
()
->
duration
.
Set
(
totalduration
*
CLOCK_FREQ
/
rep
->
timescale
.
Get
());
}
}
rep
->
setSegmentList
(
segmentList
);
}
M3U8
*
M3U8Parser
::
parse
(
stream_t
*
p_stream
,
const
std
::
string
&
playlisturl
)
{
char
*
psz_line
=
stream_ReadLine
(
p_stream
);
...
...
@@ -368,7 +369,6 @@ M3U8 * M3U8Parser::parse(stream_t *p_stream, const std::string &playlisturl)
if
(
rep
)
{
adaptSet
->
addRepresentation
(
rep
);
loadSegmentsFromPlaylistURI
(
VLC_OBJECT
(
p_stream
),
rep
);
}
}
}
...
...
@@ -391,7 +391,6 @@ M3U8 * M3U8Parser::parse(stream_t *p_stream, const std::string &playlisturl)
if
(
rep
)
{
altAdaptSet
->
addRepresentation
(
rep
);
loadSegmentsFromPlaylistURI
(
VLC_OBJECT
(
p_stream
),
rep
);
}
if
(
pair
.
second
->
getAttributeByName
(
"NAME"
))
...
...
modules/demux/hls/playlist/Parser.hpp
View file @
76bbbcfc
...
...
@@ -60,7 +60,7 @@ namespace hls
virtual
~
M3U8Parser
();
M3U8
*
parse
(
stream_t
*
p_stream
,
const
std
::
string
&
);
bool
loa
dSegmentsFromPlaylistURI
(
vlc_object_t
*
,
Representation
*
);
bool
appen
dSegmentsFromPlaylistURI
(
vlc_object_t
*
,
Representation
*
);
private:
Representation
*
createRepresentation
(
BaseAdaptationSet
*
,
const
AttributesTag
*
);
...
...
modules/demux/hls/playlist/Representation.cpp
View file @
76bbbcfc
...
...
@@ -25,6 +25,7 @@
#include "Representation.hpp"
#include "M3U8.hpp"
#include "Parser.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include "../adaptative/playlist/SegmentList.h"
...
...
@@ -37,7 +38,9 @@ Representation::Representation ( BaseAdaptationSet *set ) :
BaseRepresentation
(
set
)
{
b_live
=
true
;
b_loaded
=
false
;
switchpolicy
=
SegmentInformation
::
SWITCH_SEGMENT_ALIGNED
;
/* FIXME: based on streamformat */
nextPlaylistupdate
=
0
;
}
Representation
::~
Representation
()
...
...
@@ -77,24 +80,61 @@ Url Representation::getPlaylistUrl() const
}
}
void
Representation
::
localMergeWithPlaylist
(
M3U8
*
updated
,
mtime_t
prunebarrier
)
void
Representation
::
debug
(
vlc_object_t
*
obj
,
int
indent
)
const
{
BasePeriod
*
period
=
updated
->
getFirstPeriod
();
if
(
!
period
)
return
;
BaseRepresentation
::
debug
(
obj
,
indent
);
if
(
!
b_loaded
)
{
std
::
string
text
(
indent
+
1
,
' '
);
text
.
append
(
" (not loaded)"
);
msg_Dbg
(
obj
,
"%s"
,
text
.
c_str
());
}
}
BaseAdaptationSet
*
adapt
=
period
->
getAdaptationSets
().
front
();
if
(
!
adapt
)
return
;
bool
Representation
::
needsUpdate
()
const
{
return
true
;
}
BaseRepresentation
*
rep
=
adapt
->
getRepresentations
().
front
();
if
(
!
rep
)
return
;
void
Representation
::
runLocalUpdates
(
mtime_t
/*currentplaybacktime*/
,
uint64_t
number
)
{
const
time_t
now
=
time
(
NULL
);
const
AbstractPlaylist
*
playlist
=
getPlaylist
();
if
(
!
b_loaded
||
(
isLive
()
&&
nextPlaylistupdate
<
now
))
{
M3U8Parser
parser
;
parser
.
appendSegmentsFromPlaylistURI
(
playlist
->
getVLCObject
(),
this
);
b_loaded
=
true
;
this
->
mergeWith
(
rep
,
prunebarrier
);
pruneBySegmentNumber
(
number
);
/* Compute new update time */
mtime_t
mininterval
=
0
;
mtime_t
maxinterval
=
0
;
getDurationsRange
(
&
mininterval
,
&
maxinterval
);
if
(
playlist
->
minUpdatePeriod
.
Get
()
>
mininterval
)
mininterval
=
playlist
->
minUpdatePeriod
.
Get
();
if
(
mininterval
<
5
*
CLOCK_FREQ
)
mininterval
=
5
*
CLOCK_FREQ
;
if
(
maxinterval
<
mininterval
)
maxinterval
=
mininterval
;
nextPlaylistupdate
=
now
+
(
mininterval
+
(
maxinterval
-
mininterval
)
/
2
)
/
CLOCK_FREQ
;
msg_Dbg
(
playlist
->
getVLCObject
(),
"Updated playlist ID %s, next update in %"
PRId64
"s"
,
getID
().
str
().
c_str
(),
nextPlaylistupdate
-
now
);
debug
(
playlist
->
getVLCObject
(),
0
);
}
}
void
Representation
::
mergeWith
(
SegmentInformation
*
seginfo
,
mtime_t
prunebarrier
)
void
Representation
::
getDurationsRange
(
mtime_t
*
min
,
mtime_t
*
max
)
const
{
BaseRepresentation
::
mergeWith
(
seginfo
,
prunebarrier
);
if
(
!
b_loaded
)
return
;
BaseRepresentation
::
getDurationsRange
(
min
,
max
);
}
modules/demux/hls/playlist/Representation.hpp
View file @
76bbbcfc
...
...
@@ -44,12 +44,16 @@ namespace hls
void
setPlaylistUrl
(
const
std
::
string
&
);
Url
getPlaylistUrl
()
const
;
void
localMergeWithPlaylist
(
M3U8
*
,
mtime_t
);
bool
isLive
()
const
;
virtual
void
mergeWith
(
SegmentInformation
*
,
mtime_t
);
/* reimpl */
virtual
bool
needsUpdate
()
const
;
/* reimpl */
virtual
void
debug
(
vlc_object_t
*
,
int
)
const
;
/* reimpl */
virtual
void
runLocalUpdates
(
mtime_t
,
uint64_t
);
/* reimpl */
virtual
void
getDurationsRange
(
mtime_t
*
,
mtime_t
*
)
const
;
/* reimpl */
private:
bool
b_live
;
bool
b_loaded
;
mtime_t
nextPlaylistupdate
;
Url
playlistUrl
;
Property
<
std
::
string
>
audio
;
Property
<
std
::
string
>
video
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment