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);
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 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)
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;
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);
{
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;
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;
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);
{
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