Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
da49cdf6
Commit
da49cdf6
authored
Nov 29, 2017
by
Karthick J
Committed by
Steven Liu
Nov 29, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avformat/hlsenc: Modularized playlist creation to allow reuse
parent
eb69e7be
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
211 additions
and
95 deletions
+211
-95
Makefile
libavformat/Makefile
+1
-1
hlsenc.c
libavformat/hlsenc.c
+21
-94
hlsplaylist.c
libavformat/hlsplaylist.c
+138
-0
hlsplaylist.h
libavformat/hlsplaylist.h
+51
-0
No files found.
libavformat/Makefile
View file @
da49cdf6
...
...
@@ -215,7 +215,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o
OBJS-$(CONFIG_HEVC_DEMUXER)
+=
hevcdec.o
rawdec.o
OBJS-$(CONFIG_HEVC_MUXER)
+=
rawenc.o
OBJS-$(CONFIG_HLS_DEMUXER)
+=
hls.o
OBJS-$(CONFIG_HLS_MUXER)
+=
hlsenc.o
OBJS-$(CONFIG_HLS_MUXER)
+=
hlsenc.o
hlsplaylist.o
OBJS-$(CONFIG_HNM_DEMUXER)
+=
hnm.o
OBJS-$(CONFIG_ICO_DEMUXER)
+=
icodec.o
OBJS-$(CONFIG_ICO_MUXER)
+=
icoenc.o
...
...
libavformat/hlsenc.c
View file @
da49cdf6
...
...
@@ -46,6 +46,7 @@
#include "avformat.h"
#include "avio_internal.h"
#include "http.h"
#include "hlsplaylist.h"
#include "internal.h"
#include "os_support.h"
...
...
@@ -97,13 +98,6 @@ typedef enum {
SEGMENT_TYPE_FMP4
,
}
SegmentType
;
typedef
enum
{
PLAYLIST_TYPE_NONE
,
PLAYLIST_TYPE_EVENT
,
PLAYLIST_TYPE_VOD
,
PLAYLIST_TYPE_NB
,
}
PlaylistType
;
typedef
struct
VariantStream
{
unsigned
number
;
int64_t
sequence
;
...
...
@@ -1055,19 +1049,6 @@ static void hls_free_segments(HLSSegment *p)
}
}
static
void
write_m3u8_head_block
(
HLSContext
*
hls
,
AVIOContext
*
out
,
int
version
,
int
target_duration
,
int64_t
sequence
)
{
avio_printf
(
out
,
"#EXTM3U
\n
"
);
avio_printf
(
out
,
"#EXT-X-VERSION:%d
\n
"
,
version
);
if
(
hls
->
allowcache
==
0
||
hls
->
allowcache
==
1
)
{
avio_printf
(
out
,
"#EXT-X-ALLOW-CACHE:%s
\n
"
,
hls
->
allowcache
==
0
?
"NO"
:
"YES"
);
}
avio_printf
(
out
,
"#EXT-X-TARGETDURATION:%d
\n
"
,
target_duration
);
avio_printf
(
out
,
"#EXT-X-MEDIA-SEQUENCE:%"
PRId64
"
\n
"
,
sequence
);
av_log
(
hls
,
AV_LOG_VERBOSE
,
"EXT-X-MEDIA-SEQUENCE:%"
PRId64
"
\n
"
,
sequence
);
}
static
void
hls_rename_temp_file
(
AVFormatContext
*
s
,
AVFormatContext
*
oc
)
{
size_t
len
=
strlen
(
oc
->
filename
);
...
...
@@ -1133,8 +1114,7 @@ static int create_master_playlist(AVFormatContext *s,
goto
fail
;
}
avio_printf
(
master_pb
,
"#EXTM3U
\n
"
);
avio_printf
(
master_pb
,
"#EXT-X-VERSION:%d
\n
"
,
hls
->
version
);
ff_hls_write_playlist_version
(
master_pb
,
hls
->
version
);
/* For variant streams with video add #EXT-X-STREAM-INF tag with attributes*/
for
(
i
=
0
;
i
<
hls
->
nb_varstreams
;
i
++
)
{
...
...
@@ -1175,18 +1155,7 @@ static int create_master_playlist(AVFormatContext *s,
bandwidth
+=
aud_st
->
codecpar
->
bit_rate
;
bandwidth
+=
bandwidth
/
10
;
if
(
!
bandwidth
)
{
av_log
(
NULL
,
AV_LOG_WARNING
,
"Bandwidth info not available, set audio and video bitrates
\n
"
);
av_freep
(
&
m3u8_rel_name
);
continue
;
}
avio_printf
(
master_pb
,
"#EXT-X-STREAM-INF:BANDWIDTH=%d"
,
bandwidth
);
if
(
vid_st
&&
vid_st
->
codecpar
->
width
>
0
&&
vid_st
->
codecpar
->
height
>
0
)
avio_printf
(
master_pb
,
",RESOLUTION=%dx%d"
,
vid_st
->
codecpar
->
width
,
vid_st
->
codecpar
->
height
);
avio_printf
(
master_pb
,
"
\n
%s
\n\n
"
,
m3u8_rel_name
);
ff_hls_write_stream_info
(
vid_st
,
master_pb
,
bandwidth
,
m3u8_rel_name
);
av_freep
(
&
m3u8_rel_name
);
}
...
...
@@ -1215,6 +1184,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
char
*
iv_string
=
NULL
;
AVDictionary
*
options
=
NULL
;
double
prog_date_time
=
vs
->
initial_prog_date_time
;
double
*
prog_date_time_p
=
(
hls
->
flags
&
HLS_PROGRAM_DATE_TIME
)
?
&
prog_date_time
:
NULL
;
int
byterange_mode
=
(
hls
->
flags
&
HLS_SINGLE_FILE
)
||
(
hls
->
max_seg_size
>
0
);
hls
->
version
=
3
;
...
...
@@ -1245,12 +1215,8 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
}
vs
->
discontinuity_set
=
0
;
write_m3u8_head_block
(
hls
,
out
,
hls
->
version
,
target_duration
,
sequence
);
if
(
hls
->
pl_type
==
PLAYLIST_TYPE_EVENT
)
{
avio_printf
(
out
,
"#EXT-X-PLAYLIST-TYPE:EVENT
\n
"
);
}
else
if
(
hls
->
pl_type
==
PLAYLIST_TYPE_VOD
)
{
avio_printf
(
out
,
"#EXT-X-PLAYLIST-TYPE:VOD
\n
"
);
}
ff_hls_write_playlist_header
(
out
,
hls
->
version
,
hls
->
allowcache
,
target_duration
,
sequence
,
hls
->
pl_type
);
if
((
hls
->
flags
&
HLS_DISCONT_START
)
&&
sequence
==
hls
->
start_sequence
&&
vs
->
discontinuity_set
==
0
){
avio_printf
(
out
,
"#EXT-X-DISCONTINUITY
\n
"
);
...
...
@@ -1270,74 +1236,35 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
iv_string
=
en
->
iv_string
;
}
if
(
en
->
discont
)
{
avio_printf
(
out
,
"#EXT-X-DISCONTINUITY
\n
"
);
}
if
((
hls
->
segment_type
==
SEGMENT_TYPE_FMP4
)
&&
(
en
==
vs
->
segments
))
{
avio_printf
(
out
,
"#EXT-X-MAP:URI=
\"
%s
\"
"
,
vs
->
fmp4_init_filename
);
if
(
hls
->
flags
&
HLS_SINGLE_FILE
)
{
avio_printf
(
out
,
",BYTERANGE=
\"
%"
PRId64
"@%"
PRId64
"
\"
"
,
en
->
size
,
en
->
pos
);
}
avio_printf
(
out
,
"
\n
"
);
ff_hls_write_init_file
(
out
,
vs
->
fmp4_init_filename
,
hls
->
flags
&
HLS_SINGLE_FILE
,
en
->
size
,
en
->
pos
);
}
if
(
hls
->
flags
&
HLS_ROUND_DURATIONS
)
avio_printf
(
out
,
"#EXTINF:%ld,
\n
"
,
lrint
(
en
->
duration
));
else
avio_printf
(
out
,
"#EXTINF:%f,
\n
"
,
en
->
duration
);
if
(
byterange_mode
)
avio_printf
(
out
,
"#EXT-X-BYTERANGE:%"
PRId64
"@%"
PRId64
"
\n
"
,
en
->
size
,
en
->
pos
);
if
(
hls
->
flags
&
HLS_PROGRAM_DATE_TIME
)
{
time_t
tt
,
wrongsecs
;
int
milli
;
struct
tm
*
tm
,
tmpbuf
;
char
buf0
[
128
],
buf1
[
128
];
tt
=
(
int64_t
)
prog_date_time
;
milli
=
av_clip
(
lrint
(
1000
*
(
prog_date_time
-
tt
)),
0
,
999
);
tm
=
localtime_r
(
&
tt
,
&
tmpbuf
);
strftime
(
buf0
,
sizeof
(
buf0
),
"%Y-%m-%dT%H:%M:%S"
,
tm
);
if
(
!
strftime
(
buf1
,
sizeof
(
buf1
),
"%z"
,
tm
)
||
buf1
[
1
]
<
'0'
||
buf1
[
1
]
>
'2'
)
{
int
tz_min
,
dst
=
tm
->
tm_isdst
;
tm
=
gmtime_r
(
&
tt
,
&
tmpbuf
);
tm
->
tm_isdst
=
dst
;
wrongsecs
=
mktime
(
tm
);
tz_min
=
(
FFABS
(
wrongsecs
-
tt
)
+
30
)
/
60
;
snprintf
(
buf1
,
sizeof
(
buf1
),
"%c%02d%02d"
,
wrongsecs
<=
tt
?
'+'
:
'-'
,
tz_min
/
60
,
tz_min
%
60
);
}
avio_printf
(
out
,
"#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s
\n
"
,
buf0
,
milli
,
buf1
);
prog_date_time
+=
en
->
duration
;
}
if
(
vs
->
baseurl
)
avio_printf
(
out
,
"%s"
,
vs
->
baseurl
);
avio_printf
(
out
,
"%s
\n
"
,
en
->
filename
);
ff_hls_write_file_entry
(
out
,
en
->
discont
,
byterange_mode
,
en
->
duration
,
hls
->
flags
&
HLS_ROUND_DURATIONS
,
en
->
size
,
en
->
pos
,
vs
->
baseurl
,
en
->
filename
,
prog_date_time_p
);
}
if
(
last
&&
(
hls
->
flags
&
HLS_OMIT_ENDLIST
)
==
0
)
avio_printf
(
out
,
"#EXT-X-ENDLIST
\n
"
);
ff_hls_write_end_list
(
out
);
if
(
vs
->
vtt_m3u8_name
)
{
if
((
ret
=
s
->
io_open
(
s
,
&
sub_out
,
vs
->
vtt_m3u8_name
,
AVIO_FLAG_WRITE
,
&
options
))
<
0
)
goto
fail
;
write_m3u8_head_block
(
hls
,
sub_out
,
hls
->
version
,
target_duration
,
sequence
);
ff_hls_write_playlist_header
(
sub_out
,
hls
->
version
,
hls
->
allowcache
,
target_duration
,
sequence
,
PLAYLIST_TYPE_NONE
);
for
(
en
=
vs
->
segments
;
en
;
en
=
en
->
next
)
{
avio_printf
(
sub_out
,
"#EXTINF:%f,
\n
"
,
en
->
duration
);
if
(
byterange_mode
)
avio_printf
(
sub_out
,
"#EXT-X-BYTERANGE:%"
PRIi64
"@%"
PRIi64
"
\n
"
,
en
->
size
,
en
->
pos
);
if
(
vs
->
baseurl
)
avio_printf
(
sub_out
,
"%s"
,
vs
->
baseurl
);
avio_printf
(
sub_out
,
"%s
\n
"
,
en
->
sub_filename
);
ff_hls_write_file_entry
(
sub_out
,
0
,
byterange_mode
,
en
->
duration
,
0
,
en
->
size
,
en
->
pos
,
vs
->
baseurl
,
en
->
sub_filename
,
NULL
);
}
if
(
last
)
avio_printf
(
sub_out
,
"#EXT-X-ENDLIST
\n
"
);
ff_hls_write_end_list
(
sub_out
);
}
...
...
libavformat/hlsplaylist.c
0 → 100644
View file @
da49cdf6
/*
* Apple HTTP Live Streaming segmenter
* Copyright (c) 2012, Luca Barbato
* Copyright (c) 2017 Akamai Technologies, Inc.
*
* This file is part of FFmpeg.
*
* FFmpeg 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.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <stdint.h>
#include "libavutil/time_internal.h"
#include "avformat.h"
#include "hlsplaylist.h"
void
ff_hls_write_playlist_version
(
AVIOContext
*
out
,
int
version
)
{
if
(
!
out
)
return
;
avio_printf
(
out
,
"#EXTM3U
\n
"
);
avio_printf
(
out
,
"#EXT-X-VERSION:%d
\n
"
,
version
);
}
void
ff_hls_write_stream_info
(
AVStream
*
st
,
AVIOContext
*
out
,
int
bandwidth
,
char
*
filename
)
{
if
(
!
out
||
!
filename
)
return
;
if
(
!
bandwidth
)
{
av_log
(
NULL
,
AV_LOG_WARNING
,
"Bandwidth info not available, set audio and video bitrates
\n
"
);
return
;
}
avio_printf
(
out
,
"#EXT-X-STREAM-INF:BANDWIDTH=%d"
,
bandwidth
);
if
(
st
&&
st
->
codecpar
->
width
>
0
&&
st
->
codecpar
->
height
>
0
)
avio_printf
(
out
,
",RESOLUTION=%dx%d"
,
st
->
codecpar
->
width
,
st
->
codecpar
->
height
);
avio_printf
(
out
,
"
\n
%s
\n\n
"
,
filename
);
}
void
ff_hls_write_playlist_header
(
AVIOContext
*
out
,
int
version
,
int
allowcache
,
int
target_duration
,
int64_t
sequence
,
uint32_t
playlist_type
)
{
if
(
!
out
)
return
;
ff_hls_write_playlist_version
(
out
,
version
);
if
(
allowcache
==
0
||
allowcache
==
1
)
{
avio_printf
(
out
,
"#EXT-X-ALLOW-CACHE:%s
\n
"
,
allowcache
==
0
?
"NO"
:
"YES"
);
}
avio_printf
(
out
,
"#EXT-X-TARGETDURATION:%d
\n
"
,
target_duration
);
avio_printf
(
out
,
"#EXT-X-MEDIA-SEQUENCE:%"
PRId64
"
\n
"
,
sequence
);
av_log
(
NULL
,
AV_LOG_VERBOSE
,
"EXT-X-MEDIA-SEQUENCE:%"
PRId64
"
\n
"
,
sequence
);
if
(
playlist_type
==
PLAYLIST_TYPE_EVENT
)
{
avio_printf
(
out
,
"#EXT-X-PLAYLIST-TYPE:EVENT
\n
"
);
}
else
if
(
playlist_type
==
PLAYLIST_TYPE_VOD
)
{
avio_printf
(
out
,
"#EXT-X-PLAYLIST-TYPE:VOD
\n
"
);
}
}
void
ff_hls_write_init_file
(
AVIOContext
*
out
,
char
*
filename
,
int
byterange_mode
,
int64_t
size
,
int64_t
pos
)
{
avio_printf
(
out
,
"#EXT-X-MAP:URI=
\"
%s
\"
"
,
filename
);
if
(
byterange_mode
)
{
avio_printf
(
out
,
",BYTERANGE=
\"
%"
PRId64
"@%"
PRId64
"
\"
"
,
size
,
pos
);
}
avio_printf
(
out
,
"
\n
"
);
}
void
ff_hls_write_file_entry
(
AVIOContext
*
out
,
int
insert_discont
,
int
byterange_mode
,
double
duration
,
int
round_duration
,
int64_t
size
,
int64_t
pos
,
//Used only if HLS_SINGLE_FILE flag is set
char
*
baseurl
,
//Ignored if NULL
char
*
filename
,
double
*
prog_date_time
)
{
if
(
!
out
||
!
filename
)
return
;
if
(
insert_discont
)
{
avio_printf
(
out
,
"#EXT-X-DISCONTINUITY
\n
"
);
}
if
(
round_duration
)
avio_printf
(
out
,
"#EXTINF:%ld,
\n
"
,
lrint
(
duration
));
else
avio_printf
(
out
,
"#EXTINF:%f,
\n
"
,
duration
);
if
(
byterange_mode
)
avio_printf
(
out
,
"#EXT-X-BYTERANGE:%"
PRId64
"@%"
PRId64
"
\n
"
,
size
,
pos
);
if
(
prog_date_time
)
{
time_t
tt
,
wrongsecs
;
int
milli
;
struct
tm
*
tm
,
tmpbuf
;
char
buf0
[
128
],
buf1
[
128
];
tt
=
(
int64_t
)
*
prog_date_time
;
milli
=
av_clip
(
lrint
(
1000
*
(
*
prog_date_time
-
tt
)),
0
,
999
);
tm
=
localtime_r
(
&
tt
,
&
tmpbuf
);
strftime
(
buf0
,
sizeof
(
buf0
),
"%Y-%m-%dT%H:%M:%S"
,
tm
);
if
(
!
strftime
(
buf1
,
sizeof
(
buf1
),
"%z"
,
tm
)
||
buf1
[
1
]
<
'0'
||
buf1
[
1
]
>
'2'
)
{
int
tz_min
,
dst
=
tm
->
tm_isdst
;
tm
=
gmtime_r
(
&
tt
,
&
tmpbuf
);
tm
->
tm_isdst
=
dst
;
wrongsecs
=
mktime
(
tm
);
tz_min
=
(
FFABS
(
wrongsecs
-
tt
)
+
30
)
/
60
;
snprintf
(
buf1
,
sizeof
(
buf1
),
"%c%02d%02d"
,
wrongsecs
<=
tt
?
'+'
:
'-'
,
tz_min
/
60
,
tz_min
%
60
);
}
avio_printf
(
out
,
"#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s
\n
"
,
buf0
,
milli
,
buf1
);
*
prog_date_time
+=
duration
;
}
if
(
baseurl
)
avio_printf
(
out
,
"%s"
,
baseurl
);
avio_printf
(
out
,
"%s
\n
"
,
filename
);
}
void
ff_hls_write_end_list
(
AVIOContext
*
out
)
{
if
(
!
out
)
return
;
avio_printf
(
out
,
"#EXT-X-ENDLIST
\n
"
);
}
libavformat/hlsplaylist.h
0 → 100644
View file @
da49cdf6
/*
* Apple HTTP Live Streaming segmenter
* Copyright (c) 2012, Luca Barbato
* Copyright (c) 2017 Akamai Technologies, Inc.
*
* This file is part of FFmpeg.
*
* FFmpeg 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.
*
* FFmpeg 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVFORMAT_HLSPLAYLIST_H_
#define AVFORMAT_HLSPLAYLIST_H_
#include "libavutil/common.h"
typedef
enum
{
PLAYLIST_TYPE_NONE
,
PLAYLIST_TYPE_EVENT
,
PLAYLIST_TYPE_VOD
,
PLAYLIST_TYPE_NB
,
}
PlaylistType
;
void
ff_hls_write_playlist_version
(
AVIOContext
*
out
,
int
version
);
void
ff_hls_write_stream_info
(
AVStream
*
st
,
AVIOContext
*
out
,
int
bandwidth
,
char
*
filename
);
void
ff_hls_write_playlist_header
(
AVIOContext
*
out
,
int
version
,
int
allowcache
,
int
target_duration
,
int64_t
sequence
,
uint32_t
playlist_type
);
void
ff_hls_write_init_file
(
AVIOContext
*
out
,
char
*
filename
,
int
byterange_mode
,
int64_t
size
,
int64_t
pos
);
void
ff_hls_write_file_entry
(
AVIOContext
*
out
,
int
insert_discont
,
int
byterange_mode
,
double
duration
,
int
round_duration
,
int64_t
size
,
int64_t
pos
,
//Used only if HLS_SINGLE_FILE flag is set
char
*
baseurl
,
//Ignored if NULL
char
*
filename
,
double
*
prog_date_time
);
void
ff_hls_write_end_list
(
AVIOContext
*
out
);
#endif
/* AVFORMAT_HLSPLAYLIST_H_ */
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