1 #include "funcprotos.h"
5 void quicktime_mjqt_init(quicktime_mjqt_t
*mjqt
)
9 void quicktime_mjqt_delete(quicktime_mjqt_t
*mjqt
)
13 void quicktime_mjqt_dump(quicktime_mjqt_t
*mjqt
)
18 void quicktime_mjht_init(quicktime_mjht_t
*mjht
)
22 void quicktime_mjht_delete(quicktime_mjht_t
*mjht
)
26 void quicktime_mjht_dump(quicktime_mjht_t
*mjht
)
30 // Set esds header to a copy of the argument
31 void quicktime_set_mpeg4_header(quicktime_stsd_table_t
*table
,
35 if(table
->esds
.mpeg4_header
)
37 free(table
->esds
.mpeg4_header
);
40 table
->esds
.mpeg4_header
= calloc(1, size
);
41 memcpy(table
->esds
.mpeg4_header
, data
, size
);
42 table
->esds
.mpeg4_header_size
= size
;
45 static void read_wave(quicktime_t
*file
,
46 quicktime_stsd_table_t
*table
,
47 quicktime_atom_t
*parent_atom
)
49 quicktime_atom_t leaf_atom
;
50 while(quicktime_position(file
) < parent_atom
->end
)
52 quicktime_atom_read_header(file
, &leaf_atom
);
53 if(quicktime_atom_is(&leaf_atom
, "esds"))
55 quicktime_read_esds(file
, &leaf_atom
, &table
->esds
);
58 quicktime_atom_skip(file
, &leaf_atom
);
62 void quicktime_read_stsd_audio(quicktime_t
*file
,
63 quicktime_stsd_table_t
*table
,
64 quicktime_atom_t
*parent_atom
)
66 quicktime_atom_t leaf_atom
;
68 table
->version
= quicktime_read_int16(file
);
69 table
->revision
= quicktime_read_int16(file
);
70 quicktime_read_data(file
, table
->vendor
, 4);
71 table
->channels
= quicktime_read_int16(file
);
72 table
->sample_size
= quicktime_read_int16(file
);
73 table
->compression_id
= quicktime_read_int16(file
);
74 table
->packet_size
= quicktime_read_int16(file
);
75 table
->sample_rate
= quicktime_read_fixed32(file
);
77 // Kluge for fixed32 limitation
78 if(table
->sample_rate
+ 65536 == 96000 ||
79 table
->sample_rate
+ 65536 == 88200) table
->sample_rate
+= 65536;
83 if(table
->version
> 0)
85 table
->samples_per_packet
= quicktime_read_int32(file
);
86 table
->bytes_per_packet
= quicktime_read_int32(file
);
87 table
->bytes_per_frame
= quicktime_read_int32(file
);
88 table
->bytes_per_sample
= quicktime_read_int32(file
);
90 // Skip another 20 bytes
91 if(table
->version
== 2)
93 quicktime_set_position(file
, quicktime_position(file
) + 0x14);
96 while(quicktime_position(file
) < parent_atom
->end
)
98 quicktime_atom_read_header(file
, &leaf_atom
);
100 if(quicktime_atom_is(&leaf_atom
, "wave"))
102 read_wave(file
, table
, &leaf_atom
);
106 quicktime_atom_skip(file
, &leaf_atom
);
111 // FFMPEG says the esds sometimes contains a sample rate that overrides
113 quicktime_esds_samplerate(table
, &table
->esds
);
116 void quicktime_write_stsd_audio(quicktime_t
*file
, quicktime_stsd_table_t
*table
)
118 quicktime_write_int16(file
, table
->version
);
119 quicktime_write_int16(file
, table
->revision
);
120 quicktime_write_data(file
, table
->vendor
, 4);
121 quicktime_write_int16(file
, table
->channels
);
122 quicktime_write_int16(file
, table
->sample_size
);
124 quicktime_write_int16(file
, table
->compression_id
);
125 quicktime_write_int16(file
, table
->packet_size
);
126 quicktime_write_fixed32(file
, table
->sample_rate
);
128 // Write header for mp4v
129 if(table
->esds
.mpeg4_header_size
&& table
->esds
.mpeg4_header
)
132 quicktime_write_int32(file
, 0);
133 quicktime_write_int32(file
, 0);
134 quicktime_write_int32(file
, 0);
135 quicktime_write_int32(file
, 0);
137 quicktime_atom_t wave_atom
;
138 quicktime_atom_t frma_atom
;
139 quicktime_atom_t mp4a_atom
;
140 quicktime_atom_write_header(file
, &wave_atom
, "wave");
142 quicktime_atom_write_header(file
, &frma_atom
, "frma");
143 quicktime_write_data(file
, "mp4a", 4);
144 quicktime_atom_write_footer(file
, &frma_atom
);
146 quicktime_atom_write_header(file
, &mp4a_atom
, "mp4a");
147 quicktime_write_int32(file
, 0x0);
148 quicktime_atom_write_footer(file
, &mp4a_atom
);
150 quicktime_write_esds(file
, &table
->esds
, 0, 1);
151 quicktime_atom_write_footer(file
, &wave_atom
);
155 // Lifted from mplayer and changed a bit
156 struct __attribute__((__packed__
)) ImageDescription
{
157 // int32_t idSize; /* total size of ImageDescription including extra data ( CLUTs and other per sequence data ) */
158 char cType
[4]; /* what kind of codec compressed this data */
159 int32_t resvd1
; /* reserved for Apple use */
160 int16_t resvd2
; /* reserved for Apple use */
161 int16_t dataRefIndex
; /* set to zero */
162 int16_t version
; /* which version is this data */
163 int16_t revisionLevel
; /* what version of that codec did this */
164 char vendor
[4]; /* whose codec compressed this data */
165 uint32_t temporalQuality
; /* what was the temporal quality factor */
166 uint32_t spatialQuality
; /* what was the spatial quality factor */
167 int16_t width
; /* how many pixels wide is this data */
168 int16_t height
; /* how many pixels high is this data */
169 int32_t hRes
; /* horizontal resolution */
170 int32_t vRes
; /* vertical resolution */
171 int32_t dataSize
; /* if known, the size of data for this image descriptor */
172 int16_t frameCount
; /* number of frames this description applies to */
173 char name
[32]; /* name of codec ( in case not installed ) */
174 int16_t depth
; /* what depth is this data (1-32) or ( 33-40 grayscale ) */
175 int16_t clutID
; /* clut id or if 0 clut follows or -1 if no clut */
179 void quicktime_read_stsd_video(quicktime_t
*file
,
180 quicktime_stsd_table_t
*table
,
181 quicktime_atom_t
*parent_atom
)
183 quicktime_atom_t leaf_atom
;
186 table
->version
= quicktime_read_int16(file
);
187 table
->revision
= quicktime_read_int16(file
);
188 quicktime_read_data(file
, table
->vendor
, 4);
189 table
->temporal_quality
= quicktime_read_int32(file
);
190 table
->spatial_quality
= quicktime_read_int32(file
);
191 table
->width
= quicktime_read_int16(file
);
192 table
->height
= quicktime_read_int16(file
);
193 table
->dpi_horizontal
= quicktime_read_fixed32(file
);
194 table
->dpi_vertical
= quicktime_read_fixed32(file
);
195 table
->data_size
= quicktime_read_int32(file
);
196 table
->frames_per_sample
= quicktime_read_int16(file
);
197 len
= quicktime_read_char(file
);
198 quicktime_read_data(file
, table
->compressor_name
, 31);
199 table
->depth
= quicktime_read_int16(file
);
200 table
->ctab_id
= quicktime_read_int16(file
);
203 /* The data needed for SVQ3 codec and maybe some others ? */
204 struct ImageDescription
*id
;
205 int stsd_size
,fourcc
,c
,d
;
206 stsd_size
= parent_atom
->end
- parent_atom
->start
;
207 table
->extradata_size
= stsd_size
- 4;
208 id
= (struct ImageDescription
*) malloc(table
->extradata_size
); // we do not include size
209 table
->extradata
= (char *) id
;
211 memcpy(id
->cType
, table
->format
, 4); // Fourcc
212 id
->version
= table
->version
;
213 id
->revisionLevel
= table
->revision
;
214 memcpy(id
->vendor
, table
->vendor
, 4); // I think mplayer screws up on this one, it turns bytes around! :)
215 id
->temporalQuality
= table
->temporal_quality
;
216 id
->spatialQuality
= table
->spatial_quality
;
217 id
->width
= table
->width
;
218 id
->height
= table
->height
;
219 id
->hRes
= table
->dpi_horizontal
;
220 id
->vRes
= table
->dpi_vertical
;
221 id
->dataSize
= table
->data_size
;
222 id
->frameCount
= table
->frames_per_sample
;
224 memcpy(&(id
->name
[1]), table
->compressor_name
, 31);
225 id
->depth
= table
->depth
;
226 id
->clutID
= table
->ctab_id
;
227 if (quicktime_position(file
) < parent_atom
->end
)
229 int position
= quicktime_position(file
); // remember position
230 int datalen
= parent_atom
->end
- position
;
231 quicktime_read_data(file
, ((char*)&id
->clutID
)+2, datalen
);
232 quicktime_set_position(file
, position
); // return to previous position so parsing can go on
236 while(quicktime_position(file
) < parent_atom
->end
)
238 quicktime_atom_read_header(file
, &leaf_atom
);
240 * printf("quicktime_read_stsd_video 1 %llx %llx %llx %s\n",
241 * leaf_atom.start, leaf_atom.end, quicktime_position(file),
246 if(quicktime_atom_is(&leaf_atom
, "esds"))
248 quicktime_read_esds(file
, &leaf_atom
, &table
->esds
);
251 if(quicktime_atom_is(&leaf_atom
, "avcC"))
253 quicktime_read_avcc(file
, &leaf_atom
, &table
->avcc
);
256 if(quicktime_atom_is(&leaf_atom
, "ctab"))
258 quicktime_read_ctab(file
, &(table
->ctab
));
261 if(quicktime_atom_is(&leaf_atom
, "gama"))
263 table
->gamma
= quicktime_read_fixed32(file
);
266 if(quicktime_atom_is(&leaf_atom
, "fiel"))
268 table
->fields
= quicktime_read_char(file
);
269 table
->field_dominance
= quicktime_read_char(file
);
272 quicktime_atom_skip(file
, &leaf_atom
);
275 /* if(quicktime_atom_is(&leaf_atom, "mjqt")) */
277 /* quicktime_read_mjqt(file, &(table->mjqt)); */
280 /* if(quicktime_atom_is(&leaf_atom, "mjht")) */
282 /* quicktime_read_mjht(file, &(table->mjht)); */
286 //printf("quicktime_read_stsd_video 2\n");
289 void quicktime_write_stsd_video(quicktime_t
*file
, quicktime_stsd_table_t
*table
)
291 quicktime_write_int16(file
, table
->version
);
292 quicktime_write_int16(file
, table
->revision
);
293 quicktime_write_data(file
, table
->vendor
, 4);
294 quicktime_write_int32(file
, table
->temporal_quality
);
295 quicktime_write_int32(file
, table
->spatial_quality
);
296 quicktime_write_int16(file
, table
->width
);
297 quicktime_write_int16(file
, table
->height
);
298 quicktime_write_fixed32(file
, table
->dpi_horizontal
);
299 quicktime_write_fixed32(file
, table
->dpi_vertical
);
300 quicktime_write_int32(file
, table
->data_size
);
301 quicktime_write_int16(file
, table
->frames_per_sample
);
302 quicktime_write_char(file
, strlen(table
->compressor_name
));
303 quicktime_write_data(file
, table
->compressor_name
, 31);
304 quicktime_write_int16(file
, table
->depth
);
305 quicktime_write_int16(file
, table
->ctab_id
);
308 // Write field order for mjpa
311 quicktime_atom_t atom
;
313 quicktime_atom_write_header(file
, &atom
, "fiel");
314 quicktime_write_char(file
, table
->fields
);
315 quicktime_write_char(file
, table
->field_dominance
);
316 quicktime_atom_write_footer(file
, &atom
);
319 // Write header for mp4v
320 if(table
->esds
.mpeg4_header_size
&& table
->esds
.mpeg4_header
)
322 quicktime_write_esds(file
, &table
->esds
, 1, 0);
325 if(table
->avcc
.data_size
)
327 quicktime_write_avcc(file
, &table
->avcc
);
330 // Write another 32 bits
331 if(table
->version
== 1)
332 quicktime_write_int32(file
, 0x0);
335 void quicktime_read_stsd_table(quicktime_t
*file
, quicktime_minf_t
*minf
, quicktime_stsd_table_t
*table
)
337 quicktime_atom_t leaf_atom
;
339 quicktime_atom_read_header(file
, &leaf_atom
);
341 table
->format
[0] = leaf_atom
.type
[0];
342 table
->format
[1] = leaf_atom
.type
[1];
343 table
->format
[2] = leaf_atom
.type
[2];
344 table
->format
[3] = leaf_atom
.type
[3];
345 quicktime_read_data(file
, table
->reserved
, 6);
346 table
->data_reference
= quicktime_read_int16(file
);
348 if(minf
->is_audio
) quicktime_read_stsd_audio(file
, table
, &leaf_atom
);
349 if(minf
->is_video
) quicktime_read_stsd_video(file
, table
, &leaf_atom
);
352 void quicktime_stsd_table_init(quicktime_stsd_table_t
*table
)
355 table
->format
[0] = 'y';
356 table
->format
[1] = 'u';
357 table
->format
[2] = 'v';
358 table
->format
[3] = '2';
359 for(i
= 0; i
< 6; i
++) table
->reserved
[i
] = 0;
360 table
->data_reference
= 1;
364 table
->vendor
[0] = 'l';
365 table
->vendor
[1] = 'n';
366 table
->vendor
[2] = 'u';
367 table
->vendor
[3] = 'x';
369 table
->temporal_quality
= 100;
370 table
->spatial_quality
= 258;
373 table
->dpi_horizontal
= 72;
374 table
->dpi_vertical
= 72;
375 table
->data_size
= 0;
376 table
->frames_per_sample
= 1;
377 for(i
= 0; i
< 32; i
++) table
->compressor_name
[i
] = 0;
378 sprintf(table
->compressor_name
, "Quicktime for Linux");
380 table
->ctab_id
= 65535;
381 quicktime_ctab_init(&(table
->ctab
));
384 table
->field_dominance
= 1;
385 quicktime_mjqt_init(&(table
->mjqt
));
386 quicktime_mjht_init(&(table
->mjht
));
389 table
->sample_size
= 0;
390 table
->compression_id
= 0;
391 table
->packet_size
= 0;
392 table
->sample_rate
= 0;
394 table
->extradata
= 0;
395 table
->extradata_size
= 0;
399 void quicktime_stsd_table_delete(quicktime_stsd_table_t
*table
)
401 quicktime_ctab_delete(&(table
->ctab
));
402 quicktime_mjqt_delete(&(table
->mjqt
));
403 quicktime_mjht_delete(&(table
->mjht
));
404 if(table
->extradata
) free(table
->extradata
);
405 quicktime_delete_avcc(&(table
->avcc
));
406 quicktime_delete_esds(&(table
->esds
));
410 void quicktime_stsd_video_dump(quicktime_stsd_table_t
*table
)
412 printf(" version %d\n", table
->version
);
413 printf(" revision %d\n", table
->revision
);
414 printf(" vendor %c%c%c%c\n", table
->vendor
[0], table
->vendor
[1], table
->vendor
[2], table
->vendor
[3]);
415 printf(" temporal_quality %ld\n", table
->temporal_quality
);
416 printf(" spatial_quality %ld\n", table
->spatial_quality
);
417 printf(" width %d\n", table
->width
);
418 printf(" height %d\n", table
->height
);
419 printf(" dpi_horizontal %f\n", table
->dpi_horizontal
);
420 printf(" dpi_vertical %f\n", table
->dpi_vertical
);
421 printf(" data_size %ld\n", table
->data_size
);
422 printf(" frames_per_sample %d\n", table
->frames_per_sample
);
423 printf(" compressor_name %s\n", table
->compressor_name
);
424 printf(" depth %d\n", table
->depth
);
425 printf(" ctab_id %d\n", table
->ctab_id
);
426 printf(" gamma %f\n", table
->gamma
);
429 printf(" fields %d\n", table
->fields
);
430 printf(" field dominance %d\n", table
->field_dominance
);
432 if(!table
->ctab_id
) quicktime_ctab_dump(&(table
->ctab
));
433 quicktime_mjqt_dump(&(table
->mjqt
));
434 quicktime_mjht_dump(&(table
->mjht
));
435 quicktime_esds_dump(&table
->esds
);
436 quicktime_avcc_dump(&table
->avcc
);
439 void quicktime_stsd_audio_dump(quicktime_stsd_table_t
*table
)
441 printf(" version %d\n", table
->version
);
442 printf(" revision %d\n", table
->revision
);
443 printf(" vendor %c%c%c%c\n", table
->vendor
[0], table
->vendor
[1], table
->vendor
[2], table
->vendor
[3]);
444 printf(" channels %d\n", table
->channels
);
445 printf(" sample_size %d\n", table
->sample_size
);
446 printf(" compression_id %d\n", table
->compression_id
);
447 printf(" packet_size %d\n", table
->packet_size
);
448 printf(" sample_rate %f\n", table
->sample_rate
);
449 if(table
->version
> 0)
451 printf(" samples_per_packet %d\n", table
->samples_per_packet
);
452 printf(" bytes_per_packet %d\n", table
->bytes_per_packet
);
453 printf(" bytes_per_frame %d\n", table
->bytes_per_frame
);
454 printf(" bytes_per_sample %d\n", table
->bytes_per_sample
);
456 quicktime_esds_dump(&table
->esds
);
457 quicktime_avcc_dump(&table
->avcc
);
460 void quicktime_stsd_table_dump(void *minf_ptr
, quicktime_stsd_table_t
*table
)
462 quicktime_minf_t
*minf
= minf_ptr
;
463 printf(" format %c%c%c%c\n", table
->format
[0], table
->format
[1], table
->format
[2], table
->format
[3]);
464 quicktime_print_chars(" reserved ", table
->reserved
, 6);
465 printf(" data_reference %d\n", table
->data_reference
);
467 if(minf
->is_audio
) quicktime_stsd_audio_dump(table
);
468 if(minf
->is_video
) quicktime_stsd_video_dump(table
);
471 void quicktime_write_stsd_table(quicktime_t
*file
, quicktime_minf_t
*minf
, quicktime_stsd_table_t
*table
)
473 quicktime_atom_t atom
;
474 quicktime_atom_write_header(file
, &atom
, table
->format
);
475 /*printf("quicktime_write_stsd_table %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]); */
476 quicktime_write_data(file
, table
->reserved
, 6);
477 quicktime_write_int16(file
, table
->data_reference
);
479 if(minf
->is_audio
) quicktime_write_stsd_audio(file
, table
);
480 if(minf
->is_video
) quicktime_write_stsd_video(file
, table
);
482 quicktime_atom_write_footer(file
, &atom
);