FFmpeg
hlsplaylist.c
Go to the documentation of this file.
1 /*
2  * Apple HTTP Live Streaming segmenter
3  * Copyright (c) 2012, Luca Barbato
4  * Copyright (c) 2017 Akamai Technologies, Inc.
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config.h"
24 #include <stdint.h>
25 #include <time.h>
26 
28 
29 #include "avformat.h"
30 #include "hlsplaylist.h"
31 
33 {
34  if (!out)
35  return;
36  avio_printf(out, "#EXTM3U\n");
37  avio_printf(out, "#EXT-X-VERSION:%d\n", version);
38 }
39 
40 void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup,
41  const char *filename, const char *language,
42  int name_id, int is_default, int nb_channels)
43 {
44  if (!out || !agroup || !filename)
45  return;
46 
47  avio_printf(out, "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"group_%s\"", agroup);
48  avio_printf(out, ",NAME=\"audio_%d\",DEFAULT=%s,", name_id, is_default ? "YES" : "NO");
49  if (language) {
50  avio_printf(out, "LANGUAGE=\"%s\",", language);
51  }
52  if (nb_channels) {
53  avio_printf(out, "CHANNELS=\"%d\",", nb_channels);
54  }
55  avio_printf(out, "URI=\"%s\"\n", filename);
56 }
57 
59  const char *filename, const char *language,
60  const char *sname, int name_id, int is_default)
61 {
62  if (!out || !filename)
63  return;
64 
65  avio_printf(out, "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"%s\"", sgroup);
66  if (sname) {
67  avio_printf(out, ",NAME=\"%s\",", sname);
68  } else {
69  avio_printf(out, ",NAME=\"subtitle_%d\",", name_id);
70  }
71  avio_printf(out, "DEFAULT=%s,", is_default ? "YES" : "NO");
72  if (language) {
73  avio_printf(out, "LANGUAGE=\"%s\",", language);
74  }
75  avio_printf(out, "URI=\"%s\"\n", filename);
76 }
77 
79  int avg_bandwidth,
80  const char *filename, const char *agroup,
81  const char *codecs, const char *ccgroup,
82  const char *sgroup)
83 {
84  if (!out || !filename)
85  return;
86 
87  if (!bandwidth) {
89  "Bandwidth info not available, set audio and video bitrates\n");
90  return;
91  }
92 
93  avio_printf(out, "#EXT-X-STREAM-INF:BANDWIDTH=%d", bandwidth);
94  if (avg_bandwidth)
95  avio_printf(out, ",AVERAGE-BANDWIDTH=%d", avg_bandwidth);
96  if (st && st->codecpar->width > 0 && st->codecpar->height > 0)
97  avio_printf(out, ",RESOLUTION=%dx%d", st->codecpar->width,
98  st->codecpar->height);
99  if (codecs && codecs[0])
100  avio_printf(out, ",CODECS=\"%s\"", codecs);
101  if (agroup && agroup[0])
102  avio_printf(out, ",AUDIO=\"group_%s\"", agroup);
103  if (ccgroup && ccgroup[0])
104  avio_printf(out, ",CLOSED-CAPTIONS=\"%s\"", ccgroup);
105  if (sgroup && sgroup[0])
106  avio_printf(out, ",SUBTITLES=\"%s\"", sgroup);
107  avio_printf(out, "\n%s\n\n", filename);
108 }
109 
111  int target_duration, int64_t sequence,
112  uint32_t playlist_type, int iframe_mode)
113 {
114  if (!out)
115  return;
117  if (allowcache == 0 || allowcache == 1) {
118  avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", allowcache == 0 ? "NO" : "YES");
119  }
120  avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration);
121  avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
122  av_log(NULL, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence);
123 
124  if (playlist_type == PLAYLIST_TYPE_EVENT) {
125  avio_printf(out, "#EXT-X-PLAYLIST-TYPE:EVENT\n");
126  } else if (playlist_type == PLAYLIST_TYPE_VOD) {
127  avio_printf(out, "#EXT-X-PLAYLIST-TYPE:VOD\n");
128  }
129  if (iframe_mode) {
130  avio_printf(out, "#EXT-X-I-FRAMES-ONLY\n");
131  }
132 }
133 
134 void ff_hls_write_init_file(AVIOContext *out, const char *filename,
135  int byterange_mode, int64_t size, int64_t pos)
136 {
137  avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", filename);
138  if (byterange_mode) {
139  avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", size, pos);
140  }
141  avio_printf(out, "\n");
142 }
143 
144 int ff_hls_write_file_entry(AVIOContext *out, int insert_discont,
145  int byterange_mode, double duration,
146  int round_duration, int64_t size,
147  int64_t pos /* Used only if HLS_SINGLE_FILE flag is set */,
148  const char *baseurl /* Ignored if NULL */,
149  const char *filename, double *prog_date_time,
150  int iframe_mode)
151 {
152  if (!out || !filename)
153  return AVERROR(EINVAL);
154 
155  if (insert_discont) {
156  avio_printf(out, "#EXT-X-DISCONTINUITY\n");
157  }
158  if (round_duration)
159  avio_printf(out, "#EXTINF:%ld,\n", lrint(duration));
160  else
161  avio_printf(out, "#EXTINF:%f,\n", duration);
162  if (byterange_mode)
163  avio_printf(out, "#EXT-X-BYTERANGE:%"PRId64"@%"PRId64"\n", size, pos);
164 
165  if (prog_date_time) {
166  time_t tt, wrongsecs;
167  int milli;
168  struct tm *tm, tmpbuf;
169  char buf0[128], buf1[128];
170  tt = (int64_t)*prog_date_time;
171  milli = av_clip(lrint(1000*(*prog_date_time - tt)), 0, 999);
172  tm = localtime_r(&tt, &tmpbuf);
173  if (!strftime(buf0, sizeof(buf0), "%Y-%m-%dT%H:%M:%S", tm)) {
174  av_log(NULL, AV_LOG_DEBUG, "strftime error in ff_hls_write_file_entry\n");
175  return AVERROR_UNKNOWN;
176  }
177  if (!strftime(buf1, sizeof(buf1), "%z", tm) || buf1[1]<'0' ||buf1[1]>'2') {
178  int tz_min, dst = tm->tm_isdst;
179  tm = gmtime_r(&tt, &tmpbuf);
180  tm->tm_isdst = dst;
181  wrongsecs = mktime(tm);
182  tz_min = (FFABS(wrongsecs - tt) + 30) / 60;
183  snprintf(buf1, sizeof(buf1),
184  "%c%02d%02d",
185  wrongsecs <= tt ? '+' : '-',
186  tz_min / 60,
187  tz_min % 60);
188  }
189  avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, milli, buf1);
190  *prog_date_time += duration;
191  }
192  if (baseurl)
193  avio_printf(out, "%s", baseurl);
194  avio_printf(out, "%s\n", filename);
195 
196  return 0;
197 }
198 
200 {
201  if (!out)
202  return;
203  avio_printf(out, "#EXT-X-ENDLIST\n");
204 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
av_clip
#define av_clip
Definition: common.h:100
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
out
static FILE * out
Definition: movenc.c:55
ff_hls_write_end_list
void ff_hls_write_end_list(AVIOContext *out)
Definition: hlsplaylist.c:199
PLAYLIST_TYPE_VOD
@ PLAYLIST_TYPE_VOD
Definition: hlsplaylist.h:34
int64_t
long long int64_t
Definition: coverity.c:34
PLAYLIST_TYPE_EVENT
@ PLAYLIST_TYPE_EVENT
Definition: hlsplaylist.h:33
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_hls_write_file_entry
int ff_hls_write_file_entry(AVIOContext *out, int insert_discont, int byterange_mode, double duration, int round_duration, int64_t size, int64_t pos, const char *baseurl, const char *filename, double *prog_date_time, int iframe_mode)
Definition: hlsplaylist.c:144
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
hlsplaylist.h
ff_hls_write_playlist_header
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, int target_duration, int64_t sequence, uint32_t playlist_type, int iframe_mode)
Definition: hlsplaylist.c:110
gmtime_r
#define gmtime_r
Definition: time_internal.h:34
lrint
#define lrint
Definition: tablegen.h:53
AVCodecParameters::width
int width
The width of the video frame in pixels.
Definition: codec_par.h:143
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
time_internal.h
ff_hls_write_subtitle_rendition
void ff_hls_write_subtitle_rendition(AVIOContext *out, const char *sgroup, const char *filename, const char *language, const char *sname, int name_id, int is_default)
Definition: hlsplaylist.c:58
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:770
NULL
#define NULL
Definition: coverity.c:32
time.h
ff_hls_write_stream_info
void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth, int avg_bandwidth, const char *filename, const char *agroup, const char *codecs, const char *ccgroup, const char *sgroup)
Definition: hlsplaylist.c:78
ff_hls_write_playlist_version
void ff_hls_write_playlist_version(AVIOContext *out, int version)
Definition: hlsplaylist.c:32
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
localtime_r
#define localtime_r
Definition: time_internal.h:46
size
int size
Definition: twinvq_data.h:10344
ff_hls_write_init_file
void ff_hls_write_init_file(AVIOContext *out, const char *filename, int byterange_mode, int64_t size, int64_t pos)
Definition: hlsplaylist.c:134
codecs
static const struct codec_string codecs[]
version
version
Definition: libkvazaar.c:313
ff_hls_write_audio_rendition
void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup, const char *filename, const char *language, int name_id, int is_default, int nb_channels)
Definition: hlsplaylist.c:40
AVCodecParameters::height
int height
The height of the video frame in pixels.
Definition: codec_par.h:150
language
Undefined Behavior In the C language
Definition: undefined.txt:3
AVStream
Stream structure.
Definition: avformat.h:747
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
snprintf
#define snprintf
Definition: snprintf.h:34
duration
static int64_t duration
Definition: ffplay.c:329