59 fprintf(stderr,
"%s [-split] [-ismf] [-n basename] [-path-prefix prefix] "
60 "[-ismc-prefix prefix] [-output dir] file1 [file2] ...\n", argv0);
97 if (got_tag != expected_tag) {
98 char got_tag_str[4], expected_tag_str[4];
100 AV_WB32(expected_tag_str, expected_tag);
101 fprintf(stderr,
"wanted tag %.4s, got %.4s\n", expected_tag_str,
123 if ((got =
avio_read(in, buf, len)) != len) {
124 fprintf(stderr,
"short read, wanted %d, got %d\n", len, got);
154 fprintf(stderr,
"Unable to open %s: %s\n", filename, errbuf);
178 int split,
int ismf,
const char* output_prefix)
180 char dirname[2048], filename[2048], idxname[2048];
181 int i, j,
ret = 0, fragment_ret;
185 snprintf(idxname,
sizeof(idxname),
"%s%s.ismf", output_prefix, basename);
186 out = fopen(idxname,
"w");
193 for (i = start_index; i < tracks->
nb_tracks; i++) {
196 snprintf(dirname,
sizeof(dirname),
"%sQualityLevels(%d)", output_prefix, track->
bitrate);
198 if (mkdir(dirname, 0777) == -1 && errno != EEXIST) {
204 for (j = 0; j < track->
chunks; j++) {
205 snprintf(filename,
sizeof(filename),
"%s/Fragments(%s=%"PRId64
")",
209 fprintf(out,
"%s %"PRId64, filename,
avio_tell(in));
215 fprintf(out,
" %"PRId64
"\n",
avio_tell(in));
216 if (fragment_ret != 0) {
217 fprintf(stderr,
"failed fragment %d in track %d (%s)\n", j,
232 int version, fieldlength, i, j;
235 struct Track *track = NULL;
242 for (i = start_index; i < tracks->
nb_tracks && !track; i++)
244 track = tracks->
tracks[i];
257 for (i = 0; i < track->
chunks; i++) {
265 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
267 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
269 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
286 const char *file,
int split,
int ismf,
287 const char *basename,
const char* output_prefix)
290 const char* err_str =
"";
301 err_str =
"mfra size mismatch";
306 err_str =
"mfra tag mismatch";
309 while (!
read_tfra(tracks, start_index, f)) {
316 err_str =
"error in write_fragments";
322 fprintf(stderr,
"Unable to read the MFRA atom in %s (%s)\n", file, err_str);
339 uint16_t sps_size, pps_size;
368 int ismf,
const char *basename,
369 const char* output_prefix)
372 int err = 0, i, orig_tracks = tracks->
nb_tracks;
373 char errbuf[50], *ptr;
379 fprintf(stderr,
"Unable to open %s: %s\n", file, errbuf);
386 fprintf(stderr,
"Unable to identify %s: %s\n", file, errbuf);
391 fprintf(stderr,
"No streams found in %s\n", file);
400 fprintf(stderr,
"Skipping track %d in %s as it has zero bitrate\n",
421 if ((ptr = strrchr(file,
'/')))
422 track->
name = ptr + 1;
433 "Track %d in %s is neither video nor audio, skipping\n",
478 err =
read_mfra(tracks, orig_tracks, file, split, ismf, basename,
488 const char *output_prefix,
489 const char *path_prefix,
490 const char *ismc_prefix)
496 snprintf(filename,
sizeof(filename),
"%s%s.ism", output_prefix, basename);
497 out = fopen(filename,
"w");
502 fprintf(out,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
503 fprintf(out,
"<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
504 fprintf(out,
"\t<head>\n");
505 fprintf(out,
"\t\t<meta name=\"clientManifestRelativePath\" "
506 "content=\"%s%s.ismc\" />\n", ismc_prefix, basename);
507 fprintf(out,
"\t</head>\n");
508 fprintf(out,
"\t<body>\n");
509 fprintf(out,
"\t\t<switch>\n");
510 for (i = 0; i < tracks->
nb_tracks; i++) {
513 fprintf(out,
"\t\t\t<%s src=\"%s%s\" systemBitrate=\"%d\">\n",
515 fprintf(out,
"\t\t\t\t<param name=\"trackID\" value=\"%d\" "
516 "valueType=\"data\" />\n", track->
track_id);
517 fprintf(out,
"\t\t\t</%s>\n", type);
519 fprintf(out,
"\t\t</switch>\n");
520 fprintf(out,
"\t</body>\n");
521 fprintf(out,
"</smil>\n");
530 int should_print_time_mismatch = 1;
532 for (i = 0; i < track->
chunks; i++) {
533 for (j = main + 1; j < tracks->
nb_tracks; j++) {
536 fprintf(stderr,
"Mismatched duration of %s chunk %d in %s (%d) and %s (%d)\n",
538 should_print_time_mismatch = 1;
541 if (should_print_time_mismatch)
542 fprintf(stderr,
"Mismatched (start) time of %s chunk %d in %s (%d) and %s (%d)\n",
544 should_print_time_mismatch = 0;
548 fprintf(out,
"\t\t<c n=\"%d\" d=\"%"PRId64
"\" />\n",
554 const char *output_prefix,
int split)
561 snprintf(filename,
sizeof(filename),
"%sManifest", output_prefix);
563 snprintf(filename,
sizeof(filename),
"%s%s.ismc", output_prefix, basename);
564 out = fopen(filename,
"w");
569 fprintf(out,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
570 fprintf(out,
"<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" "
571 "Duration=\"%"PRId64
"\">\n", tracks->
duration * 10);
574 struct Track *first_track = track;
577 "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
579 "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
581 for (i = 0; i < tracks->
nb_tracks; i++) {
582 track = tracks->
tracks[i];
586 "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
587 "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" "
588 "CodecPrivateData=\"",
592 fprintf(out,
"\" />\n");
595 fprintf(stderr,
"Mismatched number of video chunks in %s (id: %d, chunks %d) and %s (id: %d, chunks %d)\n",
599 fprintf(out,
"\t</StreamIndex>\n");
603 struct Track *first_track = track;
606 "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
608 "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
610 for (i = 0; i < tracks->
nb_tracks; i++) {
611 track = tracks->
tracks[i];
615 "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
616 "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" "
617 "BitsPerSample=\"16\" PacketSize=\"%d\" "
618 "AudioTag=\"%d\" CodecPrivateData=\"",
623 fprintf(out,
"\" />\n");
626 fprintf(stderr,
"Mismatched number of audio chunks in %s and %s\n",
630 fprintf(out,
"\t</StreamIndex>\n");
632 fprintf(out,
"</SmoothStreamingMedia>\n");
639 for (i = 0; i < tracks->
nb_tracks; i++) {
648 int main(
int argc,
char **argv)
650 const char *basename = NULL;
651 const char *path_prefix =
"", *ismc_prefix =
"";
652 const char *output_prefix =
"";
653 char output_prefix_buf[2048];
654 int split = 0, ismf = 0, i;
659 for (i = 1; i < argc; i++) {
660 if (!strcmp(argv[i],
"-n")) {
661 basename = argv[i + 1];
663 }
else if (!strcmp(argv[i],
"-path-prefix")) {
664 path_prefix = argv[i + 1];
666 }
else if (!strcmp(argv[i],
"-ismc-prefix")) {
667 ismc_prefix = argv[i + 1];
669 }
else if (!strcmp(argv[i],
"-output")) {
670 output_prefix = argv[i + 1];
672 if (output_prefix[strlen(output_prefix) - 1] !=
'/') {
673 snprintf(output_prefix_buf,
sizeof(output_prefix_buf),
674 "%s/", output_prefix);
675 output_prefix = output_prefix_buf;
677 }
else if (!strcmp(argv[i],
"-split")) {
679 }
else if (!strcmp(argv[i],
"-ismf")) {
681 }
else if (argv[i][0] ==
'-') {
682 return usage(argv[0], 1);
687 basename, output_prefix))
691 if (!tracks.
nb_tracks || (!basename && !split))
692 return usage(argv[0], 1);
696 path_prefix, ismc_prefix);