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 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
);
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;
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
);
107 quicktime_atom_skip(file
, &leaf_atom
);
112 // FFMPEG says the esds sometimes contains a sample rate that overrides
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
)
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
;
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
;
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),
247 if(quicktime_atom_is(&leaf_atom
, "esds"))
249 quicktime_read_esds(file
, &leaf_atom
, &table
->esds
);
252 if(quicktime_atom_is(&leaf_atom
, "avcC"))
254 quicktime_read_avcc(file
, &leaf_atom
, &table
->avcc
);
257 if(quicktime_atom_is(&leaf_atom
, "ctab"))
259 quicktime_read_ctab(file
, &(table
->ctab
));
262 if(quicktime_atom_is(&leaf_atom
, "gama"))
264 table
->gamma
= quicktime_read_fixed32(file
);
267 if(quicktime_atom_is(&leaf_atom
, "fiel"))
269 table
->fields
= quicktime_read_char(file
);
270 table
->field_dominance
= quicktime_read_char(file
);
273 quicktime_atom_skip(file
, &leaf_atom
);
276 /* if(quicktime_atom_is(&leaf_atom, "mjqt")) */
278 /* quicktime_read_mjqt(file, &(table->mjqt)); */
281 /* if(quicktime_atom_is(&leaf_atom, "mjht")) */
283 /* quicktime_read_mjht(file, &(table->mjht)); */
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
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
)
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;
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;
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");
381 table
->ctab_id
= 65535;
382 quicktime_ctab_init(&(table
->ctab
));
385 table
->field_dominance
= 1;
386 quicktime_mjqt_init(&(table
->mjqt
));
387 quicktime_mjht_init(&(table
->mjht
));
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
);
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
);