"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/moov.c" (9 Jan 2007, 7460 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include "funcprotos.h"
    2 #include "quicktime.h"
    3 #include "workarounds.h"
    4 
    5 
    6 #include <zlib.h>
    7 
    8 
    9 int quicktime_moov_init(quicktime_moov_t *moov)
   10 {
   11     int i;
   12 
   13     moov->total_tracks = 0;
   14     for(i = 0 ; i < MAXTRACKS; i++) moov->trak[i] = 0;
   15     quicktime_mvhd_init(&(moov->mvhd));
   16     quicktime_udta_init(&(moov->udta));
   17     quicktime_ctab_init(&(moov->ctab));
   18     return 0;
   19 }
   20 
   21 int quicktime_moov_delete(quicktime_moov_t *moov)
   22 {
   23     int i;
   24     while(moov->total_tracks) quicktime_delete_trak(moov);
   25     quicktime_mvhd_delete(&(moov->mvhd));
   26     quicktime_udta_delete(&(moov->udta));
   27     quicktime_ctab_delete(&(moov->ctab));
   28     return 0;
   29 }
   30 
   31 void quicktime_moov_dump(quicktime_moov_t *moov)
   32 {
   33     int i;
   34     printf("movie\n");
   35     quicktime_mvhd_dump(&(moov->mvhd));
   36     quicktime_udta_dump(&(moov->udta));
   37     for(i = 0; i < moov->total_tracks; i++)
   38         quicktime_trak_dump(moov->trak[i]);
   39     quicktime_ctab_dump(&(moov->ctab));
   40 }
   41 
   42 static void* zalloc(void *opaque, unsigned int items, unsigned int size)
   43 {
   44     return calloc(items, size);
   45 }
   46 
   47 static void zfree(void *opaque, void *ptr)
   48 {
   49     free(ptr);
   50 }
   51 
   52 static int read_cmov(quicktime_t *file,
   53     quicktime_atom_t *parent_atom,
   54     quicktime_atom_t *moov_atom)
   55 {
   56     quicktime_atom_t leaf_atom;
   57 
   58     do
   59     {
   60         quicktime_atom_read_header(file, &leaf_atom);
   61 
   62 /* Algorithm used to compress */
   63         if(quicktime_atom_is(&leaf_atom, "dcom"))
   64         {
   65             char data[5];
   66 //printf("read_cmov 1 %lld\n", quicktime_position(file));
   67             quicktime_read_data(file, data, 4);
   68             data[4] = 0;
   69             if(strcmp(data, "zlib"))
   70             {
   71                 fprintf(stderr, 
   72                     "read_cmov: compression '%c%c%c%c' not zlib.  Giving up and going to a movie.\n",
   73                     data[0],
   74                     data[1],
   75                     data[2],
   76                     data[3]);
   77                 return 1;
   78             }
   79 
   80             quicktime_atom_skip(file, &leaf_atom);
   81         }
   82         else
   83 /* Size of uncompressed data followed by compressed data */
   84         if(quicktime_atom_is(&leaf_atom, "cmvd"))
   85         {
   86 /* Size of uncompressed data */
   87             int uncompressed_size = quicktime_read_int32(file);
   88 /* Read compressed data */
   89             int compressed_size = leaf_atom.end - quicktime_position(file);
   90             if(compressed_size > uncompressed_size)
   91             {
   92                 fprintf(stderr, 
   93                     "read_cmov: FYI compressed_size=%d uncompressed_size=%d\n",
   94                     compressed_size,
   95                     uncompressed_size);
   96             }
   97 
   98             unsigned char *data_in = calloc(1, compressed_size);
   99             quicktime_read_data(file, data_in, compressed_size);
  100 /* Decompress to another buffer */
  101             unsigned char *data_out = calloc(1, uncompressed_size + 0x400);
  102             z_stream zlib;
  103             zlib.zalloc = zalloc;
  104             zlib.zfree = zfree;
  105             zlib.opaque = NULL;
  106             zlib.avail_out = uncompressed_size + 0x400;
  107             zlib.next_out = data_out;
  108             zlib.avail_in = compressed_size;
  109             zlib.next_in = data_in;
  110             inflateInit(&zlib);
  111             inflate(&zlib, Z_PARTIAL_FLUSH);
  112             inflateEnd(&zlib);
  113             free(data_in);
  114             file->moov_data = data_out;
  115 
  116 /*
  117  * FILE *test = fopen("/tmp/test", "w");
  118  * fwrite(data_out, uncompressed_size, 1, test);
  119  * fclose(test);
  120  * exit(0);
  121  */
  122 
  123 
  124 /* Trick library into reading temporary buffer for the moov */
  125             file->moov_end = moov_atom->end;
  126             file->moov_size = moov_atom->size;
  127             moov_atom->end = moov_atom->start + uncompressed_size;
  128             moov_atom->size = uncompressed_size;
  129             file->old_preload_size = file->preload_size;
  130             file->old_preload_buffer = file->preload_buffer;
  131             file->old_preload_start = file->preload_start;
  132             file->old_preload_end = file->preload_end;
  133             file->old_preload_ptr = file->preload_ptr;
  134             file->preload_size = uncompressed_size;
  135             file->preload_buffer = data_out;
  136             file->preload_start = moov_atom->start;
  137             file->preload_end = file->preload_start + uncompressed_size;
  138             file->preload_ptr = 0;
  139             quicktime_set_position(file, file->preload_start + 8);
  140 /* Try again */
  141             if(quicktime_read_moov(file, 
  142                 &file->moov, 
  143                 moov_atom))
  144                 return 1;
  145 /* Exit the compressed state */
  146             moov_atom->size = file->moov_size;
  147             moov_atom->end = file->moov_end;
  148             file->preload_size = file->old_preload_size;
  149             file->preload_buffer = file->old_preload_buffer;
  150             file->preload_start = file->old_preload_start;
  151             file->preload_end = file->old_preload_end;
  152             file->preload_ptr = file->old_preload_ptr;
  153             quicktime_set_position(file, moov_atom->end);
  154         }
  155         else
  156             quicktime_atom_skip(file, &leaf_atom);
  157     }while(quicktime_position(file) < parent_atom->end);
  158     return 0;
  159 }
  160 
  161 
  162 int quicktime_read_moov(quicktime_t *file, 
  163     quicktime_moov_t *moov, 
  164     quicktime_atom_t *parent_atom)
  165 {
  166 /* mandatory mvhd */
  167     quicktime_atom_t leaf_atom;
  168 
  169 /* AVI translation: */
  170 /* strh -> mvhd */
  171 
  172     do
  173     {
  174 //printf("quicktime_read_moov 1 %llx\n", quicktime_position(file));
  175         quicktime_atom_read_header(file, &leaf_atom);
  176 
  177 /*
  178  * printf("quicktime_read_moov 2 %c%c%c%c\n", 
  179  * leaf_atom.type[0],
  180  * leaf_atom.type[1],
  181  * leaf_atom.type[2],
  182  * leaf_atom.type[3]);
  183  */
  184 
  185         if(quicktime_atom_is(&leaf_atom, "cmov"))
  186         {
  187             file->compressed_moov = 1;
  188             if(read_cmov(file, &leaf_atom, parent_atom)) return 1;
  189 /* Now were reading the compressed moov atom from the beginning. */
  190         }
  191         else
  192         if(quicktime_atom_is(&leaf_atom, "mvhd"))
  193         {
  194             quicktime_read_mvhd(file, &(moov->mvhd), &leaf_atom);
  195         }
  196         else
  197         if(quicktime_atom_is(&leaf_atom, "clip"))
  198         {
  199             quicktime_atom_skip(file, &leaf_atom);
  200         }
  201         else
  202         if(quicktime_atom_is(&leaf_atom, "trak"))
  203         {
  204             quicktime_trak_t *trak = quicktime_add_trak(file);
  205             quicktime_read_trak(file, trak, &leaf_atom);
  206         }
  207         else
  208         if(quicktime_atom_is(&leaf_atom, "udta"))
  209         {
  210             quicktime_read_udta(file, &(moov->udta), &leaf_atom);
  211             quicktime_atom_skip(file, &leaf_atom);
  212         }
  213         else
  214         if(quicktime_atom_is(&leaf_atom, "ctab"))
  215         {
  216             quicktime_read_ctab(file, &(moov->ctab));
  217         }
  218         else
  219             quicktime_atom_skip(file, &leaf_atom);
  220     }while(quicktime_position(file) < parent_atom->end);
  221 
  222     return 0;
  223 }
  224 
  225 void quicktime_write_moov(quicktime_t *file, 
  226     quicktime_moov_t *moov,
  227     int rewind)
  228 {
  229     quicktime_atom_t atom;
  230     int i;
  231     long int64_t_duration = 0;
  232     long duration, timescale;
  233     int result;
  234 
  235 
  236 // Try moov header immediately
  237     file->mdat.atom.end = quicktime_position(file);
  238     result = quicktime_atom_write_header(file, &atom, "moov");
  239 
  240 // Disk full.  Rewind and try again
  241     if(result)
  242     {
  243         quicktime_set_position(file, file->mdat.atom.end - (int64_t)0x100000);
  244         file->mdat.atom.end = quicktime_position(file);
  245         quicktime_atom_write_header(file, &atom, "moov");
  246     }
  247 
  248 /* get the duration from the int64_t track in the mvhd's timescale */
  249     for(i = 0; i < moov->total_tracks; i++)
  250     {
  251         quicktime_trak_fix_counts(file, moov->trak[i]);
  252         quicktime_trak_duration(moov->trak[i], &duration, &timescale);
  253 
  254         duration = (long)((float)duration / timescale * moov->mvhd.time_scale);
  255 
  256         if(duration > int64_t_duration)
  257         {
  258             int64_t_duration = duration;
  259         }
  260     }
  261     moov->mvhd.duration = int64_t_duration;
  262     moov->mvhd.selection_duration = int64_t_duration;
  263 
  264     quicktime_write_mvhd(file, &(moov->mvhd));
  265     quicktime_write_udta(file, &(moov->udta));
  266     for(i = 0; i < moov->total_tracks; i++)
  267     {
  268         quicktime_write_trak(file, moov->trak[i], moov->mvhd.time_scale);
  269     }
  270     /*quicktime_write_ctab(file, &(moov->ctab)); */
  271 
  272     quicktime_atom_write_footer(file, &atom);
  273 
  274 // Rewind to end of mdat.  Breaks make_streamable
  275 // This probably allows the file to be extended after writing the moov.
  276     if(rewind) quicktime_set_position(file, file->mdat.atom.end);
  277 }
  278 
  279 void quicktime_update_durations(quicktime_moov_t *moov)
  280 {
  281     
  282 }
  283 
  284 int quicktime_shift_offsets(quicktime_moov_t *moov, int64_t offset)
  285 {
  286     int i;
  287     for(i = 0; i < moov->total_tracks; i++)
  288     {
  289         quicktime_trak_shift_offsets(moov->trak[i], offset);
  290     }
  291     return 0;
  292 }