X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fsegment.c;h=36417f219235ece81d97736e2f3f7c61efe02171;hb=26a0cd1b4b093f3f6e4f15d28a282ec45b87bb98;hp=42471bb19063f6f03380d32fa0cc2be99af6aa4f;hpb=2ab827389bc17972dfe58b768083593b1f1bf776;p=ffmpeg diff --git a/libavformat/segment.c b/libavformat/segment.c index 42471bb1906..36417f21923 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -33,6 +33,7 @@ #include "internal.h" #include "libavutil/avassert.h" +#include "libavutil/internal.h" #include "libavutil/log.h" #include "libavutil/opt.h" #include "libavutil/avstring.h" @@ -113,6 +114,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 +262,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); @@ -347,6 +352,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) /* append new element */ memcpy(entry, &seg->cur_entry, sizeof(*entry)); + entry->filename = av_strdup(entry->filename); if (!seg->segment_list_entries) seg->segment_list_entries = seg->segment_list_entries_end = entry; else @@ -368,6 +374,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 +652,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"); @@ -774,7 +786,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) } } - av_dlog(s, "packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n", + ff_dlog(s, "packet stream:%d pts:%s pts_time:%s duration_time:%s is_key:%d frame:%d\n", pkt->stream_index, av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), av_ts2timestr(pkt->duration, &st->time_base), pkt->flags & AV_PKT_FLAG_KEY, @@ -875,6 +887,7 @@ fail: av_opt_free(seg); av_freep(&seg->times); av_freep(&seg->frames); + av_freep(&seg->cur_entry.filename); cur = seg->segment_list_entries; while (cur) {