31 fprintf(stderr,
"%s -out foo.mpd file1\n", argv0);
97 if (tag ==
MKBETAG(
's',
'i',
'd',
'x')) {
106 for (i = start_index; i < tracks->
nb_tracks; i++) {
120 if (
avio_seek(f, pos + size, SEEK_SET) != pos + size)
133 int err = 0, i, orig_tracks = tracks->
nb_tracks;
134 char errbuf[50], *ptr;
140 fprintf(stderr,
"Unable to open %s: %s\n", file, errbuf);
147 fprintf(stderr,
"Unable to identify %s: %s\n", file, errbuf);
152 fprintf(stderr,
"No streams found in %s\n", file);
163 fprintf(stderr,
"Skipping track %d in %s as it has zero bitrate\n",
184 if ((ptr = strrchr(file,
'/')))
185 track->
name = ptr + 1;
196 "Track %d in %s is neither video nor audio, skipping\n",
221 err =
find_sidx(tracks, orig_tracks, file);
233 int minutes = seconds / 60;
234 int hours = minutes / 60;
240 fprintf(out,
"%dH", hours);
241 if (hours || minutes)
242 fprintf(out,
"%dM", minutes);
243 fprintf(out,
"%d.%0*dS", seconds, decimals, fractions);
250 struct Track **adaptation_sets_buf[2] = { NULL };
251 struct Track ***adaptation_sets;
252 int nb_tracks_buf[2] = { 0 };
255 int64_t latest_start = 0;
258 adaptation_sets = adaptation_sets_buf;
259 nb_tracks = nb_tracks_buf;
261 for (i = 0; i < 2; i++) {
263 if (!adaptation_sets[i]) {
268 for (i = 0; i < tracks->
nb_tracks; i++) {
276 adaptation_sets[set_index][nb_tracks[set_index]++] = tracks->
tracks[i];
279 adaptation_sets = &tracks->
tracks;
284 out = fopen(filename,
"w");
290 fprintf(out,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
291 fprintf(out,
"<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
292 "\txmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"
293 "\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
294 "\txsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\"\n"
295 "\tprofiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"\n"
296 "\ttype=\"static\"\n");
297 fprintf(out,
"\tmediaPresentationDuration=\"");
299 fprintf(out,
"\"\n");
300 fprintf(out,
"\tminBufferTime=\"PT5S\">\n");
302 for (i = 0; i < tracks->
nb_tracks; i++) {
307 latest_start =
FFMAX(start, latest_start);
309 fprintf(out,
"\t<Period start=\"");
311 fprintf(out,
"\">\n");
314 for (
set = 0;
set < nb_sets;
set++) {
315 if (nb_tracks[
set] == 0)
317 fprintf(out,
"\t\t<AdaptationSet segmentAlignment=\"true\">\n");
319 for (i = 0; i < nb_tracks[
set]; i++) {
320 struct Track *track = adaptation_sets[
set][i];
321 if (strcmp(track->
name, adaptation_sets[
set][0]->
name))
323 fprintf(out,
"\t\t\t<ContentComponent id=\"%d\" contentType=\"%s\" />\n", track->
track_id, track->
is_audio ?
"audio" :
"video");
327 for (i = 0; i < nb_tracks[
set]; ) {
328 struct Track *first_track = adaptation_sets[
set][i];
330 fprintf(out,
"\t\t\t<Representation id=\"%d\" codecs=\"", i);
331 for (j = i; j < nb_tracks[
set]; j++) {
332 struct Track *track = adaptation_sets[
set][j];
333 if (strcmp(track->
name, first_track->
name))
340 width = track->
width;
348 fprintf(out,
"\" mimeType=\"%s/mp4\" bandwidth=\"%d\"",
349 width ?
"video" :
"audio",
bitrate);
350 if (width > 0 &&
height > 0)
351 fprintf(out,
" width=\"%d\" height=\"%d\"", width,
height);
353 fprintf(out,
" audioSamplingRate=\"%d\"",
sample_rate);
356 fprintf(out,
"\t\t\t\t<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\" />\n",
channels);
357 fprintf(out,
"\t\t\t\t<BaseURL>%s</BaseURL>\n", first_track->
name);
358 fprintf(out,
"\t\t\t\t<SegmentBase indexRange=\"%"PRId64
"-%"PRId64
"\" />\n", first_track->
sidx_start, first_track->
sidx_start + first_track->
sidx_length - 1);
359 fprintf(out,
"\t\t\t</Representation>\n");
362 fprintf(out,
"\t\t</AdaptationSet>\n");
364 fprintf(out,
"\t</Period>\n");
365 fprintf(out,
"</MPD>\n");
369 for (i = 0; i < 2; i++)
370 av_free(adaptation_sets_buf[i]);
377 for (i = 0; i < tracks->
nb_tracks; i++) {
384 int main(
int argc,
char **argv)
386 const char *
out = NULL;
387 struct Tracks tracks = { 0 };
392 for (i = 1; i < argc; i++) {
393 if (!strcmp(argv[i],
"-out")) {
396 }
else if (argv[i][0] ==
'-') {
397 return usage(argv[0], 1);
404 return usage(argv[0], 1);