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
->mpeg4_header
)
37 free(table
->mpeg4_header
);
40 table
->mpeg4_header
= calloc(1, size
);
41 memcpy(table
->mpeg4_header
, data
, size
);
42 table
->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
);
58 quicktime_atom_skip(file
, &leaf_atom
);
62 void quicktime_read_stsd_audio(quicktime_t
*file
, quicktime_stsd_table_t
*table
, quicktime_atom_t
*parent_atom
)
64 quicktime_atom_t leaf_atom
;
66 table
->version
= quicktime_read_int16(file
);
67 table
->revision
= quicktime_read_int16(file
);
68 quicktime_read_data(file
, table
->vendor
, 4);
69 table
->channels
= quicktime_read_int16(file
);
70 table
->sample_size
= quicktime_read_int16(file
);
71 table
->compression_id
= quicktime_read_int16(file
);
72 table
->packet_size
= quicktime_read_int16(file
);
73 table
->sample_rate
= quicktime_read_fixed32(file
);
75 // Kluge for fixed32 limitation
76 if(table
->sample_rate
+ 65536 == 96000 ||
77 table
->sample_rate
+ 65536 == 88200) table
->sample_rate
+= 65536;
81 if(table
->version
== 1)
83 table
->samples_per_packet
= quicktime_read_int32(file
);
84 table
->bytes_per_packet
= quicktime_read_int32(file
);
85 table
->bytes_per_frame
= quicktime_read_int32(file
);
86 table
->bytes_per_sample
= quicktime_read_int32(file
);
87 while(quicktime_position(file
) < parent_atom
->end
)
89 quicktime_atom_read_header(file
, &leaf_atom
);
90 if(quicktime_atom_is(&leaf_atom
, "wave"))
92 read_wave(file
, table
, &leaf_atom
);
95 quicktime_atom_skip(file
, &leaf_atom
);
100 void quicktime_write_stsd_audio(quicktime_t
*file
, quicktime_stsd_table_t
*table
)
102 quicktime_write_int16(file
, table
->version
);
103 quicktime_write_int16(file
, table
->revision
);
104 quicktime_write_data(file
, table
->vendor
, 4);
105 quicktime_write_int16(file
, table
->channels
);
106 quicktime_write_int16(file
, table
->sample_size
);
107 quicktime_write_int16(file
, table
->compression_id
);
108 quicktime_write_int16(file
, table
->packet_size
);
109 quicktime_write_fixed32(file
, table
->sample_rate
);
112 // Lifted from mplayer and changed a bit
113 struct __attribute__((__packed__
)) ImageDescription
{
114 // int32_t idSize; /* total size of ImageDescription including extra data ( CLUTs and other per sequence data ) */
115 char cType
[4]; /* what kind of codec compressed this data */
116 int32_t resvd1
; /* reserved for Apple use */
117 int16_t resvd2
; /* reserved for Apple use */
118 int16_t dataRefIndex
; /* set to zero */
119 int16_t version
; /* which version is this data */
120 int16_t revisionLevel
; /* what version of that codec did this */
121 char vendor
[4]; /* whose codec compressed this data */
122 uint32_t temporalQuality
; /* what was the temporal quality factor */
123 uint32_t spatialQuality
; /* what was the spatial quality factor */
124 int16_t width
; /* how many pixels wide is this data */
125 int16_t height
; /* how many pixels high is this data */
126 int32_t hRes
; /* horizontal resolution */
127 int32_t vRes
; /* vertical resolution */
128 int32_t dataSize
; /* if known, the size of data for this image descriptor */
129 int16_t frameCount
; /* number of frames this description applies to */
130 char name
[32]; /* name of codec ( in case not installed ) */
131 int16_t depth
; /* what depth is this data (1-32) or ( 33-40 grayscale ) */
132 int16_t clutID
; /* clut id or if 0 clut follows or -1 if no clut */
136 void quicktime_read_stsd_video(quicktime_t
*file
,
137 quicktime_stsd_table_t
*table
,
138 quicktime_atom_t
*parent_atom
)
140 quicktime_atom_t leaf_atom
;
143 table
->version
= quicktime_read_int16(file
);
144 table
->revision
= quicktime_read_int16(file
);
145 quicktime_read_data(file
, table
->vendor
, 4);
146 table
->temporal_quality
= quicktime_read_int32(file
);
147 table
->spatial_quality
= quicktime_read_int32(file
);
148 table
->width
= quicktime_read_int16(file
);
149 table
->height
= quicktime_read_int16(file
);
150 table
->dpi_horizontal
= quicktime_read_fixed32(file
);
151 table
->dpi_vertical
= quicktime_read_fixed32(file
);
152 table
->data_size
= quicktime_read_int32(file
);
153 table
->frames_per_sample
= quicktime_read_int16(file
);
154 len
= quicktime_read_char(file
);
155 quicktime_read_data(file
, table
->compressor_name
, 31);
156 table
->depth
= quicktime_read_int16(file
);
157 table
->ctab_id
= quicktime_read_int16(file
);
160 /* The data needed for SVQ3 codec and maybe some others ? */
161 struct ImageDescription
*id
;
162 int stsd_size
,fourcc
,c
,d
;
163 stsd_size
= parent_atom
->end
- parent_atom
->start
;
164 table
->extradata_size
= stsd_size
- 4;
165 id
= (struct ImageDescription
*) malloc(table
->extradata_size
); // we do not include size
166 table
->extradata
= (char *) id
;
168 memcpy(id
->cType
, table
->format
, 4); // Fourcc
169 id
->version
= table
->version
;
170 id
->revisionLevel
= table
->revision
;
171 memcpy(id
->vendor
, table
->vendor
, 4); // I think mplayer screws up on this one, it turns bytes around! :)
172 id
->temporalQuality
= table
->temporal_quality
;
173 id
->spatialQuality
= table
->spatial_quality
;
174 id
->width
= table
->width
;
175 id
->height
= table
->height
;
176 id
->hRes
= table
->dpi_horizontal
;
177 id
->vRes
= table
->dpi_vertical
;
178 id
->dataSize
= table
->data_size
;
179 id
->frameCount
= table
->frames_per_sample
;
181 memcpy(&(id
->name
[1]), table
->compressor_name
, 31);
182 id
->depth
= table
->depth
;
183 id
->clutID
= table
->ctab_id
;
184 if (quicktime_position(file
) < parent_atom
->end
)
186 int position
= quicktime_position(file
); // remember position
187 int datalen
= parent_atom
->end
- position
;
188 quicktime_read_data(file
, ((char*)&id
->clutID
)+2, datalen
);
189 quicktime_set_position(file
, position
); // return to previous position so parsing can go on
193 while(quicktime_position(file
) < parent_atom
->end
)
195 quicktime_atom_read_header(file
, &leaf_atom
);
196 //printf("quicktime_read_stsd_video 1 %llx %llx %llx\n", leaf_atom.start, leaf_atom.end, quicktime_position(file));
199 if(quicktime_atom_is(&leaf_atom
, "esds"))
201 quicktime_read_esds(file
, &leaf_atom
, table
);
204 if(quicktime_atom_is(&leaf_atom
, "ctab"))
206 quicktime_read_ctab(file
, &(table
->ctab
));
209 if(quicktime_atom_is(&leaf_atom
, "gama"))
211 table
->gamma
= quicktime_read_fixed32(file
);
214 if(quicktime_atom_is(&leaf_atom
, "fiel"))
216 table
->fields
= quicktime_read_char(file
);
217 table
->field_dominance
= quicktime_read_char(file
);
220 quicktime_atom_skip(file
, &leaf_atom
);
223 /* if(quicktime_atom_is(&leaf_atom, "mjqt")) */
225 /* quicktime_read_mjqt(file, &(table->mjqt)); */
228 /* if(quicktime_atom_is(&leaf_atom, "mjht")) */
230 /* quicktime_read_mjht(file, &(table->mjht)); */
234 //printf("quicktime_read_stsd_video 2\n");
237 void quicktime_write_stsd_video(quicktime_t
*file
, quicktime_stsd_table_t
*table
)
239 quicktime_write_int16(file
, table
->version
);
240 quicktime_write_int16(file
, table
->revision
);
241 quicktime_write_data(file
, table
->vendor
, 4);
242 quicktime_write_int32(file
, table
->temporal_quality
);
243 quicktime_write_int32(file
, table
->spatial_quality
);
244 quicktime_write_int16(file
, table
->width
);
245 quicktime_write_int16(file
, table
->height
);
246 quicktime_write_fixed32(file
, table
->dpi_horizontal
);
247 quicktime_write_fixed32(file
, table
->dpi_vertical
);
248 quicktime_write_int32(file
, table
->data_size
);
249 quicktime_write_int16(file
, table
->frames_per_sample
);
250 quicktime_write_char(file
, strlen(table
->compressor_name
));
251 quicktime_write_data(file
, table
->compressor_name
, 31);
252 quicktime_write_int16(file
, table
->depth
);
253 quicktime_write_int16(file
, table
->ctab_id
);
256 // Write field order for mjpa
259 quicktime_atom_t atom
;
261 quicktime_atom_write_header(file
, &atom
, "fiel");
262 quicktime_write_char(file
, table
->fields
);
263 quicktime_write_char(file
, table
->field_dominance
);
264 quicktime_atom_write_footer(file
, &atom
);
267 // Write header for mp4v
268 if(table
->mpeg4_header_size
&& table
->mpeg4_header
)
270 quicktime_write_esds(file
, table
, 1, 0);
274 void quicktime_read_stsd_table(quicktime_t
*file
, quicktime_minf_t
*minf
, quicktime_stsd_table_t
*table
)
276 quicktime_atom_t leaf_atom
;
278 quicktime_atom_read_header(file
, &leaf_atom
);
280 table
->format
[0] = leaf_atom
.type
[0];
281 table
->format
[1] = leaf_atom
.type
[1];
282 table
->format
[2] = leaf_atom
.type
[2];
283 table
->format
[3] = leaf_atom
.type
[3];
284 quicktime_read_data(file
, table
->reserved
, 6);
285 table
->data_reference
= quicktime_read_int16(file
);
287 if(minf
->is_audio
) quicktime_read_stsd_audio(file
, table
, &leaf_atom
);
288 if(minf
->is_video
) quicktime_read_stsd_video(file
, table
, &leaf_atom
);
291 void quicktime_stsd_table_init(quicktime_stsd_table_t
*table
)
294 table
->format
[0] = 'y';
295 table
->format
[1] = 'u';
296 table
->format
[2] = 'v';
297 table
->format
[3] = '2';
298 for(i
= 0; i
< 6; i
++) table
->reserved
[i
] = 0;
299 table
->data_reference
= 1;
303 table
->vendor
[0] = 'l';
304 table
->vendor
[1] = 'n';
305 table
->vendor
[2] = 'u';
306 table
->vendor
[3] = 'x';
308 table
->temporal_quality
= 100;
309 table
->spatial_quality
= 258;
312 table
->dpi_horizontal
= 72;
313 table
->dpi_vertical
= 72;
314 table
->data_size
= 0;
315 table
->frames_per_sample
= 1;
316 for(i
= 0; i
< 32; i
++) table
->compressor_name
[i
] = 0;
317 sprintf(table
->compressor_name
, "Quicktime for Linux");
319 table
->ctab_id
= 65535;
320 quicktime_ctab_init(&(table
->ctab
));
323 table
->field_dominance
= 1;
324 quicktime_mjqt_init(&(table
->mjqt
));
325 quicktime_mjht_init(&(table
->mjht
));
328 table
->sample_size
= 0;
329 table
->compression_id
= 0;
330 table
->packet_size
= 0;
331 table
->sample_rate
= 0;
333 table
->mpeg4_header
= 0;
334 table
->mpeg4_header_size
= 0;
336 table
->extradata
= 0;
337 table
->extradata_size
= 0;
341 void quicktime_stsd_table_delete(quicktime_stsd_table_t
*table
)
343 quicktime_ctab_delete(&(table
->ctab
));
344 quicktime_mjqt_delete(&(table
->mjqt
));
345 quicktime_mjht_delete(&(table
->mjht
));
346 if(table
->mpeg4_header
) free(table
->mpeg4_header
);
347 if(table
->extradata
) free(table
->extradata
);
350 void quicktime_stsd_video_dump(quicktime_stsd_table_t
*table
)
352 printf(" version %d\n", table
->version
);
353 printf(" revision %d\n", table
->revision
);
354 printf(" vendor %c%c%c%c\n", table
->vendor
[0], table
->vendor
[1], table
->vendor
[2], table
->vendor
[3]);
355 printf(" temporal_quality %ld\n", table
->temporal_quality
);
356 printf(" spatial_quality %ld\n", table
->spatial_quality
);
357 printf(" width %d\n", table
->width
);
358 printf(" height %d\n", table
->height
);
359 printf(" dpi_horizontal %f\n", table
->dpi_horizontal
);
360 printf(" dpi_vertical %f\n", table
->dpi_vertical
);
361 printf(" data_size %ld\n", table
->data_size
);
362 printf(" frames_per_sample %d\n", table
->frames_per_sample
);
363 printf(" compressor_name %s\n", table
->compressor_name
);
364 printf(" depth %d\n", table
->depth
);
365 printf(" ctab_id %d\n", table
->ctab_id
);
366 printf(" gamma %f\n", table
->gamma
);
369 printf(" fields %d\n", table
->fields
);
370 printf(" field dominance %d\n", table
->field_dominance
);
372 if(!table
->ctab_id
) quicktime_ctab_dump(&(table
->ctab
));
373 quicktime_mjqt_dump(&(table
->mjqt
));
374 quicktime_mjht_dump(&(table
->mjht
));
377 void quicktime_stsd_audio_dump(quicktime_stsd_table_t
*table
)
379 printf(" version %d\n", table
->version
);
380 printf(" revision %d\n", table
->revision
);
381 printf(" vendor %c%c%c%c\n", table
->vendor
[0], table
->vendor
[1], table
->vendor
[2], table
->vendor
[3]);
382 printf(" channels %d\n", table
->channels
);
383 printf(" sample_size %d\n", table
->sample_size
);
384 printf(" compression_id %d\n", table
->compression_id
);
385 printf(" packet_size %d\n", table
->packet_size
);
386 printf(" sample_rate %f\n", table
->sample_rate
);
387 if(table
->version
== 1)
389 printf(" samples_per_packet %d\n", table
->samples_per_packet
);
390 printf(" bytes_per_packet %d\n", table
->bytes_per_packet
);
391 printf(" bytes_per_frame %d\n", table
->bytes_per_frame
);
392 printf(" bytes_per_sample %d\n", table
->bytes_per_sample
);
396 void quicktime_stsd_table_dump(void *minf_ptr
, quicktime_stsd_table_t
*table
)
398 quicktime_minf_t
*minf
= minf_ptr
;
399 printf(" format %c%c%c%c\n", table
->format
[0], table
->format
[1], table
->format
[2], table
->format
[3]);
400 quicktime_print_chars(" reserved ", table
->reserved
, 6);
401 printf(" data_reference %d\n", table
->data_reference
);
403 if(minf
->is_audio
) quicktime_stsd_audio_dump(table
);
404 if(minf
->is_video
) quicktime_stsd_video_dump(table
);
407 void quicktime_write_stsd_table(quicktime_t
*file
, quicktime_minf_t
*minf
, quicktime_stsd_table_t
*table
)
409 quicktime_atom_t atom
;
410 quicktime_atom_write_header(file
, &atom
, table
->format
);
411 /*printf("quicktime_write_stsd_table %c%c%c%c\n", table->format[0], table->format[1], table->format[2], table->format[3]); */
412 quicktime_write_data(file
, table
->reserved
, 6);
413 quicktime_write_int16(file
, table
->data_reference
);
415 if(minf
->is_audio
) quicktime_write_stsd_audio(file
, table
);
416 if(minf
->is_video
) quicktime_write_stsd_video(file
, table
);
418 quicktime_atom_write_footer(file
, &atom
);