1 /*
2 Note 20020923 thammer:
3 movie.c should probably be rewritten to use stream.c.
4 If you are considering modifying movie.c, please discuss it
5 with coin@sim.no first.
6
7 */
8
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif /* HAVE_CONFIG_H */
16 #include <simage.h>
17 #include <simage_private.h>
18 #include <string.h>
19
20 #ifdef SIMAGE_MPEG2ENC_SUPPORT
21 #include "../mpeg2enc/api.h"
22 #endif /* SIMAGE_MPEG2ENC_SUPPORT */
23
24 #ifdef SIMAGE_AVIENC_SUPPORT
25 #include "simage_avi.h"
26 #endif /* SIMAGE_AVIENC_SUPPORT */
27
28 struct simage_movie_s {
29 char * filename;
30
31 s_movie_open_func * open;
32 s_movie_create_func * create;
33 s_movie_get_func * get;
34 s_movie_put_func * put;
35 s_movie_close_func * close;
36
37 s_params * params;
38 };
39
40 struct simage_movie_importer {
41 s_movie_open_func * open;
42 s_movie_get_func * get;
43 s_movie_close_func * close;
44
45 struct simage_movie_importer * next;
46 };
47
48 struct simage_movie_exporter {
49 s_movie_create_func * create;
50 s_movie_put_func * put;
51 s_movie_close_func * close;
52
53 struct simage_movie_exporter * next;
54 };
55
56 // FIXME: convert access to these variables into the singleton
57 // pattern. 20010917 mortene.
58 static struct simage_movie_importer * importers;
59 static struct simage_movie_exporter * exporters;
60
61 static void
add_internal_importers(void)62 add_internal_importers(void)
63 {
64 static int first = 1;
65 if (first) {
66 /* none yet */
67 first = 0;
68 }
69 }
70
71 static void
add_internal_exporters(void)72 add_internal_exporters(void)
73 {
74 static int first = 1;
75 if (first) {
76 #ifdef SIMAGE_MPEG2ENC_SUPPORT
77 s_movie_exporter_add(mpeg2enc_movie_create,
78 mpeg2enc_movie_put,
79 mpeg2enc_movie_close);
80 #endif
81 #ifdef SIMAGE_AVIENC_SUPPORT
82 s_movie_exporter_add(avienc_movie_create,
83 avienc_movie_put,
84 avienc_movie_close);
85 #endif
86 first = 0;
87 }
88 }
89
90 s_movie *
s_movie_open(const char * filename)91 s_movie_open(const char * filename)
92 {
93 struct simage_movie_importer * imp;
94 s_movie * movie = (s_movie*) malloc(sizeof(s_movie));
95 movie->params = NULL;
96 movie->filename = NULL;
97
98 add_internal_importers();
99
100 imp = importers;
101 while (imp) {
102 if (imp->open(filename, movie)) break;
103 imp = imp->next;
104 }
105 if (imp == NULL) {
106 free((void*)movie);
107 return NULL;
108 }
109
110 movie->filename = (char*) malloc(strlen(filename)+1);
111 strcpy(movie->filename, filename);
112 movie->open = imp->open;
113 movie->get = imp->get;
114 movie->close = imp->close;
115
116 return movie;
117 }
118
119 s_movie *
s_movie_create(const char * filename,s_params * params)120 s_movie_create(const char * filename, s_params * params /* | NULL */)
121 {
122 struct simage_movie_exporter * exp;
123 s_movie * movie = (s_movie*) malloc(sizeof(s_movie));
124 movie->params = NULL;
125 movie->filename = NULL;
126
127 add_internal_exporters();
128
129 exp = exporters;
130 while (exp) {
131 if (exp->create(filename, movie, params)) break;
132 exp = exp->next;
133 }
134 if (exp == NULL) {
135 free((void*) movie);
136 return NULL;
137 }
138
139 movie->filename = (char*) malloc(strlen(filename)+1);
140 movie->create = exp->create;
141 movie->put = exp->put;
142 movie->close = exp->close;
143 strcpy(movie->filename, filename);
144 return movie;
145 }
146
147 s_image *
s_movie_get_image(s_movie * movie,s_image * prealloc,s_params * params)148 s_movie_get_image(s_movie * movie, s_image * prealloc, s_params * params)
149 {
150 return movie->get(movie, prealloc, params);
151 }
152
153 int
s_movie_put_image(s_movie * movie,s_image * image,s_params * params)154 s_movie_put_image(s_movie * movie, s_image * image,
155 s_params * params)
156 {
157 return movie->put(movie, image, params);
158 }
159
160 void
s_movie_close(s_movie * movie)161 s_movie_close(s_movie * movie)
162 {
163 movie->close(movie);
164 }
165
166 void
s_movie_destroy(s_movie * movie)167 s_movie_destroy(s_movie * movie)
168 {
169 if (movie->params) s_params_destroy(movie->params);
170 if (movie->filename) free((void*) movie->filename);
171 free((void*) movie);
172 }
173
174 s_params *
s_movie_params(s_movie * movie)175 s_movie_params(s_movie * movie)
176 {
177 if (movie->params == NULL) {
178 movie->params = s_params_create();
179 }
180 return movie->params;
181 }
182
183 void
s_movie_importer_add(s_movie_open_func * open,s_movie_get_func * get,s_movie_close_func * close)184 s_movie_importer_add(s_movie_open_func * open,
185 s_movie_get_func * get,
186 s_movie_close_func * close)
187 {
188 struct simage_movie_importer * last, * imp = importers;
189 last = NULL;
190 while (imp) {
191 last = imp;
192 imp = imp->next;
193 }
194 imp = (struct simage_movie_importer*) malloc(sizeof(struct simage_movie_importer));
195 imp->open = open;
196 imp->get = get;
197 imp->close = close;
198 imp->next = NULL;
199
200 if (last == NULL) {
201 importers = imp;
202 }
203 else last->next = imp;
204 }
205
206 void
s_movie_exporter_add(s_movie_create_func * create,s_movie_put_func * put,s_movie_close_func * close)207 s_movie_exporter_add(s_movie_create_func * create,
208 s_movie_put_func * put,
209 s_movie_close_func * close)
210 {
211 struct simage_movie_exporter * last, * exp = exporters;
212 last = NULL;
213 while (exp) {
214 last = exp;
215 exp = exp->next;
216 }
217 exp = (struct simage_movie_exporter*) malloc(sizeof(struct simage_movie_exporter));
218 exp->create = create;
219 exp->put = put;
220 exp->close = close;
221 exp->next = NULL;
222
223 if (last == NULL) {
224 exporters = exp;
225 }
226 else last->next = exp;
227 }
228