bunch of small fixes, add msg.txt to about prefs
[goodguy/history.git] / cinelerra-5.0 / quicktime / stts.c
1 #include "funcprotos.h"
2 #include "quicktime.h"
3
4
5
6 void quicktime_stts_init(quicktime_stts_t *stts)
7 {
8         stts->version = 0;
9         stts->flags = 0;
10         stts->total_entries = 0;
11 }
12
13 void quicktime_stts_init_table(quicktime_stts_t *stts)
14 {
15         if(!stts->total_entries)
16         {
17                 stts->total_entries = 1;
18                 stts->table = (quicktime_stts_table_t*)malloc(sizeof(quicktime_stts_table_t) * stts->total_entries);
19         }
20 }
21
22 void quicktime_stts_init_video(quicktime_t *file, quicktime_stts_t *stts, int time_scale, float frame_rate)
23 {
24         quicktime_stts_table_t *table;
25         quicktime_stts_init_table(stts);
26         table = &(stts->table[0]);
27
28         table->sample_count = 0;      /* need to set this when closing */
29         table->sample_duration = time_scale / frame_rate;
30 //printf("quicktime_stts_init_video %d %f\n", time_scale, frame_rate);
31 }
32
33 void quicktime_stts_init_audio(quicktime_t *file, quicktime_stts_t *stts, int sample_rate)
34 {
35         quicktime_stts_table_t *table;
36         quicktime_stts_init_table(stts);
37         table = &(stts->table[0]);
38
39         table->sample_count = 0;     /* need to set this when closing */
40         table->sample_duration = 1;
41 }
42
43 void quicktime_stts_append_audio(quicktime_t *file, 
44         quicktime_stts_t *stts, 
45         int sample_duration)
46 {
47         quicktime_stts_table_t *table;
48         if(stts->total_entries)
49                 table = &(stts->table[stts->total_entries - 1]);
50         else
51                 table = 0;
52
53         stts->is_vbr = 1;
54
55 // Expand existing entry
56         if(table && table->sample_count)
57         {
58                 if(table->sample_duration == sample_duration)
59                 {
60                         table->sample_count++;
61                         return;
62                 }
63         }
64         else
65 // Override existing entry
66         if(table && table->sample_count == 0)
67         {
68                 table->sample_duration = sample_duration;
69                 table->sample_count = 1;
70                 return;
71         }
72
73 // Append new entry
74         stts->total_entries++;
75         stts->table = realloc(stts->table, 
76                 sizeof(quicktime_stts_table_t) * stts->total_entries);
77         table = &(stts->table[stts->total_entries - 1]);
78         table->sample_duration = sample_duration;
79         table->sample_count = 1;
80 }
81
82
83 int64_t quicktime_stts_total_samples(quicktime_t *file, 
84         quicktime_stts_t *stts)
85 {
86         int i;
87         int64_t result = 0;
88         for(i = 0; i < stts->total_entries; i++)
89         {
90                 result += stts->table[i].sample_count;
91         }
92         return result;
93 }
94
95
96 void quicktime_stts_delete(quicktime_stts_t *stts)
97 {
98         if(stts->total_entries) free(stts->table);
99         stts->total_entries = 0;
100 }
101
102 void quicktime_stts_dump(quicktime_stts_t *stts)
103 {
104         int i;
105         printf("     time to sample\n");
106         printf("      version %d\n", stts->version);
107         printf("      flags %ld\n", stts->flags);
108         printf("      total_entries %ld\n", stts->total_entries);
109         for(i = 0; i < stts->total_entries; i++)
110         {
111                 printf("       count %ld duration %ld\n",
112                         stts->table[i].sample_count, stts->table[i].sample_duration);
113         }
114 }
115
116 void quicktime_read_stts(quicktime_t *file, quicktime_stts_t *stts)
117 {
118         int i;
119         stts->version = quicktime_read_char(file);
120         stts->flags = quicktime_read_int24(file);
121         stts->total_entries = quicktime_read_int32(file);
122
123         stts->table = (quicktime_stts_table_t*)malloc(sizeof(quicktime_stts_table_t) * stts->total_entries);
124         for(i = 0; i < stts->total_entries; i++)
125         {
126                 stts->table[i].sample_count = quicktime_read_int32(file);
127                 stts->table[i].sample_duration = quicktime_read_int32(file);
128         }
129 }
130
131 void quicktime_write_stts(quicktime_t *file, quicktime_stts_t *stts)
132 {
133         int i;
134         quicktime_atom_t atom;
135         quicktime_atom_write_header(file, &atom, "stts");
136
137         quicktime_write_char(file, stts->version);
138         quicktime_write_int24(file, stts->flags);
139         quicktime_write_int32(file, stts->total_entries);
140         for(i = 0; i < stts->total_entries; i++)
141         {
142                 quicktime_write_int32(file, stts->table[i].sample_count);
143                 quicktime_write_int32(file, stts->table[i].sample_duration);
144         }
145
146         quicktime_atom_write_footer(file, &atom);
147 }
148
149 // Return the sample which contains the start_time argument.
150 // Stores the actual starting time of the sample in the start_time argument.
151 int quicktime_time_to_sample(quicktime_stts_t *stts, int64_t *start_time)
152 {
153         int64_t cur_time = 0, stime = *start_time;
154         int i = 0, entries = stts->total_entries, result = 0;
155         quicktime_stts_table_t *stts_table = &stts->table[0];
156
157         while( i < entries ) {
158                 int64_t count = stts_table->sample_count;
159                 int64_t end_time = cur_time + count * stts_table->sample_duration;
160                 if( end_time > stime ) break;
161                 cur_time = end_time;
162                 result += count;
163                 ++stts_table;
164                 ++i;
165         }
166
167         if( i >= entries )
168                 return entries-1;
169
170         stime = (stime - cur_time) / stts_table->sample_duration;
171         result += stime;
172         *start_time = cur_time + stime * stts_table->sample_duration;
173         return result;
174 }
175
176 int64_t quicktime_chunk_to_samples(quicktime_stts_t *stts, long chunk)
177 {
178         int64_t cur_time = 0;  long chunks = 0;
179         int i = 0, entries = stts->total_entries;
180         quicktime_stts_table_t *stts_table = &stts->table[0];
181
182         while( i < entries ) {
183                 int64_t count = stts_table->sample_count;
184                 int64_t end_time = cur_time + count * stts_table->sample_duration;
185                 long end_chunk = chunks + count;
186                 if( end_chunk > chunk ) break;
187                 chunks = end_chunk;
188                 cur_time = end_time;
189                 ++stts_table;  ++i;
190         }
191
192         if( i >= entries ) return cur_time;
193         
194         return cur_time + (chunk - chunks) * stts_table->sample_duration;
195 }
196