a6668cfb0eb28553ac5fbdb44c24200ce132c962
[sxemacs] / src / media / media.c
1 /* Media functions.
2    Copyright (C) 2006 Sebastian Freundt
3
4 This file is part of SXEmacs
5
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.
10
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.
15
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/>. */
18
19
20 /* Synched up with: Not in FSF. */
21
22 #include <config.h>
23 #include "lisp.h"
24
25 #include "buffer.h"
26
27 #include "media.h"
28 #include "sound.h"
29 #ifdef HAVE_FFMPEG
30 #include "media-ffmpeg.h"
31 #endif
32 #ifdef HAVE_SNDFILE
33 #include "media-sndfile.h"
34 #endif
35 #ifdef HAVE_INTERNAL_MEDIA
36 #include "media-internal.h"
37 #endif
38 #ifdef HAVE_MAD
39 #include "media-mad.h"
40 #endif
41 #ifdef HAVE_GSTREAMER
42 #include "media-gstreamer.h"
43 #endif
44 #ifdef HAVE_SOX
45 #include "media-sox.h"
46 #endif
47 #ifdef HAVE_XINE
48 #include "media-xine.h"
49 #endif
50
51 Lisp_Object Qmedia_streamp;
52 Lisp_Object Qunknown;
53 Lisp_Object Qunavailable;
54 /* media property syms */
55 Lisp_Object Qdemux, Qcodec, Qnchannels, Qsamplerate;
56 Lisp_Object Qbitrate, Qabitrate, Qvbitrate;
57 Lisp_Object Qwidth, Qheight, Qaspect, Qdriver, Qkind, Qfifo, Quri, Qtype;
58 Lisp_Object Qaudio, Qvideo, Qimage;
59
60 static void determine_stream_type(Lisp_Media_Stream *ms, media_driver);
61 static void media_stream_print(Lisp_Object, Lisp_Object, int);
62 static void media_substream_print(media_substream *, Lisp_Object, int);
63 static void media_substream_finalise(void*, int);
64
65 \f
66 static void determine_stream_type(Lisp_Media_Stream *ms, media_driver preferred)
67 {
68 #ifdef HAVE_FFMPEG
69         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
70             (preferred == MDRIVER_UNKNOWN ||
71              preferred == MDRIVER_FFMPEG)) {
72                 MEDIA_DEBUG("trying ffmpeg.\n");
73                 media_stream_set_meths(ms, media_ffmpeg);
74                 media_stream_meth(ms, open)(ms);
75         }
76 #endif
77 #ifdef HAVE_MAD
78         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
79             (preferred == MDRIVER_UNKNOWN ||
80              preferred == MDRIVER_MAD)) {
81                 MEDIA_DEBUG("trying mad.\n");
82                 media_stream_set_meths(ms, media_mad);
83                 media_stream_meth(ms, open)(ms);
84         }
85 #endif
86 #ifdef HAVE_SOX
87         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
88             (preferred == MDRIVER_UNKNOWN ||
89              preferred == MDRIVER_SOX)) {
90                 MEDIA_DEBUG("trying sox.\n");
91                 media_stream_set_meths(ms, media_sox);
92                 media_stream_meth(ms, open)(ms);
93         }
94 #endif
95 #ifdef HAVE_SNDFILE
96         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
97             (preferred == MDRIVER_UNKNOWN ||
98              preferred == MDRIVER_SNDFILE)) {
99                 MEDIA_DEBUG("trying sndfile.\n");
100                 media_stream_set_meths(ms, media_sndfile);
101                 media_stream_meth(ms, open)(ms);
102         }
103 #endif
104 /* not working stuff here :) */
105 #if 0
106 #ifdef HAVE_GSTREAMER
107         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
108             (preferred == MDRIVER_UNKNOWN ||
109              preferred == MDRIVER_GSTREAMER)) {
110                 MEDIA_DEBUG("trying gstreamer.\n");
111                 media_gstreamer_analyse_stream(ms);
112         }
113 #endif
114 #endif
115 #ifdef HAVE_XINE
116         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
117             (preferred == MDRIVER_UNKNOWN ||
118              preferred == MDRIVER_XINE)) {
119                 MEDIA_DEBUG("trying xine.\n");
120                 media_stream_set_meths(ms, media_xine);
121                 media_stream_meth(ms, open)(ms);
122         }
123 #endif
124 #ifdef HAVE_INTERNAL_MEDIA
125         if ((media_stream_driver(ms) == MDRIVER_UNKNOWN) &&
126             (preferred == MDRIVER_UNKNOWN ||
127              preferred == MDRIVER_INTERNAL)) {
128                 MEDIA_DEBUG("trying internal.\n");
129                 media_internal_analyse_stream(ms);
130         }
131 #endif
132         if (media_stream_driver(ms) == MDRIVER_UNKNOWN) {
133                 MEDIA_DEBUG("giving up\n");
134                 media_stream_set_meths(ms, NULL);
135         }
136         return;
137 }
138
139 \f
140 /*****************************************************************/
141 /*                          media streams                        */
142 /*****************************************************************/
143 static Lisp_Object media_stream_mark(Lisp_Object obj)
144 {
145         switch (XMEDIA_STREAM_KIND(obj)) {
146         case MKIND_FILE:
147                 mark_object(XMEDIA_STREAM(obj)->
148                             kind_properties.fprops->filename);
149                 break;
150         case MKIND_STRING:
151         case MKIND_FIFO:
152         case MKIND_STREAM:
153         case MKIND_UNKNOWN:
154         case NUMBER_OF_MEDIA_KINDS:
155         default:
156                 break;
157         }
158
159         if (XMEDIA_STREAM_METHS(obj) &&
160             XMEDIA_STREAM_METH(obj, mark))
161                 XMEDIA_STREAM_METH(obj, mark)(XMEDIA_STREAM_DATA(obj));
162
163         return Qnil;
164 }
165
166 static void
167 media_stream_finalise(void *header, int for_disksave)
168 {
169         Lisp_Media_Stream *ms = (Lisp_Media_Stream*)header;
170         media_substream *mss = NULL;
171
172         if(ms == NULL)
173                 return;
174         if (media_stream_meths(ms) &&
175             media_stream_meth(ms, close))
176                 media_stream_meth(ms, close)(media_stream_data(ms));
177
178         mss = media_stream_first(ms);
179         while (mss) {
180                 media_substream_finalise(mss, for_disksave);
181                 mss = media_substream_next(mss);
182         }
183
184 #if 0
185         switch (media_stream_driver(ms)) {
186         case MDRIVER_XINE:
187 #ifdef HAVE_XINE
188                 if (media_stream_data(ms))
189                         media_xine_close_context(media_stream_data(ms));
190 #endif
191                 break;
192         case MDRIVER_SNDFILE:
193 #ifdef HAVE_SNDFILE
194                 if (media_stream_data(ms))
195                         sf_close(media_stream_data(ms));
196 #endif
197                 break;
198         case MDRIVER_MAD:
199 #ifdef HAVE_MAD
200                 if (media_stream_data(ms))
201                         mad_decoder_finish(media_stream_data(ms));
202 #endif
203                 break;
204         case MDRIVER_SOX:
205 #ifdef HAVE_SOX
206                 if (media_stream_data(ms))
207                         st_close(media_stream_data(ms));
208 #endif
209                 break;
210         default:
211                 break;
212         }
213 #endif
214
215         switch (media_stream_kind(ms)) {
216         case MKIND_FILE: {
217                 mkind_file_properties *mkfp;
218                 mkfp = media_stream_kind_properties(ms).fprops;
219                 if (mkfp) {
220                         xfree(mkfp);
221                 }
222                 break;
223         }
224         case MKIND_STRING: {
225                 mkind_string_properties *mksp;
226                 mksp = media_stream_kind_properties(ms).sprops;
227                 if (mksp) {
228                         if (mksp->name)
229                                 xfree(mksp->name);
230 #if 0
231                         if (mksp->stream_data)
232                                 xfree(mksp->stream_data);
233 #endif
234                         xfree(mksp);
235                 }
236                 break;
237         }
238         case MKIND_UNKNOWN: