]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/hlsenc.c
Merge commit 'db7f1c7c5a1d37e7f4da64a79a97bea1c4b6e9f8'
[ffmpeg] / libavformat / hlsenc.c
index 76a7eef01259d768c44b65f1878becdd4e75ab41..11f1e5be42faebcfc975e309a381328f365c0349 100644 (file)
 #include "avformat.h"
 #include "internal.h"
 
-typedef struct ListEntry {
-    char  name[1024];
-    double   duration;
-    struct ListEntry *next;
-} ListEntry;
+typedef struct HLSSegment {
+    char filename[1024];
+    double duration; /* in seconds */
+
+    struct HLSSegment *next;
+} HLSSegment;
 
 typedef struct HLSContext {
     const AVClass *class;  // Class for private options.
@@ -43,20 +44,26 @@ typedef struct HLSContext {
     int64_t sequence;
     int64_t start_sequence;
     AVOutputFormat *oformat;
+
     AVFormatContext *avf;
+
     float time;            // Set by a private option.
-    int  size;             // Set by a private option.
+    int max_nb_segments;   // Set by a private option.
     int  wrap;             // Set by a private option.
+
     int64_t recording_time;
     int has_video;
     int64_t start_pts;
     int64_t end_pts;
     double duration;      // last segment duration computed so far, in seconds
     int nb_entries;
-    ListEntry *list;
-    ListEntry *end_list;
+
+    HLSSegment *segments;
+    HLSSegment *last_segment;
+
     char *basename;
     char *baseurl;
+
     AVIOContext *pb;
 } HLSContext;
 
@@ -85,28 +92,29 @@ static int hls_mux_init(AVFormatContext *s)
     return 0;
 }
 
-static int append_entry(HLSContext *hls, double duration)
+/* Create a new segment and append it to the segment list */
+static int hls_append_segment(HLSContext *hls, double duration)
 {
-    ListEntry *en = av_malloc(sizeof(*en));
+    HLSSegment *en = av_malloc(sizeof(*en));
 
     if (!en)
         return AVERROR(ENOMEM);
 
-    av_strlcpy(en->name, av_basename(hls->avf->filename), sizeof(en->name));
+    av_strlcpy(en->filename, av_basename(hls->avf->filename), sizeof(en->filename));
 
     en->duration = duration;
     en->next     = NULL;
 
-    if (!hls->list)
-        hls->list = en;
+    if (!hls->segments)
+        hls->segments = en;
     else
-        hls->end_list->next = en;
+        hls->last_segment->next = en;
 
-    hls->end_list = en;
+    hls->last_segment = en;
 
-    if (hls->size && hls->nb_entries >= hls->size) {
-        en = hls->list;
-        hls->list = en->next;
+    if (hls->max_nb_segments && hls->nb_entries >= hls->max_nb_segments) {
+        en = hls->segments;
+        hls->segments = en->next;
         av_free(en);
     } else
         hls->nb_entries++;
@@ -116,9 +124,9 @@ static int append_entry(HLSContext *hls, double duration)
     return 0;
 }
 
-static void free_entries(HLSContext *hls)
+static void hls_free_segments(HLSContext *hls)
 {
-    ListEntry *p = hls->list, *en;
+    HLSSegment *p = hls->segments, *en;
 
     while(p) {
         en = p;
@@ -130,7 +138,7 @@ static void free_entries(HLSContext *hls)
 static int hls_window(AVFormatContext *s, int last)
 {
     HLSContext *hls = s->priv_data;
-    ListEntry *en;
+    HLSSegment *en;
     int target_duration = 0;
     int ret = 0;
     int64_t sequence = FFMAX(hls->start_sequence, hls->sequence - hls->nb_entries);
@@ -139,7 +147,7 @@ static int hls_window(AVFormatContext *s, int last)
                           &s->interrupt_callback, NULL)) < 0)
         goto fail;
 
-    for (en = hls->list; en; en = en->next) {
+    for (en = hls->segments; en; en = en->next) {
         if (target_duration < en->duration)
             target_duration = ceil(en->duration);
     }
@@ -152,11 +160,11 @@ static int hls_window(AVFormatContext *s, int last)
     av_log(s, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n",
            sequence);
 
-    for (en = hls->list; en; en = en->next) {
+    for (en = hls->segments; en; en = en->next) {
         avio_printf(hls->pb, "#EXTINF:%f,\n", en->duration);
         if (hls->baseurl)
             avio_printf(hls->pb, "%s", hls->baseurl);
-        avio_printf(hls->pb, "%s\n", en->name);
+        avio_printf(hls->pb, "%s\n", en->filename);
     }
 
     if (last)
@@ -281,7 +289,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
                                    end_pts, AV_TIME_BASE_Q) >= 0) {
-        ret = append_entry(hls, hls->duration);
+        ret = hls_append_segment(hls, hls->duration);
         if (ret)
             return ret;
 
@@ -316,10 +324,10 @@ static int hls_write_trailer(struct AVFormatContext *s)
     avio_closep(&oc->pb);
     avformat_free_context(oc);
     av_free(hls->basename);
-    append_entry(hls, hls->duration);
+    hls_append_segment(hls, hls->duration);
     hls_window(s, 1);
 
-    free_entries(hls);
+    hls_free_segments(hls);
     avio_close(hls->pb);
     return 0;
 }
@@ -329,7 +337,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
 static const AVOption options[] = {
     {"start_number",  "set first number in the sequence",        OFFSET(start_sequence),AV_OPT_TYPE_INT64,  {.i64 = 0},     0, INT64_MAX, E},
     {"hls_time",      "set segment length in seconds",           OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E},
-    {"hls_list_size", "set maximum number of playlist entries",  OFFSET(size),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E},
+    {"hls_list_size", "set maximum number of playlist entries",  OFFSET(max_nb_segments),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E},
     {"hls_wrap",      "set number after which the index wraps",  OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
     {"hls_base_url",  "url to prepend to each playlist entry",   OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E},
     { NULL },