5
* Copyright (C) 1998 Rasca, Berlin
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Library General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Library General Public License for more details.
18
* You should have received a copy of the GNU Library General Public
19
* License along with this library; if not, write to the Free Software
20
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31
gt_atom_add (gt_atom *parent, gt_atom *child)
33
if (!parent || !child)
35
parent->suba[parent->memb++] = child;
36
parent->size += child->size;
40
* create a new movie handle, not done
43
gt_movie_new (int type, int maxsubs, const char *file)
47
movie = malloc (sizeof (gt_movie));
50
/* have at least one child: mvhd */
51
movie->moov = gt_alloc_atom (GTA_movie, 1 + maxsubs);
56
movie->max_subs = 1+ maxsubs; /* max sub atoms in the moov container */
57
(gt_atom *) movie->mvhd = movie->moov->suba[0] =
58
gt_alloc_atom (GTA_movie_header, 0);
59
movie->moov->memb = 1;
60
movie->moov->size += movie->mvhd->size;
61
movie->mvhd->ctime = gt_time();
62
movie->mvhd->mtime = gt_time();
63
movie->mvhd->time_scale = 1000;
64
movie->mvhd->duration = 1000 * 12;
65
movie->mvhd->pref_rate.high = 1;
66
movie->mvhd->matrix[1] = 1;
67
movie->mvhd->matrix[17] = 1;
68
movie->mvhd->matrix[32] = 64;
69
movie->mvhd->next_track_id = 1;
71
movie->mdat = gt_alloc_atom (GTA_movie_data, 0);
79
movie->file = strdup (file);
86
* free a movie structure
89
gt_movie_free (gt_movie *movie)
91
if (!movie || !movie->moov)
93
gt_atom_free (movie->moov);
94
gt_atom_free (movie->mdat);
99
* add a track or user data to the moov atom
102
gt_movie_add_atom (gt_movie *movie, gt_atom *atom)
104
if (!movie || !movie->moov)
106
if (movie->max_subs < (movie->moov->memb +1) )
108
movie->moov->suba[movie->moov->memb++] = atom;
109
movie->moov->size += atom->size;
110
if (atom->type == GTA_track) {
111
movie->mvhd->next_track_id = ((gt_tkhd_atom *)
112
(atom->suba[0]))->track_id+1;
115
fprintf (stderr, "gt_movie_add_atom() size=%d\n", movie->moov->size);
121
* write the moov structure to a file
124
gt_movie_write_moov (gt_movie *movie, const char *file)
135
fp = fopen (file, "wb");
138
rc = gt_write_atom (movie->moov, fp);
146
gt_media_info_new (int type, int subatoms)
151
minf = gt_alloc_atom (GTA_media_info, 2 + subatoms);
153
minf->suba[0] = (gt_atom *)hdlr = gt_alloc_atom (GTA_handler_ref, 0);
155
minf->size += hdlr->size;
157
hdlr->comp_type = GT_DATA_REF;
158
hdlr->comp_subtype = GT_ALIAS;
159
hdlr->comp_man = GT_COMP_MAN;
161
/* hdlr->comp_flags = 0x40000001; */
162
/* hdlr->comp_flags_mask = 0x00010034; */
164
if (type == GT_VIDEO) {
165
mtype = gt_alloc_atom (GTA_video_media_header, 0);
166
minf->suba[1] = mtype;
167
minf->size += mtype->size;
168
((gt_vmhd_atom *)mtype)->flags[2] = 1;
170
} else if (type == GT_SOUND) {
171
mtype = gt_alloc_atom (GTA_sound_media_header, 0);
172
minf->suba[1] = mtype;
173
minf->size += mtype->size;
175
} else { /* GT_BASE */
177
mtype = gt_alloc_atom (GTA_base_media_header, 1);
178
gmin = (gt_gmin_atom *)gt_alloc_atom (GTA_base_media_info, 0);
179
gmin->grmode = 0x0040; /* ? */
180
gt_atom_add (mtype, (gt_atom *)gmin);
181
minf->suba[1] = mtype;
182
minf->size += mtype->size;
189
* a media atom has at least one subatom: media header
190
* and we add the media handler as well..
193
gt_media_new (int type, int time_scale, int subatoms)
197
gt_hdlr_atom *mdia_hdlr;
199
mdia = gt_alloc_atom (GTA_media, 2 + subatoms);
203
mdia->suba[0] = (gt_atom *)mdhd = gt_alloc_atom (GTA_media_header, 0);
205
mdia->size += mdhd->size;
206
mdhd->ctime = gt_time();
207
mdhd->mtime = gt_time();
208
mdhd->time_scale = time_scale;
209
mdhd->duration = time_scale * 12;
211
if (type == GT_VIDEO) {
212
/* add a video media handler
214
(gt_atom *)mdia_hdlr = mdia->suba[1] =
215
gt_alloc_atom (GTA_handler_ref, strlen(GT_MID_HDLR_NAME));
216
mdia->size += mdia_hdlr->size;
219
mdia_hdlr->comp_type = GT_MEDIA_REF;
220
mdia_hdlr->comp_subtype = GT_VIDEO;
221
mdia_hdlr->comp_man = GT_COMP_MAN;
222
mdia_hdlr->comp_flags = 0x40000000; /* ? */
223
mdia_hdlr->comp_flags_mask = 0x00010047; /* or 1002b ? */
224
strcpy (mdia_hdlr->comp_name+1, GT_MID_HDLR_NAME);
225
mdia_hdlr->comp_name[0]= strlen(GT_MID_HDLR_NAME);
226
} else if (type == GT_PANORAMA) {
227
(gt_atom *)mdia_hdlr = mdia->suba[1] =
228
gt_alloc_atom (GTA_handler_ref, strlen(GT_MID_HDLR_NAME));
229
mdia->size += mdia_hdlr->size;
232
mdia_hdlr->comp_type = GT_MEDIA_REF;
233
mdia_hdlr->comp_subtype = GT_N_PANO;
234
mdia_hdlr->comp_man = GT_COMP_MAN;
235
mdia_hdlr->comp_flags = 0x40000000; /* ? */
236
mdia_hdlr->comp_flags_mask = 0x0001002b; /* ? */
237
strcpy (mdia_hdlr->comp_name+1, GT_MID_HDLR_NAME);
238
mdia_hdlr->comp_name[0]= strlen(GT_MID_HDLR_NAME);
244
* a track atom has at least a track header and a media atom
247
gt_track_new (int id, int width, int height, int type, int subatoms)
252
trak = gt_alloc_atom (GTA_track, 1 + subatoms);
255
(gt_atom *) tkhd = trak->suba[0] = gt_alloc_atom (GTA_track_header, 0);
256
tkhd->flags[2] = (char) (0x01 | 0x02);
257
tkhd->ctime = gt_time();
258
tkhd->mtime = gt_time();
260
tkhd->duration = 1000 * 12;
263
tkhd->matrix[32]= 64;
264
tkhd->width.high = width;
265
tkhd->height.high= height;
266
trak->size += tkhd->size;
269
fprintf (stderr, "gt_track_new() size=%d\n", trak->size);
276
* create a new sample table atom and it's needed subatoms
279
gt_sample_new (int format, int width, int height, int num, int subatoms)
283
gt_stsd_pano_entry *pe;
285
atom = gt_alloc_atom (GTA_sample_table, 1 + subatoms);
286
if (atom && format) {
287
if (format == GT_VID_FMT_PANO) {
288
stsd = gt_alloc_atom (GTA_sample_desc, 2);
291
pe = (gt_stsd_pano_entry *)stsd->tab;
296
pe->hpan_start.high = 0;
297
pe->hpan_end.high = 360;
298
pe->vpan_top.high = 20;
299
pe->vpan_bottom.high = -20;
301
pe->size_y = height * num;
304
pe->no_frames_y = num;
305
pe->color_depth = 24;
306
stsd->size = 16 + pe->size;
307
atom->suba[0] = (gt_atom *)stsd;
308
atom->size += stsd->size;
312
stsd = gt_alloc_atom (GTA_sample_desc, 1);
315
stsd->tab->size = 86;
316
stsd->tab->format = format;
317
stsd->tab->index = 1; /* points to an entry in 'dref' */
318
stsd->tab->spat_qual = 1023;
319
stsd->tab->width = width;
320
stsd->tab->height= height;
321
stsd->tab->hres.high = 72;
322
stsd->tab->vres.high = 72;
323
stsd->tab->frame_count = 1;
324
stsd->tab->depth = 24;
325
stsd->tab->ctab_id = -1;
326
atom->suba[0] = (gt_atom *)stsd;
327
atom->size += stsd->size;
338
gt_data_info_new (int subatoms)
343
atom = gt_alloc_atom (GTA_data_info, 1 + subatoms);
345
dref = (gt_dref_atom *)gt_alloc_atom (GTA_data_ref, 1);
347
dref->tab->size = 12;
348
dref->tab->type = GT_ALIAS;
349
dref->tab->flags[2] = 0x01; /* self reference */
351
atom->suba[0] = (gt_atom *)dref;
352
atom->size += dref->size;