mp4process.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include "wmp4player.h"
  4. #include "mp4process.h"
  5. #include "our_msg_queue.h"
  6. static DWORD __stdcall c_receive_thread (LPVOID lpThreadParameter)
  7. {
  8. CMP4Process *mp4 = (CMP4Process *)lpThreadParameter;
  9. mp4->receive_thread();
  10. ExitThread(0);
  11. return 0;
  12. }
  13. CMP4Process::CMP4Process(CString &name)
  14. {
  15. init();
  16. start_process(name); 
  17. }
  18. CMP4Process::~CMP4Process(void)
  19. {
  20. m_terminating = 1;
  21. if (kill_process() == FALSE) {
  22. TerminateProcess(m_piProcInfo.hProcess, -1);
  23. }
  24. clean_up_process();
  25. }
  26. void CMP4Process::init(void)
  27. {
  28. m_terminating = 0;
  29. m_receive_thread = NULL;
  30. m_thread_created = FALSE;
  31. m_map_file_write = NULL;
  32. m_to_client_event = NULL;
  33. m_to_client_resp_event = NULL;
  34. m_from_client_event = NULL;
  35. m_from_client_resp_event = NULL;
  36. m_map_file = NULL;
  37. ZeroMemory(&m_piProcInfo, sizeof(m_piProcInfo));
  38. // Set up security attributes for all handles/files
  39. m_saAttr.nLength = sizeof(m_saAttr);
  40.     m_saAttr.bInheritHandle = TRUE;
  41.     m_saAttr.lpSecurityDescriptor = NULL;
  42. }
  43. BOOL CMP4Process::start_process (CString &name)
  44. {
  45. if (m_thread_created != FALSE) {
  46. return FALSE;
  47. }
  48.    ZeroMemory( &m_siStartInfo, sizeof(STARTUPINFO) );
  49.    m_siStartInfo.cb = sizeof(STARTUPINFO); 
  50. m_map_file = CreateFileMapping((HANDLE)0xFFFFFFFF,
  51.  NULL,
  52.  PAGE_READWRITE,
  53.  0,
  54.  2048,
  55.  "MP4ThreadToEventFileMap");
  56.  
  57. if (m_map_file == NULL) {
  58. OutputDebugString("Can't CreateFileMappingn");
  59. clean_up_process();
  60. return FALSE;
  61. }
  62. m_map_file_write = MapViewOfFile(m_map_file,
  63. FILE_MAP_ALL_ACCESS,
  64. 0, 0, 0);
  65. if (m_map_file_write == NULL) {
  66. OutputDebugString("Can't MapViewOfFile");
  67. clean_up_process();
  68. return FALSE;
  69. }
  70.    m_to_client_event = 
  71.    CreateEvent(&m_saAttr, FALSE, FALSE, "MP4GuiToClient");
  72.    m_from_client_event = 
  73.    CreateEvent(&m_saAttr, FALSE, FALSE, "MP4ClientToGui");
  74.    m_to_client_resp_event = 
  75.    CreateEvent(&m_saAttr, FALSE, FALSE, "MP4GuiToClientResp");
  76.    m_from_client_resp_event = 
  77.    CreateEvent(&m_saAttr, FALSE, FALSE, "MP4ClientToGuiResp");
  78.    m_stop_receive_thread = 0;
  79.    
  80.    m_receive_thread = CreateThread(NULL, 0, c_receive_thread, this, 
  81.    0, &m_receive_thread_id);
  82.    char buffer[512];
  83.    _snprintf(buffer, sizeof(buffer), "%swmp4client.exe "%s"", 
  84. #ifdef _DEBUG
  85.    "win_client\debug\", 
  86. #else
  87.    "",
  88. #endif
  89.    name);
  90.    m_thread_created = CreateProcess(
  91. #ifdef _DEBUG
  92.    "win_client\debug\wmp4client.exe", 
  93. #else
  94.    "wmp4client.exe",
  95. #endif
  96. buffer,       // command line 
  97. NULL,          // process security attributes 
  98. NULL,          // primary thread security attributes 
  99. TRUE,          // handles are inherited 
  100. 0,             // creation flags 
  101. NULL,          // use parent's environment 
  102. NULL,          // use parent's current directory 
  103. &m_siStartInfo,  // STARTUPINFO pointer 
  104. &m_piProcInfo);  // receives PROCESS_INFORMATION 
  105.    if (m_thread_created == FALSE) {
  106.    char buffer[512];
  107.    sprintf(buffer, "Thread error is %d", GetLastError());
  108.    AfxMessageBox(buffer);
  109.    }
  110.    return m_thread_created;
  111. }
  112. int CMP4Process::get_initial_response (msg_initial_resp_t *init_resp,
  113. CString &errmsg)
  114. {
  115. int ret;
  116. ret = WaitForSingleObject(m_to_client_resp_event, 30 * 1000);
  117. if (ret != WAIT_OBJECT_0) {
  118. errmsg = "No response from client process";
  119. } else {
  120. msg_mbox_t *pmbox = (msg_mbox_t *)m_map_file_write;
  121. memcpy(init_resp, 
  122.    pmbox->to_client_mbox, 
  123.    sizeof(msg_initial_resp_t));
  124. errmsg = ((char *)pmbox->to_client_mbox) + sizeof(msg_initial_resp_t);
  125. return pmbox->from_client_response;
  126. }
  127. return -1;
  128. }
  129. #define CLOSE_AND_CLEAR(a) if ((a) != NULL) { CloseHandle(a); (a) = NULL; }
  130. void CMP4Process::clean_up_process(void)
  131. {
  132. if (m_receive_thread != NULL) {
  133. m_stop_receive_thread = 1;
  134. SetEvent(m_from_client_event);
  135.         SetThreadPriority(m_receive_thread, THREAD_PRIORITY_HIGHEST); 
  136.         WaitForSingleObject(m_receive_thread, INFINITE);
  137. CloseHandle(m_receive_thread);
  138. m_receive_thread = NULL;
  139. }
  140.             
  141. if (m_thread_created) {
  142. CLOSE_AND_CLEAR(m_to_client_event);
  143. CLOSE_AND_CLEAR(m_to_client_resp_event);
  144. CLOSE_AND_CLEAR(m_from_client_event);
  145. CLOSE_AND_CLEAR(m_from_client_resp_event);
  146. CLOSE_AND_CLEAR(m_piProcInfo.hThread);
  147. CLOSE_AND_CLEAR(m_piProcInfo.hProcess);
  148. if (m_map_file_write != NULL) {
  149. UnmapViewOfFile(m_map_file_write);
  150. m_map_file_write = NULL;
  151. }
  152. CLOSE_AND_CLEAR(m_map_file);
  153. m_thread_created = FALSE;
  154. }
  155. }
  156. bool CMP4Process::send_message (unsigned __int32 message,
  157.    unsigned __int64 *retval,
  158.    const char *msg_body,
  159.    int msg_len)
  160. {
  161. msg_mbox_t *pmbox = (msg_mbox_t *)m_map_file_write;
  162. pmbox->to_client_command = message;
  163. if (msg_body != NULL) {
  164. memcpy(pmbox->to_client_mbox,
  165. msg_body,
  166. MIN(msg_len, MBOX_SIZE));
  167. }
  168. pmbox->from_client_response = MBOX_RESP_EMPTY;
  169. ResetEvent(m_to_client_resp_event);
  170. SetEvent(m_to_client_event);
  171. // Now wait for response.
  172. WaitForSingleObject(m_to_client_resp_event, 2 * 1000);
  173. if (pmbox->from_client_response != MBOX_RESP_EMPTY) {
  174. if (retval != NULL) *retval = pmbox->from_client_response;
  175. return (TRUE);
  176. }
  177. return (FALSE);
  178. }
  179. bool CMP4Process::kill_process (void)
  180. {
  181. bool ret;
  182. DWORD timeout;
  183. unsigned __int64 ret_from_client;
  184. if (m_thread_created == FALSE) 
  185. return TRUE;
  186. ret = send_message(CLIENT_MSG_TERMINATE, &ret_from_client);
  187. if (ret == FALSE) {
  188. return FALSE;
  189. }
  190. timeout = WaitForSingleObject(m_piProcInfo.hProcess, 10 * 1000);
  191. if (timeout != WAIT_OBJECT_0) {
  192. OutputDebugString("Process didn't terminaten");
  193. return FALSE;
  194. }
  195. clean_up_process();
  196. return TRUE;
  197. }
  198. void CMP4Process::receive_thread (void)
  199. {
  200. HANDLE wait_handle[2];
  201. int ret;
  202. msg_mbox_t *pmbox = (msg_mbox_t *)m_map_file_write;
  203. while (m_stop_receive_thread == 0) {
  204. wait_handle[0] = m_from_client_event;
  205. wait_handle[1] = m_piProcInfo.hProcess;
  206. ret = WaitForMultipleObjects(2,
  207.  wait_handle,
  208.  FALSE,
  209.  INFINITE);
  210. switch (ret) {
  211. case WAIT_OBJECT_0:
  212. // This sends messages to theApp
  213. char buffer[80];
  214. sprintf(buffer, "Received Message %x from clientn", 
  215. pmbox->to_gui_command);
  216. OutputDebugString(buffer);
  217. switch (pmbox->to_gui_command) {
  218. case GUI_MSG_RECEIVED_QUIT:
  219. // Don't use this - release version crashes.
  220. //theApp.PostThreadMessage(WM_CLOSED_SESSION, 0, 0);
  221. theApp.m_pMainWnd->PostMessage(WM_CLOSED_SESSION);
  222. break;
  223. case GUI_MSG_SDL_KEY:
  224. const sdl_event_msg_t *ptr;
  225. ptr = (const sdl_event_msg_t *)pmbox->to_gui_mbox;
  226. ((CFrameWnd*) AfxGetApp()->m_pMainWnd)->GetActiveView()->PostMessage(WM_SDL_KEY,
  227. ptr->sym, ptr->mod);
  228. default:
  229. //theApp.PostThreadMessage(WM_USER, 0, 0);
  230. break;
  231. }
  232. pmbox->to_gui_command = BLANK_MSG;
  233. SetEvent(m_from_client_resp_event);
  234. break;
  235. case WAIT_OBJECT_0 + 1:
  236. if (m_terminating == 0)
  237. theApp.m_pMainWnd->PostMessage(WM_SESSION_DIED);
  238. break;
  239. default:
  240. TRACE1("Illegal code %d received in receive threadn", 
  241.     ret);
  242. break;
  243. }
  244. #if 0
  245. ((CFrameWnd*) AfxGetApp()->m_pMainWnd)->GetActiveView()->PostMessage(WM_CLOSED_SESSION); // This sends messages to MainFrm
  246. if (!theApp.m_pMainWnd->PostMessage(WM_USER)) {
  247. DWORD error = GetLastError();
  248. TRACE1("Can't post message - error %dn", error);
  249. }
  250. #endif
  251. }
  252. OutputDebugString("Exiting process receive threadn");
  253. ExitThread(0);
  254. }