r563: Ogg theora+vorbis export added
[cinelerra_cv/mob.git] / quicktime / stsc.c
blob7a405eb6301e8d0ddd70cf9f7716b7ce3c99bb5d
1 #include "funcprotos.h"
2 #include "quicktime.h"
6 void quicktime_stsc_init(quicktime_stsc_t *stsc)
8 stsc->version = 0;
9 stsc->flags = 0;
10 stsc->total_entries = 0;
11 stsc->entries_allocated = 0;
14 void quicktime_stsc_init_table(quicktime_t *file, quicktime_stsc_t *stsc)
16 if(!stsc->entries_allocated)
18 stsc->total_entries = 0;
19 stsc->entries_allocated = 2048;
20 stsc->table = (quicktime_stsc_table_t*)calloc(1, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated);
24 void quicktime_stsc_init_video(quicktime_t *file, quicktime_stsc_t *stsc)
26 //printf("quicktime_stsc_init_video 1\n");
27 quicktime_stsc_table_t *table;
28 quicktime_stsc_init_table(file, stsc);
29 table = &(stsc->table[0]);
30 table->chunk = 1;
31 table->samples = 1;
32 table->id = 1;
35 void quicktime_stsc_init_audio(quicktime_t *file, quicktime_stsc_t *stsc, int sample_rate)
37 quicktime_stsc_table_t *table;
38 quicktime_stsc_init_table(file, stsc);
39 table = &(stsc->table[0]);
40 table->chunk = 1;
41 table->samples = 0; /* set this after completion or after every audio chunk is written */
42 table->id = 1;
45 void quicktime_stsc_delete(quicktime_stsc_t *stsc)
47 if(stsc->total_entries) free(stsc->table);
48 stsc->total_entries = 0;
51 void quicktime_stsc_dump(quicktime_stsc_t *stsc)
53 int i;
54 printf(" sample to chunk\n");
55 printf(" version %d\n", stsc->version);
56 printf(" flags %d\n", stsc->flags);
57 printf(" total_entries %d\n", stsc->total_entries);
58 for(i = 0; i < stsc->total_entries; i++)
60 printf(" chunk %d samples %x id %d\n",
61 stsc->table[i].chunk, stsc->table[i].samples, stsc->table[i].id);
65 void quicktime_read_stsc(quicktime_t *file, quicktime_stsc_t *stsc)
67 int i;
68 stsc->version = quicktime_read_char(file);
69 stsc->flags = quicktime_read_int24(file);
70 stsc->total_entries = quicktime_read_int32(file);
72 stsc->entries_allocated = stsc->total_entries;
73 stsc->table = (quicktime_stsc_table_t*)malloc(sizeof(quicktime_stsc_table_t) * stsc->total_entries);
74 for(i = 0; i < stsc->total_entries; i++)
76 stsc->table[i].chunk = quicktime_read_int32(file);
77 stsc->table[i].samples = quicktime_read_int32(file);
78 stsc->table[i].id = quicktime_read_int32(file);
83 void quicktime_write_stsc(quicktime_t *file, quicktime_stsc_t *stsc)
85 int i, last_same;
86 quicktime_atom_t atom;
87 quicktime_atom_write_header(file, &atom, "stsc");
89 for(i = 1, last_same = 0; i < stsc->total_entries; i++)
91 if(stsc->table[i].samples != stsc->table[last_same].samples)
93 /* An entry has a different sample count. */
94 last_same++;
95 if(last_same < i)
97 /* Move it up the list. */
98 stsc->table[last_same] = stsc->table[i];
102 last_same++;
103 stsc->total_entries = last_same;
106 quicktime_write_char(file, stsc->version);
107 quicktime_write_int24(file, stsc->flags);
108 quicktime_write_int32(file, stsc->total_entries);
109 for(i = 0; i < stsc->total_entries; i++)
111 quicktime_write_int32(file, stsc->table[i].chunk);
112 quicktime_write_int32(file, stsc->table[i].samples);
113 quicktime_write_int32(file, stsc->table[i].id);
116 quicktime_atom_write_footer(file, &atom);
119 // Chunk starts at 1
120 int quicktime_update_stsc(quicktime_stsc_t *stsc, long chunk, long samples)
122 long i;
124 if(chunk > stsc->entries_allocated)
126 stsc->entries_allocated = chunk * 2;
127 stsc->table =(quicktime_stsc_table_t*)realloc(stsc->table, sizeof(quicktime_stsc_table_t) * stsc->entries_allocated);
130 stsc->table[chunk - 1].samples = samples;
131 stsc->table[chunk - 1].chunk = chunk;
132 stsc->table[chunk - 1].id = 1;
133 if(chunk > stsc->total_entries) stsc->total_entries = chunk;
134 return 0;
137 /* Optimizing while writing doesn't allow seeks during recording so */
138 /* entries are created for every chunk and only optimized during */
139 /* writeout. Unfortunately there's no way to keep audio synchronized */
140 /* after overwriting a recording as the fractional audio chunk in the */
141 /* middle always overwrites the previous location of a larger chunk. On */
142 /* writing, the table must be optimized. RealProducer requires an */
143 /* optimized table. */