Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GSoC
GSoC2018
macOS
vlc
Commits
4e6acd5b
Commit
4e6acd5b
authored
Dec 30, 2014
by
François Cartegnie
🤞
Browse files
demux: dash: track segment/periods outside of adaptation logic
Allows switching logic, and fixes startSegment handling.
parent
11008861
Changes
22
Hide whitespace changes
Inline
Side-by-side
modules/demux/Makefile.am
View file @
4e6acd5b
...
...
@@ -246,7 +246,6 @@ libdash_plugin_la_SOURCES = \
demux/dash/adaptationlogic/AlwaysBestAdaptationLogic.h
\
demux/dash/adaptationlogic/AlwaysLowestAdaptationLogic.cpp
\
demux/dash/adaptationlogic/AlwaysLowestAdaptationLogic.hpp
\
demux/dash/adaptationlogic/IAdaptationLogic.h
\
demux/dash/adaptationlogic/IDownloadRateObserver.h
\
demux/dash/adaptationlogic/RateBasedAdaptationLogic.h
\
demux/dash/adaptationlogic/RateBasedAdaptationLogic.cpp
\
...
...
@@ -326,6 +325,8 @@ libdash_plugin_la_SOURCES = \
demux/dash/Helper.cpp
\
demux/dash/Helper.h
\
demux/dash/Properties.hpp
\
demux/dash/SegmentTracker.cpp
\
demux/dash/SegmentTracker.hpp
\
demux/dash/StreamsType.hpp
\
demux/dash/Streams.cpp
\
demux/dash/Streams.hpp
...
...
modules/demux/dash/DASHManager.cpp
View file @
4e6acd5b
...
...
@@ -29,15 +29,15 @@
#include
"DASHManager.h"
#include
"adaptationlogic/AdaptationLogicFactory.h"
#include
"SegmentTracker.hpp"
using
namespace
dash
;
using
namespace
dash
::
http
;
using
namespace
dash
::
logic
;
using
namespace
dash
::
mpd
;
using
namespace
dash
::
buffer
;
DASHManager
::
DASHManager
(
MPD
*
mpd
,
I
AdaptationLogic
::
LogicType
type
,
stream_t
*
stream
)
:
Abstract
AdaptationLogic
::
LogicType
type
,
stream_t
*
stream
)
:
conManager
(
NULL
),
logicType
(
type
),
mpd
(
mpd
),
...
...
@@ -66,18 +66,33 @@ bool DASHManager::start(demux_t *demux)
const
AdaptationSet
*
set
=
period
->
getAdaptationSet
(
type
);
if
(
set
)
{
streams
[
type
]
=
new
Streams
::
Stream
(
set
->
getMimeType
());
streams
[
type
]
=
new
(
std
::
nothrow
)
Streams
::
Stream
(
set
->
getMimeType
());
if
(
!
streams
[
type
])
continue
;
AbstractAdaptationLogic
*
logic
=
AdaptationLogicFactory
::
create
(
logicType
,
mpd
);
if
(
!
logic
)
{
delete
streams
[
type
];
streams
[
type
]
=
NULL
;
continue
;
}
SegmentTracker
*
tracker
=
new
(
std
::
nothrow
)
SegmentTracker
(
logic
,
mpd
);
try
{
streams
[
type
]
->
create
(
demux
,
AdaptationLogicFactory
::
create
(
logicType
,
mpd
)
);
if
(
!
tracker
)
throw
VLC_ENOMEM
;
streams
[
type
]
->
create
(
demux
,
logic
,
tracker
);
}
catch
(
int
)
{
delete
streams
[
type
];
delete
logic
;
delete
tracker
;
streams
[
type
]
=
NULL
;
}
}
}
conManager
=
new
HTTPConnectionManager
(
stream
);
conManager
=
new
(
std
::
nothrow
)
HTTPConnectionManager
(
stream
);
if
(
!
conManager
)
return
false
;
...
...
modules/demux/dash/DASHManager.h
View file @
4e6acd5b
...
...
@@ -26,7 +26,7 @@
#define DASHMANAGER_H_
#include
"http/HTTPConnectionManager.h"
#include
"adaptationlogic/
I
AdaptationLogic.h"
#include
"adaptationlogic/
Abstract
AdaptationLogic.h"
#include
"mpd/MPD.h"
namespace
dash
...
...
@@ -35,7 +35,7 @@ namespace dash
{
public:
DASHManager
(
mpd
::
MPD
*
mpd
,
logic
::
I
AdaptationLogic
::
LogicType
type
,
stream_t
*
stream
);
logic
::
Abstract
AdaptationLogic
::
LogicType
type
,
stream_t
*
stream
);
virtual
~
DASHManager
();
bool
start
(
demux_t
*
);
...
...
@@ -47,7 +47,7 @@ namespace dash
private:
http
::
HTTPConnectionManager
*
conManager
;
logic
::
I
AdaptationLogic
::
LogicType
logicType
;
logic
::
Abstract
AdaptationLogic
::
LogicType
logicType
;
mpd
::
MPD
*
mpd
;
stream_t
*
stream
;
Streams
::
Stream
*
streams
[
Streams
::
count
];
...
...
modules/demux/dash/SegmentTracker.cpp
0 → 100644
View file @
4e6acd5b
/*
* SegmentTracker.cpp
*****************************************************************************
* Copyright (C) 2014 - VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include
"SegmentTracker.hpp"
#include
"mpd/MPD.h"
using
namespace
dash
;
using
namespace
dash
::
logic
;
using
namespace
dash
::
http
;
using
namespace
dash
::
mpd
;
SegmentTracker
::
SegmentTracker
(
AbstractAdaptationLogic
*
logic_
,
mpd
::
MPD
*
mpd_
)
{
count
=
0
;
initializing
=
true
;
prevRepresentation
=
NULL
;
currentPeriod
=
mpd_
->
getFirstPeriod
();
setAdaptationLogic
(
logic_
);
mpd
=
mpd_
;
}
SegmentTracker
::~
SegmentTracker
()
{
}
void
SegmentTracker
::
setAdaptationLogic
(
AbstractAdaptationLogic
*
logic_
)
{
logic
=
logic_
;
}
void
SegmentTracker
::
resetCounter
()
{
count
=
0
;
prevRepresentation
=
NULL
;
}
Chunk
*
SegmentTracker
::
getNextChunk
(
Streams
::
Type
type
)
{
Representation
*
rep
;
ISegment
*
segment
;
if
(
!
currentPeriod
)
return
NULL
;
if
(
prevRepresentation
&&
!
prevRepresentation
->
canBitswitch
())
rep
=
prevRepresentation
;
else
rep
=
logic
->
getCurrentRepresentation
(
type
,
currentPeriod
);
if
(
rep
==
NULL
)
return
NULL
;
if
(
rep
!=
prevRepresentation
)
{
prevRepresentation
=
rep
;
initializing
=
true
;
}
if
(
initializing
)
{
initializing
=
false
;
segment
=
rep
->
getSegment
(
Representation
::
INFOTYPE_INIT
);
if
(
segment
)
return
segment
->
toChunk
(
count
,
rep
);
}
segment
=
rep
->
getSegment
(
Representation
::
INFOTYPE_MEDIA
,
count
);
if
(
!
segment
)
{
currentPeriod
=
mpd
->
getNextPeriod
(
currentPeriod
);
resetCounter
();
return
getNextChunk
(
type
);
}
Chunk
*
chunk
=
segment
->
toChunk
(
count
,
rep
);
if
(
chunk
)
{
segment
->
done
();
count
++
;
}
return
chunk
;
}
modules/demux/dash/
adaptationlogic/IAdaptationLogic.h
→
modules/demux/dash/
SegmentTracker.hpp
View file @
4e6acd5b
/*
*
IAdaptationLogic.h
*
SegmentTracker.hpp
*****************************************************************************
* Copyright (C) 2010 - 2011 Klagenfurt University
*
* Created on: Aug 10, 2010
* Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
* Christian Timmerer <christian.timmerer@itec.uni-klu.ac.at>
* Copyright (C) 2014 - VideoLAN authors
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
...
...
@@ -21,37 +17,54 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef SEGMENTTRACKER_HPP
#define SEGMENTTRACKER_HPP
#ifndef IADAPTATIONLOGIC_H_
#define IADAPTATIONLOGIC_H_
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include
<http/Chunk.h>
#include
<adaptationlogic/IDownloadRateObserver.h>
#include
"mpd/Representation.h"
#include
"buffer/IBufferObserver.h"
#include
"StreamsType.hpp"
#include
<vlc_common.h>
namespace
dash
{
namespace
mpd
{
class
MPD
;
class
Period
;
class
Representation
;
class
Segment
;
}
namespace
logic
{
class
IAdaptationLogic
:
public
IDownloadRateObserver
{
public:
enum
LogicType
{
Default
,
AlwaysBest
,
AlwaysLowest
,
RateBased
,
FixedRate
};
virtual
dash
::
http
::
Chunk
*
getNextChunk
(
Streams
::
Type
)
=
0
;
virtual
dash
::
mpd
::
Representation
*
getCurrentRepresentation
(
Streams
::
Type
)
const
=
0
;
};
class
AbstractAdaptationLogic
;
}
namespace
http
{
class
Chunk
;
}
class
SegmentTracker
{
public:
SegmentTracker
(
logic
::
AbstractAdaptationLogic
*
,
mpd
::
MPD
*
);
~
SegmentTracker
();
void
setAdaptationLogic
(
logic
::
AbstractAdaptationLogic
*
);
void
resetCounter
();
http
::
Chunk
*
getNextChunk
(
Streams
::
Type
);
private:
bool
initializing
;
uint64_t
count
;
logic
::
AbstractAdaptationLogic
*
logic
;
mpd
::
MPD
*
mpd
;
mpd
::
Period
*
currentPeriod
;
mpd
::
Representation
*
prevRepresentation
;
};
}
#endif
/
* IADAPTATIONLOGIC_H_ */
#endif /
/ SEGMENTTRACKER_HPP
modules/demux/dash/Streams.cpp
View file @
4e6acd5b
...
...
@@ -19,8 +19,9 @@
*****************************************************************************/
#define __STDC_CONSTANT_MACROS
#include
"Streams.hpp"
#include
"adaptationlogic/
I
AdaptationLogic.h"
#include
"adaptationlogic/
Abstract
AdaptationLogic.h"
#include
"adaptationlogic/AdaptationLogicFactory.h"
#include
"SegmentTracker.hpp"
#include
<vlc_stream.h>
#include
<vlc_demux.h>
...
...
@@ -46,6 +47,7 @@ void Stream::init(const Type type_, const Format format_)
adaptationLogic
=
NULL
;
currentChunk
=
NULL
;
eof
=
false
;
segmentTracker
=
NULL
;
}
Stream
::~
Stream
()
...
...
@@ -53,6 +55,7 @@ Stream::~Stream()
delete
currentChunk
;
delete
adaptationLogic
;
delete
output
;
delete
segmentTracker
;
}
Type
Stream
::
mimeToType
(
const
std
::
string
&
mime
)
...
...
@@ -84,9 +87,8 @@ Format Stream::mimeToFormat(const std::string &mime)
return
format
;
}
void
Stream
::
create
(
demux_t
*
demux
,
I
AdaptationLogic
*
logic
)
void
Stream
::
create
(
demux_t
*
demux
,
Abstract
AdaptationLogic
*
logic
,
SegmentTracker
*
tracker
)
{
adaptationLogic
=
logic
;
switch
(
format
)
{
case
Streams
::
MP4
:
...
...
@@ -99,6 +101,8 @@ void Stream::create(demux_t *demux, IAdaptationLogic *logic)
throw
VLC_EBADVAR
;
break
;
}
adaptationLogic
=
logic
;
segmentTracker
=
tracker
;
}
bool
Stream
::
isEOF
()
const
...
...
@@ -130,7 +134,7 @@ Chunk * Stream::getChunk()
{
if
(
currentChunk
==
NULL
)
{
currentChunk
=
adaptationLogic
->
getNextChunk
(
type
);
currentChunk
=
segmentTracker
->
getNextChunk
(
type
);
if
(
currentChunk
==
NULL
)
eof
=
true
;
}
...
...
modules/demux/dash/Streams.hpp
View file @
4e6acd5b
...
...
@@ -27,12 +27,14 @@
#include
<string>
#include
<vlc_common.h>
#include
"StreamsType.hpp"
#include
"adaptationlogic/
I
AdaptationLogic.h"
#include
"adaptationlogic/
Abstract
AdaptationLogic.h"
#include
"http/HTTPConnectionManager.h"
#include
"http/Chunk.h"
namespace
dash
{
class
SegmentTracker
;
namespace
Streams
{
class
AbstractStreamOutput
;
...
...
@@ -46,7 +48,7 @@ namespace dash
bool
operator
==
(
const
Stream
&
)
const
;
static
Type
mimeToType
(
const
std
::
string
&
mime
);
static
Format
mimeToFormat
(
const
std
::
string
&
mime
);
void
create
(
demux_t
*
,
logic
::
I
AdaptationLogic
*
);
void
create
(
demux_t
*
,
logic
::
Abstract
AdaptationLogic
*
,
SegmentTracker
*
);
bool
isEOF
()
const
;
mtime_t
getPCR
()
const
;
int
getGroup
()
const
;
...
...
@@ -59,7 +61,8 @@ namespace dash
Type
type
;
Format
format
;
AbstractStreamOutput
*
output
;
logic
::
IAdaptationLogic
*
adaptationLogic
;
logic
::
AbstractAdaptationLogic
*
adaptationLogic
;
SegmentTracker
*
segmentTracker
;
http
::
Chunk
*
currentChunk
;
bool
eof
;
};
...
...
modules/demux/dash/adaptationlogic/AbstractAdaptationLogic.cpp
View file @
4e6acd5b
...
...
@@ -29,78 +29,16 @@
using
namespace
dash
::
logic
;
using
namespace
dash
::
mpd
;
using
namespace
dash
::
http
;
AbstractAdaptationLogic
::
AbstractAdaptationLogic
(
MPD
*
mpd_
)
:
mpd
(
mpd_
),
currentPeriod
(
mpd
->
getFirstPeriod
())
mpd
(
mpd_
)
{
reset
();
}
AbstractAdaptationLogic
::~
AbstractAdaptationLogic
()
{
}
void
AbstractAdaptationLogic
::
reset
()
{
count
=
0
;
prevRepresentation
=
NULL
;
}
Chunk
*
AbstractAdaptationLogic
::
getNextChunk
(
Streams
::
Type
type
)
{
if
(
!
currentPeriod
)
return
NULL
;
Representation
*
rep
;
if
(
prevRepresentation
&&
!
prevRepresentation
->
canBitswitch
())
rep
=
prevRepresentation
;
else
rep
=
getCurrentRepresentation
(
type
);
if
(
rep
==
NULL
)
return
NULL
;
bool
reinit
=
count
&&
(
rep
!=
prevRepresentation
);
prevRepresentation
=
rep
;
std
::
vector
<
ISegment
*>
segments
=
rep
->
getSegments
();
ISegment
*
first
=
segments
.
empty
()
?
NULL
:
segments
.
front
();
if
(
reinit
&&
first
&&
first
->
getClassId
()
==
InitSegment
::
CLASSID_INITSEGMENT
)
return
first
->
toChunk
(
count
,
rep
);
bool
b_templated
=
(
first
&&
!
first
->
isSingleShot
());
if
(
count
==
segments
.
size
()
&&
!
b_templated
)
{
currentPeriod
=
mpd
->
getNextPeriod
(
currentPeriod
);
reset
();
return
getNextChunk
(
type
);
}
ISegment
*
seg
=
NULL
;
if
(
segments
.
size
()
>
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
;
}
return
NULL
;
}
void
AbstractAdaptationLogic
::
updateDownloadRate
(
size_t
,
mtime_t
)
{
}
modules/demux/dash/adaptationlogic/AbstractAdaptationLogic.h
View file @
4e6acd5b
...
...
@@ -25,34 +25,42 @@
#ifndef ABSTRACTADAPTATIONLOGIC_H_
#define ABSTRACTADAPTATIONLOGIC_H_
#include
"adaptationlogic/IAdaptationLogic.h"
#include
"http/Chunk.h"
#include
"mpd/MPD.h"
#include
"mpd/Period.h"
#include
"mpd/Representation.h"
#include
<adaptationlogic/IDownloadRateObserver.h>
#include
"StreamsType.hpp"
struct
stream_t
;
//
struct stream_t;
namespace
dash
{
namespace
mpd
{
class
MPD
;
class
Period
;
class
Representation
;
}
namespace
logic
{
class
AbstractAdaptationLogic
:
public
I
AdaptationLogic
class
AbstractAdaptationLogic
:
public
I
DownloadRateObserver
{
public:
AbstractAdaptationLogic
(
mpd
::
MPD
*
mpd
);
virtual
~
AbstractAdaptationLogic
();
virtual
void
reset
();
virtual
dash
::
http
::
Chunk
*
getNextChunk
(
Streams
::
Type
);
virtual
mpd
::
Representation
*
getCurrentRepresentation
(
Streams
::
Type
,
mpd
::
Period
*
)
const
=
0
;
virtual
void
updateDownloadRate
(
size_t
,
mtime_t
);
enum
LogicType
{
Default
,
AlwaysBest
,
AlwaysLowest
,
RateBased
,
FixedRate
};
protected:
dash
::
mpd
::
MPD
*
mpd
;
dash
::
mpd
::
Period
*
currentPeriod
;
size_t
count
;
mpd
::
Representation
*
prevRepresentation
;
};
}
}
...
...
modules/demux/dash/adaptationlogic/AdaptationLogicFactory.cpp
View file @
4e6acd5b
...
...
@@ -30,19 +30,25 @@
#include
"adaptationlogic/RateBasedAdaptationLogic.h"
#include
"adaptationlogic/AlwaysLowestAdaptationLogic.hpp"
#include
<new>
using
namespace
dash
::
logic
;
using
namespace
dash
::
mpd
;
I
AdaptationLogic
*
AdaptationLogicFactory
::
create
(
IAdaptationLogic
::
LogicType
logic
,
MPD
*
mpd
)
Abstract
AdaptationLogic
*
AdaptationLogicFactory
::
create
(
AbstractAdaptationLogic
::
LogicType
logic
,
MPD
*
mpd
)
{
switch
(
logic
)
{
case
IAdaptationLogic
::
AlwaysBest
:
return
new
AlwaysBestAdaptationLogic
(
mpd
);
case
IAdaptationLogic
::
AlwaysLowest
:
return
new
AlwaysLowestAdaptationLogic
(
mpd
);
case
IAdaptationLogic
::
FixedRate
:
return
new
FixedRateAdaptationLogic
(
mpd
);
case
IAdaptationLogic
::
Default
:
case
IAdaptationLogic
::
RateBased
:
return
new
RateBasedAdaptationLogic
(
mpd
);
case
AbstractAdaptationLogic
::
AlwaysBest
:
return
new
(
std
::
nothrow
)
AlwaysBestAdaptationLogic
(
mpd
);
case
AbstractAdaptationLogic
::
AlwaysLowest
:
return
new
(
std
::
nothrow
)
AlwaysLowestAdaptationLogic
(
mpd
);
case
AbstractAdaptationLogic
::
FixedRate
:
return
new
(
std
::
nothrow
)
FixedRateAdaptationLogic
(
mpd
);
case
AbstractAdaptationLogic
::
Default
:
case
AbstractAdaptationLogic
::
RateBased
:
return
new
(
std
::
nothrow
)
RateBasedAdaptationLogic
(
mpd
);
default:
return
NULL
;
}
...
...
modules/demux/dash/adaptationlogic/AdaptationLogicFactory.h
View file @
4e6acd5b
...
...
@@ -25,18 +25,24 @@
#ifndef ADAPTATIONLOGICFACTORY_H_
#define ADAPTATIONLOGICFACTORY_H_
#include
"adaptationlogic/
I
AdaptationLogic.h"
#include
"adaptationlogic/
Abstract
AdaptationLogic.h"
struct
stream_t
;
namespace
dash
{
namespace
mpd
{
class
MPD
;
}
namespace
logic
{
class
AdaptationLogicFactory
{
public:
static
IAdaptationLogic
*
create
(
IAdaptationLogic
::
LogicType
logic
,
mpd
::
MPD
*
mpd
);
static
AbstractAdaptationLogic
*
create
(
AbstractAdaptationLogic
::
LogicType
logic
,
mpd
::
MPD
*
mpd
);
};
}
}
...
...
modules/demux/dash/adaptationlogic/AlwaysBestAdaptationLogic.cpp
View file @
4e6acd5b
...
...
@@ -36,8 +36,8 @@ AlwaysBestAdaptationLogic::AlwaysBestAdaptationLogic (MPD *mpd) :
{
}
Representation
*
AlwaysBestAdaptationLogic
::
getCurrentRepresentation
(
Streams
::
Type
type
)
const
Representation
*
AlwaysBestAdaptationLogic
::
getCurrentRepresentation
(
Streams
::
Type
type
,
mpd
::
Period
*
period
)
const
{
RepresentationSelector
selector
;
return
selector
.
select
(
currentP
eriod
,
type
);
return
selector
.
select
(
p
eriod
,
type
);
}
modules/demux/dash/adaptationlogic/AlwaysBestAdaptationLogic.h
View file @
4e6acd5b
...
...
@@ -36,7 +36,7 @@ namespace dash
public:
AlwaysBestAdaptationLogic
(
mpd
::
MPD
*
mpd
);
virtual
mpd
::
Representation
*
getCurrentRepresentation
(
Streams
::
Type
)
const
;
virtual
mpd
::
Representation
*
getCurrentRepresentation
(
Streams
::
Type
,
mpd
::
Period
*
)
const
;
};
}
}
...
...
modules/demux/dash/adaptationlogic/AlwaysLowestAdaptationLogic.cpp
View file @
4e6acd5b
...
...
@@ -28,8 +28,8 @@ AlwaysLowestAdaptationLogic::AlwaysLowestAdaptationLogic(mpd::MPD *mpd):
{
}
Representation
*
AlwaysLowestAdaptationLogic
::
getCurrentRepresentation
(
Streams
::
Type
type
)
const