3dfd0ffa8eacd56bcfe7c6e77b5017da804a642d
[platform/upstream/gstreamer.git] / libs / winloader / driver.c
1 #include <stdio.h>
2 #include <malloc.h>
3 #include <wine/driver.h>
4 #include <wine/pe_image.h>
5 #include <wine/winreg.h>
6 #include <wine/vfw.h>
7 #include <registry.h>
8
9 #include "config.h"
10
11 #define STORE_ALL \
12     __asm__ ( \
13     "push %%ebx\n\t" \
14     "push %%ecx\n\t" \
15     "push %%edx\n\t" \
16     "push %%esi\n\t" \
17     "push %%edi\n\t"::)
18
19 #define REST_ALL \
20     __asm__ ( \
21     "pop %%edi\n\t" \
22     "pop %%esi\n\t" \
23     "pop %%edx\n\t" \
24     "pop %%ecx\n\t" \
25     "pop %%ebx\n\t"::)
26
27
28 #define WIN32_PATH GST_WIN32_LIBDIR
29
30 typedef struct {
31     UINT             uDriverSignature;
32     HINSTANCE        hDriverModule;
33     DRIVERPROC       DriverProc;
34     DWORD            dwDriverID;
35 } DRVR;
36
37 typedef DRVR  *PDRVR;
38 typedef DRVR  *NPDRVR;
39 typedef DRVR  *LPDRVR;
40     
41 static DWORD dwDrvID = 0;
42
43 LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message,
44                                     LPARAM lParam1, LPARAM lParam2 )
45 {
46     DRVR* module=(DRVR*)hDriver;
47     int result;
48 #ifdef DETAILED_OUT    
49     printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2);
50 #endif
51     if(module==0)return -1;
52     if(module->hDriverModule==0)return -1;
53     if(module->DriverProc==0)return -1;
54     STORE_ALL;
55     result=module->DriverProc(module->dwDriverID,1,message,lParam1,lParam2);
56     REST_ALL;
57 #ifdef DETAILED_OUT    
58     printf("\t\tResult: %X\n", result);
59 #endif    
60     return result;
61 }                                   
62
63 static NPDRVR DrvAlloc(HDRVR*lpDriver, LPUINT lpDrvResult)
64 {
65     NPDRVR npDriver;
66     /* allocate and lock handle */
67     if (lpDriver)
68     {
69         if (*lpDriver = (HDRVR) malloc(sizeof(DRVR)) )
70         {
71             if (npDriver = (NPDRVR) *lpDriver)
72             {
73                     *lpDrvResult = MMSYSERR_NOERROR;
74                     return (npDriver);
75             }
76             free((NPDRVR)*lpDriver);
77         }
78         return (*lpDrvResult = MMSYSERR_NOMEM, (NPDRVR) 0);
79     }
80     return (*lpDrvResult = MMSYSERR_INVALPARAM, (NPDRVR) 0);
81 }
82
83 typedef struct
84 {
85     HMODULE handle;
86     char name[64];
87     int usage;
88 }codec_t;
89
90 static codec_t avi_codecs[]={
91  {0, WIN32_PATH"/divxc32.dll", 0},      //0
92  {0, WIN32_PATH"/ir50_32.dll", 0},
93  {0, WIN32_PATH"/ir41_32.dll", 0},
94  {0, WIN32_PATH"/ir32_32.dll", 0},    
95  {0, WIN32_PATH"/mpg4c32.dll", 0},
96  {0, WIN32_PATH"/iccvid.dll", 0},       //5
97  {0, WIN32_PATH"/libvideodll.so", 0},
98  {0, WIN32_PATH"/divxa32.acm", 0},      
99  {0, WIN32_PATH"/msadp32.acm", 0},
100  {0, WIN32_PATH"/ativcr1.dll", 0},
101  {0, WIN32_PATH"/ativcr2.dll", 0},      //10
102  {0, WIN32_PATH"/i263_32.drv", 0},
103  {0, WIN32_PATH"/l3codeca.acm", 0},
104 // {0, WIN32_PATH"/atiyvu9.dll", 0},
105 };
106
107                                                                                                                     
108 static void DrvFree(HDRVR hDriver)
109 {
110     int i;
111     if(hDriver)
112         if(((DRVR*)hDriver)->hDriverModule)
113         if(((DRVR*)hDriver)->DriverProc)
114         (((DRVR*)hDriver)->DriverProc)(((DRVR*)hDriver)->dwDriverID, hDriver, DRV_CLOSE, 0, 0);
115     if(hDriver)
116     for(i=0; i<sizeof(avi_codecs)/sizeof(avi_codecs[0]); i++)
117         if(avi_codecs[i].handle==((DRVR*)hDriver)->hDriverModule)
118         {
119             avi_codecs[i].usage--;      
120             if(avi_codecs[i].usage==0)
121             { 
122                 avi_codecs[i].handle=0;     
123                  if(((DRVR*)hDriver)->hDriverModule)
124                 if(((DRVR*)hDriver)->DriverProc)
125                         (((DRVR*)hDriver)->DriverProc)(0, hDriver, DRV_FREE, 0, 0);
126                 FreeLibrary(((DRVR*)hDriver)->hDriverModule);
127                 if (hDriver)
128                                 free((NPDRVR)hDriver);
129                 return; 
130             }   
131         }      
132 }       
133
134 void DrvClose(HDRVR hdrvr)
135 {
136     DrvFree(hdrvr);
137 }
138     
139 HDRVR
140 //DrvOpen(LPCSTR lpszDriverName, LPCSTR lpszSectionName, LPARAM lParam2)
141 DrvOpen(LPARAM lParam2)
142 {
143     int drv_id;
144     char filename[MAX_PATH], *f;
145     UINT uDrvResult;
146     HDRVR hDriver;
147     NPDRVR npDriver;
148      char unknown[0x24];
149     int seg;
150     int qwe;
151     int regs[10];
152
153     int fccHandler=*((int*)lParam2+2);
154     int fccType=*((int*)lParam2+1);
155     if(fccType==0x63646976)//vidc
156         switch(fccHandler)
157         {
158         case mmioFOURCC('D', 'I', 'V', '3'):
159         case mmioFOURCC('D', 'I', 'V', '4'):
160         case mmioFOURCC('d', 'i', 'v', '3'):
161         case mmioFOURCC('d', 'i', 'v', '4'):
162         case mmioFOURCC('M', 'P', '4', '1'):
163         case mmioFOURCC('M', 'P', '4', '2'):
164         case mmioFOURCC('M', 'P', '4', '3'):
165             printf("Video in DivX ;-) format\n");
166             drv_id=0;
167             break;
168         case mmioFOURCC('I', 'V', '5', '0'):        
169         case mmioFOURCC('i', 'v', '5', '0'):     
170             printf("Video in Indeo Video 5 format\n");   
171             drv_id=1;
172             break;
173         case mmioFOURCC('I', 'V', '4', '1'):        
174         case mmioFOURCC('i', 'v', '4', '1'):        
175             printf("Video in Indeo Video 4.1 format\n");   
176             drv_id=2;
177             break;
178         case mmioFOURCC('I', 'V', '3', '2'):        
179         case mmioFOURCC('i', 'v', '3', '2'):
180             printf("Video in Indeo Video 3.2 format\n");   
181             drv_id=3;
182             break;
183         
184         case mmioFOURCC('m', 'p', '4', '1'):
185         case mmioFOURCC('m', 'p', '4', '2'):
186         case mmioFOURCC('m', 'p', '4', '3'):
187         case mmioFOURCC('M', 'P', 'G', '4'):
188             printf("Video in Microsoft MPEG-4 format\n");   
189             drv_id=4;
190             break;
191         case mmioFOURCC('c', 'v', 'i', 'd'):
192             printf("Video in Cinepak format\n");   
193             drv_id=5;
194             break;      
195         case mmioFOURCC('V', 'C', 'R', '1'):
196             drv_id=9;
197             break;
198         case mmioFOURCC('V', 'C', 'R', '2'):
199             drv_id=10;
200             break;
201         case mmioFOURCC('i', '2', '6', '3'):
202         case mmioFOURCC('I', '2', '6', '3'):
203             drv_id=11;
204             break;                
205 //      case mmioFOURCC('Y', 'V', 'U', '9'):
206 //          drv_id=12;
207 //          break;  
208         default:
209             printf("Unknown codec %X='%c%c%c%c'\n", fccHandler, 
210             fccHandler&0xFF, (fccHandler&0xFF00)>>8,
211             (fccHandler&0xFF0000)>>16, (fccHandler&0xFF000000)>>24);
212             return (HDRVR)0;    
213         }
214     else
215         switch(fccHandler)
216         {
217         case 0x160://DivX audio
218         case 0x161://DivX audio
219             drv_id=7; 
220             break;
221         case 0x2://MS ADPCM
222             drv_id=8;
223             break;
224         case 0x55://MPEG Layer 3
225         printf("MPEG Layer 3 ( 0x55 )\n");
226             drv_id=12;
227             break;
228         default:
229             printf("Unknown ACM codec 0x%X\n", fccHandler);
230             return (HDRVR)0;
231         }
232         
233     if (!(npDriver = DrvAlloc(&hDriver, &uDrvResult)))
234         return ((HDRVR) 0);
235
236     if(avi_codecs[drv_id].handle==0)
237     {
238      if (!(avi_codecs[drv_id].handle=npDriver->hDriverModule = LoadLibraryA(avi_codecs[drv_id].name)))
239      {
240         printf("Can't open library %s\n", avi_codecs[drv_id].name);
241         DrvFree(hDriver);
242         return ((HDRVR) 0);
243      }
244      else avi_codecs[drv_id].usage=1;
245     }
246     else
247     {
248         npDriver->hDriverModule=avi_codecs[drv_id].handle;
249         avi_codecs[drv_id].usage++;
250     }   
251     
252 //    14c0 
253     if(drv_id==0)
254     {
255         int newkey;
256         int bitrate;    
257         int count=4;
258         if(RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\LinuxLoader\\Divx", 0, 0, &newkey)!=0)
259             goto no_reg;
260         if(RegQueryValueExA(newkey, "BitRate", 0, 0, &bitrate, &count)!=0)
261         {
262             RegCloseKey(newkey);
263             goto no_reg;
264         }    
265 //      printf("Setting default bitrate from %f to %d\n",
266 //              *(double*)((char*)npDriver->hDriverModule+0x14c0), bitrate);
267  
268         *(double*)((char*)npDriver->hDriverModule+0x14c0)=bitrate;
269         RegCloseKey(newkey);
270     no_reg:
271         ;       
272     }   
273    
274      if (!(npDriver->DriverProc = (DRIVERPROC)
275              GetProcAddress(npDriver->hDriverModule, "DriverProc")))
276          {
277          printf("Library %s is not a valid codec\n", avi_codecs[drv_id].name);
278          FreeLibrary(npDriver->hDriverModule);
279          DrvFree(hDriver);
280          return ((HDRVR) 0);
281      }
282      
283     TRACE("DriverProc == %X\n", npDriver->DriverProc);
284      npDriver->dwDriverID = ++dwDrvID;
285
286      if (avi_codecs[drv_id].usage==1)
287      {
288         STORE_ALL;
289         (npDriver->DriverProc)(0, hDriver, DRV_LOAD, 0, 0);
290         REST_ALL;
291         TRACE("DRV_LOAD Ok!\n");
292         STORE_ALL;
293         (npDriver->DriverProc)(0, hDriver, DRV_ENABLE, 0, 0);
294         REST_ALL;
295         TRACE("DRV_ENABLE Ok!\n");
296      }
297
298      // open driver 
299     STORE_ALL;
300      npDriver->dwDriverID=(npDriver->DriverProc)(npDriver->dwDriverID, hDriver, DRV_OPEN,
301          (LPARAM) (LPSTR) unknown, lParam2);
302     REST_ALL;
303
304     TRACE("DRV_OPEN Ok!(%X)\n", npDriver->dwDriverID);
305
306     if (uDrvResult)
307     {
308          DrvFree(hDriver);
309          hDriver = (HDRVR) 0;
310      }
311      return (hDriver);
312 }
313