]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/hls.c
Merge commit '6f243b17c537646b894857d43dfdac65f85ab377'
[ffmpeg] / libavformat / hls.c
index 0b4b58d4f3361b50524c9b290e2383234625b9cc..3897723b7defac135e7a4e3ab49b51acfdedf78a 100644 (file)
@@ -68,8 +68,8 @@ struct segment {
     int64_t duration;
     int64_t url_offset;
     int64_t size;
-    char url[MAX_URL_SIZE];
-    char key[MAX_URL_SIZE];
+    char *url;
+    char *key;
     enum KeyType key_type;
     uint8_t iv[16];
 };
@@ -192,8 +192,11 @@ static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
 static void free_segment_list(struct playlist *pls)
 {
     int i;
-    for (i = 0; i < pls->n_segments; i++)
+    for (i = 0; i < pls->n_segments; i++) {
+        av_free(pls->segments[i]->key);
+        av_free(pls->segments[i]->url);
         av_free(pls->segments[i]);
+    }
     av_freep(&pls->segments);
     pls->n_segments = 0;
 }
@@ -504,6 +507,7 @@ static int parse_playlist(HLSContext *c, const char *url,
     int64_t seg_size = -1;
     uint8_t *new_url = NULL;
     struct variant_info variant_info;
+    char tmp_str[MAX_URL_SIZE];
 
     if (!in) {
         AVDictionary *opts = NULL;
@@ -624,8 +628,28 @@ static int parse_playlist(HLSContext *c, const char *url,
                     memset(seg->iv, 0, sizeof(seg->iv));
                     AV_WB32(seg->iv + 12, seq);
                 }
-                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
-                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
+
+                if (key_type != KEY_NONE) {
+                    ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
+                    seg->key = av_strdup(tmp_str);
+                    if (!seg->key) {
+                        av_free(seg);
+                        ret = AVERROR(ENOMEM);
+                        goto fail;
+                    }
+                } else {
+                    seg->key = NULL;
+                }
+
+                ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
+                seg->url = av_strdup(tmp_str);
+                if (!seg->url) {
+                    av_free(seg->key);
+                    av_free(seg);
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
+
                 dynarray_add(&pls->segments, &pls->n_segments, seg);
                 is_segment = 0;
 
@@ -811,14 +835,14 @@ static void intercept_id3(struct playlist *pls, uint8_t *buf,
 
         if (ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
             struct segment *seg = pls->segments[pls->cur_seq_no - pls->start_seq_no];
-            int64_t segsize = seg->size >= 0 ? seg->size : ffurl_size(pls->input);
+            int64_t maxsize = seg->size >= 0 ? seg->size : 1024*1024;
             int taglen = ff_id3v2_tag_len(buf);
             int tag_got_bytes = FFMIN(taglen, *len);
             int remaining = taglen - tag_got_bytes;
 
-            if (taglen > segsize) {
-                av_log(pls->ctx, AV_LOG_ERROR, "Too large HLS ID3 tag (%d vs %"PRId64")\n",
-                       taglen, segsize);
+            if (taglen > maxsize) {
+                av_log(pls->ctx, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
+                       taglen, maxsize);
                 break;
             }
 
@@ -956,7 +980,7 @@ static int open_input(HLSContext *c, struct playlist *pls)
     /* Seek to the requested position. If this was a HTTP request, the offset
      * should already be where want it to, but this allows e.g. local testing
      * without a HTTP server. */
-    if (ret == 0) {
+    if (ret == 0 && seg->key_type == KEY_NONE) {
         int seekret = ffurl_seek(pls->input, seg->url_offset, SEEK_SET);
         if (seekret < 0) {
             av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);