r955: Fix the Diffkey icon.
[cinelerra_cv.git] / quicktime / stsdtable.c
blobb78e93d66b7e4556e9d253cc8a75c73d492236d6
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include <string.h>
6 void quicktime_mjqt_init(quicktime_mjqt_t *mjqt)
10 void quicktime_mjqt_delete(quicktime_mjqt_t *mjqt)
14 void quicktime_mjqt_dump(quicktime_mjqt_t *mjqt)
19 void quicktime_mjht_init(quicktime_mjht_t *mjht)
23 void quicktime_mjht_delete(quicktime_mjht_t *mjht)
27 void quicktime_mjht_dump(quicktime_mjht_t *mjht)
31 // Set esds header to a copy of the argument
32 void quicktime_set_mpeg4_header(quicktime_stsd_table_t *table,
33 unsigned char *data,
34 int size)
36 if(table->esds.mpeg4_header)
38 free(table->esds.mpeg4_header);
41 table->esds.mpeg4_header = calloc(1, size);
42 memcpy(table->esds.mpeg4_header, data, size);
43 table->esds.mpeg4_header_size = size;
46 static void read_wave(quicktime_t *file,
47 quicktime_stsd_table_t *table,
48 quicktime_atom_t *parent_atom)
50 quicktime_atom_t leaf_atom;
51 while(quicktime_position(file) < parent_atom->end)
53 quicktime_atom_read_header(file, &leaf_atom);
54 if(quicktime_atom_is(&leaf_atom, "esds"))
56 quicktime_read_esds(file, &leaf_atom, &table->esds);
58 else
59 quicktime_atom_skip(file, &leaf_atom);
63 void quicktime_read_stsd_audio(quicktime_t *file,
64 quicktime_stsd_table_t *table,
65 quicktime_atom_t *parent_atom)
67 quicktime_atom_t leaf_atom;
69 table->version = quicktime_read_int16(file);
70 table->revision = quicktime_read_int16(file);
71 quicktime_read_data(file, table->vendor, 4);
72 table->channels = quicktime_read_int16(file);
73 table->sample_size = quicktime_read_int16(file);
74 table->compression_id = quicktime_read_int16(file);
75 table->packet_size = quicktime_read_int16(file);
76 table->sample_rate = quicktime_read_fixed32(file);
78 // Kluge for fixed32 limitation
79 if(table->sample_rate + 65536 == 96000 ||
80 table->sample_rate + 65536 == 88200) table->sample_rate += 65536;
83 // Version 1 fields
84 if(table->version > 0)
86 table->samples_per_packet = quicktime_read_int32(file);
87 table->bytes_per_packet = quicktime_read_int32(file);
88 table->bytes_per_frame = quicktime_read_int32(file);
89 table->bytes_per_sample = quicktime_read_int32(file);
91 // Skip another 20 bytes
92 if(table->version == 2)
94 quicktime_set_position(file, quicktime_position(file) + 0x14);
97 while(quicktime_position(file) < parent_atom->end)
99 quicktime_atom_read_header(file, &leaf_atom);
101 if(quicktime_atom_is(&leaf_atom, "wave"))
103 read_wave(file, table, &leaf_atom);
105 else
107 quicktime_atom_skip(file, &leaf_atom);
112 // FFMPEG says the esds sometimes contains a sample rate that overrides
113 // the sample table.
114 quicktime_esds_samplerate(table, &table->esds);
117 void quicktime_write_stsd_audio(quicktime_t *file, quicktime_stsd_table_t *table)
119 quicktime_write_int16(file, table->version);
120 quicktime_write_int16(file, table->revision);
121 quicktime_write_data(file, table->vendor, 4);
122 quicktime_write_int16(file, table->channels);
123 quicktime_write_int16(file, table->sample_size);
125 quicktime_write_int16(file, table->compression_id);
126 quicktime_write_int16(file, table->packet_size);
127 quicktime_write_fixed32(file, table->sample_rate);
129 // Write header for mp4v
130 if(table->esds.mpeg4_header_size && table->esds.mpeg4_header)
132 // Version 1 info
133 quicktime_write_int32(file, 0);
134 quicktime_write_int32(file, 0);
135 quicktime_write_int32(file, 0);
136 quicktime_write_int32(file, 0);
138 quicktime_atom_t wave_atom;
139 quicktime_atom_t frma_atom;
140 quicktime_atom_t mp4a_atom;
141 quicktime_atom_write_header(file, &wave_atom, "wave");
143 quicktime_atom_write_header(file, &frma_atom, "frma");
144 quicktime_write_data(file, "mp4a", 4);
145 quicktime_atom_write_footer(file, &frma_atom);
147 quicktime_atom_write_header(file, &mp4a_atom, "mp4a");
148 quicktime_write_int32(file, 0x0);
149 quicktime_atom_write_footer(file, &mp4a_atom);
151 quicktime_write_esds(file, &table->esds, 0, 1);
152 quicktime_atom_write_footer(file, &wave_atom);
156 // Lifted from mplayer and changed a bit
157 struct __attribute__((__packed__)) ImageDescription {
158 // int32_t idSize; /* total size of ImageDescription including extra data ( CLUTs and other per sequence data ) */
159 char cType[4]; /* what kind of codec compressed this data */
160 int32_t resvd1; /* reserved for Apple use */
161 int16_t resvd2; /* reserved for Apple use */
162 int16_t dataRefIndex; /* set to zero */
163 int16_t version; /* which version is this data */
164 int16_t revisionLevel; /* what version of that codec did this */
165 char vendor[4]; /* whose codec compressed this data */
166 uint32_t temporalQuality; /* what was the temporal quality factor */
167 uint32_t spatialQuality; /* what was the spatial quality factor */
168 int16_t width; /* how many pixels wide is this data */
169 int16_t height; /* how many pixels high is this data */
170 int32_t hRes; /* horizontal resolution */
171 int32_t vRes; /* vertical resolution */
172 int32_t dataSize; /* if known, the size of data for this image descriptor */
173 int16_t frameCount; /* number of frames this description applies to */
174 char name[32]; /* name of codec ( in case not installed ) */
175 int16_t depth; /* what depth is this data (1-32) or ( 33-40 grayscale ) */
176 int16_t clutID; /* clut id or if 0 clut follows or -1 if no clut */
180 void quicktime_read_stsd_video(quicktime_t *file,
181 quicktime_stsd_table_t *table,
182 quicktime_atom_t *parent_atom)
184 quicktime_atom_t leaf_atom;
185 int len;
187 table->version = quicktime_read_int16(file);
188 table->revision = quicktime_read_int16(file);
189 quicktime_read_data(file, table->vendor, 4);
190 table->temporal_quality = quicktime_read_int32(file);
191 table->spatial_quality = quicktime_read_int32(file);
192 table->width = quicktime_read_int16(file);
193 table->height = quicktime_read_int16(file);
194 table->dpi_horizontal = quicktime_read_fixed32(file);
195 table->dpi_vertical = quicktime_read_fixed32(file);
196 table->data_size = quicktime_read_int32(file);
197 table->frames_per_sample = quicktime_read_int16(file);
198 len = quicktime_read_char(file);
199 quicktime_read_data(file, table->compressor_name, 31);
200 table->depth = quicktime_read_int16(file);
201 table->ctab_id = quicktime_read_int16(file);
204 /* The data needed for SVQ3 codec and maybe some others ? */
205 struct ImageDescription *id;
206 int stsd_size,fourcc,c,d;
207 stsd_size = parent_atom->end - parent_atom->start;
208 table->extradata_size = stsd_size - 4;
209 id = (struct ImageDescription *) malloc(table->extradata_size); // we do not include size
210 table->extradata = (char *) id;
212 memcpy(id->cType, table->format, 4); // Fourcc
213 id->version = table->version;
214 id->revisionLevel = table->revision;
215 memcpy(id->vendor, table->vendor, 4); // I think mplayer screws up on this one, it turns bytes around! :)
216 id->temporalQuality = table->temporal_quality;
217 id->spatialQuality = table->spatial_quality;
218 id->width = table->width;
219 id->height = table->height;
220 id->hRes = table->dpi_horizontal;
221 id->vRes = table->dpi_vertical;
222 id->dataSize = table->data_size;
223 id->frameCount = table->frames_per_sample;
224 id->name[0] = len;
225 memcpy(&(id->name[1]), table->compressor_name, 31);
226 id->depth = table->depth;
227 id->clutID = table->ctab_id;
228 if (quicktime_position(file) < parent_atom->end)
230 int position = quicktime_position(file); // remember position
231 int datalen = parent_atom->end - position;
232 quicktime_read_data(file, ((char*)&id->clutID)+2, datalen);
233 quicktime_set_position(file, position); // return to previous position so parsing can go on
237 while(quicktime_position(file) < parent_atom->end)
239 quicktime_atom_read_header(file, &leaf_atom);
241 * printf("quicktime_read_stsd_video 1 %llx %llx %llx %s\n",
242 * leaf_atom.start, leaf_atom.end, quicktime_position(file),
243 * leaf_atom.type);
247 if(quicktime_atom_is(&leaf_atom, "esds"))
249 quicktime_read_esds(file, &leaf_atom, &table->esds);
251 else
252 if(quicktime_atom_is(&leaf_atom, "avcC"))
254 quicktime_read_avcc(file, &leaf_atom, &table->avcc);
256 else
257 if(quicktime_atom_is(&leaf_atom, "ctab"))
259 quicktime_read_ctab(file, &(table->ctab));
261 else
262 if(quicktime_atom_is(&leaf_atom, "gama"))
264 table->gamma = quicktime_read_fixed32(file);
266 else
267 if(quicktime_atom_is(&leaf_atom, "fiel"))
269 table->fields = quicktime_read_char(file);
270 table->field_dominance = quicktime_read_char(file);
272 else
273 quicktime_atom_skip(file, &leaf_atom);
276 /* if(quicktime_atom_is(&leaf_atom, "mjqt")) */
277 /* { */
278 /* quicktime_read_mjqt(file, &(table->mjqt)); */
279 /* } */
280 /* else */
281 /* if(quicktime_atom_is(&leaf_atom, "mjht")) */
282 /* { */
283 /* quicktime_read_mjht(file, &(table->mjht)); */
284 /* } */
285 /* else */
287 //printf("quicktime_read_stsd_video 2\n");
290 void quicktime_write_stsd_video(quicktime_t *file, quicktime_stsd_table_t *table)
292 quicktime_write_int16(file, table->version);
293 quicktime_write_int16(file, table->revision);
294 quicktime_write_data(file, table->vendor, 4);
295 quicktime_write_int32(file, table->temporal_quality);
296 quicktime_write_int32(file, table->spatial_quality);
297 quicktime_write_int16(file, table->width);
298 quicktime_write_int16(file, table->height);
299 quicktime_write_fixed32(file, table->dpi_horizontal);
300 quicktime_write_fixed32(file, table->dpi_vertical);
301 quicktime_write_int32(file, table->data_size);
302 quicktime_write_int16(file, table->frames_per_sample);
303 quicktime_write_char(file, strlen(table->compressor_name));
304 quicktime_write_data(file, table->compressor_name, 31);
305 quicktime_write_int16(file, table->depth);
306 quicktime_write_int16(file, table->ctab_id);
309 // Write field order for mjpa
310 if(table->fields)
312 quicktime_atom_t atom;
314 quicktime_atom_write_header(file, &atom, "fiel");
315 quicktime_write_char(file, table->fields);
316 quicktime_write_char(file, table->field_dominance);
317 quicktime_atom_write_footer(file, &atom);
320 // Write header for mp4v
321 if(table->esds.mpeg4_header_size && table->esds.mpeg4_header)
323 quicktime_write_esds(file, &table->esds, 1, 0);
326 if(table->avcc.data_size)
328 quicktime_write_avcc(file, &table->avcc);
331 // Write another 32 bits
332 if(table->version == 1)
333 quicktime_write_int32(file, 0x0);
336 void quicktime_read_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
338 quicktime_atom_t leaf_atom;
340 quicktime_atom_read_header(file, &leaf_atom);
342 table->format[0] = leaf_atom.type[0];
343 table->format[1] = leaf_atom.type[1];
344 table->format[2] = leaf_atom.type[2];
345 table->format[3] = leaf_atom.type[3];
346 quicktime_read_data(file, table->reserved, 6);
347 table->data_reference = quicktime_read_int16(file);
349 if(minf->is_audio) quicktime_read_stsd_audio(file, table, &leaf_atom);
350 if(minf->is_video) quicktime_read_stsd_video(file, table, &leaf_atom);
353 void quicktime_stsd_table_init(quicktime_stsd_table_t *table)
355 int i;
356 table->format[0] = 'y';
357 table->format[1] = 'u';
358 table->format[2] = 'v';
359 table->format[3] = '2';
360 for(i = 0; i < 6; i++) table->reserved[i] = 0;
361 table->data_reference = 1;
363 table->version = 0;
364 table->revision = 0;
365 table->vendor[0] = 'l';
366 table->vendor[1] = 'n';
367 table->vendor[2] = 'u';
368 table->vendor[3] = 'x';
370 table->temporal_quality = 100;
371 table->spatial_quality = 258;
372 table->width = 0;
373 table->height = 0;
374 table->dpi_horizontal = 72;
375 table->dpi_vertical = 72;
376 table->data_size = 0;
377 table->frames_per_sample = 1;
378 for(i = 0; i < 32; i++) table->compressor_name[i] = 0;
379 sprintf(table->compressor_name, "Quicktime for Linux");
380 table->depth = 24;
381 table->ctab_id = 65535;
382 quicktime_ctab_init(&(table->ctab));
383 table->gamma = 0;
384 table->fields = 0;
385 table->field_dominance = 1;
386 quicktime_mjqt_init(&(table->mjqt));
387 quicktime_mjht_init(&(table->mjht));
389 table->channels = 0;
390 table->sample_size = 0;
391 table->compression_id = 0;
392 table->packet_size = 0;
393 table->sample_rate = 0;
395 table->extradata = 0;
396 table->extradata_size = 0;
400 void quicktime_stsd_table_delete(quicktime_stsd_table_t *table)
402 quicktime_ctab_delete(&(table->ctab));
403 quicktime_mjqt_delete(&(table->mjqt));
404 quicktime_mjht_delete(&(table->mjht));
405 if(table->extradata) free(table->extradata);
406 quicktime_delete_avcc(&(table->avcc));
407 quicktime_delete_esds(&(table->esds));
411 void quicktime_stsd_video_dump(quicktime_stsd_table_t *table)
413 printf(" version %d\n", table->version);
414 printf(" revision %d\n", table->revision);
415 printf(" vendor %c%c%c%c\n", table->vendor[0], table->vendor[1], table->vendor[2], table->vendor[3]);
416 printf(" temporal_quality %ld\n", table->temporal_quality);
417 printf(" spatial_quality %ld\n", table->spatial_quality);
418 printf(" width %d\n", table->width);
419 printf(" height %d\n", table->height);
420 printf(" dpi_horizontal %f\n", table->dpi_horizontal);
421 printf(" dpi_vertical %f\n", table->dpi_vertical);
422 printf(" data_size %ld\n", table->data_size);
423 printf(" frames_per_sample %d\n", table->frames_per_sample);
424 printf(" compressor_name %s\n", table->compressor_name);
425 printf(" depth %d\n", table->depth);
426 printf(" ctab_id %d\n", table->ctab_id);
427 printf(" gamma %f\n", table->gamma);
428 if(table->fields)
430 printf(" fields %d\n", table->fields);
431 printf(" field dominance %d\n", table->field_dominance);
433 if(!table->ctab_id) quicktime_ctab_dump(&(table->ctab));
434 quicktime_mjqt_dump(&(table->mjqt));
435 quicktime_mjht_dump(&(table->mjht));
436 quicktime_esds_dump(&table->esds);
437 quicktime_avcc_dump(&table->avcc);
440 void quicktime_stsd_audio_dump(quicktime_stsd_table_t *table)
442 printf(" version %d\n", table->version);
443 printf(" revision %d\n", table->revision);
444 printf(" vendor %c%c%c%c\n", table->vendor[0], table->vendor[1], table->vendor[2], table->vendor[3]);
445 printf(" channels %d\n", table->channels);
446 printf(" sample_size %d\n", table->sample_size);
447 printf(" compression_id %d\n", table->compression_id);
448 printf(" packet_size %d\n", table->packet_size);
449 printf(" sample_rate %f\n", table->sample_rate);
450 if(table->version > 0)
452 printf(" samples_per_packet %d\n", table->samples_per_packet);
453 printf(" bytes_per_packet %d\n", table->bytes_per_packet);
454 printf(" bytes_per_frame %d\n", table->bytes_per_frame);
455 printf(" bytes_per_sample %d\n", table->bytes_per_sample);
457 quicktime_esds_dump(&table->esds);
458 quicktime_avcc_dump(&table->avcc);
461 void quicktime_stsd_table_dump(void *minf_ptr, quicktime_stsd_table_t *table)
463 quicktime_minf_t *minf = minf_ptr;
464 printf(" format %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]);
465 quicktime_print_chars(" reserved ", table->reserved, 6);
466 printf(" data_reference %d\n", table->data_reference);
468 if(minf->is_audio) quicktime_stsd_audio_dump(table);
469 if(minf->is_video) quicktime_stsd_video_dump(table);
472 void quicktime_write_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
474 quicktime_atom_t atom;
475 quicktime_atom_write_header(file, &atom, table->format);
476 /*printf("quicktime_write_stsd_table %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]); */
477 quicktime_write_data(file, table->reserved, 6);
478 quicktime_write_int16(file, table->data_reference);
480 if(minf->is_audio) quicktime_write_stsd_audio(file, table);
481 if(minf->is_video) quicktime_write_stsd_video(file, table);
483 quicktime_atom_write_footer(file, &atom);