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