diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2015-08-27 23:40:25 +0200 |
---|---|---|
committer | Carl Eugen Hoyos <cehoyos@ag.or.at> | 2015-10-09 21:34:38 +0200 |
commit | 1ef419447edc95c57bab62e0c5d66e35aadb7c12 (patch) | |
tree | fb2093eb8e6ccb76639fa8da54144292e3998196 /libavformat/segment.c | |
parent | 6752f8ef04010bb9c14c69ca64a79be5fff6d719 (diff) | |
download | ffmpeg-1ef419447edc95c57bab62e0c5d66e35aadb7c12.tar.gz |
avformat/segment: atomically update list if possible
Fixes Ticket4802
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit e2b19a533dbb4cb0fba85261ea835316381bc907)
Diffstat (limited to 'libavformat/segment.c')
-rw-r--r-- | libavformat/segment.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/libavformat/segment.c b/libavformat/segment.c index 4418d0f338..7831d8b73b 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -113,6 +113,9 @@ typedef struct SegmentContext { int reference_stream_index; int break_non_keyframes; + int use_rename; + char temp_list_filename[1024]; + SegmentListEntry cur_entry; SegmentListEntry *segment_list_entries; SegmentListEntry *segment_list_entries_end; @@ -258,7 +261,8 @@ static int segment_list_open(AVFormatContext *s) SegmentContext *seg = s->priv_data; int ret; - ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE, + snprintf(seg->temp_list_filename, sizeof(seg->temp_list_filename), seg->use_rename ? "%s.tmp" : "%s", seg->list); + ret = avio_open2(&seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list); @@ -368,6 +372,8 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) if (seg->list_type == LIST_TYPE_M3U8 && is_last) avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n"); avio_closep(&seg->list_pb); + if (seg->use_rename) + ff_rename(seg->temp_list_filename, seg->list, s); } else { segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry, s); avio_flush(seg->list_pb); @@ -644,9 +650,13 @@ static int seg_write_header(AVFormatContext *s) else if (av_match_ext(seg->list, "ffcat,ffconcat")) seg->list_type = LIST_TYPE_FFCONCAT; else seg->list_type = LIST_TYPE_FLAT; } - if (!seg->list_size && seg->list_type != LIST_TYPE_M3U8) + if (!seg->list_size && seg->list_type != LIST_TYPE_M3U8) { if ((ret = segment_list_open(s)) < 0) goto fail; + } else { + const char *proto = avio_find_protocol_name(s->filename); + seg->use_rename = proto && !strcmp(proto, "file"); + } } if (seg->list_type == LIST_TYPE_EXT) av_log(s, AV_LOG_WARNING, "'ext' list type option is deprecated in favor of 'csv'\n"); |