56 fprintf(stderr,
"%s [-split] [-n basename] [-path-prefix prefix] "
57 "[-ismc-prefix prefix] [-output dir] file1 [file2] ...\n", argv0);
134 char dirname[2048], filename[2048];
137 for (i = start_index; i < tracks->
nb_tracks; i++) {
140 snprintf(dirname,
sizeof(dirname),
"%sQualityLevels(%d)", output_prefix, track->
bitrate);
141 if (mkdir(dirname, 0777) == -1)
143 for (j = 0; j < track->
chunks; j++) {
144 snprintf(filename,
sizeof(filename),
"%s/Fragments(%s=%"PRId64
")",
156 int version, fieldlength, i, j;
159 struct Track *track = NULL;
166 for (i = start_index; i < tracks->
nb_tracks && !track; i++)
168 track = tracks->
tracks[i];
181 for (i = 0; i < track->
chunks; i++) {
189 for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
191 for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
193 for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
210 const char *file,
int split,
const char *output_prefix)
229 while (!
read_tfra(tracks, start_index, f)) {
240 fprintf(stderr,
"Unable to read the MFRA atom in %s\n", file);
257 uint16_t sps_size, pps_size;
287 const char *output_prefix)
290 int err = 0, i, orig_tracks = tracks->
nb_tracks;
291 char errbuf[50], *ptr;
297 fprintf(stderr,
"Unable to open %s: %s\n", file, errbuf);
304 fprintf(stderr,
"Unable to identify %s: %s\n", file, errbuf);
309 fprintf(stderr,
"No streams found in %s\n", file);
332 if ((ptr = strrchr(file,
'/')) != NULL)
333 track->
name = ptr + 1;
344 "Track %d in %s is neither video nor audio, skipping\n",
389 err =
read_mfra(tracks, orig_tracks, file, split, output_prefix);
398 const char *output_prefix,
399 const char *path_prefix,
400 const char *ismc_prefix)
406 snprintf(filename,
sizeof(filename),
"%s%s.ism", output_prefix, basename);
407 out = fopen(filename,
"w");
412 fprintf(out,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
413 fprintf(out,
"<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
414 fprintf(out,
"\t<head>\n");
415 fprintf(out,
"\t\t<meta name=\"clientManifestRelativePath\" "
416 "content=\"%s%s.ismc\" />\n", ismc_prefix, basename);
417 fprintf(out,
"\t</head>\n");
418 fprintf(out,
"\t<body>\n");
419 fprintf(out,
"\t\t<switch>\n");
420 for (i = 0; i < tracks->
nb_tracks; i++) {
423 fprintf(out,
"\t\t\t<%s src=\"%s%s\" systemBitrate=\"%d\">\n",
425 fprintf(out,
"\t\t\t\t<param name=\"trackID\" value=\"%d\" "
426 "valueType=\"data\" />\n", track->
track_id);
427 fprintf(out,
"\t\t\t</%s>\n", type);
429 fprintf(out,
"\t\t</switch>\n");
430 fprintf(out,
"\t</body>\n");
431 fprintf(out,
"</smil>\n");
440 for (i = 0; i < track->
chunks; i++) {
441 for (j = main + 1; j < tracks->
nb_tracks; j++) {
444 fprintf(stderr,
"Mismatched duration of %s chunk %d in %s and %s\n",
447 fprintf(out,
"\t\t<c n=\"%d\" d=\"%"PRId64
"\" />\n",
453 const char *output_prefix,
int split)
460 snprintf(filename,
sizeof(filename),
"%sManifest", output_prefix);
462 snprintf(filename,
sizeof(filename),
"%s%s.ismc", output_prefix, basename);
463 out = fopen(filename,
"w");
468 fprintf(out,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
469 fprintf(out,
"<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" "
470 "Duration=\"%"PRId64
"\">\n", tracks->
duration * 10);
473 struct Track *first_track = track;
476 "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
478 "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
480 for (i = 0; i < tracks->
nb_tracks; i++) {
481 track = tracks->
tracks[i];
485 "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
486 "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" "
487 "CodecPrivateData=\"",
491 fprintf(out,
"\" />\n");
494 fprintf(stderr,
"Mismatched number of video chunks in %s and %s\n",
498 fprintf(out,
"\t</StreamIndex>\n");
502 struct Track *first_track = track;
505 "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
507 "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
509 for (i = 0; i < tracks->
nb_tracks; i++) {
510 track = tracks->
tracks[i];
514 "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
515 "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" "
516 "BitsPerSample=\"16\" PacketSize=\"%d\" "
517 "AudioTag=\"%d\" CodecPrivateData=\"",
522 fprintf(out,
"\" />\n");
525 fprintf(stderr,
"Mismatched number of audio chunks in %s and %s\n",
529 fprintf(out,
"\t</StreamIndex>\n");
531 fprintf(out,
"</SmoothStreamingMedia>\n");
538 for (i = 0; i < tracks->
nb_tracks; i++) {
547 int main(
int argc,
char **argv)
549 const char *basename = NULL;
550 const char *path_prefix =
"", *ismc_prefix =
"";
551 const char *output_prefix =
"";
552 char output_prefix_buf[2048];
558 for (i = 1; i < argc; i++) {
559 if (!strcmp(argv[i],
"-n")) {
560 basename = argv[i + 1];
562 }
else if (!strcmp(argv[i],
"-path-prefix")) {
563 path_prefix = argv[i + 1];
565 }
else if (!strcmp(argv[i],
"-ismc-prefix")) {
566 ismc_prefix = argv[i + 1];
568 }
else if (!strcmp(argv[i],
"-output")) {
569 output_prefix = argv[i + 1];
571 if (output_prefix[strlen(output_prefix) - 1] !=
'/') {
572 snprintf(output_prefix_buf,
sizeof(output_prefix_buf),
573 "%s/", output_prefix);
574 output_prefix = output_prefix_buf;
576 }
else if (!strcmp(argv[i],
"-split")) {
578 }
else if (argv[i][0] ==
'-') {
579 return usage(argv[0], 1);
581 if (
handle_file(&tracks, argv[i], split, output_prefix))
585 if (!tracks.
nb_tracks || (!basename && !split))
586 return usage(argv[0], 1);
590 path_prefix, ismc_prefix);