info.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #include "main.h"
  2. #include "resource.h"
  3. //#include <qedit.h>
  4. #include "header_asf.h"
  5. #include "header_avi.h"
  6. #include "header_mpg.h"
  7. #include "header_wav.h"
  8. #include "../nu/AutoChar.h"
  9. #include "../Agave/Language/api_language.h"
  10. #include <strsafe.h>
  11. static const wchar_t *m_fn;
  12. extern const wchar_t *extension(const wchar_t *fn);
  13. extern wchar_t m_lastfn[];
  14. extern unsigned int m_nbframes;
  15. extern DWORD m_avgfps_start;
  16. static __int64 FileSize64(HANDLE file)
  17. {
  18. LARGE_INTEGER position;
  19. position.QuadPart=0;
  20. position.LowPart = GetFileSize(file, (LPDWORD)&position.HighPart);
  21. if (position.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
  22. return INVALID_FILE_SIZE;
  23. else
  24. return position.QuadPart;
  25. }
  26. int GetFileLength(const wchar_t *filename);
  27. void getInfo(const wchar_t *fn, wchar_t *linetext, int linetextCch, wchar_t *fulltext, int fulltextCch, int *bitrate, int *channel)
  28. {
  29. wchar_t tmp[512] = {0, };
  30. wchar_t tmpline[512] = {0, };
  31. int br = 0;
  32. const wchar_t *ext = extension(fn);
  33. __int64 size = 0;
  34. HANDLE hFile = CreateFileW(fn, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
  35. if (hFile != INVALID_HANDLE_VALUE)
  36. {
  37. size = FileSize64(hFile);
  38. CloseHandle(hFile);
  39. }
  40. int l = GetFileLength(fn);
  41. wchar_t *pTmpLine = tmpline, *pTmp = tmp;
  42. size_t pTmpLineSize = 512, pTmpSize = 512;
  43. if (!_wcsicmp(ext, L"asf") || !_wcsicmp(ext, L"wmv") || !_wcsicmp(ext, L"wma"))
  44. {
  45. HeaderAsf ha;
  46. if (ha.getInfos(fn))
  47. {
  48. StringCchCopyExW(pTmpLine, pTmpLineSize, L"DShow (WMV): ", &pTmpLine, &pTmpLineSize, 0);
  49. if (ha.has_video)
  50. {
  51. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_VIDEO_SIZE), ha.video_w, ha.video_h);
  52. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_VIDEO), ha.video_w, ha.video_h);
  53. }
  54. /* benski> cut
  55. if (ha.has_audio)
  56. {
  57. char type[16] = {0};
  58. StringCchPrintfEx(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRING(IDS_AUDIO), ha.audio_srate, ha.audio_bps, ha.audio_nch);
  59. StringCchPrintfEx(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRING(IDS_AUDIO_S), ha.audio_srate / 1000, ha.audio_bps, WASABI_API_LNGSTRING_BUF((ha.audio_nch == 2 ? IDS_STEREO : IDS_MONO),type,16));
  60. }
  61. int l = ha.length / 1000;
  62. */
  63. }
  64. }
  65. else if (!_wcsicmp(ext, L"avi") || !_wcsicmp(ext, L"divx"))
  66. {
  67. HeaderAvi ha;
  68. if (ha.getInfos(fn))
  69. {
  70. StringCchCopyExW(pTmpLine, pTmpLineSize, L"DShow (AVI): ", &pTmpLine, &pTmpLineSize, 0);
  71. if (ha.has_video)
  72. {
  73. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_VIDEO_SIZE), ha.video_w, ha.video_h);
  74. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_VIDEO), ha.video_w, ha.video_h);
  75. }
  76. if (ha.has_audio)
  77. {
  78. wchar_t type[16] = {0};
  79. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_AUDIO), ha.audio_srate, ha.audio_bps, ha.audio_nch);
  80. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_AUDIO_S), ha.audio_srate / 1000, ha.audio_bps, WASABI_API_LNGSTRINGW_BUF((ha.audio_nch == 2 ? IDS_STEREO : IDS_MONO),type,16));
  81. }
  82. /* benski> cut
  83. int l = ha.length / 1000;
  84. if (l)
  85. {
  86. br = (int)(((double)size * 8 / 1000) / l);
  87. StringCchPrintfEx(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRING(IDS_LENGTH), l / 3600, (l / 60) % 60, l % 60, br);
  88. StringCchPrintfEx(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRING(IDS_DURATION), l / 3600, (l / 60) % 60, l % 60, br);
  89. }
  90. */
  91. }
  92. if (channel)
  93. {
  94. *channel = ha.audio_nch;
  95. }
  96. }
  97. else if (!_wcsicmp(ext, L"mpg") || !_wcsicmp(ext, L"mpeg"))
  98. {
  99. HeaderMpg ha;
  100. if (ha.getInfos(fn))
  101. {
  102. StringCchCopyExW(pTmpLine, pTmpLineSize, L"DShow (MPEG): ", &pTmpLine, &pTmpLineSize, 0);
  103. if (ha.has_video)
  104. {
  105. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_VIDEO_SIZE_KBPS), ha.video_w, ha.video_h, ha.video_bitrate / 1000);
  106. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_VIDEO_KBPS), ha.video_w, ha.video_h, ha.video_bitrate / 1000);
  107. }
  108. if (ha.has_audio)
  109. {
  110. wchar_t type[16] = {0};
  111. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_AUDIO_KBPS), ha.audio_srate, ha.audio_bps, ha.audio_nch, ha.audio_bitrate / 1000);
  112. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_AUDIO_S), ha.audio_srate / 1000, ha.audio_bps, WASABI_API_LNGSTRINGW_BUF((ha.audio_nch == 2 ? IDS_STEREO : IDS_MONO),type,16), ha.audio_bitrate / 1000);
  113. }
  114. /* benski> cut
  115. int l = ha.length / 1000;
  116. if (l)
  117. {
  118. br = (int)(((double)size * 8 / 1000) / l);
  119. StringCchPrintfEx(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRING(IDS_LENGTH), l / 3600, (l / 60) % 60, l % 60, br);
  120. StringCchPrintfEx(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRING(IDS_DURATION), l / 3600, (l / 60) % 60, l % 60, br);
  121. }
  122. */
  123. }
  124. }
  125. else if (!_wcsicmp(ext, L"wav"))
  126. {
  127. HeaderWav ha;
  128. if (ha.getInfos(fn))
  129. {
  130. StringCchCopyExW(pTmpLine, pTmpLineSize, L"DShow (WAV): ", &pTmpLine, &pTmpLineSize, 0);
  131. if (ha.has_audio)
  132. {
  133. char type[16] = {0};
  134. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_AUDIO_CH), ha.audio_srate, ha.audio_bps, ha.audio_nch);
  135. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_AUDIO_S), ha.audio_srate / 1000, ha.audio_bps, WASABI_API_LNGSTRING_BUF((ha.audio_nch == 2 ? IDS_STEREO : IDS_MONO),type,16));
  136. }
  137. /* benski> cut
  138. int l = ha.length / 1000;
  139. if (l)
  140. {
  141. br = (int)(((double)size * 8 / 1000) / l);
  142. StringCchPrintfEx(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRING(IDS_LENGTH), l / 3600, (l / 60) % 60, l % 60, br);
  143. StringCchPrintfEx(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRING(IDS_DURATION), l / 3600, (l / 60) % 60, l % 60, br);
  144. }
  145. else
  146. br = MulDiv(ha.audio_bps*ha.audio_nch, ha.audio_srate, 1000);
  147. */
  148. }
  149. }
  150. if (l != -1000)
  151. {
  152. br = (int)(((double)size * 8.0) / l);
  153. l/=1000;
  154. StringCchPrintfExW(pTmp, pTmpSize, &pTmp, &pTmpSize, 0, WASABI_API_LNGSTRINGW(IDS_LENGTH), l / 3600, (l / 60) % 60, l % 60, br);
  155. StringCchPrintfExW(pTmpLine, pTmpLineSize, &pTmpLine, &pTmpLineSize, 0, WASABI_API_LNGSTRINGW(IDS_DURATION), l / 3600, (l / 60) % 60, l % 60, br);
  156. }
  157. if (linetext)
  158. lstrcpynW(linetext, tmpline, linetextCch);
  159. if (fulltext)
  160. lstrcpynW(fulltext, tmp, fulltextCch);
  161. if (bitrate)
  162. *bitrate = br;
  163. }
  164. INT_PTR CALLBACK infoProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  165. {
  166. switch (uMsg)
  167. {
  168. case WM_INITDIALOG:
  169. SetDlgItemTextW(hwndDlg, IDC_FILENAME, m_fn);
  170. SetDlgItemTextW(hwndDlg, IDC_INFO, WASABI_API_LNGSTRINGW(IDS_NO_AVAILABLE_INFO));
  171. SetDlgItemTextW(hwndDlg, IDC_FPS, L"");
  172. {
  173. wchar_t text[512] = {0};
  174. getInfo(m_fn, NULL, 0, text, 512, NULL, NULL);
  175. SetDlgItemTextW(hwndDlg, IDC_INFO, text);
  176. }
  177. if (!_wcsicmp(m_fn, m_lastfn) && pGraphBuilder)
  178. {
  179. CComPtr<IEnumFilters> pEnumFilters;
  180. pGraphBuilder->EnumFilters(&pEnumFilters);
  181. if (!pEnumFilters) break;
  182. pEnumFilters->Reset();
  183. do
  184. {
  185. ULONG nfetched = 0;
  186. CComPtr<IBaseFilter> pFilter;
  187. pEnumFilters->Next(1, &pFilter, &nfetched);
  188. if (!nfetched)
  189. break;
  190. FILTER_INFO fi;
  191. pFilter->QueryFilterInfo(&fi);
  192. if (!_wcsicmp(fi.achName, L"Null Audio")
  193. || !_wcsicmp(fi.achName, L"Null Video")
  194. || !_wcsicmp(fi.achName, m_fn))
  195. {
  196. if (fi.pGraph)
  197. fi.pGraph->Release();
  198. continue;
  199. }
  200. LRESULT a = SendDlgItemMessageW(hwndDlg, IDC_FILTERLIST, LB_ADDSTRING, 0, (LPARAM)fi.achName);
  201. SendDlgItemMessage(hwndDlg, IDC_FILTERLIST, LB_SETITEMDATA, a, (LPARAM)(IBaseFilter *)pFilter); //FUCKO: if playback changes
  202. if (fi.pGraph)
  203. fi.pGraph->Release();
  204. }
  205. while (1);
  206. SendMessage(hwndDlg, WM_TIMER, 0x123, 0);
  207. SetTimer(hwndDlg, 0x123, 500, NULL);
  208. }
  209. return TRUE;
  210. case WM_COMMAND:
  211. switch (LOWORD(wParam))
  212. {
  213. case IDC_FILTERLIST:
  214. if (HIWORD(wParam) == LBN_DBLCLK)
  215. {
  216. LRESULT sel = SendDlgItemMessage(hwndDlg, IDC_FILTERLIST, LB_GETCURSEL, 0, 0);
  217. if (sel == LB_ERR) break;
  218. CComPtr<IBaseFilter> pFilter;
  219. pFilter = (IBaseFilter *)SendDlgItemMessage(hwndDlg, IDC_FILTERLIST, LB_GETITEMDATA, sel, 0);
  220. CComQIPtr<ISpecifyPropertyPages> pSPP(pFilter);
  221. if (!pSPP) break;
  222. CAUUID pages;
  223. pSPP->GetPages(&pages);
  224. IBaseFilter *f = pFilter;
  225. OleCreatePropertyFrame(
  226. hwndDlg, 30, 30, NULL,
  227. 1, (IUnknown**)&f,
  228. pages.cElems, pages.pElems,
  229. 0, 0, NULL);
  230. CoTaskMemFree(pages.pElems);
  231. }
  232. break;
  233. case IDOK:
  234. case IDCANCEL:
  235. EndDialog(hwndDlg, 0);
  236. break;
  237. }
  238. break;
  239. case WM_TIMER:
  240. if (wParam == 0x123 && pGraphBuilder && !_wcsicmp(m_fn, m_lastfn))
  241. {
  242. DWORD t = GetTickCount() - m_avgfps_start;
  243. if (t)
  244. {
  245. wchar_t tmp[512] = {0};
  246. StringCchPrintfW(tmp, 512, WASABI_API_LNGSTRINGW(IDS_AVERAGE_FPS), (double)m_nbframes*1000 / t);
  247. SetDlgItemTextW(hwndDlg, IDC_FPS, tmp);
  248. }
  249. }
  250. break;
  251. }
  252. return FALSE;
  253. }
  254. void doInfo(HINSTANCE hInstance, HWND hwndParent, const wchar_t *fn)
  255. {
  256. static int running;
  257. if (running) return ;
  258. running = 1;
  259. m_fn = fn;
  260. WASABI_API_DIALOGBOXW(IDD_FILEINFO, hwndParent, infoProc);
  261. running = 0;
  262. }