2 Copyright (C) 2006 Sebastian Freundt
4 This file is part of SXEmacs
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* Synched up with: Not in FSF. */
22 #ifndef INCLUDED_media_h_
23 #define INCLUDED_media_h_
32 #include "mule/file-coding.h"
35 typedef enum media_drivers media_driver;
36 typedef enum media_types media_type;
37 typedef enum media_kinds media_kind;
39 typedef struct mtype_audio_properties mtype_audio_properties;
40 typedef struct mtype_video_properties mtype_video_properties;
41 typedef struct mkind_file_properties mkind_file_properties;
42 typedef struct mkind_string_properties mkind_string_properties;
44 typedef struct Lisp_Media_Stream Lisp_Media_Stream;
45 typedef struct media_substream media_substream;
47 typedef void *ms_driver_data_t;
48 typedef ms_driver_data_t(*ms_open_fun)(Lisp_Media_Stream*);
49 typedef void(*ms_close_fun)(ms_driver_data_t);
50 typedef void(*ms_print_fun)(Lisp_Object stream, Lisp_Object, int);
51 typedef Lisp_Object(*ms_mark_fun)(ms_driver_data_t driver_data);
52 typedef size_t(*ms_read_fun)(media_substream*, void*, size_t);
53 typedef size_t(*ms_write_fun)(media_substream*, void*, size_t);
54 typedef void(*ms_rewind_fun)(media_substream*);
55 typedef void(*ms_seek_fun)(media_substream*, size_t);
57 typedef struct ms_meths ms_meths;
58 typedef struct media_data media_data;
61 typedef int32_t sxe_media_sample_t;
62 typedef void* audio_coerce_args;
63 typedef size_t(*audio_coerce_fun)(sxe_media_sample_t *dst,
64 sxe_media_sample_t *src,
65 size_t len, void *args);
66 typedef void(*audio_resample_fun)(void *dst, void *src, size_t len);
67 typedef struct media_sample_format_s media_sample_format_t;
68 typedef struct audio_coerce_chain_s audio_coerce_chain_t;
80 NUMBER_OF_MEDIA_DRIVERS
94 MKIND_STRING, /* better name? */
100 /* type properties */
101 struct mtype_audio_properties {
102 const char *name; /* name of the codec or whatever */
103 const char *codec_name; /* name of the codec or whatever */
105 uint16_t samplewidth; /* in bits */
107 uint16_t framesize; /* == channels * samplewidth (in bytes) */
108 media_sample_format_t *msf; /* function for upsampling */
113 struct mtype_video_properties {
114 const char *name; /* name of the codec or whatever */
115 const char *codec_name; /* name of the codec or whatever */
119 int aspect_num, aspect_den;
124 /* kind properties */
125 struct mkind_file_properties {
126 Lisp_Object filename;
130 struct mkind_string_properties {
137 struct media_substream {
138 /* navigation for the doubly linked list */
139 media_substream *next;
140 media_substream *prev;
141 Lisp_Media_Stream *up;
143 /* data and handling issues */
147 mtype_audio_properties *aprops;
148 mtype_video_properties *vprops;
152 pthread_mutex_t substream_mutex;
155 /* anonymous data, used by the various backends */
156 /* do not use it, it is not freed by gc */
157 ms_driver_data_t substream_data;
160 #define media_substream_type(mss) (mss)->type
161 #define media_substream_type_properties(mss) (mss)->type_properties
162 #define media_substream_data(mss) (mss)->substream_data
163 /* make it look like funs */
164 #define media_substream_read(mss, b, r) (media_substream_sread(mss)(mss, b, r))
165 #define media_substream_rewind(mss) (media_substream_srewind(mss)(mss))
167 #define media_substream_next(mss) (mss)->next
168 #define media_substream_prev(mss) (mss)->prev
169 #define media_substream_up(mss) (mss)->up
172 /* now stream driver dependent stuff */
180 ms_rewind_fun rewind;
184 #define DECLARE_MEDIA_DRIVER(_name) \
185 extern ms_meths _name[1]
186 #define DECLARE_MEDIA_DRIVER_OPEN_METH(_name) \
187 static ms_driver_data_t _name##_open(Lisp_Media_Stream*)
188 #define DECLARE_MEDIA_DRIVER_CLOSE_METH(_name) \
189 static void _name##_close(ms_driver_data_t)
190 #define DECLARE_MEDIA_DRIVER_PRINT_METH(_name) \
191 static void _name##_print(Lisp_Object, Lisp_Object, int);
192 #define DECLARE_MEDIA_DRIVER_MARK_METH(_name) \
193 static Lisp_Object _name##_mark(ms_driver_data_t);
194 #define DECLARE_MEDIA_DRIVER_READ_METH(_name) \
195 static size_t _name##_read(media_substream*, void*, size_t);
196 #define DECLARE_MEDIA_DRIVER_WRITE_METH(_name) \
197 static size_t _name##_write(media_substream*, void*, size_t);
198 #define DECLARE_MEDIA_DRIVER_REWIND_METH(_name) \
199 static void _name##_rewind(media_substream*);
200 #define DECLARE_MEDIA_DRIVER_SEEK_METH(_name) \
201 static void _name##_seek(media_substream*, size_t);
202 #define DECLARE_MEDIA_DRIVER_SIMPLE_METHS(_name) \
203 DECLARE_MEDIA_DRIVER_OPEN_METH(_name); \
204 DECLARE_MEDIA_DRIVER_CLOSE_METH(_name); \
205 DECLARE_MEDIA_DRIVER_PRINT_METH(_name); \
206 DECLARE_MEDIA_DRIVER_MARK_METH(_name); \
207 DECLARE_MEDIA_DRIVER_READ_METH(_name); \
208 DECLARE_MEDIA_DRIVER_WRITE_METH(_name); \
209 DECLARE_MEDIA_DRIVER_REWIND_METH(_name) \
210 DECLARE_MEDIA_DRIVER_SEEK_METH(_name); \
211 /* we currently have no write support so define a nop here */ \
213 _name##_write(media_substream *v01d, void *buf, size_t size) \
217 /* we currently have no seek support so define a nop here */ \
219 _name##_seek(media_substream *v01d, size_t position) \
224 #define DEFINE_MEDIA_DRIVER_CUSTOM(_n, _o, _c, _p, _m, _r, _w, _rw, _s) \
225 ms_meths _n[1] = { { (_o), (_c), (_p), (_m), (_r), (_w), (_rw), (_s) } }
226 #define DEFINE_MEDIA_DRIVER(_name, _o, _c, _p, _m, _r, _w, _rw, _s) \
227 DEFINE_MEDIA_DRIVER_CUSTOM((_name), \
236 #define DEFINE_MEDIA_DRIVER_SIMPLE(_name) \
237 DEFINE_MEDIA_DRIVER(_name, \
242 #define DEFINE_MEDIA_DRIVER_EMPTY(_name) \
243 DEFINE_MEDIA_DRIVER_CUSTOM((_name), \
248 #define SET_MEDIA_DRIVER_FUNCTION_CUSTOM(_driver, _slot, _function) \
249 (_driver->_slot = _function)
250 #define SET_MEDIA_DRIVER_FUNCTION(_driver, _function) \
251 SET_MEDIA_DRIVER_FUNCTION_CUSTOM(_driver, \
253 _driver##_##_function)
255 #define media_stream_set_meths(_ms, _m) ((_ms)->meths = _m)
256 #define media_stream_meths(_ms) ((_ms)->meths)
257 #define media_stream_meth(_ms, _m) (media_stream_meths(_ms)->_m)
258 #define XMEDIA_STREAM_SET_METHS(_ms, _m) (media_stream_set_meths( \
259 XMEDIA_STREAM(_ms), _m))
260 #define XMEDIA_STREAM_METHS(_ms) (media_stream_meths(XMEDIA_STREAM(_ms)))
261 #define XMEDIA_STREAM_METH(_ms, _m) (media_stream_meth(XMEDIA_STREAM(_ms), _m))
264 /* Media streams are actually containers, we use doubly linked lists with media
266 struct Lisp_Media_Stream {
267 struct lcrecord_header lheader;
269 media_substream *first; /* pointer to first substream */
270 media_substream *last; /* pointer to last substream */
276 mkind_file_properties *fprops;
277 mkind_string_properties *sprops;
280 /* methods for the stream */
281 const ms_meths *meths;
283 /* anonymous data, used by the various backends */
287 extern Lisp_Object Qmedia_streamp;
288 extern Lisp_Object Qunknown;
290 DECLARE_LRECORD(media_stream, Lisp_Media_Stream);
291 #define XMEDIA_STREAM(x) XRECORD(x, media_stream, Lisp_Media_Stream)
292 #define XSETMEDIA_STREAM(x, p) XSETRECORD(x, p, media_stream)
293 #define wrap_media_stream(p) wrap_object(p)
294 #define MEDIA_STREAMP(x) RECORDP(x, media_stream)
295 #define CHECK_MEDIA_STREAM(x) CHECK_RECORD(x, media_stream)
296 #define CONCHECK_MEDIA_STREAM(x) CONCHECK_RECORD(x, media_stream)
298 #define media_stream_first(ms) (ms)->first
299 #define media_stream_last(ms) (ms)->last
300 #define media_stream_driver(ms) (ms)->driver
301 #define media_stream_kind(ms) (ms)->kind
302 #define media_stream_kind_properties(ms) (ms)->kind_properties
303 #define media_stream_data(ms) (ms)->stream_data
304 #define media_stream_1sub(ms) media_stream_first(ms)
305 #define media_stream_nsub(ms) media_stream_last(ms)
306 #define XMEDIA_STREAM_FIRST(x) media_stream_first(XMEDIA_STREAM(x))
307 #define XMEDIA_STREAM_LAST(x) media_stream_last(XMEDIA_STREAM(x))
308 #define XMEDIA_STREAM_DRIVER(x) media_stream_driver(XMEDIA_STREAM(x))
309 #define XMEDIA_STREAM_KIND(x) media_stream_kind(XMEDIA_STREAM(x))
310 #define XMEDIA_STREAM_DATA(x) media_stream_data(XMEDIA_STREAM(x))
311 #define XMEDIA_STREAM_1SUB(x) media_stream_1sub(XMEDIA_STREAM(x))
312 #define XMEDIA_STREAM_NSUB(x) media_stream_nsub(XMEDIA_STREAM(x))
315 extern Lisp_Object make_media_stream(void);
316 extern media_substream *make_media_substream(void);
317 extern media_substream *make_media_substream_append(Lisp_Media_Stream*);
318 extern media_substream *make_media_substream_prepend(Lisp_Media_Stream*);
320 extern Lisp_Object Q_data, Q_file, Q_url;
322 EXFUN(Fmake_media_stream, 3);
324 /* A struct for virtual-I/O */
334 struct media_sample_format_s {
335 audio_resample_fun upsample;
336 audio_resample_fun downsample;
339 struct audio_coerce_chain_s {
340 audio_coerce_fun fun;
341 audio_coerce_args args;
342 audio_coerce_chain_t *next;
343 audio_coerce_chain_t *last;
346 #define DECLARE_MEDIA_SAMPLE_FORMAT(_name) \
347 extern media_sample_format_t _name[1]
348 #define DECLARE_MEDIA_SAMPLE_FORMAT_UP(_name) \
349 static void _name##_up(void*, void*, size_t);
350 #define DECLARE_MEDIA_SAMPLE_FORMAT_DOWN(_name) \
351 static void _name##_down(void*, void*, size_t);
352 #define DECLARE_MEDIA_SAMPLE_FORMAT_SIMPLE(_name) \
353 DECLARE_MEDIA_SAMPLE_FORMAT_UP(_name); \
354 DECLARE_MEDIA_SAMPLE_FORMAT_DOWN(_name);
356 #define DEFINE_MEDIA_SAMPLE_FORMAT_CUSTOM(_name, _up, _down) \
357 media_sample_format_t _name[1] = { { (_up), (_down) } }
358 #define DEFINE_MEDIA_SAMPLE_FORMAT(_name, _up, _down) \
359 DEFINE_MEDIA_SAMPLE_FORMAT_CUSTOM((_name), \
362 #define DEFINE_MEDIA_SAMPLE_FORMAT_SIMPLE(_name) \
363 DECLARE_MEDIA_SAMPLE_FORMAT_SIMPLE(_name) \
364 DEFINE_MEDIA_SAMPLE_FORMAT(_name, up, down)
365 #define DEFINE_MEDIA_SAMPLE_FORMAT_EMPTY(_name) \
366 DEFINE_MEDIA_SAMPLE_FORMAT_CUSTOM((_name), NULL, NULL)
368 #define MEDIA_SAMPLE_FORMAT_UPSAMPLE(_msf) (_msf)->upsample
369 #define MEDIA_SAMPLE_FORMAT_DOWNSAMPLE(_msf) (_msf)->downsample
371 #define MEDIA_SAMPLE_FORMAT(_msf) (_msf)
375 #define DECLARE_MEDIA_SAMPLE_EFFECT(_name, args...) \
376 extern audio_coerce_fun _name[1]; \
381 #define DEFINE_MEDIA_SAMPLE_EFFECT(_name, _fun) \
382 static size_t _fun(sxe_media_sample_t *, \
383 sxe_media_sample_t *, \
385 audio_coerce_fun _name[1] = { (_fun) }
387 #define MEDIA_SAMPLE_EFFECT(_mse) (_mse)[0]
389 #define MEDIA_SAMPLE_VOLUME_NORM 0x7f
390 #define MEDIA_SAMPLE_VOLUME_MAX 0xff
391 #define MEDIA_SAMPLE_VOLUME_MIN 0x00
392 #define MEDIA_MAX_AUDIO_CHANNELS 16 /* maximal number of audio channels */
394 #define PUT_MEDIA_SAMPLE_EFFECT(_chain, _idx, _mse, _mse_arg) \
396 (&(_chain[(_idx)]))->fun = (_mse); \
397 (&(_chain[(_idx)]))->args = (_mse_arg); \
399 #define ADD_MEDIA_SAMPLE_EFFECT(_chain, _idx, _mse, _mse_arg) \
401 PUT_MEDIA_SAMPLE_EFFECT(_chain, _idx, _mse, _mse_arg); \
404 #define GET_MEDIA_SAMPLE_EFFECT_FUN(_chain, _idx) \
405 (&(_chain[(_idx)]))->fun
406 #define GET_MEDIA_SAMPLE_EFFECT_ARGS(_chain, _idx) \
407 (&(_chain[(_idx)]))->args
408 #define CALL_MEDIA_SAMPLE_EFFECT(_chain, _idx, _dst, _src, _len) \
409 GET_MEDIA_SAMPLE_EFFECT_FUN(_chain, _idx)( \
410 (_dst), (_src), (_len), \
411 GET_MEDIA_SAMPLE_EFFECT_ARGS(_chain, _idx))
413 /* some predefined sample formats */
414 DECLARE_MEDIA_SAMPLE_FORMAT(sxe_msf_U8);
415 DECLARE_MEDIA_SAMPLE_FORMAT(sxe_msf_S16);
416 DECLARE_MEDIA_SAMPLE_FORMAT(sxe_msf_FLT);
417 DECLARE_MEDIA_SAMPLE_FORMAT(sxe_msf_S32);
418 DECLARE_MEDIA_SAMPLE_FORMAT(sxe_msf_S24); /* format internally used */
420 /* some predefined effects */
421 DECLARE_MEDIA_SAMPLE_EFFECT(sxe_mse_1ch_to_2ch);
422 DECLARE_MEDIA_SAMPLE_EFFECT(sxe_mse_2ch_to_1ch,
423 int chan;); /* which channel to keep */
424 DECLARE_MEDIA_SAMPLE_EFFECT(sxe_mse_5ch_to_2ch,
427 DECLARE_MEDIA_SAMPLE_EFFECT(sxe_mse_volume,
429 uint8_t volume[MEDIA_MAX_AUDIO_CHANNELS];);
430 DECLARE_MEDIA_SAMPLE_EFFECT(sxe_mse_rerate,
436 #define SXE_MAX_S32 2147483647.0f
437 #define SXE_MAX_S24 8388607.0f
438 #define SXE_MAX_S16 32767.0f
439 #define SXE_MAX_S8 127.0f
440 #define SXE_MAX_U8 255.0f
442 #define MEDIA_MAX_AUDIO_FRAME_SIZE 384000 /* 2 secs of 48kHz, 32bit, stereo */
444 #ifdef ALL_DEBUG_FLAGS
445 #undef MEDIA_DEBUG_FLAG
446 #define MEDIA_DEBUG_FLAG
449 #define __MEDIA_DEBUG__(args...) fprintf(stderr, "MEDIA " args)
450 #ifndef MEDIA_DEBUG_FLAG
451 #define MEDIA_DEBUG(args...)
453 #define MEDIA_DEBUG(args...) __MEDIA_DEBUG__(args)
455 #define MEDIA_DEBUG_FMT(args...) MEDIA_DEBUG("[format] " args)
456 #define MEDIA_DEBUG_COE(args...) MEDIA_DEBUG("[coerce] " args)
457 #define MEDIA_CRITICAL(args...) __MEDIA_DEBUG__("CRITICAL: " args)
459 #endif /* INCLUDED_media_h_ */