avio_printf(out, "\t\t<AdaptationSet id=\"%s\" contentType=\"%s\" segmentAlignment=\"true\" bitstreamSwitching=\"true\"",
as->id, as->media_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
+ if (as->media_type == AVMEDIA_TYPE_VIDEO && c->max_frame_rate.num && !c->ambiguous_frame_rate)
+ avio_printf(out, " %s=\"%d/%d\"", (av_cmp_q(c->min_frame_rate, c->max_frame_rate) < 0) ? "maxFrameRate" : "frameRate", c->max_frame_rate.num, c->max_frame_rate.den);
+ lang = av_dict_get(as->metadata, "language", NULL, 0);
+ if (lang)
+ avio_printf(out, " lang=\"%s\"", lang->value);
avio_printf(out, ">\n");
+ role = av_dict_get(as->metadata, "role", NULL, 0);
+ if (role)
+ avio_printf(out, "\t\t\t<Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"%s\"/>\n", role->value);
+
for (i = 0; i < s->nb_streams; i++) {
OutputStream *os = &c->streams[i];
avio_printf(out, "</MPD>\n");
avio_flush(out);
ff_format_io_close(s, &out);
- return ff_rename(temp_filename, s->filename);
+
+ if (use_rename)
+ return avpriv_io_move(temp_filename, s->filename);
+
+ return 0;
}
-static int dash_write_header(AVFormatContext *s)
+ static int dict_copy_entry(AVDictionary **dst, const AVDictionary *src, const char *key)
+ {
+ AVDictionaryEntry *entry = av_dict_get(src, key, NULL, 0);
+ if (entry)
+ av_dict_set(dst, key, entry->value, AV_DICT_DONT_OVERWRITE);
+ return 0;
+ }
+
+static int dash_init(AVFormatContext *s)
{
DASHContext *c = s->priv_data;
int ret = 0, i;
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) {
- ret = AVERROR(EINVAL);
- goto fail;
- }
+ if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT)
+ return AVERROR(EINVAL);
}
+ // copy AdaptationSet language and role from stream metadata
+ dict_copy_entry(&as->metadata, s->streams[i]->metadata, "language");
+ dict_copy_entry(&as->metadata, s->streams[i]->metadata, "role");
+
ctx = avformat_alloc_context();
- if (!ctx) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
+ if (!ctx)
+ return AVERROR(ENOMEM);
os->ctx = ctx;
ctx->oformat = oformat;
ctx->interrupt_callback = s->interrupt_callback;