1
0

decoders.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. #include <windows.h>
  2. #include "api.h"
  3. #include "main.h"
  4. #include "vfw.h"
  5. #include <api/service/services.h>
  6. #include "../nsv/svc_nsvFactory.h"
  7. #include <api/service/waservicefactory.h>
  8. #include "../../Winamp/in2.h"
  9. extern In_Module mod;
  10. // you should probably override these in your project settings
  11. // builtin decoders
  12. //#define BUILTIN_MP3_SUPPORT
  13. //#define BUILTIN_VP3_SUPPORT
  14. //#define BUILTIN_DIVX_SUPPORT
  15. //#define BUILTIN_PCM_SUPPORT
  16. //#define BUILTIN_VFW_SUPPORT
  17. // support dll decoders?
  18. //#define DLL_DECODER_SUPPORT
  19. //#define DLL_DECODER_SUPPORT_NOCURDIR
  20. #ifdef WINAMP_PLUGIN
  21. # ifndef DLL_DECODER_SUPPORT
  22. # define DLL_DECODER_SUPPORT
  23. # endif
  24. # ifndef DLL_DECODER_SUPPORT_NOCURDIR
  25. # define DLL_DECODER_SUPPORT_NOCURDIR
  26. # endif
  27. # ifndef DLL_DECODER_SUPPORT_IN_
  28. # define DLL_DECODER_SUPPORT_IN_
  29. # endif
  30. # ifndef BUILTIN_PCM_SUPPORT
  31. # define BUILTIN_PCM_SUPPORT
  32. # endif
  33. #endif
  34. #ifdef BUILTIN_VP3_SUPPORT
  35. #include "vp3stub.h"
  36. #endif
  37. #ifdef BUILTIN_VP5_SUPPORT
  38. #include "vp5stub.h"
  39. #endif
  40. #ifdef BUILTIN_MP3_SUPPORT
  41. #include "mp3stub.h"
  42. #endif
  43. #ifdef BUILTIN_VFW_SUPPORT
  44. class Gen_Decoder : public IVideoDecoder {
  45. public:
  46. Gen_Decoder(int w, int h);
  47. ~Gen_Decoder();
  48. int decode(int need_kf,
  49. void *in, int in_len,
  50. void **out, // out is set to a pointer to data
  51. unsigned int *out_type, // 'Y','V','1','2' is currently defined
  52. int *is_kf);
  53. void flush() { }
  54. int m_err;
  55. int width,height;
  56. BITMAPINFO gen_bmo,gen_bmi;
  57. HIC gen_hic;
  58. unsigned char *vidbufdec;
  59. };
  60. Gen_Decoder::Gen_Decoder(int w, int h)
  61. {
  62. width=w;
  63. height=h;
  64. m_err=0;
  65. gen_hic=0;
  66. vidbufdec=(unsigned char*)malloc(sizeof(YV12_PLANES) + w*h*3/2);
  67. }
  68. Gen_Decoder::~Gen_Decoder()
  69. {
  70. if (gen_hic)
  71. {
  72. ICDecompressEnd(gen_hic);
  73. ICClose(gen_hic);
  74. }
  75. free(vidbufdec);
  76. }
  77. int Gen_Decoder::decode(int need_kf,
  78. void *in, int in_len,
  79. void **out, // out is set to a pointer to data
  80. unsigned int *out_type, // 'Y','V','1','2' is currently defined
  81. int *is_kf)
  82. {
  83. *out_type=NSV_MAKETYPE('Y','V','1','2');
  84. gen_bmi.bmiHeader.biSizeImage = in_len;
  85. if(ICERR_OK == ICDecompress(gen_hic,0,(BITMAPINFOHEADER *) &gen_bmi, (char*)in,(BITMAPINFOHEADER *) &gen_bmo, (char*)vidbufdec+sizeof(YV12_PLANES)))
  86. {
  87. //*is_kf=!(!in_len || ((unsigned char *)in)[0] > 0x7f);
  88. *is_kf=1;
  89. if (need_kf && !*is_kf)
  90. {
  91. return 0;
  92. }
  93. YV12_PLANES *image_vbd=(YV12_PLANES *)vidbufdec;
  94. image_vbd->y.baseAddr=(unsigned char *)(image_vbd+1);
  95. image_vbd->v.baseAddr=((unsigned char *)(image_vbd+1)) + width*height;
  96. image_vbd->u.baseAddr=((unsigned char *)(image_vbd+1)) + width*height*5/4;
  97. image_vbd->y.rowBytes=width;
  98. image_vbd->v.rowBytes=width/2;
  99. image_vbd->u.rowBytes=width/2;
  100. *out=(void*)vidbufdec;
  101. return 0;
  102. }
  103. return -1;
  104. }
  105. static IVideoDecoder *createVfw(int w, int h, double framerate, unsigned int type, int *flip)
  106. {
  107. HIC gen_hic = ICOpen(ICTYPE_VIDEO, type, ICMODE_DECOMPRESS);
  108. if (!gen_hic) return 0;
  109. BITMAPINFO gen_bmo={0,},gen_bmi={0,};
  110. gen_bmi.bmiHeader.biSize=sizeof(gen_bmi.bmiHeader);
  111. gen_bmi.bmiHeader.biCompression = type;
  112. gen_bmi.bmiHeader.biHeight=h;
  113. gen_bmi.bmiHeader.biWidth =w;
  114. gen_bmi.bmiHeader.biPlanes=1;
  115. gen_bmo.bmiHeader.biSize=sizeof(gen_bmo.bmiHeader);
  116. gen_bmo.bmiHeader.biCompression = mmioFOURCC('Y','V','1','2');
  117. gen_bmo.bmiHeader.biHeight=h;
  118. gen_bmo.bmiHeader.biWidth =w;
  119. gen_bmo.bmiHeader.biSizeImage=(w*h*3)/2;
  120. gen_bmo.bmiHeader.biPlanes=1;
  121. gen_bmo.bmiHeader.biBitCount=12;
  122. if (ICERR_OK !=ICDecompressBegin(gen_hic, &gen_bmi, &gen_bmo))
  123. {
  124. ICClose(gen_hic);
  125. return 0;
  126. }
  127. Gen_Decoder *t=new Gen_Decoder(w,h);
  128. t->gen_bmi=gen_bmi;
  129. t->gen_bmo=gen_bmo;
  130. t->gen_hic=gen_hic;
  131. return t;
  132. }
  133. #endif
  134. #ifdef BUILTIN_DIVX_SUPPORT
  135. #include "../../divx5/decore.h"
  136. class CrapDivxDecoder : public IVideoDecoder {
  137. public:
  138. CrapDivxDecoder(int w, int h)
  139. {
  140. predict_keyframes=1;
  141. divx_param.x_dim = w;
  142. divx_param.y_dim = h;
  143. divx_param.output_format = DEC_USER;
  144. divx_param.codec_version = 412; // indicates that the stream is DivX 4.12 compatible
  145. divx_param.build_number = 0; // in this case, the build field is ignored
  146. divx_param.time_incr = 15; // time_incr default value
  147. g_decore((long) this, DEC_OPT_MEMORY_REQS, &divx_param, &decMemReqs);
  148. // the application allocates the data structures and the buffers
  149. divx_param.buffers.mp4_edged_ref_buffers = malloc(decMemReqs.mp4_edged_ref_buffers_size);
  150. divx_param.buffers.mp4_edged_for_buffers = malloc(decMemReqs.mp4_edged_for_buffers_size);
  151. divx_param.buffers.mp4_edged_back_buffers = malloc(decMemReqs.mp4_edged_back_buffers_size);
  152. divx_param.buffers.mp4_display_buffers = malloc(decMemReqs.mp4_display_buffers_size);
  153. divx_param.buffers.mp4_state = malloc(decMemReqs.mp4_state_size);
  154. divx_param.buffers.mp4_tables = malloc(decMemReqs.mp4_tables_size);
  155. divx_param.buffers.mp4_stream = malloc(decMemReqs.mp4_stream_size);
  156. divx_param.buffers.mp4_reference = malloc(decMemReqs.mp4_reference_size);
  157. memset(divx_param.buffers.mp4_state, 0, decMemReqs.mp4_state_size);
  158. memset(divx_param.buffers.mp4_tables, 0, decMemReqs.mp4_tables_size);
  159. memset(divx_param.buffers.mp4_stream, 0, decMemReqs.mp4_stream_size);
  160. memset(divx_param.buffers.mp4_reference, 0, decMemReqs.mp4_reference_size);
  161. g_decore((long) this, DEC_OPT_INIT, &divx_param, NULL);
  162. }
  163. ~CrapDivxDecoder()
  164. {
  165. if (g_decore)
  166. {
  167. g_decore((long) this,DEC_OPT_RELEASE,NULL,NULL);
  168. free(divx_param.buffers.mp4_display_buffers);
  169. free(divx_param.buffers.mp4_edged_for_buffers);
  170. free(divx_param.buffers.mp4_edged_back_buffers);
  171. free(divx_param.buffers.mp4_edged_ref_buffers);
  172. free(divx_param.buffers.mp4_reference);
  173. free(divx_param.buffers.mp4_state);
  174. free(divx_param.buffers.mp4_stream);
  175. free(divx_param.buffers.mp4_tables);
  176. }
  177. if (!--divx_cnt)
  178. {
  179. FreeModule(hDivxLib);
  180. hDivxLib=0;
  181. g_decore=0;
  182. }
  183. }
  184. int decode(int need_kf,
  185. void *in, int in_len,
  186. void **out, // out is set to a pointer to data
  187. unsigned int *out_type, // 'Y','V','1','2' is currently defined
  188. int *is_kf)
  189. {
  190. *out_type=NSV_MAKETYPE('Y','V','1','2');
  191. *out=NULL;
  192. int kfpredict=0;
  193. if (predict_keyframes && in_len>3)
  194. {
  195. kfpredict=!((unsigned char *)in)[3];
  196. if (need_kf && !kfpredict) return 0;
  197. }
  198. if (!in_len) return 0;
  199. *is_kf=kfpredict;
  200. DEC_PICTURE pic;
  201. DEC_FRAME decFrame;
  202. decFrame.bitstream = in;
  203. decFrame.bmp = &pic;
  204. decFrame.length = in_len;
  205. decFrame.render_flag = 1;
  206. DEC_FRAME_INFO fi;
  207. if (g_decore((long) this, DEC_OPT_FRAME, &decFrame, &fi) == DEC_OK)
  208. {
  209. if (!kfpredict != !fi.intra) predict_keyframes=0;
  210. *is_kf=fi.intra;
  211. if (need_kf && !fi.intra) return 0;
  212. image_vbd.y.baseAddr=(unsigned char *)pic.y;
  213. image_vbd.u.baseAddr=(unsigned char *)pic.u;
  214. image_vbd.v.baseAddr=(unsigned char *)pic.v;
  215. image_vbd.y.rowBytes=pic.stride_y;
  216. image_vbd.u.rowBytes=pic.stride_uv;
  217. image_vbd.v.rowBytes=pic.stride_uv;
  218. *out=&image_vbd;
  219. return 0;
  220. }
  221. return -1;
  222. }
  223. void flush() { }
  224. static int (STDCALL *g_decore)(
  225. unsigned long handle, // handle - the handle of the calling entity, must be unique
  226. unsigned long dec_opt, // dec_opt - the option for docoding, see below
  227. void *param1, // param1 - the parameter 1 (it's actually meaning depends on dec_opt
  228. void *param2); // param2 - the parameter 2 (it's actually meaning depends on dec_opt
  229. static HINSTANCE hDivxLib;
  230. static int divx_cnt;
  231. private:
  232. DEC_PARAM divx_param;
  233. YV12_PLANES image_vbd;
  234. DEC_MEM_REQS decMemReqs;
  235. int predict_keyframes;
  236. };
  237. int (STDCALL *CrapDivxDecoder::g_decore)(
  238. unsigned long handle, // handle - the handle of the calling entity, must be unique
  239. unsigned long dec_opt, // dec_opt - the option for docoding, see below
  240. void *param1, // param1 - the parameter 1 (it's actually meaning depends on dec_opt
  241. void *param2)=0; // param2 - the parameter 2 (it's actually meaning depends on dec_opt
  242. HINSTANCE CrapDivxDecoder::hDivxLib=0;
  243. int CrapDivxDecoder::divx_cnt=0;
  244. IVideoDecoder *DIVX_CREATE(int w, int h, double framerate, unsigned int fmt, int *flip)
  245. {
  246. if (fmt == NSV_MAKETYPE('D','i','v','X'))
  247. {
  248. if (!CrapDivxDecoder::divx_cnt)
  249. {
  250. CrapDivxDecoder::hDivxLib=LoadLibrary("divx.dll");
  251. if (CrapDivxDecoder::hDivxLib) *((void**)&CrapDivxDecoder::g_decore)=GetProcAddress(CrapDivxDecoder::hDivxLib,"decore");
  252. }
  253. CrapDivxDecoder::divx_cnt++;
  254. if (CrapDivxDecoder::g_decore) return new CrapDivxDecoder(w,h);
  255. }
  256. return NULL;
  257. }
  258. #endif // end of divx gayness
  259. class NullVideoDecoder : public IVideoDecoder
  260. {
  261. public:
  262. NullVideoDecoder() { }
  263. ~NullVideoDecoder() { }
  264. int decode(int need_kf,
  265. void *in, int in_len,
  266. void **out, // out is set to a pointer to data
  267. unsigned int *out_type, // 'Y','V','1','2' is currently defined
  268. int *is_kf)
  269. {
  270. *out_type=NSV_MAKETYPE('Y','V','1','2');
  271. *is_kf=1;
  272. *out=NULL;
  273. return 0;
  274. }
  275. void flush() { }
  276. };
  277. class NullAudioDecoder : public IAudioDecoder
  278. {
  279. public:
  280. NullAudioDecoder(){}
  281. ~NullAudioDecoder(){}
  282. int decode(void *in, int in_len,
  283. void *out, int *out_len,
  284. unsigned int out_fmt[8])
  285. {
  286. *out_len=0;
  287. out_fmt[0]=NSV_MAKETYPE('N','O','N','E'); // no output
  288. return 0;
  289. }
  290. void flush(){}
  291. };
  292. #ifdef BUILTIN_PCM_SUPPORT
  293. class PCMAudioDecoder : public IAudioDecoder
  294. {
  295. public:
  296. PCMAudioDecoder() { fused=4; }
  297. ~PCMAudioDecoder(){}
  298. int decode(void *in, int in_len,
  299. void *out, int *out_len,
  300. unsigned int out_fmt[8])
  301. {
  302. if (in_len < 4)
  303. {
  304. *out_len=0;
  305. out_fmt[0]=0;
  306. return 0; // screw this frame
  307. }
  308. unsigned char *t=(unsigned char *)in;
  309. int bps=t[0];
  310. int nch=t[1];
  311. int srate=((int)t[2] | (((int)t[3])<<8));
  312. out_fmt[0]=NSV_MAKETYPE('P','C','M',' ');
  313. out_fmt[1]=srate;
  314. out_fmt[2]=nch;
  315. out_fmt[3]=bps;
  316. int l=in_len-fused;
  317. if (l > *out_len) l = *out_len;
  318. l&=~(nch*(bps/8)-1);
  319. if (l) memcpy(out,(char *)in + fused,l);
  320. fused+=l;
  321. *out_len=l;
  322. if (fused >= in_len)
  323. {
  324. fused=4;
  325. return 0;
  326. }
  327. return 1;
  328. }
  329. void flush() { fused=4; }
  330. private:
  331. int fused;
  332. };
  333. #endif
  334. #ifdef DLL_DECODER_SUPPORT
  335. static char DLL_Dir[MAX_PATH];
  336. static HINSTANCE DLL_Handles[512];
  337. #endif
  338. void Decoders_Init(char *wapluginspath)
  339. {
  340. #ifdef DLL_DECODER_SUPPORT
  341. HKEY hKey;
  342. if (!DLL_Dir[0] && RegOpenKeyExA(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion",
  343. 0,KEY_READ,&hKey) == ERROR_SUCCESS)
  344. {
  345. DWORD l = sizeof(DLL_Dir);
  346. DWORD t;
  347. if (RegQueryValueExA(hKey,"CommonFilesDir",NULL,&t,(LPBYTE)DLL_Dir,&l ) != ERROR_SUCCESS || t != REG_SZ) DLL_Dir[0]=0;
  348. DLL_Dir[sizeof(DLL_Dir)-5]=0;
  349. CreateDirectoryA(DLL_Dir,NULL);
  350. strcat(DLL_Dir,"\\NSV");
  351. CreateDirectoryA(DLL_Dir,NULL);
  352. RegCloseKey(hKey);
  353. }
  354. if (!DLL_Dir[0]) GetTempPathA(sizeof(DLL_Dir),DLL_Dir);
  355. Decoders_Quit();
  356. HANDLE h;
  357. int x=0;
  358. WIN32_FIND_DATAA fd = {0};
  359. char buf[MAX_PATH*2+1] = {0};
  360. #ifndef DLL_DECODER_SUPPORT_NOCURDIR
  361. char curdir[MAX_PATH] = {0};
  362. strcpy( curdir, ".\\" );
  363. strcpy( buf, curdir );
  364. strcat( buf, "nsvdec_*.dll" );
  365. OutputDebugString( buf ); OutputDebugString( "\n" );
  366. h = FindFirstFile(buf,&fd);
  367. if (h != INVALID_HANDLE_VALUE)
  368. {
  369. do
  370. {
  371. strcpy(buf,curdir);
  372. strcat(buf,fd.cFileName);
  373. DLL_Handles[x]=LoadLibrary(buf);
  374. if (DLL_Handles[x])
  375. {
  376. if (GetProcAddress(DLL_Handles[x],"CreateVideoDecoder") ||
  377. GetProcAddress(DLL_Handles[x],"CreateAudioDecoder")) x++;
  378. else
  379. {
  380. FreeLibrary(DLL_Handles[x]);
  381. DLL_Handles[x]=0;
  382. }
  383. }
  384. } while (x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && FindNextFile(h,&fd));
  385. FindClose(h);
  386. }
  387. #endif
  388. #ifdef DLL_DECODER_SUPPORT_IN_
  389. if (wapluginspath && wapluginspath[0])
  390. {
  391. lstrcpynA(buf,wapluginspath,sizeof(buf)-16);
  392. strcat(buf,"\\in_*.dll");
  393. h = FindFirstFileA(buf,&fd);
  394. if (h != INVALID_HANDLE_VALUE)
  395. {
  396. do
  397. {
  398. strncpy(buf, wapluginspath, MAX_PATH);
  399. strncat(buf, "\\", MAX_PATH);
  400. strncat(buf, fd.cFileName, MAX_PATH);
  401. DLL_Handles[x]=LoadLibraryA(buf);
  402. if (DLL_Handles[x])
  403. {
  404. if (GetProcAddress(DLL_Handles[x],"CreateVideoDecoder") ||
  405. GetProcAddress(DLL_Handles[x],"CreateAudioDecoder")) x++;
  406. else
  407. {
  408. FreeLibrary(DLL_Handles[x]);
  409. DLL_Handles[x]=0;
  410. }
  411. }
  412. } while (x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && FindNextFileA(h,&fd));
  413. FindClose(h);
  414. }
  415. lstrcpynA(buf,wapluginspath,sizeof(buf)-16);
  416. strcat(buf,"\\nsvdec_*.dll");
  417. h = FindFirstFileA(buf,&fd);
  418. if (h != INVALID_HANDLE_VALUE)
  419. {
  420. do
  421. {
  422. strncpy(buf, wapluginspath, MAX_PATH);
  423. strncat(buf, "\\", MAX_PATH);
  424. strncat(buf, fd.cFileName, MAX_PATH);
  425. DLL_Handles[x]=LoadLibraryA(buf);
  426. if (DLL_Handles[x])
  427. {
  428. if (GetProcAddress(DLL_Handles[x],"CreateVideoDecoder") ||
  429. GetProcAddress(DLL_Handles[x],"CreateAudioDecoder")) x++;
  430. else
  431. {
  432. FreeLibrary(DLL_Handles[x]);
  433. DLL_Handles[x]=0;
  434. }
  435. }
  436. } while (x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && FindNextFileA(h,&fd));
  437. FindClose(h);
  438. }
  439. }
  440. #endif
  441. #ifndef WINAMPX
  442. strncpy(buf, DLL_Dir, MAX_PATH);
  443. strncat(buf, "\\nsvdec_*.dll", MAX_PATH);
  444. h = FindFirstFileA(buf,&fd);
  445. if (h != INVALID_HANDLE_VALUE)
  446. {
  447. do
  448. {
  449. strncpy(buf, DLL_Dir, MAX_PATH);
  450. strncat(buf, "\\", MAX_PATH);
  451. strncat(buf, fd.cFileName, MAX_PATH);
  452. DLL_Handles[x]=LoadLibraryA(buf);
  453. if (DLL_Handles[x])
  454. {
  455. if (GetProcAddress(DLL_Handles[x],"CreateVideoDecoder") ||
  456. GetProcAddress(DLL_Handles[x],"CreateAudioDecoder")) x++;
  457. else
  458. {
  459. FreeLibrary(DLL_Handles[x]);
  460. DLL_Handles[x]=0;
  461. }
  462. }
  463. } while (x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && FindNextFileA(h,&fd));
  464. FindClose(h);
  465. }
  466. #endif
  467. #endif
  468. }
  469. void Decoders_Quit()
  470. {
  471. #ifdef DLL_DECODER_SUPPORT
  472. int x;
  473. for (x = 0; x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && DLL_Handles[x]; x ++)
  474. {
  475. FreeLibrary(DLL_Handles[x]);
  476. DLL_Handles[x]=0;
  477. }
  478. #endif
  479. }
  480. static IAudioDecoder *CreateAudioDecoderWasabi(unsigned int type, IAudioOutput **output)
  481. {
  482. int n = 0;
  483. waServiceFactory *sf = 0;
  484. while (sf = mod.service->service_enumService(WaSvc::NSVFACTORY, n++))
  485. {
  486. svc_nsvFactory *factory = (svc_nsvFactory *)sf->getInterface();
  487. if (factory)
  488. {
  489. IAudioDecoder *decoder = factory->CreateAudioDecoder(type, output);
  490. sf->releaseInterface(factory);
  491. if (decoder)
  492. return decoder;
  493. }
  494. }
  495. return 0;
  496. }
  497. static IVideoDecoder *CreateVideoDecoderWasabi(int w, int h, double framerate, unsigned int type, int *flip)
  498. {
  499. int n=0;
  500. waServiceFactory *sf = 0;
  501. while (sf = mod.service->service_enumService(WaSvc::NSVFACTORY, n++))
  502. {
  503. svc_nsvFactory *factory = (svc_nsvFactory *)sf->getInterface();
  504. if (factory)
  505. {
  506. IVideoDecoder *decoder = factory->CreateVideoDecoder(w, h, framerate, type, flip);
  507. sf->releaseInterface(factory);
  508. if (decoder)
  509. return decoder;
  510. }
  511. }
  512. return 0;
  513. }
  514. IAudioDecoder *CreateAudioDecoder(unsigned int type, int *wasNotNull, IAudioOutput **output)
  515. {
  516. IAudioDecoder *a=NULL;
  517. if (mod.service && !a)
  518. a = CreateAudioDecoderWasabi(type, output);
  519. #ifdef BUILTIN_MP3_SUPPORT
  520. if (!a) a=MP3_CREATE(type);
  521. #endif
  522. #ifdef BUILTIN_PCM_SUPPORT
  523. if (!a && type == NSV_MAKETYPE('P','C','M',' ')) a=new PCMAudioDecoder;
  524. #endif
  525. #ifdef BUILTIN_AAC_SUPPORT
  526. extern IAudioDecoder *AAC_CREATE(unsigned int fmt, IAudioOutput **output);
  527. if (!a && (type == NSV_MAKETYPE('A','A','C',' ') || type == NSV_MAKETYPE('V','L','B',' '))) a=AAC_CREATE(type,NULL);
  528. #endif
  529. #ifdef BUILTIN_AACP_SUPPOT
  530. extern IAudioDecoder *AACP_CREATE(unsigned int fmt, IAudioOutput **output);
  531. if (!a && (type == NSV_MAKETYPE('A','A','C','P') || type == NSV_MAKETYPE('A','A','C',' '))) a=AAC_CREATE(type,NULL);
  532. #endif
  533. #ifdef DLL_DECODER_SUPPORT
  534. int x;
  535. for (x = 0; !a && x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && DLL_Handles[x]; x ++)
  536. {
  537. IAudioDecoder *(*cad)(unsigned int type, IAudioOutput **output);
  538. *((void**)&cad) = (void*)GetProcAddress(DLL_Handles[x],"CreateAudioDecoder");
  539. if (cad) a=cad(type,output);
  540. }
  541. #endif
  542. if (!a)
  543. {
  544. *wasNotNull=0;
  545. void *mem = WASABI_API_MEMMGR->sysMalloc(sizeof(NullAudioDecoder));
  546. a = new (mem) NullAudioDecoder();
  547. }
  548. else *wasNotNull=1;
  549. return a;
  550. }
  551. IVideoDecoder *CreateVideoDecoder(int w, int h, double framerate, unsigned int type, int *flip, int *wasNotNull)
  552. {
  553. IVideoDecoder *v=NULL;
  554. if (mod.service && !v)
  555. v = CreateVideoDecoderWasabi(w, h, framerate, type, flip);
  556. #ifdef BUILTIN_DIVX_SUPPORT
  557. if (!v) v=DIVX_CREATE(w,h,framerate,type,flip);
  558. #endif
  559. #ifdef BUILTIN_VP3_SUPPORT
  560. if (!v) v=VP3_CREATE(w,h,framerate,type,flip);
  561. #endif
  562. #ifdef BUILTIN_VP5_SUPPORT
  563. if (!v) v=VP5_CREATE(w,h,framerate,type,flip);
  564. #endif
  565. #ifdef BUILTIN_VP6_SUPPORT
  566. extern IVideoDecoder *VP6_CREATE(int w, int h, double framerate, unsigned int fmt, int *flip);
  567. if (!v) v=VP6_CREATE(w,h,framerate,type,flip);
  568. #endif
  569. #ifdef DLL_DECODER_SUPPORT
  570. int x;
  571. for (x = 0; !v && x < sizeof(DLL_Handles)/sizeof(DLL_Handles[0]) && DLL_Handles[x]; x ++)
  572. {
  573. IVideoDecoder *(*cvd)(int w, int h, double framerate, unsigned int type, int *flip);
  574. *((void**)&cvd) = (void*)GetProcAddress(DLL_Handles[x],"CreateVideoDecoder");
  575. if (cvd) v=cvd(w,h,framerate,type,flip);
  576. }
  577. #endif
  578. #ifdef BUILTIN_VFW_SUPPORT
  579. if (!v)
  580. {
  581. v=createVfw(w,h,framerate,type,flip);
  582. }
  583. #endif
  584. if (!v)
  585. {
  586. if (wasNotNull) *wasNotNull=0;
  587. void *mem = WASABI_API_MEMMGR->sysMalloc(sizeof(NullVideoDecoder));
  588. v = new (mem) NullVideoDecoder();
  589. }
  590. else if (wasNotNull) *wasNotNull=1;
  591. return v;
  592. }