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
9565350a
Commit
9565350a
authored
May 08, 2015
by
Francois Cartegnie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
demux: hls: add adaptative based hls demuxer
parent
621b86f9
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1973 additions
and
40 deletions
+1973
-40
NEWS
NEWS
+1
-0
modules/MODULES_LIST
modules/MODULES_LIST
+1
-0
modules/demux/Makefile.am
modules/demux/Makefile.am
+70
-40
modules/demux/hls/HLSManager.cpp
modules/demux/hls/HLSManager.cpp
+142
-0
modules/demux/hls/HLSManager.hpp
modules/demux/hls/HLSManager.hpp
+44
-0
modules/demux/hls/hls.cpp
modules/demux/hls/hls.cpp
+310
-0
modules/demux/hls/hls.hpp
modules/demux/hls/hls.hpp
+32
-0
modules/demux/hls/playlist/HLSSegment.cpp
modules/demux/hls/playlist/HLSSegment.cpp
+154
-0
modules/demux/hls/playlist/HLSSegment.hpp
modules/demux/hls/playlist/HLSSegment.hpp
+69
-0
modules/demux/hls/playlist/M3U8.cpp
modules/demux/hls/playlist/M3U8.cpp
+74
-0
modules/demux/hls/playlist/M3U8.hpp
modules/demux/hls/playlist/M3U8.hpp
+46
-0
modules/demux/hls/playlist/Parser.cpp
modules/demux/hls/playlist/Parser.cpp
+371
-0
modules/demux/hls/playlist/Parser.hpp
modules/demux/hls/playlist/Parser.hpp
+77
-0
modules/demux/hls/playlist/Representation.cpp
modules/demux/hls/playlist/Representation.cpp
+69
-0
modules/demux/hls/playlist/Representation.hpp
modules/demux/hls/playlist/Representation.hpp
+58
-0
modules/demux/hls/playlist/Tags.cpp
modules/demux/hls/playlist/Tags.cpp
+316
-0
modules/demux/hls/playlist/Tags.hpp
modules/demux/hls/playlist/Tags.hpp
+138
-0
po/POTFILES.in
po/POTFILES.in
+1
-0
No files found.
NEWS
View file @
9565350a
...
@@ -57,6 +57,7 @@ Demuxers:
...
@@ -57,6 +57,7 @@ Demuxers:
* Support for Creative ADPCM/alaw/ulaw/S16L in VOC files
* Support for Creative ADPCM/alaw/ulaw/S16L in VOC files
* Support for Creative ADPCM in AVI
* Support for Creative ADPCM in AVI
* Directory Demux can now sort items, ignore extensions and hidden files
* Directory Demux can now sort items, ignore extensions and hidden files
* Replaced httplive stream filter with new hls demuxer
Stream filter:
Stream filter:
* Added ARIB STD-B25 TS streams decoder
* Added ARIB STD-B25 TS streams decoder
...
...
modules/MODULES_LIST
View file @
9565350a
...
@@ -175,6 +175,7 @@ $Id$
...
@@ -175,6 +175,7 @@ $Id$
* hevc: HEVC demuxer
* hevc: HEVC demuxer
* hotkeys: hotkeys control module
* hotkeys: hotkeys control module
* hqdn3d: High Quality denoising filter
* hqdn3d: High Quality denoising filter
* hls: HTTP Live Streaming demuxer
* http: HTTP Network access module
* http: HTTP Network access module
* httplive: HTTP Live streaming for playback
* httplive: HTTP Live streaming for playback
* i420_rgb: planar YUV to packed RGB conversion functions
* i420_rgb: planar YUV to packed RGB conversion functions
...
...
modules/demux/Makefile.am
View file @
9565350a
...
@@ -244,45 +244,7 @@ if HAVE_DVBPSI
...
@@ -244,45 +244,7 @@ if HAVE_DVBPSI
demux_LTLIBRARIES
+=
libts_plugin.la
demux_LTLIBRARIES
+=
libts_plugin.la
endif
endif
libdash_plugin_la_SOURCES
=
\
adaptative_SOURCES
=
\
demux/dash/mpd/AdaptationSet.cpp
\
demux/dash/mpd/AdaptationSet.h
\
demux/dash/mpd/DASHCommonAttributesElements.cpp
\
demux/dash/mpd/DASHCommonAttributesElements.h
\
demux/dash/mpd/DASHSegment.cpp
\
demux/dash/mpd/DASHSegment.h
\
demux/dash/mpd/ContentDescription.cpp
\
demux/dash/mpd/ContentDescription.h
\
demux/dash/mpd/IsoffMainParser.cpp
\
demux/dash/mpd/IsoffMainParser.h
\
demux/dash/mpd/MPD.cpp
\
demux/dash/mpd/MPD.h
\
demux/dash/mpd/MPDFactory.cpp
\
demux/dash/mpd/MPDFactory.h
\
demux/dash/mpd/Period.cpp
\
demux/dash/mpd/Period.h
\
demux/dash/mpd/Profile.cpp
\
demux/dash/mpd/Profile.hpp
\
demux/dash/mpd/ProgramInformation.cpp
\
demux/dash/mpd/ProgramInformation.h
\
demux/dash/mpd/Representation.cpp
\
demux/dash/mpd/Representation.h
\
demux/dash/mpd/TrickModeType.cpp
\
demux/dash/mpd/TrickModeType.h
\
demux/dash/mp4/AtomsReader.cpp
\
demux/dash/mp4/AtomsReader.hpp
\
demux/dash/xml/DOMHelper.cpp
\
demux/dash/xml/DOMHelper.h
\
demux/dash/xml/DOMParser.cpp
\
demux/dash/xml/DOMParser.h
\
demux/dash/xml/Node.cpp
\
demux/dash/xml/Node.h
\
demux/dash/dash.cpp
\
demux/dash/dash.hpp
\
demux/dash/DASHManager.cpp
\
demux/dash/DASHManager.h
libdash_plugin_la_SOURCES
+=
\
demux/adaptative/playlist/AbstractPlaylist.cpp
\
demux/adaptative/playlist/AbstractPlaylist.cpp
\
demux/adaptative/playlist/AbstractPlaylist.hpp
\
demux/adaptative/playlist/AbstractPlaylist.hpp
\
demux/adaptative/playlist/BaseAdaptationSet.cpp
\
demux/adaptative/playlist/BaseAdaptationSet.cpp
\
...
@@ -345,8 +307,46 @@ libdash_plugin_la_SOURCES += \
...
@@ -345,8 +307,46 @@ libdash_plugin_la_SOURCES += \
demux/adaptative/tools/Retrieve.cpp
\
demux/adaptative/tools/Retrieve.cpp
\
demux/adaptative/tools/Retrieve.hpp
demux/adaptative/tools/Retrieve.hpp
libdash_plugin_la_SOURCES
+=
demux/mp4/libmp4.c demux/mp4/libmp4.h
libdash_plugin_la_SOURCES
=
\
demux/dash/mpd/AdaptationSet.cpp
\
demux/dash/mpd/AdaptationSet.h
\
demux/dash/mpd/DASHCommonAttributesElements.cpp
\
demux/dash/mpd/DASHCommonAttributesElements.h
\
demux/dash/mpd/DASHSegment.cpp
\
demux/dash/mpd/DASHSegment.h
\
demux/dash/mpd/ContentDescription.cpp
\
demux/dash/mpd/ContentDescription.h
\
demux/dash/mpd/IsoffMainParser.cpp
\
demux/dash/mpd/IsoffMainParser.h
\
demux/dash/mpd/MPD.cpp
\
demux/dash/mpd/MPD.h
\
demux/dash/mpd/MPDFactory.cpp
\
demux/dash/mpd/MPDFactory.h
\
demux/dash/mpd/Period.cpp
\
demux/dash/mpd/Period.h
\
demux/dash/mpd/Profile.cpp
\
demux/dash/mpd/Profile.hpp
\
demux/dash/mpd/ProgramInformation.cpp
\
demux/dash/mpd/ProgramInformation.h
\
demux/dash/mpd/Representation.cpp
\
demux/dash/mpd/Representation.h
\
demux/dash/mpd/TrickModeType.cpp
\
demux/dash/mpd/TrickModeType.h
\
demux/dash/mp4/AtomsReader.cpp
\
demux/dash/mp4/AtomsReader.hpp
\
demux/dash/xml/DOMHelper.cpp
\
demux/dash/xml/DOMHelper.h
\
demux/dash/xml/DOMParser.cpp
\
demux/dash/xml/DOMParser.h
\
demux/dash/xml/Node.cpp
\
demux/dash/xml/Node.h
\
demux/dash/dash.cpp
\
demux/dash/dash.hpp
\
demux/dash/DASHManager.cpp
\
demux/dash/DASHManager.h
libdash_plugin_la_SOURCES
+=
$(adaptative_SOURCES)
libdash_plugin_la_SOURCES
+=
demux/mp4/libmp4.c demux/mp4/libmp4.h
libdash_plugin_la_CXXFLAGS
=
$(AM_CFLAGS)
-I
$(srcdir)
/demux/dash
libdash_plugin_la_CXXFLAGS
=
$(AM_CFLAGS)
-I
$(srcdir)
/demux/dash
libdash_plugin_la_LIBADD
=
$(SOCKET_LIBS)
$(LIBM)
libdash_plugin_la_LIBADD
=
$(SOCKET_LIBS)
$(LIBM)
if
HAVE_ZLIB
if
HAVE_ZLIB
...
@@ -354,6 +354,36 @@ libdash_plugin_la_LIBADD += -lz
...
@@ -354,6 +354,36 @@ libdash_plugin_la_LIBADD += -lz
endif
endif
demux_LTLIBRARIES
+=
libdash_plugin.la
demux_LTLIBRARIES
+=
libdash_plugin.la
libhls_plugin_la_SOURCES
=
\
demux/hls/playlist/M3U8.hpp
\
demux/hls/playlist/M3U8.cpp
\
demux/hls/playlist/Parser.hpp
\
demux/hls/playlist/Parser.cpp
\
demux/hls/playlist/Representation.hpp
\
demux/hls/playlist/Representation.cpp
\
demux/hls/playlist/HLSSegment.hpp
\
demux/hls/playlist/HLSSegment.cpp
\
demux/hls/playlist/Tags.hpp
\
demux/hls/playlist/Tags.cpp
\
demux/hls/HLSManager.hpp
\
demux/hls/HLSManager.cpp
\
demux/hls/hls.cpp
\
demux/hls/hls.hpp
libhls_plugin_la_SOURCES
+=
$(adaptative_SOURCES)
libhls_plugin_la_CXXFLAGS
=
$(AM_CFLAGS)
-I
$(srcdir)
/demux/hls
libhls_plugin_la_LIBADD
=
$(SOCKET_LIBS)
$(LIBM)
if
HAVE_ZLIB
libhls_plugin_la_LIBADD
+=
-lz
endif
if
HAVE_GCRYPT
libhls_plugin_la_CXXFLAGS
+=
$(GCRYPT_CFLAGS)
libhls_plugin_la_LIBADD
+=
$(GCRYPT_LIBS)
endif
demux_LTLIBRARIES
+=
libhls_plugin.la
libttml_plugin_la_SOURCES
=
demux/ttml.c
libttml_plugin_la_SOURCES
=
demux/ttml.c
demux_LTLIBRARIES
+=
libttml_plugin.la
demux_LTLIBRARIES
+=
libttml_plugin.la
modules/demux/hls/HLSManager.cpp
0 → 100644
View file @
9565350a
/*****************************************************************************
* HLSManager.cpp
*****************************************************************************
* Copyright © 2015 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 "HLSManager.hpp"
#include "../adaptative/logic/RateBasedAdaptationLogic.h"
#include "../adaptative/tools/Retrieve.hpp"
#include "playlist/Parser.hpp"
#include <vlc_stream.h>
using
namespace
adaptative
;
using
namespace
adaptative
::
logic
;
using
namespace
hls
;
using
namespace
hls
::
playlist
;
HLSManager
::
HLSManager
(
M3U8
*
playlist
,
AbstractAdaptationLogic
::
LogicType
type
,
stream_t
*
stream
)
:
PlaylistManager
(
playlist
,
type
,
stream
)
{
}
HLSManager
::~
HLSManager
()
{
}
AbstractAdaptationLogic
*
HLSManager
::
createLogic
(
AbstractAdaptationLogic
::
LogicType
type
)
{
size_t
bps
=
var_InheritInteger
(
stream
,
"hls-prefbw"
)
*
8192
;
switch
(
type
)
{
case
AbstractAdaptationLogic
:
:
FixedRate
:
{
size_t
bps
=
var_InheritInteger
(
stream
,
"hls-prefbw"
)
*
8192
;
return
new
(
std
::
nothrow
)
FixedRateAdaptationLogic
(
bps
);
}
case
AbstractAdaptationLogic
:
:
Default
:
case
AbstractAdaptationLogic
:
:
RateBased
:
{
int
width
=
var_InheritInteger
(
stream
,
"hls-prefwidth"
);
int
height
=
var_InheritInteger
(
stream
,
"hls-prefheight"
);
return
new
(
std
::
nothrow
)
RateBasedAdaptationLogic
(
width
,
height
);
}
default:
return
PlaylistManager
::
createLogic
(
type
);
}
}
bool
HLSManager
::
updatePlaylist
()
{
if
(
!
playlist
->
isLive
()
||
!
playlist
->
minUpdatePeriod
.
Get
())
return
true
;
mtime_t
now
=
time
(
NULL
);
if
(
nextPlaylistupdate
&&
now
<
nextPlaylistupdate
)
return
true
;
M3U8
*
updatedplaylist
=
NULL
;
/* do update */
if
(
nextPlaylistupdate
)
{
std
::
string
url
(
stream
->
psz_access
);
url
.
append
(
"://"
);
url
.
append
(
stream
->
psz_path
);
uint8_t
*
p_data
=
NULL
;
size_t
i_data
=
Retrieve
::
HTTP
(
VLC_OBJECT
(
stream
),
url
,
(
void
**
)
&
p_data
);
if
(
!
p_data
)
return
false
;
stream_t
*
updatestream
=
stream_MemoryNew
(
stream
,
p_data
,
i_data
,
false
);
if
(
!
updatestream
)
{
free
(
p_data
);
nextPlaylistupdate
=
now
+
playlist
->
minUpdatePeriod
.
Get
();
return
false
;
}
Parser
parser
(
updatestream
);
updatedplaylist
=
parser
.
parse
(
url
);
if
(
!
updatedplaylist
)
{
stream_Delete
(
updatestream
);
nextPlaylistupdate
=
now
+
playlist
->
minUpdatePeriod
.
Get
();
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 */
for
(
int
type
=
0
;
type
<
StreamTypeCount
;
type
++
)
{
if
(
!
streams
[
type
])
continue
;
streams
[
type
]
->
prune
();
}
}
else
{
playlist
->
getPlaylistDurationsRange
(
&
mininterval
,
&
maxinterval
);
}
if
(
playlist
->
minUpdatePeriod
.
Get
()
*
CLOCK_FREQ
>
mininterval
)
mininterval
=
playlist
->
minUpdatePeriod
.
Get
()
*
CLOCK_FREQ
;
if
(
maxinterval
<
mininterval
)
maxinterval
=
mininterval
;
nextPlaylistupdate
=
now
+
(
mininterval
+
maxinterval
)
/
(
2
*
CLOCK_FREQ
);
msg_Dbg
(
stream
,
"Updated playlist, next update in %"
PRId64
"s %ld %ld"
,
nextPlaylistupdate
-
now
,
mininterval
,
maxinterval
);
return
true
;
}
modules/demux/hls/HLSManager.hpp
0 → 100644
View file @
9565350a
/*
* HLSManager.hpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifndef HLSMANAGER_HPP
#define HLSMANAGER_HPP
#include "../adaptative/PlaylistManager.h"
#include "../adaptative/logic/AbstractAdaptationLogic.h"
#include "playlist/M3U8.hpp"
namespace
hls
{
using
namespace
adaptative
;
class
HLSManager
:
public
PlaylistManager
{
public:
HLSManager
(
playlist
::
M3U8
*
,
logic
::
AbstractAdaptationLogic
::
LogicType
type
,
stream_t
*
stream
);
virtual
~
HLSManager
();
virtual
AbstractAdaptationLogic
*
createLogic
(
AbstractAdaptationLogic
::
LogicType
);
virtual
bool
updatePlaylist
();
};
}
#endif // HLSMANAGER_HPP
modules/demux/hls/hls.cpp
0 → 100644
View file @
9565350a
/*****************************************************************************
* hls.cpp: HTTP Live Streaming module
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#define __STDC_CONSTANT_MACROS 1
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdint.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_demux.h>
#include <vlc_meta.h>
#include <errno.h>
#include "../adaptative/logic/AbstractAdaptationLogic.h"
#include "HLSManager.hpp"
#include "playlist/Parser.hpp"
#include "playlist/M3U8.hpp"
#include "hls.hpp"
using
namespace
adaptative
;
using
namespace
adaptative
::
logic
;
using
namespace
adaptative
::
playlist
;
using
namespace
hls
;
using
namespace
hls
::
playlist
;
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
#define HLS_WIDTH_TEXT N_("Preferred Width")
#define HLS_WIDTH_LONGTEXT N_("Preferred Width")
#define HLS_HEIGHT_TEXT N_("Preferred Height")
#define HLS_HEIGHT_LONGTEXT N_("Preferred Height")
#define HLS_BW_TEXT N_("Fixed Bandwidth in KiB/s")
#define HLS_BW_LONGTEXT N_("Preferred bandwidth for non adaptative streams")
#define HLS_LOGIC_TEXT N_("Adaptation Logic")
static
const
int
pi_logics
[]
=
{
AbstractAdaptationLogic
::
RateBased
,
AbstractAdaptationLogic
::
FixedRate
,
AbstractAdaptationLogic
::
AlwaysLowest
,
AbstractAdaptationLogic
::
AlwaysBest
};
static
const
char
*
const
ppsz_logics
[]
=
{
N_
(
"Bandwidth Adaptive"
),
N_
(
"Fixed Bandwidth"
),
N_
(
"Lowest Bandwidth/Quality"
),
N_
(
"Highest Bandwith/Quality"
)};
vlc_module_begin
()
set_shortname
(
N_
(
"hls"
))
set_description
(
N_
(
"HTTP Live Streaming"
)
)
set_capability
(
"demux"
,
12
)
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_DEMUX
)
add_integer
(
"hls-logic"
,
AbstractAdaptationLogic
::
Default
,
HLS_LOGIC_TEXT
,
NULL
,
false
)
change_integer_list
(
pi_logics
,
ppsz_logics
)
add_integer
(
"hls-prefwidth"
,
480
,
HLS_WIDTH_TEXT
,
HLS_WIDTH_LONGTEXT
,
true
)
add_integer
(
"hls-prefheight"
,
360
,
HLS_HEIGHT_TEXT
,
HLS_HEIGHT_LONGTEXT
,
true
)
add_integer
(
"hls-prefbw"
,
250
,
HLS_BW_TEXT
,
HLS_BW_LONGTEXT
,
false
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Demux
(
demux_t
*
);
static
int
Control
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
);
/*****************************************************************************
* Open:
*****************************************************************************/
static
bool
isHTTPLiveStreaming
(
stream_t
*
s
)
{
const
uint8_t
*
peek
;
int
size
=
stream_Peek
(
s
,
&
peek
,
46
);
if
(
size
<
7
)
return
false
;
if
(
memcmp
(
peek
,
"#EXTM3U"
,
7
)
!=
0
)
return
false
;
peek
+=
7
;
size
-=
7
;
/* Parse stream and search for
* EXT-X-TARGETDURATION or EXT-X-STREAM-INF tag, see
* http://tools.ietf.org/html/draft-pantos-http-live-streaming-04#page-8 */
while
(
size
--
)
{
static
const
char
*
const
ext
[]
=
{
"TARGETDURATION"
,
"MEDIA-SEQUENCE"
,
"KEY"
,
"ALLOW-CACHE"
,
"ENDLIST"
,
"STREAM-INF"
,
"DISCONTINUITY"
,
"VERSION"
};
if
(
*
peek
++
!=
'#'
)
continue
;
if
(
size
<
6
)
continue
;
if
(
memcmp
(
peek
,
"EXT-X-"
,
6
))
continue
;
peek
+=
6
;
size
-=
6
;
for
(
size_t
i
=
0
;
i
<
ARRAY_SIZE
(
ext
);
i
++
)
{
size_t
len
=
strlen
(
ext
[
i
]);
if
(
size
<
0
||
(
size_t
)
size
<
len
)
continue
;
if
(
!
memcmp
(
peek
,
ext
[
i
],
len
))
return
true
;
}
}
return
false
;
}
static
int
Open
(
vlc_object_t
*
p_obj
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_obj
;
if
(
!
isHTTPLiveStreaming
(
p_demux
->
s
))
return
VLC_EGENERIC
;
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
malloc
(
sizeof
(
demux_sys_t
));
if
(
unlikely
(
p_sys
==
NULL
))
return
VLC_ENOMEM
;
Parser
parser
(
p_demux
->
s
);
p_sys
->
p_playlist
=
parser
.
parse
(
std
::
string
());
if
(
!
p_sys
->
p_playlist
)
{
free
(
p_sys
);
return
VLC_EGENERIC
;
}
int
logic
=
var_InheritInteger
(
p_obj
,
"hls-logic"
);
HLSManager
*
p_manager
=
new
(
std
::
nothrow
)
HLSManager
(
p_sys
->
p_playlist
,
static_cast
<
AbstractAdaptationLogic
::
LogicType
>
(
logic
),
p_demux
->
s
);
BasePeriod
*
period
=
p_sys
->
p_playlist
->
getFirstPeriod
();
if
(
period
&&
!
p_manager
->
start
(
p_demux
))
{
delete
p_manager
;
free
(
p_sys
);
return
VLC_EGENERIC
;
}
p_sys
->
p_manager
=
p_manager
;
p_demux
->
p_sys
=
p_sys
;
p_demux
->
pf_demux
=
Demux
;
p_demux
->
pf_control
=
Control
;
p_sys
->
i_nzpcr
=
VLC_TS_INVALID
;
msg_Dbg
(
p_obj
,
"opening mpd file (%s)"
,
p_demux
->
s
->
psz_path
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Close:
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_obj
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_obj
;
demux_sys_t
*
p_sys
=
(
demux_sys_t
*
)
p_demux
->
p_sys
;
delete
p_sys
->
p_manager
;
free
(
p_sys
);
}
/*****************************************************************************
* Callbacks:
*****************************************************************************/
#define DEMUX_INCREMENT (CLOCK_FREQ / 20)
static
int
Demux
(
demux_t
*
p_demux
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
Stream
::
status
status
=
p_sys
->
p_manager
->
demux
(
p_sys
->
i_nzpcr
+
DEMUX_INCREMENT
);
switch
(
status
)
{
case
Stream
:
:
status_eof
:
return
VLC_DEMUXER_EOF
;
case
Stream
:
:
status_buffering
:
break
;
case
Stream
:
:
status_demuxed
:
if
(
p_sys
->
i_nzpcr
==
VLC_TS_INVALID
)
p_sys
->
i_nzpcr
=
p_sys
->
p_manager
->
getPCR
();
else
p_sys
->
i_nzpcr
+=
DEMUX_INCREMENT
;
int
group
=
p_sys
->
p_manager
->
getGroup
();
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_GROUP_PCR
,
group
,
VLC_TS_0
+
p_sys
->
i_nzpcr
);
break
;
}
if
(
!
p_sys
->
p_manager
->
updatePlaylist
()
)
msg_Warn
(
p_demux
,
"Can't update playlist"
);
return
VLC_DEMUXER_SUCCESS
;
}
static
int
Control
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
{
demux_sys_t
*
p_sys
=
p_demux
->
p_sys
;
switch
(
i_query
)
{
case
DEMUX_CAN_SEEK
:
*
(
va_arg
(
args
,
bool
*
))
=
p_sys
->
p_manager
->
seekAble
();
break
;
case
DEMUX_CAN_CONTROL_PACE
:
*
(
va_arg
(
args
,
bool
*
))
=
true
;
break
;
case
DEMUX_CAN_PAUSE
:
*
(
va_arg
(
args
,
bool
*
))
=
p_sys
->
p_playlist
->
isLive
();
break
;
case
DEMUX_GET_TIME
:
*
(
va_arg
(
args
,
int64_t
*
))
=
p_sys
->
i_nzpcr
;
break
;
case
DEMUX_GET_LENGTH
:
*
(
va_arg
(
args
,
int64_t
*
))
=
p_sys
->
p_manager
->
getDuration
();
break
;
case
DEMUX_GET_POSITION
:
if
(
!
p_sys
->
p_manager
->
getDuration
())
return
VLC_EGENERIC
;
*
(
va_arg
(
args
,
double
*
))
=
(
double
)
p_sys
->
i_nzpcr
/
p_sys
->
p_manager
->
getDuration
();
break
;
case
DEMUX_SET_POSITION
:
{
int64_t
time
=
p_sys
->
p_manager
->
getDuration
()
*
va_arg
(
args
,
double
);
if
(
p_sys
->
p_playlist
->
isLive
()
||
!
p_sys
->
p_manager
->
getDuration
()
||
!
p_sys
->
p_manager
->
setPosition
(
time
))
return
VLC_EGENERIC
;
p_sys
->
i_nzpcr
=
VLC_TS_INVALID
;
break
;
}
case
DEMUX_SET_TIME
:
{
int64_t
time
=
va_arg
(
args
,
int64_t
);
if
(
p_sys
->
p_playlist
->
isLive
()
||
!
p_sys
->
p_manager
->
setPosition
(
time
))
return
VLC_EGENERIC
;
p_sys
->
i_nzpcr
=
VLC_TS_INVALID
;
break
;
}
case
DEMUX_GET_PTS_DELAY
:
*
va_arg
(
args
,
int64_t
*
)
=
INT64_C
(
1000
)
*
var_InheritInteger
(
p_demux
,
"network-caching"
);
break
;
default:
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
modules/demux/hls/hls.hpp
0 → 100644
View file @
9565350a
/*****************************************************************************
* hls.hpp: HTTP Live Streaming module
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifndef HLS_HPP
#define HLS_HPP
struct
demux_sys_t
{
adaptative
::
PlaylistManager
*
p_manager
;
hls
::
playlist
::
M3U8
*
p_playlist
;
mtime_t
i_nzpcr
;
};
#endif // HLS_HPP
modules/demux/hls/playlist/HLSSegment.cpp
0 → 100644
View file @
9565350a
/*
* HLSSegment.cpp
*****************************************************************************
* Copyright (C) 2015 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "HLSSegment.hpp"
#include <vlc_common.h>
#include <vlc_block.h>
#ifdef HAVE_GCRYPT
#include <vlc_gcrypt.h>
#endif
using
namespace
hls
::
playlist
;
SegmentEncryption
::
SegmentEncryption
()
{
method
=
SegmentEncryption
::
NONE
;
}
HLSSegment
::
HLSSegment
(
ICanonicalUrl
*
parent
,
uint64_t
seq
)
:
Segment
(
parent
)
{
sequence
=
seq
;
#ifdef HAVE_GCRYPT
ctx
=
NULL
;
#endif
}
HLSSegment
::~
HLSSegment
()
{
#ifdef HAVE_GCRYPT
if
(
ctx
)
gcry_cipher_close
(
ctx
);
#endif
}
void
HLSSegment
::
onChunkDownload
(
block_t
**
pp_block
,
Chunk
*
chunk
,
BaseRepresentation
*
)
{
block_t
*
p_block
=
*
pp_block
;
#ifdef HAVE_GCRYPT
if
(
encryption
.
method
==
SegmentEncryption
::
AES_128
)
{
block_t
*
p_block
=
*
pp_block
;
/* first bytes */
if
(
!
ctx
&&
chunk
->
getBytesRead
()
==
p_block
->
i_buffer
)
{
vlc_gcrypt_init
();
if
(
encryption
.
iv
.
size
()
!=
16
)
{
encryption
.
iv
.
clear
();
encryption
.
iv
.
resize
(
16
);
encryption
.
iv
[
15
]
=
sequence
&
0xff
;
encryption
.
iv
[
14
]
=
(
sequence
>>
8
)
&
0xff
;
encryption
.
iv
[
13
]
=
(
sequence
>>
16
)
&
0xff
;
encryption
.
iv
[
12
]
=
(
sequence
>>
24
)
&
0xff
;
}
if
(
gcry_cipher_open
(
&
ctx
,
GCRY_CIPHER_AES
,
GCRY_CIPHER_MODE_CBC
,
0
)
||
gcry_cipher_setkey
(
ctx
,
&
encryption
.
key
[
0
],
16
)
||
gcry_cipher_setiv
(
ctx
,
&
encryption
.
iv
[
0
],
16
)
)
{
gcry_cipher_close
(
ctx
);
ctx
=
NULL
;
}
}
if
(
ctx
)
{
if
((
p_block
->
i_buffer
%
16
)
!=
0
||
p_block
->
i_buffer
<
16
||
gcry_cipher_decrypt
(
ctx
,
p_block
->
p_buffer
,
p_block
->
i_buffer
,
NULL
,
0
))
{
p_block
->
i_buffer
=
0
;
gcry_cipher_close
(
ctx
);
ctx
=
NULL
;
}
else
{
/* last bytes */
if
(
chunk
->
getBytesToRead
()
==
0
)
{
/* remove the PKCS#7 padding from the buffer */
const
uint8_t
pad
=
p_block
->
p_buffer
[
p_block
->
i_buffer
-
1
];
for
(
uint8_t
i
=
0
;
i
<
pad
&&
i
<=
16
;
i
++
)
{
if
(
p_block
->
p_buffer
[
p_block
->
i_buffer
-
i
-
1
]
!=
pad
)
break
;
if
(
i
==
pad
)
p_block
->
i_buffer
-=
pad
;
}
gcry_cipher_close
(
ctx
);
ctx
=
NULL
;
}
}
}
}
else
#endif
if
(
encryption
.
method
!=
SegmentEncryption
::
NONE
)
{
p_block
->
i_buffer
=
0
;
}
}
void
HLSSegment
::
setEncryption
(
SegmentEncryption
&
enc
)
{
encryption
=
enc
;
}
void
HLSSegment
::
debug
(
vlc_object_t
*
obj
,
int
indent
)
const
{
std
::
stringstream
ss
;
ss
<<
std
::
string
(
indent
,
' '
)
<<
debugName
<<
" #"
<<
sequence
<<
" url="
<<
getUrlSegment
().
toString
();
if
(
startByte
!=
endByte
)
ss
<<
" @"
<<
startByte
<<
".."
<<
endByte
;
msg_Dbg
(
obj
,
"%s"
,
ss
.
str
().
c_str
());
}
int
HLSSegment
::
compare
(
ISegment
*
segment
)
const
{
HLSSegment
*
hlssegment
=
dynamic_cast
<
HLSSegment
*>
(
segment
);
if
(
hlssegment
)
{
if
(
sequence
>
hlssegment
->
sequence
)
return
1
;
else
if
(
sequence
<
hlssegment
->
sequence
)
return
-
1
;
else
return
0
;
}
else
return
ISegment
::
compare
(
segment
);
}
modules/demux/hls/playlist/HLSSegment.hpp
0 → 100644
View file @
9565350a
/*
* HLSSegment.hpp
*****************************************************************************
* Copyright (C) 2015 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.
*****************************************************************************/
#ifndef HLSSEGMENT_HPP
#define HLSSEGMENT_HPP
#include "../adaptative/playlist/Segment.h"
#include <vector>
#include <gcrypt.h>
namespace
hls
{
namespace
playlist
{
using
namespace
adaptative
::
playlist
;
class
SegmentEncryption
{
public:
SegmentEncryption
();
enum
{
NONE
,
AES_128
,
AES_SAMPLE
,
}
method
;
std
::
vector
<
uint8_t
>
key
;
std
::
vector
<
uint8_t
>
iv
;
};
class
HLSSegment
:
public
Segment
{
public:
HLSSegment
(
ICanonicalUrl
*
parent
,
uint64_t
sequence
);
virtual
~
HLSSegment
();
void
setEncryption
(
SegmentEncryption
&
);
void
debug
(
vlc_object_t
*
,
int
)
const
;
/* reimpl */
virtual
int
compare
(
ISegment
*
)
const
;
/* reimpl */
protected:
virtual
void
onChunkDownload
(
block_t
**
,
Chunk
*
,
BaseRepresentation
*
);
/* reimpl */
uint64_t
sequence
;
SegmentEncryption
encryption
;
#ifdef HAVE_GCRYPT
gcry_cipher_hd_t
ctx
;
#endif
};
}
}
#endif // HLSSEGMENT_HPP
modules/demux/hls/playlist/M3U8.cpp
0 → 100644
View file @
9565350a
/*
* M3U8.cpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "M3U8.hpp"
#include "Representation.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include <vlc_common.h>
#include <vlc_stream.h>
using
namespace
hls
::
playlist
;
M3U8
::
M3U8
(
stream_t
*
stream_
)
:
AbstractPlaylist
(
stream_
)
{
minUpdatePeriod
.
Set
(
5
);
}
M3U8
::~
M3U8
()
{
}
bool
M3U8
::
isLive
()
const
{
std
::
vector
<
BasePeriod
*>::
const_iterator
itp
;
for
(
itp
=
periods
.
begin
();
itp
!=
periods
.
end
();
++
itp
)
{
const
BasePeriod
*
period
=
*
itp
;
std
::
vector
<
BaseAdaptationSet
*>::
const_iterator
ita
;
for
(
ita
=
period
->
getAdaptationSets
().
begin
();
ita
!=
period
->
getAdaptationSets
().
end
();
++
ita
)
{
BaseAdaptationSet
*
adaptSet
=
*
ita
;
std
::
vector
<
BaseRepresentation
*>::
iterator
itr
;
for
(
itr
=
adaptSet
->
getRepresentations
().
begin
();
itr
!=
adaptSet
->
getRepresentations
().
end
();
++
itr
)
{
const
Representation
*
rep
=
dynamic_cast
<
const
Representation
*>
(
*
itr
);
if
(
rep
->
isLive
())
return
true
;
}
}
}
return
false
;
}
void
M3U8
::
debug
()
{
std
::
vector
<
BasePeriod
*>::
const_iterator
i
;
for
(
i
=
periods
.
begin
();
i
!=
periods
.
end
();
++
i
)
(
*
i
)
->
debug
(
VLC_OBJECT
(
stream
));
}
modules/demux/hls/playlist/M3U8.hpp
0 → 100644
View file @
9565350a
/*
* M3U8.hpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifndef M3U8_H_
#define M3U8_H_
#include "../adaptative/playlist/AbstractPlaylist.hpp"
namespace
hls
{
namespace
playlist
{
using
namespace
adaptative
::
playlist
;
class
M3U8
:
public
AbstractPlaylist
{
public:
M3U8
(
stream_t
*
);
virtual
~
M3U8
();
virtual
bool
isLive
()
const
;
virtual
void
debug
();
private:
std
::
string
data
;
};
}
}
#endif
/* M3U8_H_ */
modules/demux/hls/playlist/Parser.cpp
0 → 100644
View file @
9565350a
/*
* Parser.cpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "Parser.hpp"
#include "playlist/HLSSegment.hpp"
#include "playlist/Representation.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include "../adaptative/playlist/SegmentList.h"
#include "../adaptative/tools/Retrieve.hpp"
#include "M3U8.hpp"
#include "Tags.hpp"
#include <vlc_strings.h>
#include <vlc_stream.h>
#include <cstdio>
#include <sstream>
using
namespace
adaptative
;
using
namespace
adaptative
::
playlist
;
using
namespace
hls
::
playlist
;
Parser
::
Parser
(
stream_t
*
stream
)
{
p_stream
=
stream
;
}
Parser
::~
Parser
()
{
}
static
std
::
list
<
Tag
*>
getTagsFromList
(
std
::
list
<
Tag
*>
&
list
,
int
tag
)
{
std
::
list
<
Tag
*>
ret
;
std
::
list
<
Tag
*>::
const_iterator
it
;
for
(
it
=
list
.
begin
();
it
!=
list
.
end
();
++
it
)
{
if
(
(
*
it
)
->
getType
()
==
tag
)
ret
.
push_back
(
*
it
);
}
return
ret
;
}
static
void
releaseTagsList
(
std
::
list
<
Tag
*>
&
list
)
{
std
::
list
<
Tag
*>::
const_iterator
it
;
for
(
it
=
list
.
begin
();
it
!=
list
.
end
();
++
it
)
delete
*
it
;
list
.
clear
();
}
void
Parser
::
parseAdaptationSet
(
BasePeriod
*
period
,
const
AttributesTag
*
)
{
BaseAdaptationSet
*
adaptSet
=
new
(
std
::
nothrow
)
BaseAdaptationSet
(
period
);
if
(
adaptSet
)
{
period
->
addAdaptationSet
(
adaptSet
);
}
}
void
Parser
::
parseRepresentation
(
BaseAdaptationSet
*
adaptSet
,
const
AttributesTag
*
streaminftag
)
{
if
(
!
streaminftag
->
getAttributeByName
(
"URI"
))
return
;
Url
url
=
Url
(
streaminftag
->
getAttributeByName
(
"URI"
)
->
value
);
if
(
!
url
.
hasScheme
())
url
=
url
.
prepend
(
adaptSet
->
getUrlSegment
());
void
*
p_data
;
const
size_t
i_data
=
Retrieve
::
HTTP
((
vlc_object_t
*
)
p_stream
,
url
.
toString
(),
&
p_data
);
if
(
p_data
)
{
stream_t
*
substream
=
stream_MemoryNew
((
vlc_object_t
*
)
p_stream
,
(
uint8_t
*
)
p_data
,
i_data
,
false
);
if
(
substream
)
{
std
::
list
<
Tag
*>
tagslist
=
parseEntries
(
substream
);
stream_Delete
(
substream
);
parseRepresentation
(
adaptSet
,
streaminftag
,
tagslist
);
releaseTagsList
(
tagslist
);
}
}
}
void
Parser
::
parseRepresentation
(
BaseAdaptationSet
*
adaptSet
,
const
AttributesTag
*
streaminftag
,
const
std
::
list
<
Tag
*>
&
tagslist
)
{
const
Attribute
*
uriAttr
=
streaminftag
->
getAttributeByName
(
"URI"
);
const
Attribute
*
bwAttr
=
streaminftag
->
getAttributeByName
(
"BANDWIDTH"
);
Representation
*
rep
=
new
(
std
::
nothrow
)
Representation
(
adaptSet
);
if
(
rep
)
{
rep
->
setMimeType
(
"video/mp2t"
);
if
(
uriAttr
)
{
size_t
pos
=
uriAttr
->
value
.
find_last_of
(
'/'
);
if
(
pos
!=
std
::
string
::
npos
)
rep
->
baseUrl
.
Set
(
new
Url
(
uriAttr
->
value
.
substr
(
0
,
pos
+
1
)));
}
if
(
bwAttr
)
rep
->
setBandwidth
(
bwAttr
->
decimal
());
parseSegments
(
rep
,
tagslist
);
adaptSet
->
addRepresentation
(
rep
);
}
}
void
Parser
::
parseSegments
(
Representation
*
rep
,
const
std
::
list
<
Tag
*>
&
tagslist
)
{
SegmentList
*
segmentList
=
new
(
std
::
nothrow
)
SegmentList
(
rep
);
rep
->
setSegmentList
(
segmentList
);
rep
->
timescale
.
Set
(
100
);
int64_t
totalduration
=
0
;
int64_t
nzStartTime
=
0
;
uint64_t
sequenceNumber
=
0
;
std
::
size_t
prevbyterangeoffset
=
0
;
const
SingleValueTag
*
ctx_byterange
=
NULL
;
SegmentEncryption
encryption
;
std
::
list
<
Tag
*>::
const_iterator
it
;
for
(
it
=
tagslist
.
begin
();
it
!=
tagslist
.
end
();
++
it
)
{
const
Tag
*
tag
=
*
it
;
switch
(
tag
->
getType
())
{
/* using static cast as attribute type permits avoiding class check */
case
SingleValueTag
:
:
EXTXMEDIASEQUENCE
:
{
sequenceNumber
=
(
static_cast
<
const
SingleValueTag
*>
(
tag
))
->
getValue
().
decimal
();
}
break
;
case
URITag
:
:
EXTINF
:
{
const
URITag
*
uritag
=
static_cast
<
const
URITag
*>
(
tag
);
HLSSegment
*
segment
=
new
(
std
::
nothrow
)
HLSSegment
(
rep
,
sequenceNumber
++
);
if
(
!
segment
)
break
;
if
(
uritag
->
getAttributeByName
(
"URI"
))
segment
->
setSourceUrl
(
uritag
->
getAttributeByName
(
"URI"
)
->
value
);
if
(
uritag
->
getAttributeByName
(
"DURATION"
))
{
segment
->
duration
.
Set
(
uritag
->
getAttributeByName
(
"DURATION"
)
->
floatingPoint
()
*
rep
->
timescale
.
Get
());
segment
->
startTime
.
Set
(
nzStartTime
);
nzStartTime
+=
segment
->
duration
.
Get
();
totalduration
+=
segment
->
duration
.
Get
();
}
segmentList
->
addSegment
(
segment
);
if
(
ctx_byterange
)
{
std
::
pair
<
std
::
size_t
,
std
::
size_t
>
range
=
ctx_byterange
->
getValue
().
getByteRange
();
if
(
range
.
first
==
0
)
range
.
first
=
prevbyterangeoffset
;
prevbyterangeoffset
=
range
.
first
+
range
.
second
;
segment
->
setByteRange
(
range
.
first
,
prevbyterangeoffset
);
ctx_byterange
=
NULL
;
}
if
(
encryption
.
method
!=
SegmentEncryption
::
NONE
)
segment
->
setEncryption
(
encryption
);
}
break
;
case
SingleValueTag
:
:
EXTXPLAYLISTTYPE
:
rep
->
b_live
=
(
static_cast
<
const
SingleValueTag
*>
(
tag
)
->
getValue
().
value
!=
"VOD"
);
break
;
case
SingleValueTag
:
:
EXTXBYTERANGE
:
ctx_byterange
=
static_cast
<
const
SingleValueTag
*>
(
tag
);
break
;
case
AttributesTag
:
:
EXTXKEY
:
{
const
AttributesTag
*
keytag
=
static_cast
<
const
AttributesTag
*>
(
tag
);
if
(
keytag
->
getAttributeByName
(
"METHOD"
)
&&
keytag
->
getAttributeByName
(
"METHOD"
)
->
value
==
"AES-128"
&&
keytag
->
getAttributeByName
(
"URI"
)
)
{
encryption
.
method
=
SegmentEncryption
::
AES_128
;
encryption
.
key
.
clear
();
uint8_t
*
p_data
;
const
uint64_t
read
=
Retrieve
::
HTTP
(
VLC_OBJECT
(
p_stream
),
keytag
->
getAttributeByName
(
"URI"
)
->
quotedString
(),
(
void
**
)
&
p_data
);
if
(
p_data
)
{
if
(
read
==
16
)
{
encryption
.
key
.
resize
(
16
);
memcpy
(
&
encryption
.
key
[
0
],
p_data
,
16
);
}
free
(
p_data
);
}
if
(
keytag
->
getAttributeByName
(
"IV"
))
{
encryption
.
iv
.
clear
();
encryption
.
iv
=
keytag
->
getAttributeByName
(
"IV"
)
->
hexSequence
();
}
}
else
{
/* unsupported or invalid */
encryption
.
method
=
SegmentEncryption
::
NONE
;
encryption
.
key
.
clear
();
encryption
.
iv
.
clear
();
}
}
break
;
case
Tag
:
:
EXTXENDLIST
:
rep
->
b_live
=
false
;
break
;
}
}
if
(
rep
->
isLive
())
{
rep
->
getPlaylist
()
->
duration
.
Set
(
0
);
}
else
if
(
totalduration
>
rep
->
getPlaylist
()
->
duration
.
Get
())
{
rep
->
getPlaylist
()
->
duration
.
Set
(
CLOCK_FREQ
*
totalduration
/
rep
->
timescale
.
Get
());
}
}
M3U8
*
Parser
::
parse
(
const
std
::
string
&
playlisturl
)
{
char
*
psz_line
=
stream_ReadLine
(
p_stream
);
if
(
!
psz_line
||
strcmp
(
psz_line
,
"#EXTM3U"
))
{
free
(
psz_line
);
return
NULL
;
}
M3U8
*
playlist
=
new
(
std
::
nothrow
)
M3U8
(
p_stream
);
if
(
!
playlist
)
return
NULL
;
if
(
!
playlisturl
.
empty
())
{
size_t
pos
=
playlisturl
.
find_last_of
(
'/'
);
if
(
pos
!=
std
::
string
::
npos
)
playlist
->
addBaseUrl
(
playlisturl
.
substr
(
0
,
pos
+
1
));
}
BasePeriod
*
period
=
new
(
std
::
nothrow
)
BasePeriod
(
playlist
);
if
(
!
period
)
return
playlist
;
std
::
list
<
Tag
*>
tagslist
=
parseEntries
(
p_stream
);
bool
b_masterplaylist
=
!
getTagsFromList
(
tagslist
,
AttributesTag
::
EXTXSTREAMINF
).
empty
();
if
(
b_masterplaylist
)
{
BaseAdaptationSet
*
adaptSet
=
new
(
std
::
nothrow
)
BaseAdaptationSet
(
period
);
if
(
adaptSet
)
{
std
::
list
<
Tag
*>
mediainfotags
=
getTagsFromList
(
tagslist
,
AttributesTag
::
EXTXSTREAMINF
);
std
::
list
<
Tag
*>::
const_iterator
it
;
for
(
it
=
mediainfotags
.
begin
();
it
!=
mediainfotags
.
end
();
++
it
)
parseRepresentation
(
adaptSet
,
dynamic_cast
<
AttributesTag
*>
(
*
it
));
period
->
addAdaptationSet
(
adaptSet
);
}
}
else
{
BaseAdaptationSet
*
adaptSet
=
new
(
std
::
nothrow
)
BaseAdaptationSet
(
period
);
if
(
adaptSet
)
{
period
->
addAdaptationSet
(
adaptSet
);
AttributesTag
*
tag
=
new
AttributesTag
(
AttributesTag
::
EXTXSTREAMINF
,
""
);
parseRepresentation
(
adaptSet
,
tag
,
tagslist
);
delete
tag
;
}
}
playlist
->
addPeriod
(
period
);
releaseTagsList
(
tagslist
);
playlist
->
debug
();
return
playlist
;
}
std
::
list
<
Tag
*>
Parser
::
parseEntries
(
stream_t
*
stream
)
{
std
::
list
<
Tag
*>
entrieslist
;
Tag
*
lastTag
=
NULL
;
char
*
psz_line
;
while
((
psz_line
=
stream_ReadLine
(
stream
)))
{
if
(
*
psz_line
==
'#'
)
{
if
(
!
strncmp
(
psz_line
,
"#EXT"
,
4
))
//tag
{
std
::
string
key
;
std
::
string
attributes
;
const
char
*
split
=
strchr
(
psz_line
,
':'
);
if
(
split
)
{
key
=
std
::
string
(
psz_line
+
1
,
split
-
psz_line
-
1
);
attributes
=
std
::
string
(
split
+
1
);
}
else
{
key
=
std
::
string
(
psz_line
);
}
if
(
!
key
.
empty
())
{
Tag
*
tag
=
TagFactory
::
createTagByName
(
key
,
attributes
);
if
(
tag
)
entrieslist
.
push_back
(
tag
);
lastTag
=
tag
;
}
}
}
else
if
(
*
psz_line
&&
lastTag
)
{
AttributesTag
*
attrTag
=
dynamic_cast
<
AttributesTag
*>
(
lastTag
);
if
(
attrTag
)
{
Attribute
*
uriAttr
=
new
(
std
::
nothrow
)
Attribute
(
"URI"
,
std
::
string
(
psz_line
));
if
(
uriAttr
)
attrTag
->
addAttribute
(
uriAttr
);
}
lastTag
=
NULL
;
}
else
// drop
{
lastTag
=
NULL
;
}
free
(
psz_line
);
}
return
entrieslist
;
}
modules/demux/hls/playlist/Parser.hpp
0 → 100644
View file @
9565350a
/*
* Parser.hpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifndef PARSER_HPP
#define PARSER_HPP
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "../adaptative/playlist/SegmentInfoCommon.h"
#include <cstdlib>
#include <sstream>
#include <vlc_common.h>
namespace
adaptative
{
namespace
playlist
{
class
SegmentInformation
;
class
MediaSegmentTemplate
;
class
BasePeriod
;
class
BaseAdaptationSet
;
}
}
namespace
hls
{
namespace
playlist
{
using
namespace
adaptative
::
playlist
;
class
M3U8
;
class
AttributesTag
;
class
Tag
;
class
Representation
;
class
Parser
{
public:
Parser
(
stream_t
*
p_stream
);
virtual
~
Parser
();
M3U8
*
parse
(
const
std
::
string
&
);
private:
void
parseAdaptationSet
(
BasePeriod
*
,
const
AttributesTag
*
);
void
parseRepresentation
(
BaseAdaptationSet
*
,
const
AttributesTag
*
);
void
parseRepresentation
(
BaseAdaptationSet
*
,
const
AttributesTag
*
,
const
std
::
list
<
Tag
*>&
);
void
parseSegments
(
Representation
*
,
const
std
::
list
<
Tag
*>&
);
std
::
list
<
Tag
*>
parseEntries
(
stream_t
*
);
stream_t
*
p_stream
;
};
}
}
#endif // PARSER_HPP
modules/demux/hls/playlist/Representation.cpp
0 → 100644
View file @
9565350a
/*
* Representation.cpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <cstdlib>
#include "Representation.hpp"
#include "M3U8.hpp"
#include "../adaptative/playlist/BasePeriod.h"
#include "../adaptative/playlist/BaseAdaptationSet.h"
#include "../adaptative/playlist/SegmentList.h"
using
namespace
hls
::
playlist
;
Representation
::
Representation
(
BaseAdaptationSet
*
set
)
:
BaseRepresentation
(
set
)
{
b_live
=
true
;
}
Representation
::~
Representation
()
{
}
bool
Representation
::
isLive
()
const
{
return
b_live
;
}
void
Representation
::
localMergeWithPlaylist
(
M3U8
*
updated
,
mtime_t
prunebarrier
)
{
BasePeriod
*
period
=
updated
->
getFirstPeriod
();
if
(
!
period
)
return
;
BaseAdaptationSet
*
adapt
=
period
->
getAdaptationSets
().
front
();
if
(
!
adapt
)
return
;
BaseRepresentation
*
rep
=
adapt
->
getRepresentations
().
front
();
if
(
!
rep
)
return
;
this
->
mergeWith
(
rep
,
prunebarrier
);
}
void
Representation
::
mergeWith
(
SegmentInformation
*
seginfo
,
mtime_t
prunebarrier
)
{
BaseRepresentation
::
mergeWith
(
seginfo
,
prunebarrier
);
}
modules/demux/hls/playlist/Representation.hpp
0 → 100644
View file @
9565350a
/*
* Representation.hpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifndef HLSREPRESENTATION_H_
#define HLSREPRESENTATION_H_
#include "../adaptative/playlist/BaseRepresentation.h"
#include "../adaptative/tools/Properties.hpp"
namespace
hls
{
namespace
playlist
{
class
M3U8
;
using
namespace
adaptative
::
playlist
;
class
Representation
:
public
BaseRepresentation
{
friend
class
Parser
;
public:
Representation
(
BaseAdaptationSet
*
);
virtual
~
Representation
();
void
localMergeWithPlaylist
(
M3U8
*
,
mtime_t
);
bool
isLive
()
const
;
virtual
void
mergeWith
(
SegmentInformation
*
,
mtime_t
);
/* reimpl */
private:
bool
b_live
;
Property
<
std
::
string
>
playlistUrl
;
Property
<
std
::
string
>
audio
;
Property
<
std
::
string
>
video
;
Property
<
std
::
string
>
subtitles
;
Property
<
std
::
string
>
closedcaptions
;
};
}
}
#endif
/* HLSREPRESENTATION_H_ */
modules/demux/hls/playlist/Tags.cpp
0 → 100644
View file @
9565350a
/*
* Tags.cpp
*****************************************************************************
* Copyright © 2015 - 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 "Tags.hpp"
#include <sstream>
#include <stack>
#define __STDC_CONSTANT_MACROS
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
using
namespace
hls
::
playlist
;
Attribute
::
Attribute
(
const
std
::
string
&
name_
,
const
std
::
string
&
value_
)
{
name
=
name_
;
value
=
value_
;
}
uint64_t
Attribute
::
decimal
()
const
{
std
::
istringstream
is
(
value
);
uint64_t
ret
;
is
>>
ret
;
return
ret
;
}
double
Attribute
::
floatingPoint
()
const
{
std
::
istringstream
is
(
value
);
is
.
imbue
(
std
::
locale
(
""
));
double
ret
;
is
>>
ret
;
return
ret
;
}
std
::
vector
<
uint8_t
>
Attribute
::
hexSequence
()
const
{
std
::
vector
<
uint8_t
>
ret
;
if
(
value
.
length
()
>
2
&&
(
value
.
substr
(
0
,
2
)
==
"0X"
||
value
.
substr
(
0
,
2
)
==
"0x"
)
)
{
for
(
size_t
i
=
2
;
i
<=
(
value
.
length
()
-
2
);
i
+=
2
)
{
unsigned
val
;
std
::
stringstream
ss
(
value
.
substr
(
i
,
2
));
ss
>>
std
::
hex
>>
val
;
ret
.
push_back
(
val
);
}
}
return
ret
;
}
std
::
pair
<
std
::
size_t
,
std
::
size_t
>
Attribute
::
getByteRange
()
const
{
std
::
pair
<
std
::
size_t
,
std
::
size_t
>
ret
;
std
::
size_t
length
=
0
;
std
::
size_t
offset
=
0
;
std
::
istringstream
is
(
value
);
if
(
!
is
.
eof
())
{
is
>>
length
;
if
(
!
is
.
eof
())
{
char
c
=
is
.
get
();
if
(
c
==
'@'
&&
!
is
.
eof
())
is
>>
offset
;
}
}
ret
=
std
::
make_pair
(
offset
,
length
);
return
ret
;
}
std
::
string
Attribute
::
quotedString
()
const
{
if
(
value
.
length
()
<
2
)
return
""
;
std
::
istringstream
is
(
value
.
substr
(
1
,
value
.
length
()
-
2
));
std
::
ostringstream
os
;
char
c
;
while
(
is
.
get
(
c
))
{
if
(
c
==
'\\'
)
{
if
(
!
is
.
get
(
c
))
break
;
}
os
<<
c
;
}
return
os
.
str
();
}
Tag
::
Tag
(
int
type_
)
{
type
=
type_
;
}
Tag
::~
Tag
()
{
}
int
Tag
::
getType
()
const
{
return
type
;
}
SingleValueTag
::
SingleValueTag
(
int
type
,
const
std
::
string
&
v
)
:
Tag
(
type
),
attr
(
""
,
v
)
{
}
SingleValueTag
::~
SingleValueTag
()
{
}
const
Attribute
&
SingleValueTag
::
getValue
()
const
{
return
attr
;
}
AttributesTag
::
AttributesTag
(
int
type
,
const
std
::
string
&
v
)
:
Tag
(
type
)
{
parseAttributes
(
v
);
}
AttributesTag
::~
AttributesTag
()
{
std
::
list
<
Attribute
*>::
const_iterator
it
;
for
(
it
=
attributes
.
begin
();
it
!=
attributes
.
end
();
++
it
)
delete
*
it
;
}
const
Attribute
*
AttributesTag
::
getAttributeByName
(
const
char
*
name
)
const
{
std
::
list
<
Attribute
*>::
const_iterator
it
;
for
(
it
=
attributes
.
begin
();
it
!=
attributes
.
end
();
++
it
)
if
((
*
it
)
->
name
==
name
)
return
*
it
;
return
NULL
;
}
void
AttributesTag
::
addAttribute
(
Attribute
*
attr
)
{
attributes
.
push_back
(
attr
);
}
void
AttributesTag
::
parseAttributes
(
const
std
::
string
&
field
)
{
std
::
istringstream
iss
(
field
);
std
::
ostringstream
oss
;
while
(
!
iss
.
eof
())
{
/* parse attribute name */
while
(
!
iss
.
eof
())
{
char
c
=
iss
.
peek
();
if
((
c
>=
'A'
&&
c
<=
'Z'
)
||
c
==
'-'
)
{
oss
.
put
((
char
)
iss
.
get
());
}
else
if
(
c
==
'='
)
{
iss
.
get
();
break
;
}
else
/* out of range */
return
;
}
std
::
string
attrname
=
oss
.
str
();
oss
.
str
(
""
);
/* parse attributes value */
bool
b_quoted
=
false
;
while
(
!
iss
.
eof
())
{
char
c
=
iss
.
peek
();
if
(
c
==
'\\'
&&
b_quoted
)
{
iss
.
get
();
}
else
if
(
c
==
','
&&
!
b_quoted
)
{
iss
.
get
();
break
;
}
else
if
(
c
==
'"'
)
{
b_quoted
=
!
b_quoted
;
}
if
(
!
iss
.
eof
())
oss
.
put
((
char
)
iss
.
get
());
}
std
::
string
attrvalue
=
oss
.
str
();
oss
.
str
(
""
);
Attribute
*
attribute
=
new
(
std
::
nothrow
)
Attribute
(
attrname
,
attrvalue
);
if
(
attribute
)
attributes
.
push_back
(
attribute
);
}
}
URITag
::
URITag
(
const
std
::
string
&
v
)
:
AttributesTag
(
URITag
::
EXTINF
,
v
)
{
parseAttributes
(
v
);
}
URITag
::~
URITag
()
{
}
void
URITag
::
parseAttributes
(
const
std
::
string
&
field
)
{
std
::
size_t
pos
=
field
.
find
(
','
);
if
(
pos
!=
std
::
string
::
npos
)
{
Attribute
*
attr
=
new
(
std
::
nothrow
)
Attribute
(
"DURATION"
,
field
.
substr
(
0
,
pos
));
if
(
attr
)
addAttribute
(
attr
);
attr
=
new
(
std
::
nothrow
)
Attribute
(
"TITLE"
,
field
.
substr
(
pos
));
if
(
attr
)
addAttribute
(
attr
);
}
}
Tag
*
TagFactory
::
createTagByName
(
const
std
::
string
&
name
,
const
std
::
string
&
value
)
{
struct
{
const
char
*
psz
;
const
int
i
;
}
const
exttagmapping
[]
=
{
{
"EXT-X-BYTERANGE"
,
SingleValueTag
::
EXTXBYTERANGE
},
{
"EXT-X-DISCONTINUITY"
,
Tag
::
EXTXDISCONTINUITY
},
{
"EXT-X-KEY"
,
AttributesTag
::
EXTXKEY
},
{
"EXT-X-MAP"
,
AttributesTag
::
EXTXMAP
},
{
"EXT-X-PROGRAM-DATE-TIME"
,
SingleValueTag
::
EXTXPROGRAMDATETIME
},
{
"EXT-X-TARGETDURATION"
,
SingleValueTag
::
EXTXTARGETDURATION
},
{
"EXT-X-MEDIA-SEQUENCE"
,
SingleValueTag
::
EXTXMEDIASEQUENCE
},
{
"EXT-X-DISCONTINUITY-SEQUENCE"
,
SingleValueTag
::
EXTXDISCONTINUITYSEQUENCE
},
{
"EXT-X-ENDLIST"
,
Tag
::
EXTXENDLIST
},
{
"EXT-X-PLAYLIST-TYPE"
,
SingleValueTag
::
EXTXPLAYLISTTYPE
},
{
"EXT-X-I-FRAMES-ONLY"
,
Tag
::
EXTXIFRAMESONLY
},
{
"EXT-X-MEDIA"
,
AttributesTag
::
EXTXMEDIA
},
{
"EXT-X-STREAM-INF"
,
AttributesTag
::
EXTXSTREAMINF
},
{
"EXTINF"
,
URITag
::
EXTINF
},
{
NULL
,
0
},
};
for
(
int
i
=
0
;
exttagmapping
[
i
].
psz
;
i
++
)
{
if
(
name
!=
exttagmapping
[
i
].
psz
)
continue
;
switch
(
exttagmapping
[
i
].
i
)
{
case
Tag
:
:
EXTXDISCONTINUITY
:
case
Tag
:
:
EXTXENDLIST
:
case
Tag
:
:
EXTXIFRAMESONLY
:
return
new
(
std
::
nothrow
)
Tag
(
exttagmapping
[
i
].
i
);
case
SingleValueTag
:
:
EXTXVERSION
:
case
SingleValueTag
:
:
EXTXBYTERANGE
:
case
SingleValueTag
:
:
EXTXPROGRAMDATETIME
:
case
SingleValueTag
:
:
EXTXTARGETDURATION
:
case
SingleValueTag
:
:
EXTXMEDIASEQUENCE
:
case
SingleValueTag
:
:
EXTXDISCONTINUITYSEQUENCE
:
case
SingleValueTag
:
:
EXTXPLAYLISTTYPE
:
return
new
(
std
::
nothrow
)
SingleValueTag
(
exttagmapping
[
i
].
i
,
value
);
case
AttributesTag
:
:
EXTXKEY
:
case
AttributesTag
:
:
EXTXMAP
:
case
AttributesTag
:
:
EXTXMEDIA
:
case
AttributesTag
:
:
EXTXSTREAMINF
:
return
new
(
std
::
nothrow
)
AttributesTag
(
exttagmapping
[
i
].
i
,
value
);
case
URITag
:
:
EXTINF
:
return
new
URITag
(
value
);
}
}
return
NULL
;
}
modules/demux/hls/playlist/Tags.hpp
0 → 100644
View file @
9565350a
/*
* Tags.hpp
*****************************************************************************
* Copyright © 2015 - 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.
*****************************************************************************/
#ifndef TAGS_HPP
#define TAGS_HPP
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdint.h>
#include <string>
#include <vector>
#include <list>
#include <utility>
namespace
hls
{
namespace
playlist
{
class
Attribute
{
public:
Attribute
(
const
std
::
string
&
,
const
std
::
string
&
);
uint64_t
decimal
()
const
;
std
::
string
quotedString
()
const
;
double
floatingPoint
()
const
;
std
::
vector
<
uint8_t
>
hexSequence
()
const
;
std
::
pair
<
std
::
size_t
,
std
::
size_t
>
getByteRange
()
const
;
std
::
string
name
;
std
::
string
value
;
};
class
Tag
{
public:
enum
{
EXTXDISCONTINUITY
=
0
,
EXTXENDLIST
,
EXTXIFRAMESONLY
,
};
Tag
(
int
);
virtual
~
Tag
();
int
getType
()
const
;
private:
int
type
;
};
class
SingleValueTag
:
public
Tag
{
public:
enum
{
EXTXVERSION
=
10
,
EXTXBYTERANGE
,
EXTXPROGRAMDATETIME
,
EXTXTARGETDURATION
,
EXTXMEDIASEQUENCE
,
EXTXDISCONTINUITYSEQUENCE
,
EXTXPLAYLISTTYPE
,
};
SingleValueTag
(
int
,
const
std
::
string
&
);
virtual
~
SingleValueTag
();
const
Attribute
&
getValue
()
const
;
private:
Attribute
attr
;
};
class
AttributesTag
:
public
Tag
{
public:
enum
{
EXTXKEY
=
20
,
EXTXMAP
,
EXTXMEDIA
,
EXTXSTREAMINF
,
};
AttributesTag
(
int
,
const
std
::
string
&
);
virtual
~
AttributesTag
();
const
Attribute
*
getAttributeByName
(
const
char
*
)
const
;
void
addAttribute
(
Attribute
*
);
protected:
virtual
void
parseAttributes
(
const
std
::
string
&
);
std
::
list
<
Attribute
*>
attributes
;
};
class
URITag
:
public
AttributesTag
{
public:
enum
{
EXTINF
=
30
};
URITag
(
const
std
::
string
&
);
virtual
~
URITag
();
protected:
virtual
void
parseAttributes
(
const
std
::
string
&
);
};
class
TagFactory
{
public:
static
Tag
*
createTagByName
(
const
std
::
string
&
,
const
std
::
string
&
);
static
Attribute
*
createAttributeByName
(
const
std
::
string
&
);
};
}
}
#endif // TAGS_HPP
po/POTFILES.in
View file @
9565350a
...
@@ -465,6 +465,7 @@ modules/demux/demuxdump.c
...
@@ -465,6 +465,7 @@ modules/demux/demuxdump.c
modules/demux/dirac.c
modules/demux/dirac.c
modules/demux/flac.c
modules/demux/flac.c
modules/demux/gme.c
modules/demux/gme.c
modules/demux/hls/hls.cpp
modules/demux/image.c
modules/demux/image.c
modules/demux/mjpeg.c
modules/demux/mjpeg.c
modules/demux/mkv/chapter_command.cpp
modules/demux/mkv/chapter_command.cpp
...
...
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