~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to gt/gtapi.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2004-08-29 10:53:42 UTC
  • Revision ID: james.westby@ubuntu.com-20040829105342-qgmnry37eadfkoxx
Tags: upstream-1.1.3
ImportĀ upstreamĀ versionĀ 1.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * gtapi.c
 
3
 * GnuTime module
 
4
 *
 
5
 * Copyright (C) 1998 Rasca, Berlin
 
6
 * EMail: thron@gmx.de
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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.
 
21
 */
 
22
 
 
23
#include <stdio.h>
 
24
#include <string.h>
 
25
#include <stdlib.h>
 
26
#include <gt/gt.h>
 
27
 
 
28
/*
 
29
 */
 
30
void
 
31
gt_atom_add (gt_atom *parent, gt_atom *child)
 
32
{
 
33
        if (!parent || !child)
 
34
                return;
 
35
        parent->suba[parent->memb++] = child;
 
36
        parent->size += child->size;
 
37
}
 
38
 
 
39
/*
 
40
 * create a new movie handle, not done
 
41
 */
 
42
gt_movie *
 
43
gt_movie_new (int type, int maxsubs, const char *file)
 
44
{
 
45
        gt_movie *movie;
 
46
 
 
47
        movie = malloc (sizeof (gt_movie));
 
48
        if (!movie)
 
49
                return NULL;
 
50
        /* have at least one child: mvhd */
 
51
        movie->moov = gt_alloc_atom (GTA_movie, 1 + maxsubs);
 
52
        if (!movie->moov) {
 
53
                free (movie);
 
54
                return NULL;
 
55
        }
 
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;
 
70
 
 
71
        movie->mdat = gt_alloc_atom (GTA_movie_data, 0);
 
72
        if (!movie->mdat) {
 
73
                free (movie->moov);
 
74
                free (movie->mvhd);
 
75
                free (movie);
 
76
                return NULL;
 
77
        }
 
78
        if (file)
 
79
                movie->file = strdup (file);
 
80
        else
 
81
                movie->file = NULL;
 
82
        return movie;
 
83
}
 
84
 
 
85
/*
 
86
 * free a movie structure
 
87
 */
 
88
void
 
89
gt_movie_free (gt_movie *movie)
 
90
{
 
91
        if (!movie || !movie->moov)
 
92
                return;
 
93
        gt_atom_free (movie->moov);
 
94
        gt_atom_free (movie->mdat);
 
95
        free (movie);
 
96
}
 
97
 
 
98
/*
 
99
 * add a track or user data to the moov atom
 
100
 */
 
101
int
 
102
gt_movie_add_atom (gt_movie *movie, gt_atom *atom)
 
103
{
 
104
        if (!movie || !movie->moov)
 
105
                return FALSE;
 
106
        if (movie->max_subs < (movie->moov->memb +1) )
 
107
                return FALSE;
 
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;
 
113
        }
 
114
#ifdef DEBUG
 
115
        fprintf (stderr, "gt_movie_add_atom() size=%d\n", movie->moov->size);
 
116
#endif
 
117
        return TRUE;
 
118
}
 
119
 
 
120
/*
 
121
 * write the moov structure to a file
 
122
 */
 
123
int
 
124
gt_movie_write_moov (gt_movie *movie, const char *file)
 
125
{
 
126
        FILE *fp;
 
127
        int rc;
 
128
 
 
129
        if (!movie)
 
130
                return 0;
 
131
        if (!file)
 
132
                file = movie->file;
 
133
        if (!file)
 
134
                return 0;
 
135
        fp = fopen (file, "wb");
 
136
        if (!fp)
 
137
                return 0;
 
138
        rc = gt_write_atom (movie->moov, fp);
 
139
        fclose (fp);
 
140
        return rc;
 
141
}
 
142
 
 
143
/*
 
144
 */
 
145
gt_minf_atom *
 
146
gt_media_info_new (int type, int subatoms)
 
147
{
 
148
        gt_minf_atom *minf;
 
149
        gt_hdlr_atom *hdlr;
 
150
        gt_atom *mtype;
 
151
        minf = gt_alloc_atom (GTA_media_info, 2 + subatoms);
 
152
 
 
153
        minf->suba[0] = (gt_atom *)hdlr = gt_alloc_atom (GTA_handler_ref, 0);
 
154
        minf->memb = 1;
 
155
        minf->size += hdlr->size;
 
156
 
 
157
        hdlr->comp_type = GT_DATA_REF;
 
158
        hdlr->comp_subtype = GT_ALIAS;
 
159
        hdlr->comp_man  = GT_COMP_MAN;
 
160
        /* ? */
 
161
        /* hdlr->comp_flags = 0x40000001; */
 
162
        /* hdlr->comp_flags_mask = 0x00010034; */
 
163
 
 
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;
 
169
                minf->memb++;
 
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;
 
174
                minf->memb++;
 
175
        } else { /* GT_BASE */
 
176
                gt_gmin_atom *gmin;
 
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;
 
183
                minf->memb++;
 
184
        }
 
185
        return (minf);
 
186
}
 
187
 
 
188
/*
 
189
 * a media atom has at least one subatom: media header
 
190
 * and we add the media handler as well..
 
191
 */
 
192
gt_mdia_atom *
 
193
gt_media_new (int type, int time_scale, int subatoms)
 
194
{
 
195
        gt_mdia_atom *mdia;
 
196
        gt_mdhd_atom *mdhd;
 
197
        gt_hdlr_atom *mdia_hdlr;
 
198
 
 
199
        mdia = gt_alloc_atom (GTA_media, 2 + subatoms);
 
200
        if (!mdia)
 
201
                return NULL;
 
202
        mdia->memb = 1;
 
203
        mdia->suba[0] = (gt_atom *)mdhd = gt_alloc_atom (GTA_media_header, 0);
 
204
 
 
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;
 
210
 
 
211
        if (type == GT_VIDEO) {
 
212
                /* add a video media handler
 
213
                 */
 
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;
 
217
                mdia->memb++;
 
218
 
 
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;
 
230
                mdia->memb++;
 
231
 
 
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);
 
239
        }
 
240
        return (mdia);
 
241
}
 
242
 
 
243
/*
 
244
 * a track atom has at least a track header and a media atom
 
245
 */
 
246
gt_trak_atom *
 
247
gt_track_new (int id, int width, int height, int type, int subatoms)
 
248
{
 
249
        gt_trak_atom *trak;
 
250
        gt_tkhd_atom *tkhd;
 
251
 
 
252
        trak = gt_alloc_atom (GTA_track, 1 + subatoms);
 
253
        if (trak) {
 
254
                trak->memb = 1;
 
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();
 
259
                tkhd->track_id = id;
 
260
                tkhd->duration = 1000 * 12;
 
261
                tkhd->matrix[1] = 1;
 
262
                tkhd->matrix[17]= 1;
 
263
                tkhd->matrix[32]= 64;
 
264
                tkhd->width.high = width;
 
265
                tkhd->height.high= height;
 
266
                trak->size += tkhd->size;
 
267
 
 
268
#ifdef DEBUG
 
269
                fprintf (stderr, "gt_track_new() size=%d\n", trak->size);
 
270
#endif
 
271
        }
 
272
        return (trak);
 
273
}
 
274
 
 
275
/*
 
276
 * create a new sample table atom and it's needed subatoms
 
277
 */
 
278
gt_atom *
 
279
gt_sample_new (int format, int width, int height, int num, int subatoms)
 
280
{
 
281
        gt_atom *atom;
 
282
        gt_stsd_atom *stsd;
 
283
        gt_stsd_pano_entry *pe;
 
284
 
 
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);
 
289
                        if (stsd) {
 
290
                                stsd->count = 1;
 
291
                                pe = (gt_stsd_pano_entry *)stsd->tab;
 
292
                                pe->size = 152;
 
293
                                pe->format = format;
 
294
                                pe->index = 1;
 
295
                                pe->track_id = 1;
 
296
                                pe->hpan_start.high = 0;
 
297
                                pe->hpan_end.high = 360;
 
298
                                pe->vpan_top.high = 20;
 
299
                                pe->vpan_bottom.high = -20;
 
300
                                pe->size_x = width;
 
301
                                pe->size_y = height * num;
 
302
                                pe->no_frames = num;
 
303
                                pe->no_frames_x = 1;
 
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;
 
309
                                atom->memb++;
 
310
                        }
 
311
                } else {
 
312
                        stsd = gt_alloc_atom (GTA_sample_desc, 1);
 
313
                        if (stsd) {
 
314
                                stsd->count = 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;
 
328
                                atom->memb++;
 
329
                        }
 
330
                }
 
331
        }
 
332
        return atom;
 
333
}
 
334
 
 
335
/*
 
336
 */
 
337
gt_atom *
 
338
gt_data_info_new (int subatoms)
 
339
{
 
340
        gt_atom *atom;
 
341
        gt_dref_atom *dref;
 
342
 
 
343
        atom = gt_alloc_atom (GTA_data_info, 1 + subatoms);
 
344
        if (atom) {
 
345
                dref = (gt_dref_atom *)gt_alloc_atom (GTA_data_ref, 1);
 
346
                dref->count = 1;
 
347
                dref->tab->size = 12;
 
348
                dref->tab->type = GT_ALIAS;
 
349
                dref->tab->flags[2] = 0x01; /* self reference */
 
350
                atom->memb++;
 
351
                atom->suba[0] = (gt_atom *)dref;
 
352
                atom->size += dref->size;
 
353
        }
 
354
        return atom;
 
355
}
 
356