[FFmpeg-cvslog] avformat/dashenc: Only use temporary files when outputting to file protocol

Thomas Stephens git at videolan.org
Tue Feb 14 18:14:10 EET 2017


ffmpeg | branch: master | Thomas Stephens <thomas at ustudio.com> | Tue Feb  7 14:20:32 2017 -0600| [5fe2b437023f46394dfd4a4c991aa4a3ac3d8e72] | committer: Michael Niedermayer

avformat/dashenc: Only use temporary files when outputting to file protocol

Skips using temporary files when outputting to a protocol other than
"file", which enables dash to output content over network
protocols. The logic has been copied from the HLS format.

Reviewed-by: Steven Liu <lingjiujianke at gmail.com>
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5fe2b437023f46394dfd4a4c991aa4a3ac3d8e72
---

 libavformat/dashenc.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 534fa75..fa56505 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -444,9 +444,15 @@ static int write_manifest(AVFormatContext *s, int final)
     AVIOContext *out;
     char temp_filename[1024];
     int ret, i;
+    const char *proto = avio_find_protocol_name(s->filename);
+    int use_rename = proto && !strcmp(proto, "file");
+    static unsigned int warned_non_file = 0;
     AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
 
-    snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename);
+    if (!use_rename && !warned_non_file++)
+        av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
+
+    snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename);
     ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
@@ -548,7 +554,11 @@ static int write_manifest(AVFormatContext *s, int final)
     avio_printf(out, "</MPD>\n");
     avio_flush(out);
     ff_format_io_close(s, &out);
-    return avpriv_io_move(temp_filename, s->filename);
+
+    if (use_rename)
+        return avpriv_io_move(temp_filename, s->filename);
+
+    return 0;
 }
 
 static int dash_init(AVFormatContext *s)
@@ -796,6 +806,10 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
 {
     DASHContext *c = s->priv_data;
     int i, ret = 0;
+
+    const char *proto = avio_find_protocol_name(s->filename);
+    int use_rename = proto && !strcmp(proto, "file");
+
     int cur_flush_segment_index = 0;
     if (stream >= 0)
         cur_flush_segment_index = c->streams[stream].segment_index;
@@ -833,7 +847,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
         if (!c->single_file) {
             dash_fill_tmpl_params(filename, sizeof(filename), c->media_seg_name, i, os->segment_index, os->bit_rate, os->start_pts);
             snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, filename);
-            snprintf(temp_path, sizeof(temp_path), "%s.tmp", full_path);
+            snprintf(temp_path, sizeof(temp_path), use_rename ? "%s.tmp" : "%s", full_path);
             ret = s->io_open(s, &os->out, temp_path, AVIO_FLAG_WRITE, NULL);
             if (ret < 0)
                 break;
@@ -851,9 +865,12 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
             find_index_range(s, full_path, start_pos, &index_length);
         } else {
             ff_format_io_close(s, &os->out);
-            ret = avpriv_io_move(temp_path, full_path);
-            if (ret < 0)
-                break;
+
+            if (use_rename) {
+                ret = avpriv_io_move(temp_path, full_path);
+                if (ret < 0)
+                    break;
+            }
         }
         add_segment(os, filename, os->start_pts, os->max_pts - os->start_pts, start_pos, range_length, index_length);
         av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, full_path);



More information about the ffmpeg-cvslog mailing list