CPI_Stream_Internet.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:7k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "globals.h"
  3. #include "CPI_Stream.h"
  4. #include "CPI_CircleBuffer.h"
  5. #include "CPI_Player_Messages.h"
  6. #define CIC_STREAMBUFFERSIZE 0x40000
  7. #define CIC_PREBUFFERAMOUNT 0x8000
  8. #define CIC_READCHUNKSIZE 0x1000
  9. typedef struct _CPs_BufferFillerContext
  10. {
  11.     char* m_pcFlexiURL;
  12.     CPs_CircleBuffer* m_pCircleBuffer;
  13.     BOOL m_bTerminate;
  14.     HWND m_hWndNotify;
  15. } CPs_BufferFillerContext;
  16. typedef struct _CPs_InStream_Internet
  17. {
  18.     CPs_CircleBuffer* m_pCircleBuffer;
  19.     HANDLE m_hFillerThread;
  20.     CPs_BufferFillerContext* m_pBufferFillContext;
  21. } CPs_InStream_Internet;
  22. void CPSINET_Uninitialise(CPs_InStream* pStream);
  23. BOOL CPSINET_Read(CPs_InStream* pStream, void* pDestBuffer, const unsigned int iBytesToRead, unsigned int* piBytesRead);
  24. void CPSINET_Seek(CPs_InStream* pStream, const unsigned int iNewOffset);
  25. UINT CPSINET_Tell(CPs_InStream* pStream);
  26. UINT CPSINET_GetLength(CPs_InStream* pStream);
  27. BOOL CPSINET_IsSeekable(CPs_InStream* pStream);
  28. ////////////////////////////////////////////////////////////////////////////////
  29. unsigned int _stdcall EP_FillerThread(void* _pContext)
  30. {
  31.     CPs_BufferFillerContext* pContext = (CPs_BufferFillerContext*)_pContext;
  32.     HINTERNET hInternet;
  33.     HINTERNET hURLStream;
  34.     DWORD dwTimeout;
  35.     BOOL bStreamComplete = FALSE;
  36.     INTERNET_BUFFERS internetbuffer;
  37.     BYTE bReadBuffer[CIC_READCHUNKSIZE];
  38.     CP_CHECKOBJECT(pContext);
  39.     PostMessage(pContext->m_hWndNotify, CPNM_SETSTREAMINGSTATE, (WPARAM)TRUE, (LPARAM)0);
  40.     hInternet = InternetOpen( "CoolPlayer",
  41.                               INTERNET_OPEN_TYPE_PRECONFIG,
  42.                               NULL, NULL, 0L);
  43.     if(hInternet == NULL)
  44.     {
  45.         pContext->m_pCircleBuffer->SetComplete(pContext->m_pCircleBuffer);
  46.         CP_TRACE0("EP_FillerThread::NoInternetOpen");
  47.         return 0;
  48.     }
  49.     dwTimeout = 2000;
  50.     InternetSetOption(hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &dwTimeout, sizeof(dwTimeout));
  51.     hURLStream = InternetOpenUrl( hInternet,
  52.                                   pContext->m_pcFlexiURL,
  53.                                   NULL,
  54.                                   0,
  55.                                   INTERNET_FLAG_NO_CACHE_WRITE
  56.                                   | INTERNET_FLAG_PRAGMA_NOCACHE,
  57.                                   0);
  58.     if(hURLStream == NULL)
  59.     {
  60.         InternetCloseHandle(hInternet);
  61.         pContext->m_pCircleBuffer->SetComplete(pContext->m_pCircleBuffer);
  62.         CP_TRACE1("EP_FillerThread::NoOpenURL %s",pContext->m_pcFlexiURL);
  63.         return 0;
  64.     }
  65.     internetbuffer.dwStructSize = sizeof(internetbuffer);
  66.     internetbuffer.Next = NULL;
  67.     internetbuffer.lpcszHeader = NULL;
  68.     internetbuffer.lpvBuffer = bReadBuffer;
  69.     internetbuffer.dwBufferLength = CIC_READCHUNKSIZE;
  70.     while(pContext->m_bTerminate == FALSE && bStreamComplete == FALSE)
  71.     {
  72.         BOOL bReadResult;
  73.         if(pContext->m_pCircleBuffer->GetFreeSize(pContext->m_pCircleBuffer) < CIC_READCHUNKSIZE)
  74.         {
  75.             Sleep(20);
  76.             continue;
  77.         }
  78.         internetbuffer.dwBufferLength = CIC_READCHUNKSIZE;
  79.         bReadResult = InternetReadFileEx(hURLStream, &internetbuffer, IRF_NO_WAIT, 0);
  80.         if(bReadResult == FALSE)
  81.             bStreamComplete = TRUE;
  82.         if(internetbuffer.dwBufferLength)
  83.         {
  84.             pContext->m_pCircleBuffer->Write( pContext->m_pCircleBuffer,
  85.                                               internetbuffer.lpvBuffer,
  86.                                               internetbuffer.dwBufferLength);
  87.             PostMessage( pContext->m_hWndNotify,
  88.                          CPNM_SETSTREAMINGSTATE,
  89.                          (WPARAM)TRUE,
  90.                          (LPARAM)(pContext->m_pCircleBuffer->GetUsedSize(pContext->m_pCircleBuffer)*100)/CIC_STREAMBUFFERSIZE);
  91.         }
  92.         else
  93.             Sleep(20);
  94.     }
  95.     InternetCloseHandle(hURLStream);
  96.     InternetCloseHandle(hInternet);
  97.     pContext->m_pCircleBuffer->SetComplete(pContext->m_pCircleBuffer);
  98.     PostMessage(pContext->m_hWndNotify, CPNM_SETSTREAMINGSTATE, (WPARAM)FALSE, (LPARAM)0);
  99.     CP_TRACE0("EP_FillerThread normal shutdown");
  100.     return 0;
  101. }
  102. //
  103. CPs_InStream* CP_CreateInStream_Internet(const char* pcFlexiURL, HWND hWndOwner)
  104. {
  105.     CPs_InStream* pNewStream;
  106.     CPs_InStream_Internet* pContext;
  107.     unsigned int iUsedSpace;
  108.     {
  109.         pNewStream = (CPs_InStream*)malloc(sizeof(CPs_InStream));
  110.         pContext = (CPs_InStream_Internet*)malloc(sizeof(CPs_InStream_Internet));
  111.         pNewStream->Uninitialise = CPSINET_Uninitialise;
  112.         pNewStream->Read = CPSINET_Read;
  113.         pNewStream->Seek = CPSINET_Seek;
  114.         pNewStream->GetLength = CPSINET_GetLength;
  115.         pNewStream->IsSeekable = CPSINET_IsSeekable;
  116.         pNewStream->m_pModuleCookie = pContext;
  117.         pContext->m_pCircleBuffer = CP_CreateCircleBuffer(CIC_STREAMBUFFERSIZE);
  118.     }
  119.     {
  120.         CPs_BufferFillerContext* pBufferFillContext;
  121.         UINT uiThreadID;
  122.         pBufferFillContext = (CPs_BufferFillerContext*)malloc(sizeof(CPs_BufferFillerContext));
  123.         pBufferFillContext->m_pCircleBuffer = pContext->m_pCircleBuffer;
  124.         pBufferFillContext->m_bTerminate = FALSE;
  125.         STR_AllocSetString(&pBufferFillContext->m_pcFlexiURL, pcFlexiURL, FALSE);
  126.         pBufferFillContext->m_hWndNotify = hWndOwner;
  127.         pContext->m_hFillerThread = (HANDLE)_beginthreadex(NULL, 0, EP_FillerThread, pBufferFillContext, 0, &uiThreadID);
  128.         pContext->m_pBufferFillContext = pBufferFillContext;
  129.     }
  130.     do
  131.     {
  132.         MSG msg;
  133.         BOOL bMessageReceived;
  134.         if(pContext->m_pCircleBuffer->IsComplete(pContext->m_pCircleBuffer))
  135.             break;
  136.         Sleep(100);
  137.         iUsedSpace = pContext->m_pCircleBuffer->GetUsedSize(pContext->m_pCircleBuffer);
  138.         bMessageReceived = PeekMessage(&msg, NULL, CPTM_STOP, CPTM_STOP, PM_NOREMOVE);
  139.         if(bMessageReceived)
  140.             break;
  141.     }
  142.     while(iUsedSpace < CIC_PREBUFFERAMOUNT);
  143.     return pNewStream;
  144. }
  145. //
  146. void CPSINET_Uninitialise(CPs_InStream* pStream)
  147. {
  148.     CPs_InStream_Internet* pContext = (CPs_InStream_Internet*)pStream->m_pModuleCookie;
  149.     CP_CHECKOBJECT(pContext);
  150.     pContext->m_pBufferFillContext->m_bTerminate = TRUE;
  151.     WaitForSingleObject(pContext->m_hFillerThread, INFINITE);
  152.     CloseHandle(pContext->m_hFillerThread);
  153.     free(pContext->m_pBufferFillContext->m_pcFlexiURL);
  154.     free(pContext->m_pBufferFillContext);
  155.     pContext->m_pCircleBuffer->Uninitialise(pContext->m_pCircleBuffer);
  156.     free(pContext);
  157.     free(pStream);
  158. }
  159. //
  160. BOOL CPSINET_Read(CPs_InStream* pStream, void* pDestBuffer, const unsigned int iBytesToRead, unsigned int* piBytesRead)
  161. {
  162.     CPs_InStream_Internet* pContext = (CPs_InStream_Internet*)pStream->m_pModuleCookie;
  163.     CP_CHECKOBJECT(pContext);
  164.     return pContext->m_pCircleBuffer->Read(pContext->m_pCircleBuffer, pDestBuffer, iBytesToRead, piBytesRead);
  165. }
  166. //
  167. void CPSINET_Seek(CPs_InStream* pStream, const unsigned int iNewOffset)
  168. {
  169.     CPs_InStream_Internet* pContext = (CPs_InStream_Internet*)pStream->m_pModuleCookie;
  170.     CP_CHECKOBJECT(pContext);
  171. }
  172. //
  173. unsigned int CPSINET_GetLength(CPs_InStream* pStream)
  174. {
  175.     CPs_InStream_Internet* pContext = (CPs_InStream_Internet*)pStream->m_pModuleCookie;
  176.     CP_CHECKOBJECT(pContext);
  177.     return 0;
  178. }
  179. //
  180. BOOL CPSINET_IsSeekable(CPs_InStream* pStream)
  181. {
  182.     return FALSE;
  183. }
  184. UINT CPSINET_Tell(CPs_InStream* pStream)
  185. {
  186. return 0;
  187. }