1 #include "funcprotos.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,
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 //printf("read_wave 1 start=0x%llx\n", quicktime_position(file));
52 while(quicktime_position(file) < parent_atom->end)
54 quicktime_atom_read_header(file, &leaf_atom);
55 if(quicktime_atom_is(&leaf_atom, "esds"))
57 quicktime_read_esds(file, &leaf_atom, &table->esds);
60 if(quicktime_atom_is(&leaf_atom, "frma"))
62 // Extra data for QDM2
63 quicktime_read_frma(file, parent_atom, &leaf_atom, &table->frma);
66 quicktime_atom_skip(file, &leaf_atom);
70 void quicktime_read_stsd_audio(quicktime_t *file,
71 quicktime_stsd_table_t *table,
72 quicktime_atom_t *parent_atom)
74 quicktime_atom_t leaf_atom;
76 table->version = quicktime_read_int16(file);
77 table->revision = quicktime_read_int16(file);
78 quicktime_read_data(file, table->vendor, 4);
79 table->channels = quicktime_read_int16(file);
80 table->sample_size = quicktime_read_int16(file);
81 table->compression_id = quicktime_read_int16(file);
82 table->packet_size = quicktime_read_int16(file);
83 table->sample_rate = quicktime_read_fixed32(file);
85 // Kluge for fixed32 limitation
86 if(table->sample_rate + 65536 == 96000 ||
87 table->sample_rate + 65536 == 88200) table->sample_rate += 65536;
91 if(table->version > 0)
93 table->samples_per_packet = quicktime_read_int32(file);
94 table->bytes_per_packet = quicktime_read_int32(file);
95 table->bytes_per_frame = quicktime_read_int32(file);
96 table->bytes_per_sample = quicktime_read_int32(file);
98 // Skip another 20 bytes
99 if(table->version == 2)
101 quicktime_set_position(file, quicktime_position(file) + 0x14);
105 while(quicktime_position(file) < parent_atom->end) {
106 quicktime_atom_read_header(file, &leaf_atom);
107 if( quicktime_atom_is(&leaf_atom, "wave") )
108 read_wave(file, table, &leaf_atom);
109 else if( quicktime_atom_is(&leaf_atom, "esds") )
110 quicktime_read_esds(file, &leaf_atom, &table->esds);
112 quicktime_atom_skip(file, &leaf_atom);
115 // FFMPEG says the esds sometimes contains a sample rate that overrides
117 quicktime_esds_samplerate(table, &table->esds);
120 void quicktime_write_stsd_audio(quicktime_t *file, quicktime_stsd_table_t *table)
122 quicktime_write_int16(file, table->version);
123 quicktime_write_int16(file, table->revision);
124 quicktime_write_data(file, table->vendor, 4);
125 quicktime_write_int16(file, table->channels);
126 quicktime_write_int16(file, table->sample_size);
128 quicktime_write_int16(file, table->compression_id);
129 quicktime_write_int16(file, table->packet_size);
130 quicktime_write_fixed32(file, table->sample_rate);
132 // Write header for mp4a
133 if(table->esds.mpeg4_header_size && table->esds.mpeg4_header)
135 // Android requires leaving out the WAVE header
136 if( table->version > 0 ) {
137 // newer version info
138 int padding = table->version == 1 ?
139 0x10/sizeof(int32_t) : 0x24/sizeof(int32_t);
140 while( --padding >= 0 ) quicktime_write_int32(file, 0);
142 quicktime_atom_t wave_atom;
143 quicktime_atom_t frma_atom;
144 quicktime_atom_t mp4a_atom;
145 quicktime_atom_write_header(file, &wave_atom, "wave");
147 quicktime_atom_write_header(file, &frma_atom, "frma");
148 quicktime_write_data(file, "mp4a", 4);
149 quicktime_atom_write_footer(file, &frma_atom);
151 quicktime_atom_write_header(file, &mp4a_atom, "mp4a");
152 quicktime_write_int32(file, 0x0);
153 quicktime_atom_write_footer(file, &mp4a_atom);
154 quicktime_write_esds(file, &table->esds, 0, 1);
155 quicktime_atom_write_footer(file, &wave_atom);
158 quicktime_write_esds(file, &table->esds, 0, 1);
162 // Lifted from mplayer and changed a bit
163 struct __attribute__((__packed__)) ImageDescription {
164 // int32_t idSize; /* total size of ImageDescription including extra data ( CLUTs and other per sequence data ) */
165 char cType[4]; /* what kind of codec compressed this data */
166 int32_t resvd1; /* reserved for Apple use */
167 int16_t resvd2; /* reserved for Apple use */
168 int16_t dataRefIndex; /* set to zero */
169 int16_t version; /* which version is this data */
170 int16_t revisionLevel; /* what version of that codec did this */
171 char vendor[4]; /* whose codec compressed this data */
172 uint32_t temporalQuality; /* what was the temporal quality factor */
173 uint32_t spatialQuality; /* what was the spatial quality factor */
174 int16_t width; /* how many pixels wide is this data */
175 int16_t height; /* how many pixels high is this data */
176 int32_t hRes; /* horizontal resolution */
177 int32_t vRes; /* vertical resolution */
178 int32_t dataSize; /* if known, the size of data for this image descriptor */
179 int16_t frameCount; /* number of frames this description applies to */
180 char name[32]; /* name of codec ( in case not installed ) */
181 int16_t depth; /* what depth is this data (1-32) or ( 33-40 grayscale ) */
182 int16_t clutID; /* clut id or if 0 clut follows or -1 if no clut */
186 void quicktime_read_stsd_video(quicktime_t *file,
187 quicktime_stsd_table_t *table,
188 quicktime_atom_t *parent_atom)
190 quicktime_atom_t leaf_atom;
193 table->version = quicktime_read_int16(file);
194 table->revision = quicktime_read_int16(file);
195 quicktime_read_data(file, table->vendor, 4);
196 table->temporal_quality = quicktime_read_int32(file);
197 table->spatial_quality = quicktime_read_int32(file);
198 table->width = quicktime_read_int16(file);
199 table->height = quicktime_read_int16(file);
200 table->dpi_horizontal = quicktime_read_fixed32(file);
201 table->dpi_vertical = quicktime_read_fixed32(file);
202 table->data_size = quicktime_read_int32(file);
203 table->frames_per_sample = quicktime_read_int16(file);
204 len = quicktime_read_char(file);
205 quicktime_read_data(file, table->compressor_name, 31);
206 table->depth = quicktime_read_int16(file);
207 table->ctab_id = quicktime_read_int16(file);
210 /* The data needed for SVQ3 codec and maybe some others ? */
211 struct ImageDescription *id;
212 int stsd_size = parent_atom->end - parent_atom->start;
213 table->extradata_size = stsd_size - 4;
214 id = (struct ImageDescription *) malloc(table->extradata_size); // we do not include size
215 table->extradata = (char *) id;
217 memcpy(id->cType, table->format, 4); // Fourcc
218 id->version = table->version;
219 id->revisionLevel = table->revision;
220 memcpy(id->vendor, table->vendor, 4); // I think mplayer screws up on this one, it turns bytes around! :)
221 id->temporalQuality = table->temporal_quality;
222 id->spatialQuality = table->spatial_quality;
223 id->width = table->width;
224 id->height = table->height;
225 id->hRes = table->dpi_horizontal;
226 id->vRes = table->dpi_vertical;
227 id->dataSize = table->data_size;
228 id->frameCount = table->frames_per_sample;
230 memcpy(&(id->name[1]), table->compressor_name, 31);
231 id->depth = table->depth;
232 id->clutID = table->ctab_id;
233 if (quicktime_position(file) < parent_atom->end)
235 int position = quicktime_position(file); // remember position
236 int datalen = parent_atom->end - position;
237 quicktime_read_data(file, ((char*)&id->clutID)+2, datalen);
238 quicktime_set_position(file, position); // return to previous position so parsing can go on
241 while(quicktime_position(file) < parent_atom->end)
243 quicktime_atom_read_header(file, &leaf_atom);
245 * printf("quicktime_read_stsd_video 1 %llx %llx %llx %s\n",
246 * leaf_atom.start, leaf_atom.end, quicktime_position(file),
251 if(quicktime_atom_is(&leaf_atom, "esds"))
253 quicktime_read_esds(file, &leaf_atom, &table->esds);
256 if(quicktime_atom_is(&leaf_atom, "avcC"))
258 quicktime_read_avcc(file, &leaf_atom, &table->avcc);
261 if(quicktime_atom_is(&leaf_atom, "ctab"))
263 quicktime_read_ctab(file, &(table->ctab));
266 if(quicktime_atom_is(&leaf_atom, "gama"))
268 table->gamma = quicktime_read_fixed32(file);
271 if(quicktime_atom_is(&leaf_atom, "fiel"))
273 table->fields = quicktime_read_char(file);
274 table->field_dominance = quicktime_read_char(file);
277 quicktime_atom_skip(file, &leaf_atom);
280 /* if(quicktime_atom_is(&leaf_atom, "mjqt")) */
282 /* quicktime_read_mjqt(file, &(table->mjqt)); */
285 /* if(quicktime_atom_is(&leaf_atom, "mjht")) */
287 /* quicktime_read_mjht(file, &(table->mjht)); */
291 //printf("quicktime_read_stsd_video 2\n");
294 void quicktime_write_stsd_video(quicktime_t *file, quicktime_stsd_table_t *table)
296 quicktime_write_int16(file, table->version);
297 quicktime_write_int16(file, table->revision);
298 quicktime_write_data(file, table->vendor, 4);
299 quicktime_write_int32(file, table->temporal_quality);
300 quicktime_write_int32(file, table->spatial_quality);
301 quicktime_write_int16(file, table->width);
302 quicktime_write_int16(file, table->height);
303 quicktime_write_fixed32(file, table->dpi_horizontal);
304 quicktime_write_fixed32(file, table->dpi_vertical);
305 quicktime_write_int32(file, table->data_size);
306 quicktime_write_int16(file, table->frames_per_sample);
307 quicktime_write_char(file, strlen(table->compressor_name));
308 quicktime_write_data(file, table->compressor_name, 31);
309 quicktime_write_int16(file, table->depth);
310 quicktime_write_int16(file, table->ctab_id);
313 // Write field order for mjpa
316 quicktime_atom_t atom;
318 quicktime_atom_write_header(file, &atom, "fiel");
319 quicktime_write_char(file, table->fields);
320 quicktime_write_char(file, table->field_dominance);
321 quicktime_atom_write_footer(file, &atom);
324 // Write header for mp4v
325 if(table->esds.mpeg4_header_size && table->esds.mpeg4_header)
327 quicktime_write_esds(file, &table->esds, 1, 0);
330 if(table->avcc.data_size)
332 quicktime_write_avcc(file, &table->avcc);
335 // Write another 32 bits
336 if(table->version == 1)
337 quicktime_write_int32(file, 0x0);
340 void quicktime_read_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
342 quicktime_atom_t leaf_atom;
344 quicktime_atom_read_header(file, &leaf_atom);
346 table->format[0] = leaf_atom.type[0];
347 table->format[1] = leaf_atom.type[1];
348 table->format[2] = leaf_atom.type[2];
349 table->format[3] = leaf_atom.type[3];
350 quicktime_read_data(file, table->reserved, 6);
351 table->data_reference = quicktime_read_int16(file);
353 if(minf->is_audio) quicktime_read_stsd_audio(file, table, &leaf_atom);
354 if(minf->is_video) quicktime_read_stsd_video(file, table, &leaf_atom);
357 void quicktime_stsd_table_init(quicktime_stsd_table_t *table)
360 table->format[0] = 'y';
361 table->format[1] = 'u';
362 table->format[2] = 'v';
363 table->format[3] = '2';
364 for(i = 0; i < 6; i++) table->reserved[i] = 0;
365 table->data_reference = 1;
369 table->vendor[0] = 'l';
370 table->vendor[1] = 'n';
371 table->vendor[2] = 'u';
372 table->vendor[3] = 'x';
374 table->temporal_quality = 100;
375 table->spatial_quality = 258;
378 table->dpi_horizontal = 72;
379 table->dpi_vertical = 72;
380 table->data_size = 0;
381 table->frames_per_sample = 1;
382 for(i = 0; i < 32; i++) table->compressor_name[i] = 0;
383 sprintf(table->compressor_name, "Quicktime for Linux");
385 table->ctab_id = 65535;
386 quicktime_ctab_init(&(table->ctab));
389 table->field_dominance = 1;
390 quicktime_mjqt_init(&(table->mjqt));
391 quicktime_mjht_init(&(table->mjht));
394 table->sample_size = 0;
395 table->compression_id = 0;
396 table->packet_size = 0;
397 table->sample_rate = 0;
399 table->extradata = 0;
400 table->extradata_size = 0;
403 void quicktime_stsd_table_delete(quicktime_stsd_table_t *table)
405 quicktime_ctab_delete(&(table->ctab));
406 quicktime_mjqt_delete(&(table->mjqt));
407 quicktime_mjht_delete(&(table->mjht));
408 quicktime_delete_avcc(&(table->avcc));
409 quicktime_delete_esds(&(table->esds));
410 quicktime_delete_frma(&(table->frma));
414 void quicktime_stsd_video_dump(quicktime_stsd_table_t *table)
416 printf(" version %d\n", table->version);
417 printf(" revision %d\n", table->revision);
418 printf(" vendor %c%c%c%c\n", table->vendor[0], table->vendor[1], table->vendor[2], table->vendor[3]);
419 printf(" temporal_quality %ld\n", table->temporal_quality);
420 printf(" spatial_quality %ld\n", table->spatial_quality);
421 printf(" width %d\n", table->width);
422 printf(" height %d\n", table->height);
423 printf(" dpi_horizontal %f\n", table->dpi_horizontal);
424 printf(" dpi_vertical %f\n", table->dpi_vertical);
425 printf(" data_size %ld\n", table->data_size);
426 printf(" frames_per_sample %d\n", table->frames_per_sample);
427 printf(" compressor_name %s\n", table->compressor_name);
428 printf(" depth %d\n", table->depth);
429 printf(" ctab_id %d\n", table->ctab_id);
430 printf(" gamma %f\n", table->gamma);
433 printf(" fields %d\n", table->fields);
434 printf(" field dominance %d\n", table->field_dominance);
436 if(!table->ctab_id) quicktime_ctab_dump(&(table->ctab));
437 quicktime_mjqt_dump(&(table->mjqt));
438 quicktime_mjht_dump(&(table->mjht));
439 quicktime_esds_dump(&table->esds);
440 quicktime_avcc_dump(&table->avcc);
441 quicktime_frma_dump(&table->frma);
444 void quicktime_stsd_audio_dump(quicktime_stsd_table_t *table)
446 printf(" version %d\n", table->version);
447 printf(" revision %d\n", table->revision);
448 printf(" vendor %c%c%c%c\n", table->vendor[0], table->vendor[1], table->vendor[2], table->vendor[3]);
449 printf(" channels %d\n", table->channels);
450 printf(" sample_size %d\n", table->sample_size);
451 printf(" compression_id 0x%x\n", table->compression_id);
452 printf(" packet_size %d\n", table->packet_size);
453 printf(" sample_rate %f\n", table->sample_rate);
454 if(table->version > 0)
456 printf(" samples_per_packet %d\n", table->samples_per_packet);
457 printf(" bytes_per_packet %d\n", table->bytes_per_packet);
458 printf(" bytes_per_frame %d\n", table->bytes_per_frame);
459 printf(" bytes_per_sample %d\n", table->bytes_per_sample);
461 quicktime_esds_dump(&table->esds);
462 quicktime_avcc_dump(&table->avcc);
463 quicktime_frma_dump(&table->frma);
466 void quicktime_stsd_table_dump(void *minf_ptr, quicktime_stsd_table_t *table)
468 quicktime_minf_t *minf = minf_ptr;
469 printf(" format %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]);
470 quicktime_print_chars(" reserved ", table->reserved, 6);
471 printf(" data_reference %d\n", table->data_reference);
473 if(minf->is_audio) quicktime_stsd_audio_dump(table);
474 if(minf->is_video) quicktime_stsd_video_dump(table);
477 void quicktime_write_stsd_table(quicktime_t *file, quicktime_minf_t *minf, quicktime_stsd_table_t *table)
479 quicktime_atom_t atom;
480 quicktime_atom_write_header(file, &atom, table->format);
481 /*printf("quicktime_write_stsd_table %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]); */
482 quicktime_write_data(file, table->reserved, 6);
483 quicktime_write_int16(file, table->data_reference);
485 if(minf->is_audio) quicktime_write_stsd_audio(file, table);
486 if(minf->is_video) quicktime_write_stsd_video(file, table);
488 quicktime_atom_write_footer(file, &atom);