lavf/segment: add escaping for filename field of the CSV list file
authorStefano Sabatini <stefasab@gmail.com>
Sat, 1 Sep 2012 14:12:29 +0000 (16:12 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Tue, 4 Sep 2012 09:25:14 +0000 (11:25 +0200)
CSV escaping code is borrowed from ffprobe.c.

doc/muxers.texi
libavformat/segment.c

index b5a27d1..df8763b 100644 (file)
@@ -498,8 +498,8 @@ each line matching the format:
 @end example
 
 @var{segment_filename} is the name of the output file generated by the
-muxer according to the provided pattern, and should not contain the
-"," character for simplifying parsing operations.
+muxer according to the provided pattern. CSV escaping (according to
+RFC4180) is applied if required.
 
 @var{segment_start_time} and @var{segment_end_time} specify
 the segment start and end time expressed in seconds.
index 1dda310..ecd4ae8 100644 (file)
@@ -67,6 +67,30 @@ typedef struct {
     double start_time, end_time;
 } SegmentContext;
 
+static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
+{
+    const char *p;
+    int quote = 0;
+
+    /* check if input needs quoting */
+    for (p = str; *p; p++)
+        if (strchr("\",\n\r", *p)) {
+            quote = 1;
+            break;
+        }
+
+    if (quote)
+        avio_w8(ctx, '"');
+
+    for (p = str; *p; p++) {
+        if (*p == '"')
+            avio_w8(ctx, '"');
+        avio_w8(ctx, *p);
+    }
+    if (quote)
+        avio_w8(ctx, '"');
+}
+
 static int segment_start(AVFormatContext *s)
 {
     SegmentContext *seg = s->priv_data;
@@ -169,7 +193,8 @@ static int segment_end(AVFormatContext *s)
         if (seg->list_type == LIST_TYPE_FLAT) {
             avio_printf(seg->list_pb, "%s\n", oc->filename);
         } else if (seg->list_type == LIST_TYPE_EXT) {
-            avio_printf(seg->list_pb, "%s,%f,%f\n", oc->filename, seg->start_time, seg->end_time);
+            print_csv_escaped_str(seg->list_pb, oc->filename);
+            avio_printf(seg->list_pb, ",%f,%f\n", seg->start_time, seg->end_time);
         } else if (seg->list_type == LIST_TYPE_M3U8) {
             avio_printf(seg->list_pb, "#EXTINF:%f,\n%s\n",
                         seg->end_time - seg->start_time, oc->filename);