430int main(
int argc,
char *argv[])
435 uint32_t atom_type = 0;
436 uint64_t atom_size = 0;
437 uint64_t atom_offset = 0;
439 unsigned char *moov_atom =
NULL;
440 unsigned char *ftyp_atom =
NULL;
441 uint64_t moov_atom_size;
442 uint64_t ftyp_atom_size = 0;
444 unsigned char *copy_buffer =
NULL;
446 uint64_t free_size = 0;
447 uint64_t moov_size = 0;
450 printf(
"Usage: qt-faststart <infile.mov> <outfile.mov>\n"
451 "Note: alternatively you can use -movflags +faststart in ffmpeg\n");
455 if (!strcmp(argv[1], argv[2])) {
456 fprintf(stderr,
"input and output files need to be different\n");
460 infile = fopen(argv[1],
"rb");
468 while (!feof(infile)) {
472 atom_size =
BE_32(&atom_bytes[0]);
473 atom_type =
BE_32(&atom_bytes[4]);
478 fprintf(stderr,
"ftyp atom size %"PRIu64
" too big\n",
482 ftyp_atom_size = atom_size;
484 ftyp_atom = malloc(ftyp_atom_size);
486 fprintf(stderr,
"could not allocate %"PRIu64
" bytes for ftyp atom\n",
491 fread(ftyp_atom, atom_size, 1, infile) != 1 ||
492 (start_offset = ftello(infile)) < 0) {
499 if (atom_size == 1) {
503 atom_size =
BE_64(&atom_bytes[0]);
513 printf(
"%c%c%c%c %10"PRIu64
" %"PRIu64
"\n",
514 (atom_type >> 24) & 255,
515 (atom_type >> 16) & 255,
516 (atom_type >> 8) & 255,
517 (atom_type >> 0) & 255,
530 fprintf(stderr,
"encountered non-QT top-level atom (is this a QuickTime file?)\n");
533 atom_offset += atom_size;
542 moov_size = atom_size;
544 if (moov_size && atom_type ==
FREE_ATOM) {
545 free_size += atom_size;
547 atom_size = moov_size;
552 printf(
"last atom in file was not a moov atom\n");
558 if (atom_size < 16) {
559 fprintf(stderr,
"bad moov atom size\n");
565 if (fseeko(infile, -(atom_size + free_size), SEEK_END)) {
569 last_offset = ftello(infile);
570 if (last_offset < 0) {
574 moov_atom_size = atom_size;
575 moov_atom = malloc(moov_atom_size);
577 fprintf(stderr,
"could not allocate %"PRIu64
" bytes for moov atom\n", atom_size);
580 if (fread(moov_atom, atom_size, 1, infile) != 1) {
588 fprintf(stderr,
"this utility does not support compressed moov atoms yet\n");
601 infile = fopen(argv[1],
"rb");
607 if (start_offset > 0) {
608 if (fseeko(infile, start_offset, SEEK_SET)) {
613 last_offset -= start_offset;
616 outfile = fopen(argv[2],
"wb");
623 if (ftyp_atom_size > 0) {
624 printf(
" writing ftyp atom...\n");
625 if (fwrite(ftyp_atom, ftyp_atom_size, 1,
outfile) != 1) {
632 printf(
" writing moov atom...\n");
633 if (fwrite(moov_atom, moov_atom_size, 1,
outfile) != 1) {
640 copy_buffer = malloc(bytes_to_copy);
642 fprintf(stderr,
"could not allocate %d bytes for copy_buffer\n", bytes_to_copy);
645 printf(
" copying rest of file...\n");
646 while (last_offset) {
647 bytes_to_copy =
MIN(bytes_to_copy, last_offset);
649 if (fread(copy_buffer, bytes_to_copy, 1, infile) != 1) {
653 if (fwrite(copy_buffer, bytes_to_copy, 1,
outfile) != 1) {
657 last_offset -= bytes_to_copy;
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
uint64_t stco_offset_count
uint64_t original_moov_size