Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / ffmpeg / libavformat / hlsenc.c
index 12bd07b..11f1e5b 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,9 +147,9 @@ 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 = (int) floor(en->duration + 0.5);
+            target_duration = ceil(en->duration);
     }
 
     avio_printf(hls->pb, "#EXTM3U\n");
@@ -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)
@@ -241,7 +249,7 @@ static int hls_write_header(AVFormatContext *s)
         goto fail;
 
     if ((ret = avformat_write_header(hls->avf, NULL)) < 0)
-        return ret;
+        goto fail;
 
 
 fail:
@@ -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;
 
@@ -302,7 +310,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
             return ret;
     }
 
-    ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
+    ret = ff_write_chained(oc, pkt->stream_index, pkt, s, 0);
 
     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 },
@@ -348,8 +356,8 @@ AVOutputFormat ff_hls_muxer = {
     .long_name      = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
     .extensions     = "m3u8",
     .priv_data_size = sizeof(HLSContext),
-    .audio_codec    = AV_CODEC_ID_MP2,
-    .video_codec    = AV_CODEC_ID_MPEG2VIDEO,
+    .audio_codec    = AV_CODEC_ID_AAC,
+    .video_codec    = AV_CODEC_ID_H264,
     .flags          = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH,
     .write_header   = hls_write_header,
     .write_packet   = hls_write_packet,