FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
qt-faststart.c
Go to the documentation of this file.
1 /*
2  * qt-faststart.c, v0.2
3  * by Mike Melanson (melanson@pcisys.net)
4  * This file is placed in the public domain. Use the program however you
5  * see fit.
6  *
7  * This utility rearranges a Quicktime file such that the moov atom
8  * is in front of the data, thus facilitating network streaming.
9  *
10  * To compile this program, start from the base directory from which you
11  * are building FFmpeg and type:
12  * make tools/qt-faststart
13  * The qt-faststart program will be built in the tools/ directory. If you
14  * do not build the program in this manner, correct results are not
15  * guaranteed, particularly on 64-bit platforms.
16  * Invoke the program with:
17  * qt-faststart <infile.mov> <outfile.mov>
18  *
19  * Notes: Quicktime files can come in many configurations of top-level
20  * atoms. This utility stipulates that the very last atom in the file needs
21  * to be a moov atom. When given such a file, this utility will rearrange
22  * the top-level atoms by shifting the moov atom from the back of the file
23  * to the front, and patch the chunk offsets along the way. This utility
24  * presently only operates on uncompressed moov atoms.
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <inttypes.h>
30 #include <string.h>
31 #include <limits.h>
32 
33 #ifdef __MINGW32__
34 #undef fseeko
35 #define fseeko(x, y, z) fseeko64(x, y, z)
36 #undef ftello
37 #define ftello(x) ftello64(x)
38 #elif defined(_WIN32)
39 #undef fseeko
40 #define fseeko(x, y, z) _fseeki64(x, y, z)
41 #undef ftello
42 #define ftello(x) _ftelli64(x)
43 #endif
44 
45 #define MIN(a,b) ((a) > (b) ? (b) : (a))
46 
47 #define BE_32(x) (((uint32_t)(((uint8_t*)(x))[0]) << 24) | \
48  (((uint8_t*)(x))[1] << 16) | \
49  (((uint8_t*)(x))[2] << 8) | \
50  ((uint8_t*)(x))[3])
51 
52 #define BE_64(x) (((uint64_t)(((uint8_t*)(x))[0]) << 56) | \
53  ((uint64_t)(((uint8_t*)(x))[1]) << 48) | \
54  ((uint64_t)(((uint8_t*)(x))[2]) << 40) | \
55  ((uint64_t)(((uint8_t*)(x))[3]) << 32) | \
56  ((uint64_t)(((uint8_t*)(x))[4]) << 24) | \
57  ((uint64_t)(((uint8_t*)(x))[5]) << 16) | \
58  ((uint64_t)(((uint8_t*)(x))[6]) << 8) | \
59  ((uint64_t)( (uint8_t*)(x))[7]))
60 
61 #define AV_WB32(p, val) { \
62  ((uint8_t*)(p))[0] = ((val) >> 24) & 0xff; \
63  ((uint8_t*)(p))[1] = ((val) >> 16) & 0xff; \
64  ((uint8_t*)(p))[2] = ((val) >> 8) & 0xff; \
65  ((uint8_t*)(p))[3] = (val) & 0xff; \
66  }
67 
68 #define AV_WB64(p, val) { \
69  AV_WB32(p, (val) >> 32) \
70  AV_WB32(p + 4, val) \
71  }
72 
73 #define BE_FOURCC(ch0, ch1, ch2, ch3) \
74  ( (uint32_t)(unsigned char)(ch3) | \
75  ((uint32_t)(unsigned char)(ch2) << 8) | \
76  ((uint32_t)(unsigned char)(ch1) << 16) | \
77  ((uint32_t)(unsigned char)(ch0) << 24) )
78 
79 #define QT_ATOM BE_FOURCC
80 /* top level atoms */
81 #define FREE_ATOM QT_ATOM('f', 'r', 'e', 'e')
82 #define JUNK_ATOM QT_ATOM('j', 'u', 'n', 'k')
83 #define MDAT_ATOM QT_ATOM('m', 'd', 'a', 't')
84 #define MOOV_ATOM QT_ATOM('m', 'o', 'o', 'v')
85 #define PNOT_ATOM QT_ATOM('p', 'n', 'o', 't')
86 #define SKIP_ATOM QT_ATOM('s', 'k', 'i', 'p')
87 #define WIDE_ATOM QT_ATOM('w', 'i', 'd', 'e')
88 #define PICT_ATOM QT_ATOM('P', 'I', 'C', 'T')
89 #define FTYP_ATOM QT_ATOM('f', 't', 'y', 'p')
90 #define UUID_ATOM QT_ATOM('u', 'u', 'i', 'd')
91 
92 #define CMOV_ATOM QT_ATOM('c', 'm', 'o', 'v')
93 #define TRAK_ATOM QT_ATOM('t', 'r', 'a', 'k')
94 #define MDIA_ATOM QT_ATOM('m', 'd', 'i', 'a')
95 #define MINF_ATOM QT_ATOM('m', 'i', 'n', 'f')
96 #define STBL_ATOM QT_ATOM('s', 't', 'b', 'l')
97 #define STCO_ATOM QT_ATOM('s', 't', 'c', 'o')
98 #define CO64_ATOM QT_ATOM('c', 'o', '6', '4')
99 
100 #define ATOM_PREAMBLE_SIZE 8
101 #define COPY_BUFFER_SIZE 33554432
102 #define MAX_FTYP_ATOM_SIZE 1048576
103 
104 typedef struct {
105  uint32_t type;
106  uint32_t header_size;
107  uint64_t size;
108  unsigned char *data;
109 } atom_t;
110 
111 typedef struct {
112  uint64_t moov_atom_size;
114  uint64_t stco_data_size;
116  uint32_t depth;
118 
119 typedef struct {
120  unsigned char *dest;
122  uint64_t new_moov_size;
124 
125 typedef int (*parse_atoms_callback_t)(void *context, atom_t *atom);
126 
127 static int parse_atoms(
128  unsigned char *buf,
129  uint64_t size,
131  void *context)
132 {
133  unsigned char *pos = buf;
134  unsigned char *end = pos + size;
135  atom_t atom;
136  int ret;
137 
138  while (end - pos >= ATOM_PREAMBLE_SIZE) {
139  atom.size = BE_32(pos);
140  atom.type = BE_32(pos + 4);
141  pos += ATOM_PREAMBLE_SIZE;
143 
144  switch (atom.size) {
145  case 1:
146  if (end - pos < 8) {
147  fprintf(stderr, "not enough room for 64 bit atom size\n");
148  return -1;
149  }
150 
151  atom.size = BE_64(pos);
152  pos += 8;
153  atom.header_size = ATOM_PREAMBLE_SIZE + 8;
154  break;
155 
156  case 0:
157  atom.size = ATOM_PREAMBLE_SIZE + end - pos;
158  break;
159  }
160 
161  if (atom.size < atom.header_size) {
162  fprintf(stderr, "atom size %"PRIu64" too small\n", atom.size);
163  return -1;
164  }
165 
166  atom.size -= atom.header_size;
167 
168  if (atom.size > end - pos) {
169  fprintf(stderr, "atom size %"PRIu64" too big\n", atom.size);
170  return -1;
171  }
172 
173  atom.data = pos;
174  ret = callback(context, &atom);
175  if (ret < 0) {
176  return ret;
177  }
178 
179  pos += atom.size;
180  }
181 
182  return 0;
183 }
184 
186 {
187  uint32_t current_offset;
188  uint32_t offset_count;
189  unsigned char *pos;
190  unsigned char *end;
191 
192  printf(" patching stco atom...\n");
193  if (atom->size < 8) {
194  fprintf(stderr, "stco atom size %"PRIu64" too small\n", atom->size);
195  return -1;
196  }
197 
198  offset_count = BE_32(atom->data + 4);
199  if (offset_count > (atom->size - 8) / 4) {
200  fprintf(stderr, "stco offset count %"PRIu32" too big\n", offset_count);
201  return -1;
202  }
203 
204  context->stco_offset_count += offset_count;
205  context->stco_data_size += atom->size - 8;
206 
207  for (pos = atom->data + 8, end = pos + offset_count * 4;
208  pos < end;
209  pos += 4) {
210  current_offset = BE_32(pos);
211  if (current_offset > UINT_MAX - context->moov_atom_size) {
212  context->stco_overflow = 1;
213  }
214  current_offset += context->moov_atom_size;
215  AV_WB32(pos, current_offset);
216  }
217 
218  return 0;
219 }
220 
222 {
223  uint64_t current_offset;
224  uint32_t offset_count;
225  unsigned char *pos;
226  unsigned char *end;
227 
228  printf(" patching co64 atom...\n");
229  if (atom->size < 8) {
230  fprintf(stderr, "co64 atom size %"PRIu64" too small\n", atom->size);
231  return -1;
232  }
233 
234  offset_count = BE_32(atom->data + 4);
235  if (offset_count > (atom->size - 8) / 8) {
236  fprintf(stderr, "co64 offset count %"PRIu32" too big\n", offset_count);
237  return -1;
238  }
239 
240  for (pos = atom->data + 8, end = pos + offset_count * 8;
241  pos < end;
242  pos += 8) {
243  current_offset = BE_64(pos);
244  current_offset += context->moov_atom_size;
245  AV_WB64(pos, current_offset);
246  }
247 
248  return 0;
249 }
250 
251 static int update_chunk_offsets_callback(void *ctx, atom_t *atom)
252 {
254  int ret;
255 
256  switch (atom->type) {
257  case STCO_ATOM:
258  return update_stco_offsets(context, atom);
259 
260  case CO64_ATOM:
261  return update_co64_offsets(context, atom);
262 
263  case MOOV_ATOM:
264  case TRAK_ATOM:
265  case MDIA_ATOM:
266  case MINF_ATOM:
267  case STBL_ATOM:
268  context->depth++;
269  if (context->depth > 10) {
270  fprintf(stderr, "atoms too deeply nested\n");
271  return -1;
272  }
273 
274  ret = parse_atoms(
275  atom->data,
276  atom->size,
278  context);
279  context->depth--;
280  return ret;
281  }
282 
283  return 0;
284 }
285 
286 static void set_atom_size(unsigned char *header, uint32_t header_size, uint64_t size)
287 {
288  switch (header_size) {
289  case 8:
290  AV_WB32(header, size);
291  break;
292 
293  case 16:
294  AV_WB64(header + 8, size);
295  break;
296  }
297 }
298 
299 static void upgrade_stco_atom(upgrade_stco_context_t *context, atom_t *atom)
300 {
301  unsigned char *pos;
302  unsigned char *end;
303  uint64_t new_offset;
304  uint32_t offset_count;
305  uint32_t original_offset;
306 
307  /* Note: not performing validations since they were performed on the first pass */
308 
309  offset_count = BE_32(atom->data + 4);
310 
311  /* write the header */
312  memcpy(context->dest, atom->data - atom->header_size, atom->header_size + 8);
313  AV_WB32(context->dest + 4, CO64_ATOM);
314  set_atom_size(context->dest, atom->header_size, atom->header_size + 8 + offset_count * 8);
315  context->dest += atom->header_size + 8;
316 
317  /* write the data */
318  for (pos = atom->data + 8, end = pos + offset_count * 4;
319  pos < end;
320  pos += 4) {
321  original_offset = BE_32(pos) - context->original_moov_size;
322  new_offset = (uint64_t)original_offset + context->new_moov_size;
323  AV_WB64(context->dest, new_offset);
324  context->dest += 8;
325  }
326 }
327 
328 static int upgrade_stco_callback(void *ctx, atom_t *atom)
329 {
330  upgrade_stco_context_t *context = ctx;
331  unsigned char *start_pos;
332  uint64_t copy_size;
333 
334  switch (atom->type) {
335  case STCO_ATOM:
336  upgrade_stco_atom(context, atom);
337  break;
338 
339  case MOOV_ATOM:
340  case TRAK_ATOM:
341  case MDIA_ATOM:
342  case MINF_ATOM:
343  case STBL_ATOM:
344  /* write the atom header */
345  memcpy(context->dest, atom->data - atom->header_size, atom->header_size);
346  start_pos = context->dest;
347  context->dest += atom->header_size;
348 
349  /* parse internal atoms*/
350  if (parse_atoms(
351  atom->data,
352  atom->size,
354  context) < 0) {
355  return -1;
356  }
357 
358  /* update the atom size */
359  set_atom_size(start_pos, atom->header_size, context->dest - start_pos);
360  break;
361 
362  default:
363  copy_size = atom->header_size + atom->size;
364  memcpy(context->dest, atom->data - atom->header_size, copy_size);
365  context->dest += copy_size;
366  break;
367  }
368 
369  return 0;
370 }
371 
372 static int update_moov_atom(
373  unsigned char **moov_atom,
374  uint64_t *moov_atom_size)
375 {
377  upgrade_stco_context_t upgrade_context;
378  unsigned char *new_moov_atom;
379 
380  update_context.moov_atom_size = *moov_atom_size;
381 
382  if (parse_atoms(
383  *moov_atom,
384  *moov_atom_size,
386  &update_context) < 0) {
387  return -1;
388  }
389 
390  if (!update_context.stco_overflow) {
391  return 0;
392  }
393 
394  printf(" upgrading stco atoms to co64...\n");
395  upgrade_context.new_moov_size = *moov_atom_size +
396  update_context.stco_offset_count * 8 -
397  update_context.stco_data_size;
398 
399  new_moov_atom = malloc(upgrade_context.new_moov_size);
400  if (new_moov_atom == NULL) {
401  fprintf(stderr, "could not allocate %"PRIu64" bytes for updated moov atom\n",
402  upgrade_context.new_moov_size);
403  return -1;
404  }
405 
406  upgrade_context.original_moov_size = *moov_atom_size;
407  upgrade_context.dest = new_moov_atom;
408 
409  if (parse_atoms(
410  *moov_atom,
411  *moov_atom_size,
413  &upgrade_context) < 0) {
414  free(new_moov_atom);
415  return -1;
416  }
417 
418  free(*moov_atom);
419  *moov_atom = new_moov_atom;
420  *moov_atom_size = upgrade_context.new_moov_size;
421 
422  if (upgrade_context.dest != *moov_atom + *moov_atom_size) {
423  fprintf(stderr, "unexpected - wrong number of moov bytes written\n");
424  return -1;
425  }
426 
427  return 0;
428 }
429 
430 int main(int argc, char *argv[])
431 {
432  FILE *infile = NULL;
433  FILE *outfile = NULL;
434  unsigned char atom_bytes[ATOM_PREAMBLE_SIZE];
435  uint32_t atom_type = 0;
436  uint64_t atom_size = 0;
437  uint64_t atom_offset = 0;
438  int64_t last_offset;
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;
443  int64_t start_offset = 0;
444  unsigned char *copy_buffer = NULL;
445  int bytes_to_copy;
446 
447  if (argc != 3) {
448  printf("Usage: qt-faststart <infile.mov> <outfile.mov>\n"
449  "Note: alternatively you can use -movflags +faststart in ffmpeg\n");
450  return 0;
451  }
452 
453  if (!strcmp(argv[1], argv[2])) {
454  fprintf(stderr, "input and output files need to be different\n");
455  return 1;
456  }
457 
458  infile = fopen(argv[1], "rb");
459  if (!infile) {
460  perror(argv[1]);
461  goto error_out;
462  }
463 
464  /* traverse through the atoms in the file to make sure that 'moov' is
465  * at the end */
466  while (!feof(infile)) {
467  if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
468  break;
469  }
470  atom_size = BE_32(&atom_bytes[0]);
471  atom_type = BE_32(&atom_bytes[4]);
472 
473  /* keep ftyp atom */
474  if (atom_type == FTYP_ATOM) {
475  if (atom_size > MAX_FTYP_ATOM_SIZE) {
476  fprintf(stderr, "ftyp atom size %"PRIu64" too big\n",
477  atom_size);
478  goto error_out;
479  }
480  ftyp_atom_size = atom_size;
481  free(ftyp_atom);
482  ftyp_atom = malloc(ftyp_atom_size);
483  if (!ftyp_atom) {
484  fprintf(stderr, "could not allocate %"PRIu64" bytes for ftyp atom\n",
485  atom_size);
486  goto error_out;
487  }
488  if (fseeko(infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR) ||
489  fread(ftyp_atom, atom_size, 1, infile) != 1 ||
490  (start_offset = ftello(infile)) < 0) {
491  perror(argv[1]);
492  goto error_out;
493  }
494  } else {
495  int ret;
496  /* 64-bit special case */
497  if (atom_size == 1) {
498  if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
499  break;
500  }
501  atom_size = BE_64(&atom_bytes[0]);
502  ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
503  } else {
504  ret = fseeko(infile, atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
505  }
506  if (ret) {
507  perror(argv[1]);
508  goto error_out;
509  }
510  }
511  printf("%c%c%c%c %10"PRIu64" %"PRIu64"\n",
512  (atom_type >> 24) & 255,
513  (atom_type >> 16) & 255,
514  (atom_type >> 8) & 255,
515  (atom_type >> 0) & 255,
516  atom_offset,
517  atom_size);
518  if ((atom_type != FREE_ATOM) &&
519  (atom_type != JUNK_ATOM) &&
520  (atom_type != MDAT_ATOM) &&
521  (atom_type != MOOV_ATOM) &&
522  (atom_type != PNOT_ATOM) &&
523  (atom_type != SKIP_ATOM) &&
524  (atom_type != WIDE_ATOM) &&
525  (atom_type != PICT_ATOM) &&
526  (atom_type != UUID_ATOM) &&
527  (atom_type != FTYP_ATOM)) {
528  fprintf(stderr, "encountered non-QT top-level atom (is this a QuickTime file?)\n");
529  break;
530  }
531  atom_offset += atom_size;
532 
533  /* The atom header is 8 (or 16 bytes), if the atom size (which
534  * includes these 8 or 16 bytes) is less than that, we won't be
535  * able to continue scanning sensibly after this atom, so break. */
536  if (atom_size < 8)
537  break;
538  }
539 
540  if (atom_type != MOOV_ATOM) {
541  printf("last atom in file was not a moov atom\n");
542  free(ftyp_atom);
543  fclose(infile);
544  return 0;
545  }
546 
547  if (atom_size < 16) {
548  fprintf(stderr, "bad moov atom size\n");
549  goto error_out;
550  }
551 
552  /* moov atom was, in fact, the last atom in the chunk; load the whole
553  * moov atom */
554  if (fseeko(infile, -atom_size, SEEK_END)) {
555  perror(argv[1]);
556  goto error_out;
557  }
558  last_offset = ftello(infile);
559  if (last_offset < 0) {
560  perror(argv[1]);
561  goto error_out;
562  }
563  moov_atom_size = atom_size;
564  moov_atom = malloc(moov_atom_size);
565  if (!moov_atom) {
566  fprintf(stderr, "could not allocate %"PRIu64" bytes for moov atom\n", atom_size);
567  goto error_out;
568  }
569  if (fread(moov_atom, atom_size, 1, infile) != 1) {
570  perror(argv[1]);
571  goto error_out;
572  }
573 
574  /* this utility does not support compressed atoms yet, so disqualify
575  * files with compressed QT atoms */
576  if (BE_32(&moov_atom[12]) == CMOV_ATOM) {
577  fprintf(stderr, "this utility does not support compressed moov atoms yet\n");
578  goto error_out;
579  }
580 
581  /* close; will be re-opened later */
582  fclose(infile);
583  infile = NULL;
584 
585  if (update_moov_atom(&moov_atom, &moov_atom_size) < 0) {
586  goto error_out;
587  }
588 
589  /* re-open the input file and open the output file */
590  infile = fopen(argv[1], "rb");
591  if (!infile) {
592  perror(argv[1]);
593  goto error_out;
594  }
595 
596  if (start_offset > 0) { /* seek after ftyp atom */
597  if (fseeko(infile, start_offset, SEEK_SET)) {
598  perror(argv[1]);
599  goto error_out;
600  }
601 
602  last_offset -= start_offset;
603  }
604 
605  outfile = fopen(argv[2], "wb");
606  if (!outfile) {
607  perror(argv[2]);
608  goto error_out;
609  }
610 
611  /* dump the same ftyp atom */
612  if (ftyp_atom_size > 0) {
613  printf(" writing ftyp atom...\n");
614  if (fwrite(ftyp_atom, ftyp_atom_size, 1, outfile) != 1) {
615  perror(argv[2]);
616  goto error_out;
617  }
618  }
619 
620  /* dump the new moov atom */
621  printf(" writing moov atom...\n");
622  if (fwrite(moov_atom, moov_atom_size, 1, outfile) != 1) {
623  perror(argv[2]);
624  goto error_out;
625  }
626 
627  /* copy the remainder of the infile, from offset 0 -> last_offset - 1 */
628  bytes_to_copy = MIN(COPY_BUFFER_SIZE, last_offset);
629  copy_buffer = malloc(bytes_to_copy);
630  if (!copy_buffer) {
631  fprintf(stderr, "could not allocate %d bytes for copy_buffer\n", bytes_to_copy);
632  goto error_out;
633  }
634  printf(" copying rest of file...\n");
635  while (last_offset) {
636  bytes_to_copy = MIN(bytes_to_copy, last_offset);
637 
638  if (fread(copy_buffer, bytes_to_copy, 1, infile) != 1) {
639  perror(argv[1]);
640  goto error_out;
641  }
642  if (fwrite(copy_buffer, bytes_to_copy, 1, outfile) != 1) {
643  perror(argv[2]);
644  goto error_out;
645  }
646  last_offset -= bytes_to_copy;
647  }
648 
649  fclose(infile);
650  fclose(outfile);
651  free(moov_atom);
652  free(ftyp_atom);
653  free(copy_buffer);
654 
655  return 0;
656 
657 error_out:
658  if (infile)
659  fclose(infile);
660  if (outfile)
661  fclose(outfile);
662  free(moov_atom);
663  free(ftyp_atom);
664  free(copy_buffer);
665  return 1;
666 }
static int parse_atoms(unsigned char *buf, uint64_t size, parse_atoms_callback_t callback, void *context)
Definition: qt-faststart.c:127
#define NULL
Definition: coverity.c:32
#define MOOV_ATOM
Definition: qt-faststart.c:84
#define MIN(a, b)
Definition: qt-faststart.c:45
int(* parse_atoms_callback_t)(void *context, atom_t *atom)
Definition: qt-faststart.c:125
#define BE_32(x)
Definition: qt-faststart.c:47
uint64_t size
Definition: qt-faststart.c:107
#define COPY_BUFFER_SIZE
Definition: qt-faststart.c:101
static int update_co64_offsets(update_chunk_offsets_context_t *context, atom_t *atom)
Definition: qt-faststart.c:221
#define FREE_ATOM
Definition: qt-faststart.c:81
unsigned char * dest
Definition: qt-faststart.c:120
static int update_moov_atom(unsigned char **moov_atom, uint64_t *moov_atom_size)
Definition: qt-faststart.c:372
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
#define MDIA_ATOM
Definition: qt-faststart.c:94
#define AV_WB32(p, val)
Definition: qt-faststart.c:61
#define PNOT_ATOM
Definition: qt-faststart.c:85
#define ATOM_PREAMBLE_SIZE
Definition: qt-faststart.c:100
#define JUNK_ATOM
Definition: qt-faststart.c:82
uint32_t type
Definition: qt-faststart.c:105
ptrdiff_t size
Definition: opengl_enc.c:101
static const uint8_t header[24]
Definition: sdr2.c:67
#define CMOV_ATOM
Definition: qt-faststart.c:92
#define MDAT_ATOM
Definition: qt-faststart.c:83
#define CO64_ATOM
Definition: qt-faststart.c:98
#define MAX_FTYP_ATOM_SIZE
Definition: qt-faststart.c:102
#define TRAK_ATOM
Definition: qt-faststart.c:93
#define MINF_ATOM
Definition: qt-faststart.c:95
#define UUID_ATOM
Definition: qt-faststart.c:90
static void callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time, enum dshowDeviceType devtype)
Definition: dshow.c:161
static int upgrade_stco_callback(void *ctx, atom_t *atom)
Definition: qt-faststart.c:328
AVFormatContext * ctx
Definition: movenc.c:48
uint32_t header_size
Definition: qt-faststart.c:106
unsigned char * data
Definition: qt-faststart.c:108
static void update_context(VignetteContext *s, AVFilterLink *inlink, AVFrame *frame)
Definition: vf_vignette.c:161
static void set_atom_size(unsigned char *header, uint32_t header_size, uint64_t size)
Definition: qt-faststart.c:286
void * buf
Definition: avisynth_c.h:690
#define STCO_ATOM
Definition: qt-faststart.c:97
#define WIDE_ATOM
Definition: qt-faststart.c:87
#define STBL_ATOM
Definition: qt-faststart.c:96
#define BE_64(x)
Definition: qt-faststart.c:52
static int update_chunk_offsets_callback(void *ctx, atom_t *atom)
Definition: qt-faststart.c:251
#define FTYP_ATOM
Definition: qt-faststart.c:89
int
int main(int argc, char *argv[])
Definition: qt-faststart.c:430
#define AV_WB64(p, val)
Definition: qt-faststart.c:68
#define SKIP_ATOM
Definition: qt-faststart.c:86
#define PICT_ATOM
Definition: qt-faststart.c:88
static int update_stco_offsets(update_chunk_offsets_context_t *context, atom_t *atom)
Definition: qt-faststart.c:185
FILE * outfile
Definition: audiogen.c:96
static void upgrade_stco_atom(upgrade_stco_context_t *context, atom_t *atom)
Definition: qt-faststart.c:299