avformat/hlsenc: detecting duplicated segment filenames
authorBela Bodecs <bodecsb@vivanet.hu>
Mon, 26 Dec 2016 10:14:40 +0000 (18:14 +0800)
committerBela Bodecs <bodecsb@vivanet.hu>
Mon, 26 Dec 2016 10:14:40 +0000 (18:14 +0800)
  ffmpeg-devel

with use_localtime parameter hlsenc may produce identical filenames for
different but still existing segments. It happens when
hls_segment_filename contains
syntacticaly correct but inadequate format parameters. Currently there
is no any log message when such a situaton occurs but these cases should
be avoided in most times. This patch generate warning log messages in
these cases.

ticketID: #6043

Signed-off-by: Bela Bodecs <bodecsb@vivanet.hu>
Signed-off-by: Steven Liu <lingjiujianke@gmail.com>
libavformat/hlsenc.c

index acf3a30..e46e9b4 100644 (file)
@@ -653,6 +653,38 @@ fail:
     return ret;
 }
 
+static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename)
+{
+    /* filename may contain rel/abs path, but segments store only basename */
+    char *p = NULL, *dirname = NULL, *path = NULL;
+    int path_size;
+    HLSSegment *ret_segment = NULL;
+    dirname = av_strdup(filename);
+    if (!dirname)
+        return NULL;
+    p = (char *)av_basename(dirname); // av_dirname would return . in case of no dir
+    *p = '\0'; // maybe empty
+
+    while (segment) {
+        path_size = strlen(dirname) + strlen(segment->filename) + 1;
+        path = av_malloc(path_size);
+        if (!path)
+            goto end;
+        av_strlcpy(path, dirname, path_size);
+        av_strlcat(path, segment->filename, path_size);
+        if (!strcmp(path,filename)) {
+            ret_segment = segment;
+            av_free(path);
+            goto end;
+        }
+        av_free(path);
+        segment = segment->next;
+    }
+end:
+    av_free(dirname);
+    return ret_segment;
+}
+
 static int hls_start(AVFormatContext *s)
 {
     HLSContext *c = s->priv_data;
@@ -686,6 +718,10 @@ static int hls_start(AVFormatContext *s)
                 return AVERROR(EINVAL);
             }
 
+            if (find_segment_by_filename(c->segments, oc->filename)
+                || find_segment_by_filename(c->old_segments, oc->filename)) {
+                av_log(c, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", oc->filename);
+            }
             if (c->use_localtime_mkdir) {
                 const char *dir;
                 char *fn_copy = av_strdup(oc->filename);