1 /***************************************************************************
2 ADM_coreMuxer.cpp - description
3 -------------------
4 copyright : (C) 2008 by mean
5 email : fixounet@free.fr
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "BVector.h"
18 #include "ADM_default.h"
19 #include "ADM_muxerInternal.h"
20 #include "ADM_muxerProto.h"
21
22 extern "C" {
23 #include "libavformat/url.h"
24 }
25
26 void ADM_MuxersCleanup(void);
27
28 ADM_muxer *ADM_muxerSpawn(uint32_t magic,const char *name);
29
30 BVector <ADM_dynMuxer *> ListOfMuxers;
31 /**
32 \fn ADM_mux_configure
33 \brief
34 */
ADM_mux_configure(int index)35 bool ADM_mux_configure(int index)
36 {
37 ADM_assert(index<ListOfMuxers.size());
38 return ListOfMuxers[index]->configure();
39 }
40
41 /**
42 \fn ADM_mx_getNbMuxers
43 \brief Returns the number of muxers plugins except one
44 */
ADM_mx_getNbMuxers(void)45 uint32_t ADM_mx_getNbMuxers(void)
46 {
47 return ListOfMuxers.size();
48 }
49 /**
50 \fn ADM_mx_getDisplayName
51 \brief Returns display name for muxer i
52 */
ADM_mx_getDisplayName(uint32_t i)53 const char *ADM_mx_getDisplayName(uint32_t i)
54 {
55 ADM_assert(i<ListOfMuxers.size());
56 return ListOfMuxers[i]->displayName;
57 }
58 /**
59 \fn ADM_MuxerGetDefaultExtension
60 \brief returns the default extension (i.e. mkv, avi) from index
61 */
ADM_MuxerGetDefaultExtension(int i)62 const char *ADM_MuxerGetDefaultExtension(int i)
63 {
64 ADM_assert(i<ListOfMuxers.size());
65 return ListOfMuxers[i]->defaultExtension;
66 }
67 /**
68 \fn ADM_mx_getName
69 \brief Returns internal name for muxer i
70 */
ADM_mx_getName(uint32_t i)71 const char *ADM_mx_getName(uint32_t i)
72 {
73 ADM_assert(i<ListOfMuxers.size());
74 return ListOfMuxers[i]->name;
75 }
76
77 /**
78 \fn ADM_dm_getDemuxerInfo
79 \brief Get Infos about the demuxer #th plugin
80 */
ADM_mx_getMuxerInfo(int filter,const char ** name,uint32_t * major,uint32_t * minor,uint32_t * patch)81 bool ADM_mx_getMuxerInfo(int filter, const char **name, uint32_t *major,uint32_t *minor,uint32_t *patch)
82 {
83 ADM_assert(filter<ListOfMuxers.size());
84 ListOfMuxers[filter]->getVersion(major,minor,patch);
85 *name=ListOfMuxers[filter]->descriptor;
86 return true;
87 }
88 /**
89 \fn tryLoadingMuxerPlugin
90 \brief Try loading the file given as argument as a muxer
91
92 */
93 #define Fail(x) {printf("%s:"#x"\n",file);goto er;}
tryLoadingMuxerPlugin(const char * file)94 static bool tryLoadingMuxerPlugin(const char *file)
95 {
96 ADM_dynMuxer *dll=new ADM_dynMuxer(file);
97 if(!dll->initialised) Fail(CannotLoad);
98 if(dll->apiVersion!=ADM_MUXER_API_VERSION) Fail(WrongApiVersion);
99
100 ListOfMuxers.append(dll); // Needed for cleanup. FIXME TODO Delete it.
101 printf("[Muxers] Registered filter %s as %s\n",file,dll->descriptor);
102 return true;
103 // Fail!
104 er:
105 delete dll;
106 return false;
107
108 }
109 /**
110 * \fn ADM_mx_loadPlugins
111 * \brief load all audio device plugins
112 */
ADM_mx_loadPlugins(const char * path)113 uint8_t ADM_mx_loadPlugins(const char *path)
114 {
115 #define MAX_EXTERNAL_FILTER 100
116 // FIXME Factorize
117
118 char *files[MAX_EXTERNAL_FILTER];
119 uint32_t nbFile;
120
121 memset(files,0,sizeof(char *)*MAX_EXTERNAL_FILTER);
122 printf("[ADM_mx_plugin] Scanning directory %s\n",path);
123
124 if(!buildDirectoryContent(&nbFile, path, files, MAX_EXTERNAL_FILTER, SHARED_LIB_EXT))
125 {
126 printf("[ADM_av_plugin] Cannot parse plugin\n");
127 return 0;
128 }
129
130 for(int i=0;i<nbFile;i++)
131 tryLoadingMuxerPlugin(files[i]);
132
133 printf("[ADM_mx_plugin] Scanning done\n");
134 // Sort muxers by displayName, bubble sort
135 int nb=ListOfMuxers.size();
136 for(int i=0;i<nb;i++)
137 for(int j=i+1;j<nb;j++)
138 {
139 ADM_dynMuxer *a,*b;
140 a=ListOfMuxers[i];
141 b=ListOfMuxers[j];
142 if(strcmp(a->displayName,b->displayName)>0)
143 {
144 ListOfMuxers[j]=a;
145 ListOfMuxers[i]=b;
146 }
147 }
148 clearDirectoryContent(nbFile,files);
149 return 1;
150 }
151 /**
152 \fn ADM_mx_cleanup
153 */
ADM_mx_cleanup(void)154 bool ADM_mx_cleanup(void)
155 {
156 ADM_MuxersCleanup();
157 return true;
158 }
159 /**
160 \fn ADM_mx_getExtraConf
161 \brief Retrieve extra configuration from current muxer
162 */
ADM_mx_getExtraConf(int index,CONFcouple ** c)163 bool ADM_mx_getExtraConf(int index,CONFcouple **c)
164 {
165 *c=NULL;
166 if(index>=ListOfMuxers.size())
167 {
168 ADM_error("Given index exceeds muxer list\n",index);
169 return false;
170 }
171 ADM_dynMuxer *mux=ListOfMuxers[index];
172 return mux->getConfiguration(c);
173
174 }
175 /**
176 \fn ADM_mx_setExtraConf
177 \brief Set extra configuration from current muxer
178 */
ADM_mx_setExtraConf(int index,CONFcouple * c)179 bool ADM_mx_setExtraConf(int index,CONFcouple *c)
180 {
181 if(!c) return true;
182 if(index>=ListOfMuxers.size())
183 {
184 ADM_error("Given index exceeds muxer list\n",index);
185 return false;
186 }
187 ADM_dynMuxer *mux=ListOfMuxers[index];
188 return mux->setConfiguration(c);
189
190 }
191 /**
192 \fn ADM_MuxersCleanup
193 \brief Current device is no longer used, delete
194 */
ADM_MuxersCleanup(void)195 void ADM_MuxersCleanup(void)
196 {
197 int nb=ListOfMuxers.size();
198 for(int i=0;i<nb;i++)
199 {
200 if(ListOfMuxers[i]) delete ListOfMuxers[i];
201 ListOfMuxers[i]=NULL;
202 }
203 }
204
205 /**
206 \fn ADM_muxerIndexFromName
207 \brief return muxer index from name, -1 if error
208 */
ADM_MuxerIndexFromName(const char * name)209 int ADM_MuxerIndexFromName(const char *name)
210 {
211 int n=ListOfMuxers.size();
212 for(int i=0;i<n;i++)
213 {
214 ADM_dynMuxer *mux=ListOfMuxers[i];
215 if(!strcasecmp(mux->name,name)) return i;
216 }
217 return -1;
218 }
219 /**
220 \fn ADM_MuxerSpawn
221 \brief Locate the correct demuxer and instantiate it
222
223 */
ADM_MuxerSpawn(const char * name)224 ADM_muxer *ADM_MuxerSpawn(const char *name)
225 {
226 int found=-1;
227 uint32_t score=0;
228 uint32_t mark;
229 found=ADM_MuxerIndexFromName(name);
230 if(score && found!=-1)
231 {
232 return ListOfMuxers[found]->createmuxer();
233 }
234 return NULL;
235 }
236
237 /**
238 \fn ADM_MuxerSpawnFromIndex
239 \brief Locate the correct demuxer and instantiate it
240
241 */
ADM_MuxerSpawnFromIndex(int index)242 ADM_muxer *ADM_MuxerSpawnFromIndex(int index)
243 {
244 ADM_assert(index<ListOfMuxers.size());
245 return ListOfMuxers[index]->createmuxer();
246 }
247
248
249 //___________________________________________
250 extern "C"
251 {
252 #include "libavformat/avformat.h"
253 #include "libavutil/mem.h"
254 };
255
ADM_lavFormatInit(void)256 void ADM_lavFormatInit(void)
257 {
258 av_register_all();
259
260 // Make sure avformat is correctly configured
261 const char* formats[] = {"mpegts", "dvd", "vcd", "svcd", "mp4", "psp", "flv", "matroska"};
262 AVOutputFormat *avfmt;
263
264 for (int i = 0; i < 8; i++)
265 {
266 avfmt = av_guess_format(formats[i], NULL, NULL);
267
268 if (avfmt == NULL)
269 {
270 printf("Error: %s muxer isn't registered\n", formats[i]);
271 ADM_assert(0);
272 }
273 }
274
275 const URLProtocol **prot=ffurl_get_protocols("file",NULL);
276 bool found=false;
277 if(prot)
278 {
279 if (!strcmp(prot[0]->name, "file"))
280 {
281 found=true;
282 }
283 av_freep(&prot);
284 }
285 if(!found)
286 {
287 printf("Error: file protocol isn't registered\n");
288 ADM_assert(0);
289 }
290 }
291 // EOF
292
293