main.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. #include "main.h"
  2. #include "../winamp/wa_ipc.h"
  3. #include "api__in_avi.h"
  4. #include "../nsavi/nsavi.h"
  5. #include "win32_avi_reader.h"
  6. #include "resource.h"
  7. #include <strsafe.h>
  8. #define AVI_PLUGIN_VERSION L"0.78"
  9. // {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
  10. static const GUID playbackConfigGroupGUID =
  11. { 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
  12. void SetFileExtensions(void)
  13. {
  14. static char fileExtensionsString[256] = {0}; // "AVI\0Audio/Video Interleave (AVI)\0"
  15. char* end = 0;
  16. size_t remaining = 0;
  17. StringCchCopyExA(fileExtensionsString, 256, "AVI", &end, &remaining, 0);
  18. StringCchCopyExA(end+1, remaining-1, WASABI_API_LNGSTRING(IDS_AVI_DESC), 0, 0, 0);
  19. plugin.FileExtensions = fileExtensionsString;
  20. }
  21. HANDLE killswitch = 0, seek_event = 0;
  22. volatile LONG seek_position=-1;
  23. int g_duration = -1;
  24. nu::VideoClock video_clock;
  25. int paused = 0;
  26. static HANDLE play_thread = 0;
  27. int video_only=0;
  28. In_Module *dshow_mod = 0;
  29. HMODULE in_dshow=0;
  30. wchar_t pluginName[256] = {0};
  31. static int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
  32. {
  33. MSGBOXPARAMS msgbx = {sizeof(MSGBOXPARAMS),0};
  34. msgbx.lpszText = message;
  35. msgbx.lpszCaption = title;
  36. msgbx.lpszIcon = MAKEINTRESOURCE(102);
  37. msgbx.hInstance = GetModuleHandle(0);
  38. msgbx.dwStyle = MB_USERICON;
  39. msgbx.hwndOwner = parent;
  40. return MessageBoxIndirect(&msgbx);
  41. }
  42. void About(HWND hwndParent)
  43. {
  44. wchar_t message[1024] = {0}, text[1024] = {0};
  45. WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_AVI_OLD,text,1024);
  46. StringCchPrintf(message, 1024, WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
  47. plugin.description, TEXT(__DATE__));
  48. DoAboutMessageBox(hwndParent,text,message);
  49. }
  50. int Init()
  51. {
  52. if (!IsWindow(plugin.hMainWindow))
  53. return IN_INIT_FAILURE;
  54. WasabiInit();
  55. StringCchPrintfW(pluginName, ARRAYSIZE(pluginName),
  56. WASABI_API_LNGSTRINGW(IDS_NULLSOFT_AVI), AVI_PLUGIN_VERSION);
  57. plugin.description = (char*)pluginName;
  58. SetFileExtensions();
  59. return IN_INIT_SUCCESS;
  60. }
  61. void Quit()
  62. {
  63. WasabiQuit();
  64. if (in_dshow)
  65. {
  66. FreeLibrary(in_dshow);
  67. in_dshow = NULL;
  68. }
  69. }
  70. void GetFileInfo(const wchar_t *file, wchar_t *title, int *length_in_ms)
  71. {
  72. if (title)
  73. *title=0;
  74. if (length_in_ms)
  75. {
  76. if (file && *file)
  77. {
  78. *length_in_ms = -1000; // fallback if anything fails
  79. AVIReaderWin32 reader;
  80. if (reader.Open(file) == nsavi::READ_OK)
  81. {
  82. nsavi::Duration duration(&reader);
  83. duration.GetDuration(length_in_ms);
  84. reader.Close();
  85. }
  86. }
  87. else
  88. {
  89. if (dshow_mod)
  90. {
  91. dshow_mod->GetFileInfo(file, title, length_in_ms);
  92. }
  93. else
  94. {
  95. *length_in_ms=g_duration;
  96. }
  97. }
  98. }
  99. }
  100. int InfoBox(const wchar_t *file, HWND hwndParent)
  101. {
  102. AVIReaderWin32 reader;
  103. if (reader.Open(file) == nsavi::READ_OK)
  104. {
  105. nsavi::Metadata metadata(&reader);
  106. uint32_t type;
  107. if (metadata.GetRIFFType(&type) == nsavi::READ_OK && type == ' IVA')
  108. {
  109. WASABI_API_DIALOGBOXPARAMW(IDD_INFODIALOG, hwndParent, InfoDialog, (LPARAM)&metadata);
  110. }
  111. reader.Close();
  112. }
  113. return INFOBOX_UNCHANGED;
  114. }
  115. int IsOurFile(const wchar_t *fn)
  116. {
  117. return 0;
  118. }
  119. int Play(const wchar_t *fn) // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
  120. {
  121. g_duration = -1;
  122. seek_position = -1;
  123. video_clock.Reset();
  124. video_only=false;
  125. paused=0;
  126. if (!killswitch)
  127. killswitch = CreateEvent(NULL, TRUE, FALSE, NULL);
  128. if (!seek_event)
  129. seek_event = CreateEvent(NULL, TRUE, FALSE, NULL);
  130. ResetEvent(killswitch);
  131. ResetEvent(seek_event);
  132. play_thread = CreateThread(0, 0, AVIPlayThread, _wcsdup(fn), 0, 0);
  133. SetThreadPriority(play_thread, (int)AGAVE_API_CONFIG->GetInt(playbackConfigGroupGUID, L"priority", THREAD_PRIORITY_HIGHEST));
  134. return 0; // success
  135. }
  136. void Pause()
  137. {
  138. paused = 1;
  139. if (dshow_mod)
  140. {
  141. dshow_mod->Pause();
  142. }
  143. else if (video_only)
  144. {
  145. video_clock.Pause();
  146. }
  147. else
  148. {
  149. plugin.outMod->Pause(1);
  150. }
  151. }
  152. void UnPause()
  153. {
  154. paused = 0;
  155. if (dshow_mod)
  156. {
  157. dshow_mod->UnPause();
  158. }
  159. else if (video_only)
  160. {
  161. video_clock.Unpause();
  162. }
  163. else
  164. {
  165. plugin.outMod->Pause(0);
  166. }
  167. }
  168. int IsPaused()
  169. {
  170. if (dshow_mod)
  171. return dshow_mod->IsPaused();
  172. return paused;
  173. }
  174. void Stop()
  175. {
  176. if (dshow_mod)
  177. {
  178. dshow_mod->Stop();
  179. dshow_mod=0;
  180. }
  181. else if (play_thread)
  182. {
  183. SetEvent(killswitch);
  184. WaitForSingleObject(play_thread, INFINITE);
  185. ResetEvent(killswitch);
  186. play_thread=0;
  187. }
  188. }
  189. // time stuff
  190. int GetLength()
  191. {
  192. if (dshow_mod)
  193. return dshow_mod->GetLength();
  194. else
  195. return g_duration;
  196. }
  197. int GetOutputTime()
  198. {
  199. if (dshow_mod)
  200. return dshow_mod->GetOutputTime();
  201. else if (video_only)
  202. return video_clock.GetOutputTime();
  203. if (plugin.outMod)
  204. return plugin.outMod->GetOutputTime();
  205. else
  206. return 0;
  207. }
  208. void SetOutputTime(int time_in_ms)
  209. {
  210. if (dshow_mod)
  211. {
  212. dshow_mod->SetOutputTime(time_in_ms);
  213. }
  214. else if (seek_event)
  215. {
  216. InterlockedExchange(&seek_position, time_in_ms);
  217. SetEvent(seek_event);
  218. }
  219. }
  220. void SetVolume(int volume)
  221. {
  222. if (dshow_mod)
  223. {
  224. dshow_mod->SetVolume(volume);
  225. }
  226. else
  227. {
  228. plugin.outMod->SetVolume(volume);
  229. }
  230. }
  231. void SetPan(int pan)
  232. {
  233. if (dshow_mod)
  234. {
  235. dshow_mod->SetPan(pan);
  236. }
  237. else
  238. {
  239. plugin.outMod->SetPan(pan);
  240. }
  241. }
  242. void EQSet(int on, char data[10], int preamp)
  243. {
  244. if (dshow_mod)
  245. {
  246. dshow_mod->EQSet(on, data, preamp);
  247. return;
  248. }
  249. }
  250. In_Module plugin =
  251. {
  252. IN_VER_RET,
  253. "nullsoft(in_avi.dll)",
  254. NULL, // hMainWindow
  255. NULL, // hDllInstance
  256. 0 /*"AVI\0Audio/Video Interleave (AVI)\0"*/,
  257. 1, // is seekable
  258. IN_MODULE_FLAG_USES_OUTPUT_PLUGIN, //UsesOutputPlug
  259. About,
  260. About,
  261. Init,
  262. Quit,
  263. GetFileInfo,
  264. InfoBox,
  265. IsOurFile,
  266. Play,
  267. Pause,
  268. UnPause,
  269. IsPaused,
  270. Stop,
  271. GetLength,
  272. GetOutputTime,
  273. SetOutputTime,
  274. SetVolume,
  275. SetPan,
  276. 0,
  277. 0,
  278. 0,
  279. 0,
  280. 0,
  281. 0,
  282. 0,
  283. 0,
  284. 0,
  285. 0,
  286. 0,
  287. EQSet,
  288. 0,
  289. 0
  290. };
  291. extern "C" __declspec(dllexport) In_Module * winampGetInModule2()
  292. {
  293. return &plugin;
  294. }