70 for (
i = 0;
i <
s->nb_streams;
i++) {
83 double min_buffer_time = 1.0;
84 avio_printf(pb,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
86 avio_printf(pb,
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
87 avio_printf(pb,
" xmlns=\"urn:mpeg:DASH:schema:MPD:2011\"\n");
88 avio_printf(pb,
" xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011\"\n");
89 avio_printf(pb,
" type=\"%s\"\n",
w->is_live ?
"dynamic" :
"static");
91 avio_printf(pb,
" mediaPresentationDuration=\"PT%gS\"\n",
94 avio_printf(pb,
" minBufferTime=\"PT%gS\"\n", min_buffer_time);
96 w->is_live ?
"urn:mpeg:dash:profile:isoff-live:2011" :
"urn:mpeg:dash:profile:webm-on-demand:2012",
97 w->is_live ?
"\n" :
">\n");
99 time_t local_time = time(
NULL);
100 struct tm gmt_buffer;
101 struct tm *gmt =
gmtime_r(&local_time, &gmt_buffer);
103 if (!strftime(gmt_iso, 21,
"%Y-%m-%dT%H:%M:%SZ", gmt)) {
109 avio_printf(pb,
" availabilityStartTime=\"%s\"\n", gmt_iso);
110 avio_printf(pb,
" timeShiftBufferDepth=\"PT%gS\"\n",
w->time_shift_buffer_depth);
111 avio_printf(pb,
" minimumUpdatePeriod=\"PT%dS\"",
w->minimum_update_period);
113 if (
w->utc_timing_url) {
115 avio_printf(pb,
" schemeIdUri=\"urn:mpeg:dash:utc:http-iso:2014\"\n");
116 avio_printf(pb,
" value=\"%s\"/>\n",
w->utc_timing_url);
148 if (!gold_track_num)
return 0;
171 int output_width,
int output_height,
172 int output_sample_rate)
178 const char *bandwidth_str;
181 bandwidth_str = bandwidth->
value;
182 }
else if (
w->is_live) {
188 avio_printf(pb,
" bandwidth=\"%s\"", bandwidth_str);
209 if (!irange || !cues_start || !cues_end || !filename)
231 first_width =
s->streams[as->
streams[0]]->codecpar->width;
233 if (first_width !=
s->streams[as->
streams[
i]]->codecpar->width)
245 first_height =
s->streams[as->
streams[0]]->codecpar->height;
247 if (first_height !=
s->streams[as->
streams[
i]]->codecpar->height)
257 int first_sample_rate,
i;
259 first_sample_rate =
s->streams[as->
streams[0]]->codecpar->sample_rate;
261 if (first_sample_rate !=
s->streams[as->
streams[
i]]->codecpar->sample_rate)
270 for (
i = 0;
i <
w->nb_as;
i++) {
289 *underscore_pos = strrchr(filename,
'_');
290 if (!*underscore_pos)
292 *period_pos = strchr(*underscore_pos,
'.');
310 static const char boolean[2][6] = {
"false",
"true" };
311 int subsegmentStartsWithSAP = 1;
317 int width_in_as = 1, height_in_as = 1, sample_rate_in_as = 1;
349 if (!
w->is_live && (!kf || !strncmp(kf->
value,
"0", 1))) subsegmentStartsWithSAP = 0;
351 avio_printf(pb,
" subsegmentStartsWithSAP=\"%d\"", subsegmentStartsWithSAP);
357 char *underscore_pos, *period_pos;
363 *underscore_pos =
'\0';
364 avio_printf(pb,
"<ContentComponent id=\"1\" type=\"%s\"/>\n",
369 avio_printf(pb,
" media=\"%s_$RepresentationID$_$Number$.chk\"",
371 avio_printf(pb,
" startNumber=\"%d\"",
w->chunk_start_index);
372 avio_printf(pb,
" initialization=\"%s_$RepresentationID$.hdr\"",
375 *underscore_pos =
'_';
379 char buf[25], *representation_id = buf, *underscore_pos, *period_pos;
390 representation_id = underscore_pos + 1;
393 snprintf(buf,
sizeof(buf),
"%d",
w->representation_id++);
396 !height_in_as, !sample_rate_in_as);
408 char *p =
w->adaptation_sets;
410 enum { new_set, parsed_id, parsing_streams }
state;
411 if (!
w->adaptation_sets) {
419 if (
state == new_set)
423 }
else if (
state == new_set && *p ==
' ') {
426 }
else if (
state == new_set && !strncmp(p,
"id=", 3)) {
427 void *mem =
av_realloc(
w->as,
sizeof(*
w->as) * (
w->nb_as + 1));
433 w->as[
w->nb_as - 1].nb_streams = 0;
434 w->as[
w->nb_as - 1].streams =
NULL;
436 q =
w->as[
w->nb_as - 1].id;
437 comma = strchr(p,
',');
438 if (!comma || comma - p >=
sizeof(
w->as[
w->nb_as - 1].id)) {
442 while (*p !=
',') *q++ = *p++;
446 }
else if (
state == parsed_id && !strncmp(p,
"streams=", 8)) {
448 state = parsing_streams;
449 }
else if (
state == parsing_streams) {
456 num = strtoll(p, &q, 10);
457 if (!
av_isdigit(*p) || (*q !=
' ' && *q !=
'\0' && *q !=
',') ||
458 num < 0 || num >=
s->nb_streams) {
463 if (*q ==
'\0')
break;
464 if (*q ==
' ')
state = new_set;
480 for (
unsigned i = 0;
i <
s->nb_streams;
i++) {
502 for (
i = 0;
i <
w->nb_as;
i++) {
513 return ret < 0 ? ret : 0;
521 #define OFFSET(x) offsetof(WebMDashMuxContext, x)
523 {
"adaptation_sets",
"Adaptation sets. Syntax: id=0,streams=0,1,2 id=1,streams=3,4 and so on",
OFFSET(adaptation_sets),
AV_OPT_TYPE_STRING, { 0 }, 0, 0,
AV_OPT_FLAG_ENCODING_PARAM },
528 {
"time_shift_buffer_depth",
"Smallest time (in seconds) shifting buffer for which any Representation is guaranteed to be available.",
OFFSET(time_shift_buffer_depth),
AV_OPT_TYPE_DOUBLE, { .dbl = 60.0 }, 1.0, DBL_MAX,
AV_OPT_FLAG_ENCODING_PARAM },
541 .
name =
"webm_dash_manifest",
543 .mime_type =
"application/xml",
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
AVCodecID
Identify the syntax and semantics of the bitstream.
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EOF
End of file.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array through a pointer to a pointer.
static av_const int av_isdigit(int c)
Locale-independent conversion of ASCII isdigit.
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
#define LIBAVUTIL_VERSION_INT
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define INITIALIZATION_RANGE
#define AV_OPT_FLAG_ENCODING_PARAM
a generic parameter which can be set by the user for muxing or encoding
Describe the class of an AVClass context structure.
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
const char * name
Name of the codec described by this descriptor.
This struct describes the properties of an encoded stream.
int extradata_size
Size of the extradata content in bytes.
enum AVMediaType codec_type
General type of the encoded data.
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int sample_rate
Audio only.
This structure stores compressed data.
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int minimum_update_period
double time_shift_buffer_depth
static const AVClass webm_dash_class
static int check_matching_width(AVFormatContext *s, const AdaptationSet *as)
static const AVOption options[]
static int check_matching_sample_rate(AVFormatContext *s, const AdaptationSet *as)
static int write_representation(AVFormatContext *s, AVStream *st, char *id, int output_width, int output_height, int output_sample_rate)
static int check_matching_height(AVFormatContext *s, const AdaptationSet *as)
static void free_adaptation_sets(AVFormatContext *s)
static int split_filename(char *filename, char **underscore_pos, char **period_pos)
static void write_footer(AVFormatContext *s)
static double get_duration(AVFormatContext *s)
static int bitstream_switching(AVFormatContext *s, const AdaptationSet *as)
static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt)
static int write_header(AVFormatContext *s)
static int subsegment_alignment(AVFormatContext *s, const AdaptationSet *as)
AVOutputFormat ff_webm_dash_manifest_muxer
static int parse_adaptation_sets(AVFormatContext *s)
static int webm_dash_manifest_write_header(AVFormatContext *s)
static const char * get_codec_name(int codec_id)
static int write_adaptation_set(AVFormatContext *s, int as_index)