X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fdashenc.c;h=1f31968ab99d00a29a8fee9a7ec8eb008e8bbc88;hb=95a72aed764aa8a08c56ba0e8cf5153f5b769222;hp=534fa754b4dd418852e71ec72034d0d8ae09b5ea;hpb=591cf8aa0ee9e09aac29861f4229616df7604172;p=ffmpeg diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 534fa754b4d..1f31968ab99 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,35 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\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 set_bitrate(AVFormatContext *s) +{ + DASHContext *c = s->priv_data; + int i; + + for (i = 0; i < s->nb_streams; i++) { + OutputStream *os = &c->streams[i]; + + os->bit_rate = s->streams[i]->codecpar->bit_rate; + if (os->bit_rate) { + snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), + " bandwidth=\"%d\"", os->bit_rate); + } else { + int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? + AV_LOG_ERROR : AV_LOG_WARNING; + av_log(s, level, "No bit rate set for stream %d\n", i); + if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) + return AVERROR(EINVAL); + } + } + + return 0; } static int dash_init(AVFormatContext *s) @@ -587,6 +621,10 @@ static int dash_init(AVFormatContext *s) if (!c->streams) return AVERROR(ENOMEM); + ret = set_bitrate(s); + if (ret < 0) + return ret; + for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; AVFormatContext *ctx; @@ -594,18 +632,6 @@ static int dash_init(AVFormatContext *s) AVDictionary *opts = NULL; char filename[1024]; - os->bit_rate = s->streams[i]->codecpar->bit_rate; - if (os->bit_rate) { - snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), - " bandwidth=\"%d\"", os->bit_rate); - } else { - int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? - AV_LOG_ERROR : AV_LOG_WARNING; - av_log(s, level, "No bit rate set for stream %d\n", i); - if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) - return AVERROR(EINVAL); - } - ctx = avformat_alloc_context(); if (!ctx) return AVERROR(ENOMEM); @@ -796,6 +822,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 +863,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 +881,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); @@ -964,6 +997,8 @@ static int dash_write_trailer(AVFormatContext *s) { DASHContext *c = s->priv_data; + set_bitrate(s); + if (s->nb_streams > 0) { OutputStream *os = &c->streams[0]; // If no segments have been written so far, try to do a crude