Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Steve Lhomme
VLC
Commits
a03587d3
Commit
a03587d3
authored
Dec 11, 2014
by
François Cartegnie
🤞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
stream_filter: dash: add support for templates/live profile
parent
070ce589
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
158 additions
and
75 deletions
+158
-75
modules/stream_filter/dash/adaptationlogic/AbstractAdaptationLogic.cpp
...m_filter/dash/adaptationlogic/AbstractAdaptationLogic.cpp
+17
-6
modules/stream_filter/dash/mpd/AdaptationSet.cpp
modules/stream_filter/dash/mpd/AdaptationSet.cpp
+24
-1
modules/stream_filter/dash/mpd/AdaptationSet.h
modules/stream_filter/dash/mpd/AdaptationSet.h
+5
-0
modules/stream_filter/dash/mpd/BasicCMParser.cpp
modules/stream_filter/dash/mpd/BasicCMParser.cpp
+1
-2
modules/stream_filter/dash/mpd/IsoffMainParser.cpp
modules/stream_filter/dash/mpd/IsoffMainParser.cpp
+46
-1
modules/stream_filter/dash/mpd/IsoffMainParser.h
modules/stream_filter/dash/mpd/IsoffMainParser.h
+1
-0
modules/stream_filter/dash/mpd/MPDFactory.cpp
modules/stream_filter/dash/mpd/MPDFactory.cpp
+1
-0
modules/stream_filter/dash/mpd/Representation.cpp
modules/stream_filter/dash/mpd/Representation.cpp
+8
-12
modules/stream_filter/dash/mpd/Representation.h
modules/stream_filter/dash/mpd/Representation.h
+1
-3
modules/stream_filter/dash/mpd/Segment.cpp
modules/stream_filter/dash/mpd/Segment.cpp
+16
-9
modules/stream_filter/dash/mpd/Segment.h
modules/stream_filter/dash/mpd/Segment.h
+2
-2
modules/stream_filter/dash/mpd/SegmentTemplate.cpp
modules/stream_filter/dash/mpd/SegmentTemplate.cpp
+23
-33
modules/stream_filter/dash/mpd/SegmentTemplate.h
modules/stream_filter/dash/mpd/SegmentTemplate.h
+13
-6
No files found.
modules/stream_filter/dash/adaptationlogic/AbstractAdaptationLogic.cpp
View file @
a03587d3
...
...
@@ -56,20 +56,31 @@ Chunk* AbstractAdaptationLogic::getNextChunk(Streams::Type type)
return
NULL
;
std
::
vector
<
ISegment
*>
segments
=
rep
->
getSegments
();
if
(
count
==
segments
.
size
()
)
ISegment
*
first
=
segments
.
empty
()
?
NULL
:
segments
.
front
();
bool
b_templated
=
(
first
&&
!
first
->
isSingleShot
());
if
(
count
==
segments
.
size
()
&&
!
b_templated
)
{
currentPeriod
=
mpd
->
getNextPeriod
(
currentPeriod
);
count
=
0
;
return
getNextChunk
(
type
);
}
ISegment
*
seg
=
NULL
;
if
(
segments
.
size
()
>
count
)
{
ISegment
*
seg
=
segments
.
at
(
count
);
Chunk
*
chunk
=
seg
->
toChunk
();
//In case of UrlTemplate, we must stay on the same segment.
if
(
seg
->
isSingleShot
()
==
true
)
count
++
;
seg
=
segments
.
at
(
count
);
}
else
if
(
b_templated
)
{
seg
=
segments
.
back
();
}
if
(
seg
)
{
Chunk
*
chunk
=
seg
->
toChunk
(
count
,
rep
);
count
++
;
seg
->
done
();
return
chunk
;
}
...
...
modules/stream_filter/dash/mpd/AdaptationSet.cpp
View file @
a03587d3
...
...
@@ -31,6 +31,7 @@
#include <vlc_common.h>
#include <vlc_arrays.h>
#include "SegmentTemplate.h"
#include "SegmentInfoDefault.h"
#include "Period.h"
...
...
@@ -40,7 +41,9 @@ AdaptationSet::AdaptationSet(Period *period) :
ICanonicalUrl
(
period
),
subsegmentAlignmentFlag
(
false
),
segmentInfoDefault
(
NULL
),
isBitstreamSwitching
(
false
)
isBitstreamSwitching
(
false
),
mediaTemplate
(
NULL
),
initTemplate
(
NULL
)
{
}
...
...
@@ -48,6 +51,8 @@ AdaptationSet::~AdaptationSet ()
{
delete
this
->
segmentInfoDefault
;
vlc_delete_all
(
this
->
representations
);
delete
mediaTemplate
;
delete
initTemplate
;
}
const
std
::
string
&
AdaptationSet
::
getMimeType
()
const
...
...
@@ -103,6 +108,24 @@ void AdaptationSet::addRepresentation (Represe
this
->
representations
.
push_back
(
rep
);
}
void
AdaptationSet
::
setTemplates
(
SegmentTemplate
*
media
,
SegmentTemplate
*
init
)
{
mediaTemplate
=
media
;
initTemplate
=
init
;
}
std
::
vector
<
SegmentTemplate
*>
AdaptationSet
::
getTemplates
()
const
{
std
::
vector
<
SegmentTemplate
*>
ret
;
if
(
mediaTemplate
)
{
if
(
initTemplate
)
ret
.
push_back
(
initTemplate
);
ret
.
push_back
(
mediaTemplate
);
}
return
ret
;
}
void
AdaptationSet
::
setBitstreamSwitching
(
bool
value
)
{
this
->
isBitstreamSwitching
=
value
;
...
...
modules/stream_filter/dash/mpd/AdaptationSet.h
View file @
a03587d3
...
...
@@ -39,6 +39,7 @@ namespace dash
{
class
SegmentInfoDefault
;
class
Period
;
class
SegmentTemplate
;
class
AdaptationSet
:
public
CommonAttributesElements
,
public
ICanonicalUrl
{
...
...
@@ -54,6 +55,8 @@ namespace dash
const
SegmentInfoDefault
*
getSegmentInfoDefault
()
const
;
void
setSegmentInfoDefault
(
const
SegmentInfoDefault
*
seg
);
void
setBitstreamSwitching
(
bool
value
);
void
setTemplates
(
SegmentTemplate
*
,
SegmentTemplate
*
=
NULL
);
std
::
vector
<
SegmentTemplate
*>
getTemplates
()
const
;
bool
getBitstreamSwitching
()
const
;
void
addRepresentation
(
Representation
*
rep
);
virtual
Url
getUrlSegment
()
const
;
/* reimpl */
...
...
@@ -63,6 +66,8 @@ namespace dash
std
::
vector
<
Representation
*>
representations
;
const
SegmentInfoDefault
*
segmentInfoDefault
;
bool
isBitstreamSwitching
;
SegmentTemplate
*
mediaTemplate
;
SegmentTemplate
*
initTemplate
;
};
}
}
...
...
modules/stream_filter/dash/mpd/BasicCMParser.cpp
View file @
a03587d3
...
...
@@ -265,7 +265,6 @@ void BasicCMParser::setRepresentations (Node *root, AdaptationSet *group)
const
std
::
map
<
std
::
string
,
std
::
string
>
attributes
=
representations
.
at
(
i
)
->
getAttributes
();
Representation
*
rep
=
new
Representation
(
group
,
getMPD
());
rep
->
setParentGroup
(
group
);
this
->
currentRepresentation
=
rep
;
if
(
this
->
parseCommonAttributesElements
(
representations
.
at
(
i
),
rep
,
group
)
==
false
)
{
...
...
@@ -366,7 +365,7 @@ Segment* BasicCMParser::parseSegment( Node* node, bool init )
msg_Err
(
p_stream
,
"Failed to substitute URLTemplate identifier."
);
return
NULL
;
}
seg
=
new
SegmentTemplate
(
runtimeToken
,
this
->
currentRepresentation
);
seg
=
new
SegmentTemplate
(
currentRepresentation
);
}
else
{
...
...
modules/stream_filter/dash/mpd/IsoffMainParser.cpp
View file @
a03587d3
...
...
@@ -27,10 +27,13 @@
#endif
#include "IsoffMainParser.h"
#include "SegmentTemplate.h"
#include "SegmentInfoDefault.h"
#include "xml/DOMHelper.h"
#include <vlc_strings.h>
#include <vlc_stream.h>
#include <cstdio>
#include <sstream>
using
namespace
dash
::
mpd
;
using
namespace
dash
::
xml
;
...
...
@@ -72,6 +75,45 @@ void IsoffMainParser::setMPDAttributes ()
mpd
->
setType
(
it
->
second
);
}
void
IsoffMainParser
::
parseTemplate
(
Node
*
templateNode
,
AdaptationSet
*
set
)
{
if
(
templateNode
==
NULL
||
!
templateNode
->
hasAttribute
(
"media"
))
return
;
std
::
string
mediaurl
=
templateNode
->
getAttributeValue
(
"media"
);
SegmentTemplate
*
mediaTemplate
=
NULL
;
if
(
mediaurl
.
empty
()
||
!
(
mediaTemplate
=
new
(
std
::
nothrow
)
SegmentTemplate
(
set
))
)
return
;
mediaTemplate
->
setSourceUrl
(
mediaurl
);
if
(
templateNode
->
hasAttribute
(
"startNumber"
))
{
std
::
istringstream
in
(
templateNode
->
getAttributeValue
(
"startNumber"
));
size_t
i
;
in
>>
i
;
mediaTemplate
->
setStartIndex
(
i
);
}
if
(
templateNode
->
hasAttribute
(
"duration"
))
{
std
::
istringstream
in
(
templateNode
->
getAttributeValue
(
"duration"
));
size_t
i
;
in
>>
i
;
mediaTemplate
->
setDuration
(
i
);
}
InitSegmentTemplate
*
initTemplate
=
NULL
;
if
(
templateNode
->
hasAttribute
(
"initialization"
))
{
std
::
string
initurl
=
templateNode
->
getAttributeValue
(
"initialization"
);
if
(
!
initurl
.
empty
()
&&
(
initTemplate
=
new
(
std
::
nothrow
)
InitSegmentTemplate
(
set
)))
initTemplate
->
setSourceUrl
(
initurl
);
}
set
->
setTemplates
(
mediaTemplate
,
initTemplate
);
}
void
IsoffMainParser
::
setAdaptationSets
(
Node
*
periodNode
,
Period
*
period
)
{
std
::
vector
<
Node
*>
adaptationSets
=
DOMHelper
::
getElementByTagName
(
periodNode
,
"AdaptationSet"
,
false
);
...
...
@@ -84,6 +126,9 @@ void IsoffMainParser::setAdaptationSets (Node *periodNode, Period *period)
continue
;
if
((
*
it
)
->
hasAttribute
(
"mimeType"
))
adaptationSet
->
setMimeType
((
*
it
)
->
getAttributeValue
(
"mimeType"
));
parseTemplate
(
DOMHelper
::
getFirstChildElementByName
(
*
it
,
"SegmentTemplate"
),
adaptationSet
);
setRepresentations
((
*
it
),
adaptationSet
);
period
->
addAdaptationSet
(
adaptationSet
);
}
...
...
@@ -122,7 +167,7 @@ void IsoffMainParser::setRepresentations (Node *adaptationSetNode, Adaptation
setSegmentBase
(
segmentBase
,
currentRepresentation
);
setSegmentList
(
segmentList
,
currentRepresentation
);
if
(
segmentBase
.
empty
()
&&
segmentList
.
empty
())
if
(
segmentBase
.
empty
()
&&
segmentList
.
empty
()
&&
adaptationSet
->
getTemplates
().
empty
()
)
{
/* unranged & segment less representation, add fake segment */
SegmentList
*
list
=
new
SegmentList
();
...
...
modules/stream_filter/dash/mpd/IsoffMainParser.h
View file @
a03587d3
...
...
@@ -57,6 +57,7 @@ namespace dash
void
setSegmentList
(
std
::
vector
<
xml
::
Node
*>
&
,
Representation
*
rep
);
void
setInitSegment
(
dash
::
xml
::
Node
*
segBaseNode
,
SegmentBase
*
base
);
void
setSegments
(
dash
::
xml
::
Node
*
segListNode
,
SegmentList
*
list
);
void
parseTemplate
(
dash
::
xml
::
Node
*
templateNode
,
AdaptationSet
*
);
};
}
}
...
...
modules/stream_filter/dash/mpd/MPDFactory.cpp
View file @
a03587d3
...
...
@@ -42,6 +42,7 @@ MPD* MPDFactory::create (dash::xml::Node *root, stream_t *p_stream,
break
;
case
Profile
::
ISOOnDemand
:
case
Profile
::
ISOMain
:
case
Profile
::
ISOLive
:
parser
=
new
IsoffMainParser
(
root
,
p_stream
);
default:
break
;
...
...
modules/stream_filter/dash/mpd/Representation.cpp
View file @
a03587d3
...
...
@@ -30,17 +30,18 @@
#include "Representation.h"
#include "mpd/AdaptationSet.h"
#include "mpd/MPD.h"
#include "mpd/SegmentTemplate.h"
using
namespace
dash
::
mpd
;
Representation
::
Representation
(
AdaptationSet
*
set
,
MPD
*
mpd_
)
:
ICanonicalUrl
(
set
),
mpd
(
mpd_
),
adaptationSet
(
set
),
bandwidth
(
0
),
qualityRanking
(
-
1
),
segmentInfo
(
NULL
),
trickModeType
(
NULL
),
parentGroup
(
NULL
),
segmentBase
(
NULL
),
segmentList
(
NULL
),
baseUrl
(
NULL
),
...
...
@@ -94,17 +95,6 @@ void Representation::setTrickMode (TrickModeType *trickMod
this
->
trickModeType
=
trickModeType
;
}
const
AdaptationSet
*
Representation
::
getParentGroup
()
const
{
return
this
->
parentGroup
;
}
void
Representation
::
setParentGroup
(
const
AdaptationSet
*
group
)
{
if
(
group
!=
NULL
)
this
->
parentGroup
=
group
;
}
void
Representation
::
setSegmentInfo
(
SegmentInfo
*
info
)
{
this
->
segmentInfo
=
info
;
...
...
@@ -171,6 +161,12 @@ std::vector<ISegment *> Representation::getSegments() const
}
}
if
(
retSegments
.
empty
())
{
std
::
vector
<
SegmentTemplate
*>
list
=
adaptationSet
->
getTemplates
();
retSegments
.
insert
(
retSegments
.
end
(),
list
.
begin
(),
list
.
end
()
);
}
return
retSegments
;
}
...
...
modules/stream_filter/dash/mpd/Representation.h
View file @
a03587d3
...
...
@@ -73,8 +73,6 @@ namespace dash
void
setSegmentInfo
(
SegmentInfo
*
info
);
void
setTrickMode
(
TrickModeType
*
trickModeType
);
const
AdaptationSet
*
getParentGroup
()
const
;
void
setParentGroup
(
const
AdaptationSet
*
group
);
std
::
vector
<
ISegment
*>
getSegments
()
const
;
void
setSegmentList
(
SegmentList
*
list
);
...
...
@@ -99,13 +97,13 @@ namespace dash
private:
MPD
*
mpd
;
AdaptationSet
*
adaptationSet
;
uint64_t
bandwidth
;
std
::
string
id
;
int
qualityRanking
;
std
::
list
<
const
Representation
*>
dependencies
;
SegmentInfo
*
segmentInfo
;
TrickModeType
*
trickModeType
;
const
AdaptationSet
*
parentGroup
;
SegmentBase
*
segmentBase
;
SegmentList
*
segmentList
;
BaseUrl
*
baseUrl
;
...
...
modules/stream_filter/dash/mpd/Segment.cpp
View file @
a03587d3
...
...
@@ -53,12 +53,12 @@ dash::http::Chunk * ISegment::getChunk(const std::string &url)
return
new
(
std
::
nothrow
)
SegmentChunk
(
this
,
url
);
}
dash
::
http
::
Chunk
*
ISegment
::
toChunk
()
dash
::
http
::
Chunk
*
ISegment
::
toChunk
(
size_t
index
,
const
Representation
*
ctxrep
)
{
Chunk
*
chunk
;
try
{
chunk
=
getChunk
(
getUrlSegment
());
chunk
=
getChunk
(
getUrlSegment
()
.
toString
(
index
,
ctxrep
)
);
if
(
!
chunk
)
return
NULL
;
}
...
...
@@ -149,12 +149,19 @@ void ISegment::SegmentChunk::onDownload(void *, size_t)
}
Segment
::
Segment
(
ICanonicalUrl
*
parent
)
:
ISegment
(
parent
),
parentRepresentation
(
NULL
)
{
size
=
-
1
;
classId
=
CLASSID_SEGMENT
;
}
Segment
::
Segment
(
Representation
*
parent
)
:
ISegment
(
parent
),
parentRepresentation
(
parent
)
{
assert
(
parent
!=
NULL
);
if
(
parent
->
getSegmentInfo
()
!=
NULL
&&
parent
->
getSegmentInfo
()
->
getDuration
()
>=
0
)
if
(
parent
&&
parent
->
getSegmentInfo
()
!=
NULL
&&
parent
->
getSegmentInfo
()
->
getDuration
()
>=
0
)
this
->
size
=
parent
->
getBandwidth
()
*
parent
->
getSegmentInfo
()
->
getDuration
();
else
this
->
size
=
-
1
;
...
...
@@ -203,18 +210,18 @@ std::string Segment::toString() const
}
}
std
::
string
Segment
::
getUrlSegment
()
const
Url
Segment
::
getUrlSegment
()
const
{
std
::
string
ret
=
getParentUrlSegment
();
Url
ret
=
getParentUrlSegment
();
if
(
!
sourceUrl
.
empty
())
ret
.
append
(
sourceUrl
);
return
ret
;
}
dash
::
http
::
Chunk
*
Segment
::
toChunk
()
dash
::
http
::
Chunk
*
Segment
::
toChunk
(
size_t
index
,
const
Representation
*
ctxrep
)
{
Chunk
*
chunk
=
ISegment
::
toChunk
();
if
(
chunk
)
Chunk
*
chunk
=
ISegment
::
toChunk
(
index
,
ctxrep
);
if
(
chunk
&&
parentRepresentation
)
chunk
->
setBitrate
(
parentRepresentation
->
getBandwidth
());
return
chunk
;
}
...
...
modules/stream_filter/dash/mpd/Segment.h
View file @
a03587d3
...
...
@@ -51,7 +51,7 @@ namespace dash
*/
virtual
bool
isSingleShot
()
const
;
virtual
void
done
();
virtual
dash
::
http
::
Chunk
*
toChunk
();
virtual
dash
::
http
::
Chunk
*
toChunk
(
size_t
,
const
Representation
*
=
NULL
);
virtual
void
setByteRange
(
size_t
start
,
size_t
end
);
virtual
void
setStartTime
(
mtime_t
ztime
);
virtual
mtime_t
getStartTime
()
const
;
...
...
@@ -95,7 +95,7 @@ namespace dash
~
Segment
();
virtual
void
setSourceUrl
(
const
std
::
string
&
url
);
virtual
Url
getUrlSegment
()
const
;
/* impl */
virtual
dash
::
http
::
Chunk
*
toChunk
();
virtual
dash
::
http
::
Chunk
*
toChunk
(
size_t
,
const
Representation
*
=
NULL
);
virtual
std
::
vector
<
ISegment
*>
subSegments
();
virtual
Representation
*
getRepresentation
()
const
;
virtual
std
::
string
toString
()
const
;
...
...
modules/stream_filter/dash/mpd/SegmentTemplate.cpp
View file @
a03587d3
...
...
@@ -32,43 +32,32 @@
using
namespace
dash
::
mpd
;
SegmentTemplate
::
SegmentTemplate
(
bool
containRuntimeIdentifier
,
Representation
*
representation
)
:
Segment
(
representation
),
containRuntimeIdentifier
(
containRuntimeIdentifier
),
currentSegmentIndex
(
0
)
SegmentTemplate
::
SegmentTemplate
(
ICanonicalUrl
*
parent
)
:
Segment
(
parent
),
startIndex
(
0
)
{
debugName
=
"SegmentTemplate"
;
classId
=
Segment
::
CLASSID_SEGMENT
;
}
std
::
string
SegmentTemplate
::
getUrlSegment
()
const
Url
SegmentTemplate
::
getUrlSegment
()
const
{
std
::
string
res
=
Segment
::
getUrlSegment
();
if
(
!
containRuntimeIdentifier
)
return
res
;
size_t
beginTime
=
res
.
find
(
"$Time$"
);
// size_t beginIndex = res.find( "$Index$" );
if
(
beginTime
!=
std
::
string
::
npos
)
Url
ret
=
getParentUrlSegment
();
if
(
!
sourceUrl
.
empty
())
{
//FIXME: This should use the current representation SegmentInfo
//which "inherits" the SegmentInfoDefault values.
if
(
parentRepresentation
->
getParentGroup
()
->
getSegmentInfoDefault
()
!=
NULL
&&
parentRepresentation
->
getParentGroup
()
->
getSegmentInfoDefault
()
->
getSegmentTimeline
()
!=
NULL
)
{
const
SegmentTimeline
::
Element
*
el
=
parentRepresentation
->
getParentGroup
()
->
getSegmentInfoDefault
()
->
getSegmentTimeline
()
->
getElement
(
currentSegmentIndex
);
if
(
el
!=
NULL
)
{
std
::
ostringstream
oss
;
oss
<<
el
->
t
;
res
.
replace
(
beginTime
,
strlen
(
"$Time$"
),
oss
.
str
()
);
}
}
ret
.
append
(
Url
::
Component
(
sourceUrl
,
this
));
}
return
ret
;
}
return
res
;
size_t
SegmentTemplate
::
getStartIndex
()
const
{
return
startIndex
;
}
void
SegmentTemplate
::
setStartIndex
(
size_t
i
)
{
startIndex
=
i
;
}
bool
SegmentTemplate
::
isSingleShot
()
const
...
...
@@ -76,8 +65,9 @@ bool SegmentTemplate::isSingleShot() const
return
false
;
}
void
SegmentTemplate
::
done
()
InitSegmentTemplate
::
InitSegmentTemplate
(
ICanonicalUrl
*
parent
)
:
SegmentTemplate
(
parent
)
{
this
->
currentSegmentIndex
++
;
debugName
=
"InitSegmentTemplate"
;
classId
=
InitSegment
::
CLASSID_INITSEGMENT
;
}
modules/stream_filter/dash/mpd/SegmentTemplate.h
View file @
a03587d3
...
...
@@ -30,18 +30,25 @@ namespace dash
{
namespace
mpd
{
class
Representation
;
class
ICanonicalUrl
;
class
SegmentTemplate
:
public
Segment
{
public:
SegmentTemplate
(
bool
containRuntimeIdentifier
,
Representation
*
rep
);
virtual
std
::
string
getUrlSegment
()
const
;
/* reimpl */
SegmentTemplate
(
ICanonicalUrl
*
=
NULL
);
virtual
Url
getUrlSegment
()
const
;
/* reimpl */
virtual
bool
isSingleShot
()
const
;
virtual
void
done
();
size_t
getStartIndex
()
const
;
void
setStartIndex
(
size_t
);
private:
bool
containRuntimeIdentifier
;
int
currentSegmentIndex
;
size_t
startIndex
;
};
class
InitSegmentTemplate
:
public
SegmentTemplate
{
public:
InitSegmentTemplate
(
ICanonicalUrl
*
=
NULL
);
};
}
}
...
...
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