Index: source/mpiptvsource.cpp
===================================================================
--- source/mpiptvsource.cpp	(revision 25271)
+++ source/mpiptvsource.cpp	(working copy)
@@ -23,75 +23,25 @@
 //
 #pragma warning(disable : 4996)
 #include <windows.h>
+#include <winbase.h>
 #include <stdio.h>
 #include <shlobj.h>
 #include "mpiptvsource.h"
 
-//#define logging
-
-#ifdef logging
-static char logFile[MAX_PATH];
-static WORD logFileParsed = -1;
-
-void GetLogFile(char *pLog)
-{
-  SYSTEMTIME systemTime;
-  GetLocalTime(&systemTime);
-  if(logFileParsed != systemTime.wDay)
-  {
-    TCHAR folder[MAX_PATH];
-    ::SHGetSpecialFolderPath(NULL,folder,CSIDL_COMMON_APPDATA,FALSE);
-    sprintf(logFile,"%s\\Team MediaPortal\\MediaPortal TV Server\\log\\MPIPTVSource-%04.4d-%02.2d-%02.2d.Log",folder, systemTime.wYear, systemTime.wMonth, systemTime.wDay);
-    logFileParsed=systemTime.wDay; // rec
-  }
-  strcpy(pLog, &logFile[0]);
-}
-
-void LogDebug(const char *fmt, ...)
-{
-  va_list ap;
-  va_start(ap,fmt);
-
-  char buffer[1000];
-  int tmp;
-  va_start(ap,fmt);
-  tmp=vsprintf(buffer, fmt, ap);
-  va_end(ap);
-  SYSTEMTIME systemTime;
-  GetLocalTime(&systemTime);
-
-  TCHAR filename[1024];
-  GetLogFile(filename);
-  FILE* fp = fopen(filename,"a+");
-
-  if (fp!=NULL)
-  {
-    fprintf(fp,"%02.2d-%02.2d-%04.4d %02.2d:%02.2d:%02.2d.%03.3d [%x]%s\n",
-      systemTime.wDay, systemTime.wMonth, systemTime.wYear,
-      systemTime.wHour,systemTime.wMinute,systemTime.wSecond,
-      systemTime.wMilliseconds,
-      GetCurrentThreadId(),
-      buffer);
-    fclose(fp);
-  }
-  char buf[1000];
-  sprintf(buf,"%02.2d-%02.2d-%04.4d %02.2d:%02.2d:%02.2d %s\n",
-    systemTime.wDay, systemTime.wMonth, systemTime.wYear,
-    systemTime.wHour,systemTime.wMinute,systemTime.wSecond,
-    buffer);
-  ::OutputDebugString(buf);
-};
-#endif
-
 CMPIptvSourceStream::CMPIptvSourceStream(HRESULT *phr, CSource *pFilter)
   : CSourceStream(NAME("MediaPortal IPTV Stream"), phr, pFilter, L"Out"),
   ip(NULL),
-  localip(NULL),
+  username(NULL),
+  get_string(NULL),
   protocol(NULL),
   port(0) ,
+  transport(0),
   m_socket(-1),
   m_seqNumber(0),
-  m_buffsize(0)
+  hData(NULL),
+  hConnection(NULL),
+  hINet(NULL)
+//  isRTP(false)
 {
 }
 
@@ -102,7 +52,21 @@
 
 void CMPIptvSourceStream::Clear() 
 {
-  if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
+  switch (transport) {
+    case tUDP:
+    case tRTP:
+      if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;};
+      break;
+    case tHTTP:
+      InternetCloseHandle(hData);
+      hData = NULL;
+      InternetCloseHandle(hConnection);
+      hConnection = NULL;
+      InternetCloseHandle(hINet);
+      hINet = NULL;
+      break;
+  }
+
   if(CAMThread::ThreadExists())
   {
     CAMThread::CallWorker(CMD_EXIT);
@@ -112,63 +76,20 @@
     CoTaskMemFree(ip);
     ip = NULL;
   }
-  if (localip) {
-    CoTaskMemFree(localip);
-    localip = NULL;
+  if (username) {
+    CoTaskMemFree(username);
+    username = NULL;
   }
+  if (get_string) {
+    CoTaskMemFree(get_string);
+	  get_string = NULL;
+  }
   if (protocol) {
     CoTaskMemFree(protocol);
     protocol = NULL;
   }
 }
 
-HRESULT CMPIptvSourceStream::FillBuffer(IMediaSample *pSamp)
-{
-#ifndef FILL_DIRECTLY_INTO_BUFFER
-  BYTE *pData;
-  long cbData;
-#endif
-
-  CheckPointer(pSamp, E_POINTER);
-#ifndef FILL_DIRECTLY_INTO_BUFFER
-  CAutoLock cAutoLock(m_pFilter->pStateLock());
-// Access the sample's data buffer
-  pSamp->GetPointer(&pData);
-  cbData = pSamp->GetSize();
-
-  memcpy(pData, m_buffer, min(m_buffsize, cbData));
-#endif
-#ifdef logging
-#ifdef FILL_DIRECTLY_INTO_BUFFER
-  LogDebug("Posting %d / %d bytes at seq # %d", m_buffsize, pSamp->GetSize(), m_seqNumber);
-#else
-  LogDebug("Posting %d / %d bytes at seq # %d", m_buffsize, cbData, m_seqNumber);
-#endif
-#endif
-
-  REFERENCE_TIME rtStart = m_seqNumber;
-  REFERENCE_TIME rtStop  = ++m_seqNumber;
-
-  pSamp->SetTime(&rtStart, &rtStop);
-#ifdef FILL_DIRECTLY_INTO_BUFFER
-  pSamp->SetActualDataLength(m_buffsize);
-  m_buffsize = 0; //We successfully posted the buffer so it can be cleared
-#else
-  pSamp->SetActualDataLength(min(m_buffsize, cbData));
-  if (cbData < m_buffsize)
-  { //The buffer was posted only partially, so we need to retain the remaining data
-    memmove(m_buffer, m_buffer + cbData, m_buffsize - cbData);
-    m_buffsize -= cbData;
-  }
-  else
-    m_buffsize = 0; //We successfully posted the buffer so it can be cleared
-#endif
-
-  pSamp->SetSyncPoint(TRUE);
-
-  return S_OK;
-}
-
 HRESULT CMPIptvSourceStream::GetMediaType(__inout CMediaType *pMediaType) 
 {
   pMediaType->majortype = MEDIATYPE_Stream;
@@ -210,257 +131,355 @@
   return S_OK;
 }
 
-HRESULT CMPIptvSourceStream::DoBufferProcessingLoop(void) 
-{
-  Command com;
+HRESULT CMPIptvSourceStream::OnThreadCreate(void) {
+ return NOERROR;
+}
 
-  OnThreadStartPlay();
-
-  WSADATA wsaData;
-  WSAStartup(MAKEWORD(2, 2), &wsaData);
-
-#ifdef logging
-  LogDebug("Starting grabber thread");
-#endif
-  sockaddr_in addr;
-  memset(&addr, 0, sizeof(addr));
-  addr.sin_family = AF_INET;
-  if (localip) {
-    addr.sin_addr.s_addr = inet_addr(localip);
-  } else {
-    addr.sin_addr.s_addr = htonl(INADDR_ANY);
-  }
-  addr.sin_port = htons((u_short)port);
-
-  ip_mreq imr; 
-  imr.imr_multiaddr.s_addr = inet_addr(ip);
-  if (localip) {
-    imr.imr_interface.s_addr = inet_addr(localip);
-  } else {
-    imr.imr_interface.s_addr = INADDR_ANY;
-  }
+HRESULT CMPIptvSourceStream::OnThreadStartPlay(void) {
   unsigned long nonblocking = 1;
+  switch (transport) {
+  case tUDP:
+  case tRTP:
+    WSADATA wsaData;
+    WSAStartup(MAKEWORD(2, 2), &wsaData);
 
-  if((m_socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
-  {
-    /*		u_long argp = 1;
-    ioctlsocket(m_socket, FIONBIO, &argp);
-    */
-    DWORD dw = TRUE;
-    int dwLen = sizeof(dw);
-    if(setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&dw, sizeof(dw)) < 0)
-    {
-      closesocket(m_socket);
-      m_socket = -1;
+    memset(&addr, 0, sizeof(addr));
+    addr.sin_family = AF_INET;
+    if (username) {
+      addr.sin_addr.s_addr = inet_addr(username);
+    } else {
+      addr.sin_addr.s_addr = htonl(INADDR_ANY);
     }
+    addr.sin_port = htons((u_short)port);
 
-    if(setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (const char*)&dw, sizeof(dw)) < 0)
-    {
-      closesocket(m_socket);
-      m_socket = -1;
+    ip_mreq imr; 
+    imr.imr_multiaddr.s_addr = inet_addr(ip);
+    if (username) {
+      imr.imr_interface.s_addr = inet_addr(username);
+    } else {
+      imr.imr_interface.s_addr = INADDR_ANY;
     }
 
-    getsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&dw, &dwLen);
-#ifdef logging
-    LogDebug("Socket receive buffer is: %d (%d)", dw, dwLen);
-
-    LogDebug("Trying to set receive buffer to %d", IPTV_SOCKET_BUFFER_SIZE);
-#endif
-    dw = IPTV_SOCKET_BUFFER_SIZE;
-    if(setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (const char*)&dw, sizeof(dw)) < 0)
+    if((m_socket = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
     {
-      closesocket(m_socket);
-      m_socket = -1;
-    }
+      DWORD dw = TRUE;
+      int dwLen = sizeof(dw);
+      if(setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&dw, sizeof(dw)) < 0)
+      {
+        closesocket(m_socket);
+        m_socket = -1;
+        return E_FAIL;
+      }
 
-    dwLen = sizeof(dw);
-    getsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&dw, &dwLen);
-#ifdef logging
-    LogDebug("New socket receive buffer is: %d (%d)", dw, dwLen);
-#endif
-    if (ioctlsocket(m_socket, FIONBIO, &nonblocking) != 0) {
-      closesocket(m_socket);
-      m_socket = -1;
-    }
+      if(setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (const char*)&dw, sizeof(dw)) < 0)
+      {
+        closesocket(m_socket);
+        m_socket = -1;
+        return E_FAIL;
+      }
 
-    if(bind(m_socket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
-    {
-      closesocket(m_socket);
-      m_socket = -1;
+      getsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&dw, &dwLen);
+      dw = IPTV_SOCKET_BUFFER_SIZE;
+      if(setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (const char*)&dw, sizeof(dw)) < 0)
+      {
+        closesocket(m_socket);
+        m_socket = -1;
+        return E_FAIL;
+      }
+
+      dwLen = sizeof(dw);
+      getsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&dw, &dwLen);
+      if (ioctlsocket(m_socket, FIONBIO, &nonblocking) != 0) {
+        closesocket(m_socket);
+        m_socket = -1;
+        return E_FAIL;
+      }
+
+      if(bind(m_socket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+      {
+        closesocket(m_socket);
+        m_socket = -1;
+      }
+
+      if(IN_MULTICAST(htonl(imr.imr_multiaddr.s_addr)))
+      {
+        int ret = setsockopt(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&imr, sizeof(imr));
+        if(ret < 0) ret = ::WSAGetLastError();
+        ret = ret;
+      }
+    } else
+      return E_FAIL;
+    break;
+  case tHTTP: 
+    hINet = InternetOpen("Mozilla/4.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+    if ( hINet ) 
+      hConnection = InternetConnect( hINet, ip, port, " ", " ", INTERNET_SERVICE_HTTP, 0, 0 );
+
+    if ( hConnection ) {
+      hData = HttpOpenRequest( hConnection, "GET", get_string, 
+        NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0 );
+    } else {
+      InternetCloseHandle(hINet);
     }
 
-    if(IN_MULTICAST(htonl(imr.imr_multiaddr.s_addr)))
-    {
-      int ret = setsockopt(m_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&imr, sizeof(imr));
-      if(ret < 0) ret = ::WSAGetLastError();
-      ret = ret;
-    }
+    if ( hData ) {
+		  if (!HttpSendRequest( hData, NULL, -1, NULL, 0)) {
+		  }
+	  } else {
+		  InternetCloseHandle(hINet);
+		  InternetCloseHandle(hConnection);
+		  return E_FAIL;
+	  }
+    break;
   }
+  totalReceived = 0;
+  RTPfailPackets = 0;
 
-  SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL);
+  SetThreadPriority(m_hThread, THREAD_PRIORITY_ABOVE_NORMAL);
+}
 
-  int fromlen = sizeof(addr);
+HRESULT CMPIptvSourceStream::FillBuffer(IMediaSample *pSamp)
+{
+  CheckPointer(pSamp, E_POINTER);
 
-  m_buffsize = 0;
-  timeval tv; //Will be used for select() below
-  tv.tv_sec = 0;
-  tv.tv_usec = 100000; //100 msec
-  do 
-  {
-    BOOL requestAvail;
-    while ((requestAvail = CheckRequest(&com)) == FALSE) 
+  // Now get buffers address
+  char *pData;
+  long cbData;
+
+  int resp; 
+  int len;
+  
+  if (pSamp->GetPointer((BYTE **)&pData) != S_OK) {
+    return E_FAIL;
+  }
+  cbData = pSamp->GetSize();
+  if (cbData <= 0) {
+    return E_FAIL;
+  }
+
+  // Decide what to do on protocol
+  switch (transport) {
+  case tUDP:
+
+    len = recv(m_socket,pData, cbData, 0);
+
+    //if (len <= 0) return E_FAIL;
+    if(len <= 0)
     {
-      DWORD startRecvTime;
-      startRecvTime = GetTickCount();
-#ifdef FILL_DIRECTLY_INTO_BUFFER
-      IMediaSample *pSample;
-      char *pData;
-      long cbData;
+      timeval tv; //Will be used for select() below
+      tv.tv_sec = 0; // 0 sec
+      tv.tv_usec = 100000; //0 msec
+      //Wait until there's something in the receive buffer
+      fd_set myFDsocket;
+      myFDsocket.fd_count = 1;
+      myFDsocket.fd_array[0] = m_socket;
+      // Wait until 100 msec exceeded or there is something in the receive buffer
+      int selectRet = select(0, &myFDsocket, NULL, NULL, &tv);
+      // Try again to read data. Even if there is still no data, we have to move on to handle messages from other threads
+      len = recv(m_socket,pData, cbData, 0);
+      if (len <= 0) {
+        pSamp->SetActualDataLength(0); 
+        return S_OK;
+      }
+    }
+    pSamp->SetActualDataLength(len);
+    totalReceived += len;
+    // On an udp stream we cannot see if there was a packet lost, nor if this is a synchron point nor the timestamps. 
+    // So, just leave it like it is and let the other filter decide
+    return S_OK;
+  case tHTTP: 
+    len = 0;
+    resp = InternetReadFile( hData, pData, cbData, (LPDWORD)&len ) ;
+    
+    if (!resp) {
+      return E_FAIL;
+		}
+    // If nothing recieved wait 100ms and read once more
+    if (len == 0) {
+      Sleep(100);  
+      resp = InternetReadFile( hData, pData, cbData, (LPDWORD)&len ) ;
+    
+      if (!resp) {
+        return E_FAIL;
+		  }
+    }
+//    writeStream(pData, len);
+    totalReceived += len;
+    pSamp->SetActualDataLength(len);
+    return S_OK;
 
-      HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
-      if (FAILED(hr))
-        continue;	
-      CheckPointer(pSample, E_POINTER);
-    // Access the sample's data buffer
-      pSample->GetPointer((BYTE **)&pData);
-      cbData = pSample->GetSize();
-#endif
-      do 
+  case tRTP:
+    // This is an rtp stream
+
+   // This buffer will hold the data only for a short time. Its nessecary because we need to skip the first 12 bytes
+    char *pRawData = new char[cbData];
+    // Was there an error in the stream?
+    bool failPacket = false;
+    // Loop until the buffer is filled up
+    while (!rtpHandler.checkDataCanBePosted(cbData)) {
+      // Get packet
+      int len = recv(m_socket,pRawData, cbData, 0);
+      // Check if we got some data
+      if(len <= 0)
       {
-        //Try to read the complete remaining buffer size
-        //But stop reading after 100ms have passed (slow streams like internet radio)
-#ifdef FILL_DIRECTLY_INTO_BUFFER
-        int len = recvfrom(m_socket, &pData[m_buffsize], cbData - m_buffsize, 0, (SOCKADDR*)&addr, &fromlen);
-#else
-        int len = recvfrom(m_socket, &m_buffer[m_buffsize], IPTV_BUFFER_SIZE - m_buffsize, 0, (SOCKADDR*)&addr, &fromlen);
-#endif
-        if(len <= 0)
-        {
-          //Wait until there's something in the receive buffer
-          fd_set myFDsocket;
-          myFDsocket.fd_count = 1;
-          myFDsocket.fd_array[0] = m_socket;
-          int selectRet = select(0, &myFDsocket, NULL, NULL, &tv);
-#ifdef logging
-          LogDebug("select return code: %d", selectRet);
-#endif
-          continue; //On error or nothing read just repeat the loop
+        timeval tv; //Will be used for select() below
+        tv.tv_sec = 0; //0 sec
+        tv.tv_usec = 100000; //00 msec
+        //Wait until there's something in the receive buffer
+        fd_set myFDsocket;
+        myFDsocket.fd_count = 1;
+        myFDsocket.fd_array[0] = m_socket;
+        // Wait until 100 msec exceeded or there is something in the receive buffer
+        int selectRet = select(0, &myFDsocket, NULL, NULL, &tv);
+        // If there is data, repeat the loop to get it
+        if (selectRet > 0) 
+          continue;
+        else {
+          //Even if there is still no data, we have to move on to handle messages from other threads
+          REFERENCE_TIME rtStart = 0;
+          REFERENCE_TIME rtStop  = 0;
+          pSamp->SetTime(&rtStart, &rtStop);
+          pSamp->SetActualDataLength(0);
+          return S_OK;
         }
-#ifdef logging
-        LogDebug("Read %d bytes at pos %d of %d", len, m_buffsize, IPTV_BUFFER_SIZE); 
-#endif
-        m_buffsize += len;
-#ifdef FILL_DIRECTLY_INTO_BUFFER
-      } while ((requestAvail = CheckRequest(&com)) == FALSE && m_buffsize < (cbData           * 3 / 4) && abs((signed long)(GetTickCount() - startRecvTime)) < 100);
-#else
-      } while ((requestAvail = CheckRequest(&com)) == FALSE && m_buffsize < (IPTV_BUFFER_SIZE * 3 / 4) && abs((signed long)(GetTickCount() - startRecvTime)) < 100);
-#endif
-      if (requestAvail) break;
-#ifndef FILL_DIRECTLY_INTO_BUFFER
-      if (m_buffsize == 0) continue; //100ms passed but no buffer received
-      IMediaSample *pSample;
-      HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0);
-      if (FAILED(hr))
-      {
-        continue;	
-        // go round again. Perhaps the error will go away
-        // or the allocator is decommited & we will be asked to
-        // exit soon.
       }
-#endif
-      // fill buffer
-      hr = FillBuffer(pSample);
 
-      if (hr == S_OK) 
-      {
-        hr = Deliver(pSample);
-        pSample->Release();
-
-        // downstream filter returns S_FALSE if it wants us to
-        // stop or an error if it's reporting an error.
-        if(hr != S_OK)
-        {
-#ifdef logging
-          LogDebug("Deliver() returned %08x; stopping", hr);
-#endif
-          if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
-          WSACleanup();
-          return S_OK;
+      // Do some basic checks to see if this is really a rtp packet
+      if (!rtpHandler.isRTPpacket(pRawData, len)) {
+        RTPfailPackets++;
+        if (RTPfailPackets >= RTP_MAX_FAIL_PACKETS) {
+          // This is not a rtp stream! Consider it as raw udp.
+          transport = tUDP;
+          // Complete this media sample
+          return FillBuffer(pSamp);
         }
+        // This is still not a correct rtp packet -> skip it
+        continue;
+      } else
+        RTPfailPackets = 0;
 
-      } else if (hr == S_FALSE) {
-        // derived class wants us to stop pushing data
-        pSample->Release();
-        DeliverEndOfStream();
-        if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
-        WSACleanup();
-        return S_OK;
-      } else {
-        // derived class encountered an error
-        pSample->Release();
-#ifdef logging
-        LogDebug("Error %08lX from FillBuffer!!!", hr);
-#endif
-        DeliverEndOfStream();
-        m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
-        if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
-        WSACleanup();
-        return hr;
-      }
+      // Now we can be sure, that this is a rtp packet -> process it
+      if (!rtpHandler.processPacket(pRawData, len))
+        return E_FAIL;
+      totalReceived += len;
 
-      // all paths release the sample
     }
+    delete[] pRawData;
 
-    // For all commands sent to us there must be a Reply call!
+    // Now get the data and fill the buffer
+    unsigned int firstTimestamp;
+    unsigned int lastTimestamp;
+    bool isContinous;
+    int processedBytes = rtpHandler.getPacketData(pData, cbData, firstTimestamp, lastTimestamp, isContinous);
 
-    if (com == CMD_RUN || com == CMD_PAUSE) {
-      Reply(NOERROR);
-    } else if (com != CMD_STOP) {
-      Reply((DWORD) E_UNEXPECTED);
-#ifdef logging
-      LogDebug("Unexpected command %d!!!", com);
-#endif
-    }
-  } while (com != CMD_STOP);
-  if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;}
-  WSACleanup();
-  return S_FALSE;
+    REFERENCE_TIME rtStart = 0; //firstTimestamp;
+    REFERENCE_TIME rtStop  = 0; //lastTimestamp;
+    pSamp->SetTime(&rtStart, &rtStop);
+    pSamp->SetActualDataLength(processedBytes);
+    pSamp->SetDiscontinuity(!isContinous);
+    return S_OK;
+  }
+
 }
 
+HRESULT CMPIptvSourceStream::OnThreadDestroy(void) {
+  switch (transport) {
+    case tUDP:
+    case tRTP:
+      if(m_socket >= 0) {closesocket(m_socket); m_socket = -1;};
+      WSACleanup();
+      break;
+    case tHTTP:
+      InternetCloseHandle(hData);
+      InternetCloseHandle(hConnection);
+      InternetCloseHandle(hINet);
+      break;
+  }
+
+  return NOERROR;
+}
+
+void ZeroURL(URL_COMPONENTS *url) {
+  url->lpszScheme = NULL;
+  url->lpszExtraInfo = NULL;
+  url->lpszHostName = NULL;
+  url->lpszPassword = NULL;
+  url->lpszUrlPath = NULL;
+  url->lpszUserName = NULL;
+
+  url->dwSchemeLength    = -1;
+  url->dwHostNameLength  = -1;
+  url->dwUrlPathLength   = -1;
+  url->dwExtraInfoLength = -1;
+};
+
+typedef bool (__cdecl * pICFUNC)(URL_COMPONENTS url, char* buffer); 
+#define dllMAX 256
+extern int dllTotal;
+extern struct preauthlib {
+  char* protocol;
+  int transport;
+  pICFUNC GetRealURL;
+} dllPreAuth[dllMAX];
+
 bool CMPIptvSourceStream::Load(const TCHAR* fn) 
 {
   Clear();
   URL_COMPONENTS url;
+  ZeroURL(&url);
   url.dwStructSize = sizeof(URL_COMPONENTS);
-  url.lpszScheme = NULL;
-  url.lpszExtraInfo = NULL;
-  url.lpszHostName = NULL;
-  url.lpszPassword = NULL;
-  url.lpszUrlPath = NULL;
-  url.lpszUserName = NULL;
-  //	TCHAR *srcurl = "udp://192.168.2.197@233.1.1.1:1234";
   if (!InternetCrackUrl(fn, 0, 0, &url)) {
     return false;
   }
+  char pBuff[2048];
+  memset(pBuff,0,2048);
+  memcpy(pBuff,fn,strlen(fn)+1);
+  int i=0;
+  while (i<dllTotal) {
+    if (strnicmp(url.lpszScheme,dllPreAuth[i].protocol,url.dwSchemeLength) == 0) {
+      transport = dllPreAuth[i].transport;
+      if (dllPreAuth[i].GetRealURL != NULL) {
+        dllPreAuth[i].GetRealURL(url, pBuff);
+      }
+      break;
+    }
+    i++;
+  }
+  if (i == dllTotal) {
+    return false;
+  }
+
+  ZeroURL(&url);
+  url.dwStructSize = sizeof(URL_COMPONENTS);
+  if (!InternetCrackUrl(pBuff, 0, 0, &url)) {
+    return false;
+  }
+  if (!(protocol = (TCHAR*) CoTaskMemAlloc((url.dwSchemeLength + 1) * sizeof(TCHAR)))) {
+    return false;
+  }
+  memset(protocol, 0, (url.dwSchemeLength + 1) * sizeof(TCHAR));
+  strncat(protocol, url.lpszScheme, url.dwSchemeLength);
+
   if (!(ip = (TCHAR*) CoTaskMemAlloc((url.dwHostNameLength + 1) * sizeof(TCHAR)))) {
     return false;
   }
   memset(ip, 0, (url.dwHostNameLength + 1) * sizeof(TCHAR));
   strncat(ip, url.lpszHostName, url.dwHostNameLength);
   if (url.dwUserNameLength > 0) {
-    if (!(localip = (TCHAR*) CoTaskMemAlloc((url.dwUserNameLength + 1) * sizeof(TCHAR)))) {
+    if (!(username = (TCHAR*) CoTaskMemAlloc((url.dwUserNameLength + 1) * sizeof(TCHAR)))) {
       return false;
     }
-    memset(localip, 0, (url.dwUserNameLength + 1) * sizeof(TCHAR));
-    strncat(localip, url.lpszUserName, url.dwUserNameLength);
+    memset(username, 0, (url.dwUserNameLength + 1) * sizeof(TCHAR));
+    strncat(username, url.lpszUserName, url.dwUserNameLength);
   }
-  if (!(protocol = (TCHAR*) CoTaskMemAlloc((url.dwSchemeLength + 1) * sizeof(TCHAR)))) {
-    return false;
+
+  if (!(get_string = (TCHAR*) CoTaskMemAlloc((url.dwUrlPathLength + url.dwExtraInfoLength + 1) * sizeof(TCHAR)))) {
+	return false;
   }
-  memset(protocol, 0, (url.dwSchemeLength + 1) * sizeof(TCHAR));
-  strncat(protocol, url.lpszScheme, url.dwSchemeLength);
+  memset(get_string, 0, (url.dwUrlPathLength + url.dwExtraInfoLength + 1) * sizeof(TCHAR));
+  strncat(get_string, url.lpszUrlPath, url.dwUrlPathLength );
+  strncat(get_string, url.lpszExtraInfo, url.dwExtraInfoLength );
   port = url.nPort;
-
   return true;
 }
 
@@ -540,3 +559,4 @@
 
   return pNewFilter;
 }
+
Index: source/mpiptvsource.h
===================================================================
--- source/mpiptvsource.h	(revision 25271)
+++ source/mpiptvsource.h	(working copy)
@@ -29,6 +29,7 @@
 #pragma comment(lib, "wininet.lib")
 
 #include <wininet.h>
+#include "rtpsource.h"
 
 // {D3DD4C59-D3A7-4b82-9727-7B9203EB67C0}
 DEFINE_GUID(CLSID_MPIptvSource, 
@@ -42,10 +43,15 @@
 #define EMPTY_STRING ""
 #define UDP_PROTOCOL "udp"
 #define RTP_PROTOCOL "rtp"
-#define IPTV_BUFFER_SIZE 128 * 1024 //By default 64KB buffer size
-#define IPTV_SOCKET_BUFFER_SIZE 32 * 1024 //Socket receive buffer size - not related to read buffer size above
-#define FILL_DIRECTLY_INTO_BUFFER
+#define IPTV_BUFFER_SIZE 10 * 1024 //By default 32KB buffer size
+#define IPTV_SOCKET_BUFFER_SIZE 512 * 1024 //Socket receive buffer size - not related to read buffer size above
+#define RTP_MAX_FAIL_PACKETS 5  //Nr. of wrong (=wrong header) packets after the rtp-stream is considered as raw udp instead of rtp
 
+// definitions of transport layer
+#define tUDP 1
+#define tRTP 2
+#define tHTTP 3
+
 class CMPIptvSourceStream : public CSourceStream
 {
 
@@ -54,19 +60,26 @@
 	TCHAR* protocol; // udp/rtp
 	TCHAR* ip;
 	WORD port;
-	TCHAR* localip;
+	TCHAR* username;
+	TCHAR* get_string;
+  HINTERNET hINet; 
+  HINTERNET hConnection;
+  HINTERNET hData;
 	SOCKET m_socket;
 
+  long totalReceived;
+
 	DWORD m_seqNumber;
-#ifndef FILL_DIRECTLY_INTO_BUFFER
-  char m_buffer[IPTV_BUFFER_SIZE];
-#endif
-  int m_buffsize;
+  sockaddr_in addr;
 
 	HRESULT FillBuffer(IMediaSample *pSamp);
 	HRESULT GetMediaType(__inout CMediaType *pMediaType);
 	HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest);
-  HRESULT DoBufferProcessingLoop(void);
+  //HRESULT DoBufferProcessingLoop(void);
+	HRESULT OnThreadCreate(void);
+  HRESULT OnThreadDestroy(void);
+  HRESULT OnThreadStartPlay(void);
+	bool Get_Url_Kartina(URL_COMPONENTS url, TCHAR* buffer);
 
 public:
 
@@ -76,6 +89,10 @@
 	bool Load(const TCHAR* fn);
 	void Clear();
 
+private:
+  int transport;
+  int RTPfailPackets;
+  rtpsource rtpHandler;
 };
 
 // This class is exported from the mpiptvsource.dll
Index: source/rtpsource.cpp
===================================================================
--- source/rtpsource.cpp	(revision 0)
+++ source/rtpsource.cpp	(revision 0)
@@ -0,0 +1,279 @@
+/* 
+*	Copyright (C) 2006-2009 Team MediaPortal
+*	http://www.team-mediaportal.com
+*
+*  This Program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2, or (at your option)
+*  any later version.
+*   
+*  This Program is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+*  GNU General Public License for more details.
+*   
+*  You should have received a copy of the GNU General Public License
+*  along with GNU Make; see the file COPYING.  If not, write to
+*  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+*  http://www.gnu.org/copyleft/gpl.html
+*
+*/
+
+#include "rtpsource.h"
+#include "windows.h"
+#include <stdio.h>
+#include <shlobj.h>
+
+rtpsource::rtpsource() {
+  RTPssrc = 1;
+  isFirstPacket = true;
+  rtpStreamRunning = false;
+  firstItem = NULL;
+  lastItem = NULL;
+  packetSizeTotal = 0;
+}
+
+rtpsource::~rtpsource() {
+  // Clean buffer
+  while (firstItem != NULL) {
+    packetItem *temp = firstItem;
+    firstItem = firstItem->next;
+    delete temp->data;
+    delete temp;
+  }
+  firstItem = NULL;
+  lastItem = NULL;
+}
+
+void rtpsource::addPacket(char* data, int length, unsigned int timestamp, unsigned int sequenceNr) {
+  packetItem* newItem = new packetItem();
+  newItem->data = new char[length];
+  memcpy(newItem->data, data, length);
+  newItem->size = length;
+  newItem->next = NULL;
+  newItem->sequenceNr = sequenceNr;
+  newItem->timestamp = timestamp;
+
+  if (firstItem == NULL) {
+    firstItem = newItem;
+    lastItem = newItem;
+    packetSizeTotal = length;
+    // This is the first item. Set "lastSequenceNumber" accordingly
+    this->lastSequenceNr = newItem->sequenceNr == 0 ? 0x0000FFFF : newItem->sequenceNr-1;
+  } else {
+    // Check if this packet belongs after the last packet (most likely situation, handle this first)
+    if ((newItem->sequenceNr > lastItem->sequenceNr) ||
+      // The sequence number restarts after 65536, this must be handled
+      (lastItem->sequenceNr >= 0xFFF0 && newItem->sequenceNr <= 0x000F)) {
+      lastItem->next = newItem;
+      packetSizeTotal += length;
+      lastItem = newItem;
+      // Check if this packet is far too late (would belong before the first packet in the buffer) and drop it
+    } else if (newItem->sequenceNr < firstItem->sequenceNr-1) {
+      delete newItem->data;
+      delete newItem;
+
+     // The packet belongs somewhere in the middle of the buffer. Find the position and post data in there
+    } else {
+      packetItem *currentItem = firstItem;
+      while (currentItem != NULL && !packetBelongsBetween(newItem, currentItem, currentItem->next)) {
+        currentItem = currentItem->next;
+      }
+      // Check if we found the position
+      if (currentItem != NULL && currentItem->next != NULL) {
+        // Insert new item
+        newItem->next = currentItem->next;
+        currentItem->next = newItem;
+        packetSizeTotal += newItem->size;
+        packetItem *tempItem = firstItem;
+      } else {
+        // This shouldn't happen at all!!
+        delete newItem->data;
+        delete newItem;
+      }
+    }
+  }
+}
+
+bool rtpsource::packetBelongsBetween(packetItem *item, packetItem *itemBefore, packetItem *itemAfter) {
+  if (item == NULL || itemBefore == NULL || itemAfter == NULL) return false;
+  // Most likely situation: the packets are in ascending order 
+  if (itemBefore->sequenceNr < itemAfter->sequenceNr) {
+    return (item->sequenceNr > itemBefore->sequenceNr && item->sequenceNr < itemAfter->sequenceNr);
+  // The sequnce number is resetted between itemBefore and itemAfter
+  } else {
+    return (item->sequenceNr > itemBefore->sequenceNr || item->sequenceNr < itemAfter->sequenceNr);
+  }
+}
+
+bool rtpsource::sequenceIsContinuous(unsigned int sequnceNr0, unsigned int sequnceNr1) {
+  return (sequnceNr0+1 == sequnceNr1) || (sequnceNr0 == 0xFFFF && sequnceNr1 == 0);
+}
+
+int rtpsource::getPacketData(char* buffer, int bufferSize, unsigned int &firstTimestamp, unsigned int &lastTimestamp, bool &isContinous) {
+  //if (packetSizeTotal <= 0 || firstItem == NULL || lastItem == NULL) return;
+  int bytesTransferred = 0;
+  int firstsequenceNr = 0;
+  
+  // Duplicate first data if there are some packets missing in the beginning
+  while (!sequenceIsContinuous(lastSequenceNr, firstItem->sequenceNr)) {
+    packetItem* newItem = new packetItem();
+    // Test: Zero memory instead of copying data
+    newItem->data = new char[firstItem->size];
+    //memcpy(newItem->data, firstItem->data, firstItem->size);
+    ZeroMemory(newItem->data, firstItem->size);
+    newItem->size = firstItem->size;
+    newItem->next = firstItem;
+    newItem->sequenceNr = firstItem->sequenceNr-1;
+    if (newItem->sequenceNr > 0xFFFF) newItem->sequenceNr = 0xFFFF;
+    newItem->timestamp = firstItem->timestamp;
+    firstItem = newItem;
+  }
+
+  packetItem* currentItem = firstItem;
+  isContinous = true;
+  while (currentItem != NULL && currentItem->next != NULL /*&& sequenceIsContinuous(currentItem->sequenceNr, currentItem->next->sequenceNr)*/ && (bytesTransferred + currentItem->size) <= bufferSize) {
+    // Copy data to destination buffer
+    memcpy(buffer+bytesTransferred, currentItem->data, currentItem->size);
+
+    //isContinous &= sequenceIsContinuous(currentItem->sequenceNr, currentItem->next->sequenceNr);
+    isContinous = true;
+
+    // First item?
+    if (bytesTransferred == 0) {
+      firstTimestamp = currentItem->timestamp;
+      //isContinous = sequenceIsContinuous(lastSequenceNr, currentItem->sequenceNr);
+      firstsequenceNr = currentItem->sequenceNr;
+    }
+    // Set new total copied bytes
+    bytesTransferred += currentItem->size;
+
+    // Set last data (might be the last item to process)
+    lastTimestamp = currentItem->timestamp;
+    lastSequenceNr = currentItem->sequenceNr;
+
+    packetSizeTotal -= currentItem->size;
+        
+    // Remember current Item
+    packetItem *temp = currentItem;
+
+    // Set next current item
+    currentItem = currentItem->next;
+
+    // Check if next packet is continous. If not, add dummy-data
+    int currentSequenceNr = temp->sequenceNr;
+    while (!sequenceIsContinuous(currentSequenceNr, currentItem->sequenceNr) && (bytesTransferred + currentItem->size) <= bufferSize) {
+      // Test: Zero memory instead of copying data
+      //memcpy(buffer+bytesTransferred, currentItem->data, currentItem->size);
+      ZeroMemory((buffer+bytesTransferred), currentItem->size);
+      bytesTransferred += currentItem->size;
+      currentSequenceNr++;
+      if (currentSequenceNr > 0xFFFF) currentSequenceNr = 0;
+    }
+    
+    // Free some memory
+    delete temp->data;
+    delete temp;
+  }
+
+  // Set new first Item
+  if (currentItem == NULL) {
+    firstItem = NULL;
+    lastItem = NULL;
+  } else
+    firstItem = currentItem;
+  
+
+  // Return processed bytes
+  return bytesTransferred;
+}
+
+bool rtpsource::checkDataCanBePosted(int bufferSize) {
+  // If buffer is greater than IPTV_RTP_INTERNAL_BUFFER_SIZE deliver data
+  if (packetSizeTotal >= IPTV_RTP_INTERNAL_BUFFER_SIZE) return true;
+
+  // Deliver data if there are enough continuous packets to fill the mediasample buffer
+  packetItem *currentItem = firstItem;
+  int continuousData = currentItem == NULL ? 0 : currentItem->size;
+  while (currentItem != NULL && continuousData < bufferSize) {
+    if (currentItem->next != NULL) {
+      if (currentItem->sequenceNr+1 == currentItem->next->sequenceNr || (currentItem->sequenceNr == 0x0000ffff && currentItem->next->sequenceNr == 0)) {
+        continuousData += currentItem->next->size;
+      } else {
+        break;
+      }
+    }
+    currentItem = currentItem->next;
+  }
+  if (!rtpStreamRunning && continuousData < packetSizeTotal) {
+    //LogDebug("continouseData: %d, packetSizeTotal: %d", continuousData, packetSizeTotal);
+    return firstItem != NULL;
+  }
+  if (!rtpStreamRunning && continuousData >= bufferSize) {
+    rtpStreamRunning = true;
+  }
+  return (continuousData >= bufferSize);
+}
+
+bool rtpsource::isRTPpacket(char *data, int datalen)
+ {
+  if (datalen < RTP_HEADER_SIZE) return false;
+     
+  // 1. check: First bit must be one, and second bit must be zero
+  bool failPacket = ((((char)*(data))&0xC0) != 0x80);
+  // 2. check: SSRC (source identifier) must be the same for every packet
+  unsigned int ssrc0 = ((unsigned int)*(data+8))&0x000000ff;
+  unsigned int ssrc1 = ((unsigned int)*(data+9))&0x000000ff;
+  unsigned int ssrc2 = ((unsigned int)*(data+10))&0x000000ff;
+  unsigned int ssrc3 = ((unsigned int)*(data+11))&0x000000ff;
+  unsigned int ssrc = (ssrc0<<24) + (ssrc1<<16) + (ssrc2<<8) + (ssrc3<<0);
+  // Is it the same like last packet?
+  if (ssrc != RTPssrc) {
+    // Save ssrc for next packet
+    RTPssrc = ssrc;
+    // This is OK on first packet (ssrc unknown at first). On other: This is not a rtp packet
+    failPacket &= isFirstPacket;
+  }
+
+  isFirstPacket = false;
+
+  return !failPacket;
+}
+
+bool rtpsource::processPacket(char *data, int datalen) {
+  // Padding is used rarely. But we need to handle it
+  int padding = 0;
+  if (((*data)&0x20) != 0) {
+    padding = ((int)*(data+datalen-1))&0x000000ff;
+  }
+
+ unsigned int headerExtension = 0;
+ if (((*data)&0x10) != 0) {
+    unsigned int hx0 = ((unsigned int)*(data+RTP_HEADER_SIZE+2))&0x000000ff;
+    unsigned int hx1 = ((unsigned int)*(data+RTP_HEADER_SIZE+3))&0x000000ff;
+    headerExtension = (hx0<<8) + (hx1<<0);
+    // The header-extension identifier and length field must be taken into account
+    headerExtension += 1;
+    // Header length is given in 32-bit words
+    headerExtension *= 4;
+  }
+
+  // The rtp header is 12 bytes long
+  if (datalen <= RTP_HEADER_SIZE) return false;
+  // Get timestamp
+  unsigned int ts0 = ((unsigned int)*(data+4))&0x000000ff;
+  unsigned int ts1 = ((unsigned int)*(data+5))&0x000000ff;
+  unsigned int ts2 = ((unsigned int)*(data+6))&0x000000ff;
+  unsigned int ts3 = ((unsigned int)*(data+7))&0x000000ff;
+  unsigned int timestamp = (ts0<<24) + (ts1<<16) + (ts2<<8) + (ts3<<0);
+
+  // Get sequence number
+  unsigned int sn0 = ((unsigned int)*(data+2))&0x000000ff;
+  unsigned int sn1 = ((unsigned int)*(data+3))&0x000000ff;
+  unsigned int sequencenr = (sn0<<8) + (sn1<<0);
+
+  // Store packet
+  addPacket(data+RTP_HEADER_SIZE+headerExtension, datalen-RTP_HEADER_SIZE-padding-headerExtension, timestamp, sequencenr);
+  return true;
+
+}
\ No newline at end of file
Index: source/rtpsource.h
===================================================================
--- source/rtpsource.h	(revision 0)
+++ source/rtpsource.h	(revision 0)
@@ -0,0 +1,181 @@
+/* 
+ *	Copyright (C) 2006-2009 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#ifndef __RTPSOURCE_DEFINED
+#define __RTPSOURCE_DEFINED
+
+#define IPTV_RTP_INTERNAL_BUFFER_SIZE 64 * 1024 //Used to reorder packages in rtp streams
+#define RTP_HEADER_SIZE 12
+
+class rtpsource {
+private:
+
+  struct packetItem {
+    char* data;
+    int size;
+    unsigned int timestamp;
+    unsigned int sequenceNr;
+    packetItem* next;
+  };
+
+  
+  
+  unsigned int RTPssrc;
+  bool isFirstPacket;
+  unsigned int lastSequenceNr;
+  bool rtpStreamRunning;
+
+  // Everything for packetItem
+  packetItem* firstItem;
+  packetItem* lastItem;
+  int packetSizeTotal;
+  
+  // Returns true, if seuenceNr1 is the next packet after sequenceNr0
+  bool sequenceIsContinuous(unsigned int sequnceNr0, unsigned int sequnceNr1);
+
+  // Returns true, if the "item" belongs between "itemBefore" and "itemAfter"
+  bool packetBelongsBetween(packetItem *item, packetItem *itemBefore, packetItem *itemAfter);
+
+public:
+  rtpsource();
+  ~rtpsource();
+
+
+  // Add one packed to the buffer
+  void addPacket(char* data, int length, unsigned int timestamp, unsigned int sequenceNr);
+  
+  // Gets packets from the buffer, put them into "buffer" and deletes them from the list.
+  int getPacketData(char* buffer, int bufferSize, unsigned int &firstTimestamp, unsigned int &lastTimestamp, bool &isContinous);
+
+  // Check if data should be copied from the list to the mediaSample buffer
+  bool checkDataCanBePosted(int bufferSize);
+
+  // Checks if this is a valid rtp packet (does 2 simple header checks)
+  // Returns true, if it is a valid packet.
+  bool isRTPpacket(char *data, int datalen);
+
+  // Processes the packet (cheks the sequence number and adds it to the internal buffer)
+  // Returns false if something went wrong. The thread should be stopped if this function returns false!!
+  bool processPacket(char *data, int datalen);
+
+};
+
+
+
+
+
+
+
+
+
+#endif
+/* 
+ *	Copyright (C) 2006-2009 Team MediaPortal
+ *	http://www.team-mediaportal.com
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *   
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *   
+ *  You should have received a copy of the GNU General Public License
+ *  along with GNU Make; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+#ifndef __RTPSOURCE_DEFINED
+#define __RTPSOURCE_DEFINED
+
+#define IPTV_RTP_INTERNAL_BUFFER_SIZE 256 * 1024 //Used to reorder packages in rtp streams
+#define RTP_HEADER_SIZE 12
+
+
+class rtpsource {
+private:
+
+  struct packetItem {
+    char* data;
+    int size;
+    unsigned int timestamp;
+    unsigned int sequenceNr;
+    packetItem* next;
+  };
+
+  
+  
+  unsigned int RTPssrc;
+  bool isFirstPacket;
+  unsigned int lastSequenceNr;
+  bool rtpStreamRunning;
+
+  // Everything for packetItem
+  packetItem* firstItem;
+  packetItem* lastItem;
+  int packetSizeTotal;
+  
+  // Returns true, if seuenceNr1 is the next packet after sequenceNr0
+  bool sequenceIsContinuous(unsigned int sequnceNr0, unsigned int sequnceNr1);
+
+  // Returns true, if the "item" belongs between "itemBefore" and "itemAfter"
+  bool packetBelongsBetween(packetItem *item, packetItem *itemBefore, packetItem *itemAfter);
+
+public:
+  rtpsource();
+  ~rtpsource();
+
+
+  // Add one packed to the buffer
+  void addPacket(char* data, int length, unsigned int timestamp, unsigned int sequenceNr);
+  
+  // Gets packets from the buffer, put them into "buffer" and deletes them from the list.
+  int getPacketData(char* buffer, int bufferSize, unsigned int &firstTimestamp, unsigned int &lastTimestamp, bool &isContinous);
+
+  // Check if data should be copied from the list to the mediaSample buffer
+  bool checkDataCanBePosted(int bufferSize);
+
+  // Checks if this is a valid rtp packet (does 2 simple header checks)
+  // Returns true, if it is a valid packet.
+  bool isRTPpacket(char *data, int datalen);
+
+  // Processes the packet (cheks the sequence number and adds it to the internal buffer)
+  // Returns false if something went wrong. The thread should be stopped if this function returns false!!
+  bool processPacket(char *data, int datalen);
+
+};
+
+
+
+
+
+
+
+
+
+#endif
\ No newline at end of file
Index: source/setup.cpp
===================================================================
--- source/setup.cpp	(revision 25271)
+++ source/setup.cpp	(working copy)
@@ -19,8 +19,10 @@
  *
  */
 
+#pragma warning(disable : 4996)
 #include <streams.h>
 #include <initguid.h>
+#include "Shlwapi.h"
 #include "mpiptvsource.h"
 
 #define g_wszPushSource     L"MediaPortal IPTV Source Filter"
@@ -72,8 +74,19 @@
 
 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);    
 
+#define dllMAX 256
+typedef bool (__cdecl * pICFUNC)(URL_COMPONENTS url, char* buffer); 
+typedef void (__cdecl * pICFUNC1)(int* transport, char** protocol); 
+pICFUNC dllGetRealURL[dllMAX];
+struct preauthlib {
+  char* protocol;
+  int transport;
+  pICFUNC GetRealURL;
+} dllPreAuth[dllMAX];
 
+int dllTotal;
 
+
 ////////////////////////////////////////////////////////////////////////
 //
 // Exported entry points for registration and unregistration 
@@ -96,10 +109,76 @@
 //
 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
 
+//extern void GetLogFile1(char *pLog);
+extern void LogDebug(const char *fmt, ...);
+void LoadPreAuthPlugins();
+void LoadDefautProtocols();
+
 BOOL APIENTRY DllMain(HANDLE hModule, 
                       DWORD  dwReason, 
                       LPVOID lpReserved)
 {
-	return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
+  dllTotal = 0;
+  LoadDefautProtocols();
+  LoadPreAuthPlugins();
+  return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
 }
 
+void LoadDefautProtocols()
+{
+  dllPreAuth[dllTotal].GetRealURL = NULL;
+  dllPreAuth[dllTotal].protocol = "udp";
+  dllPreAuth[dllTotal].transport = 1; //tUDP
+  dllTotal++;
+  dllPreAuth[dllTotal].GetRealURL = NULL;
+  dllPreAuth[dllTotal].protocol = "rtp";
+  dllPreAuth[dllTotal].transport = 2; //tRTP
+  dllTotal++;
+  dllPreAuth[dllTotal].GetRealURL = NULL;
+  dllPreAuth[dllTotal].protocol = "http";
+  dllPreAuth[dllTotal].transport = 3; //tHTTP
+  dllTotal++;
+}
+
+void LoadPreAuthPlugins()
+{
+  WIN32_FIND_DATA info;
+  HANDLE h;
+
+  LPTSTR  strDLLPath = new TCHAR[_MAX_PATH];
+  LPTSTR  strDLLSearch = new TCHAR[_MAX_PATH];
+  GetModuleFileName(NULL, strDLLPath, _MAX_PATH);
+  PathRemoveFileSpec(strDLLPath);
+  strcat(strDLLPath, "\\MPIPTVplugins\\");
+  strcpy(strDLLSearch, strDLLPath);
+  strcat(strDLLSearch, "*.dll");
+  h = FindFirstFile(strDLLSearch, &info);
+  if (h != INVALID_HANDLE_VALUE) {
+    do {
+      LPTSTR strDLLName = new TCHAR[_MAX_PATH];
+      strcpy(strDLLName, strDLLPath);
+      strcat(strDLLName, info.cFileName);
+      HINSTANCE hGetProcIDDLL = LoadLibrary(strDLLName);
+      if (hGetProcIDDLL == NULL) continue;
+
+      FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hGetProcIDDLL),"GetRealURL"); 
+      if (lpfnGetProcessID == NULL) continue;
+
+//      dllGetRealURL[dllTotal++] = pICFUNC(lpfnGetProcessID); 
+      dllPreAuth[dllTotal].GetRealURL = pICFUNC(lpfnGetProcessID);
+
+      FARPROC lpfnGetProcessID1 = GetProcAddress(HMODULE(hGetProcIDDLL),"GetProtocol"); 
+      if (lpfnGetProcessID1 == NULL) continue;
+      pICFUNC1 GetProtocol;
+      GetProtocol = pICFUNC1(lpfnGetProcessID1);
+      GetProtocol(&dllPreAuth[dllTotal].transport,&dllPreAuth[dllTotal].protocol);
+      dllTotal++;
+      delete strDLLName;
+      if (dllTotal == dllMAX) break;
+    } while (FindNextFile(h, &info));
+    FindClose(h);
+  } else {
+  }
+  delete strDLLPath;
+  delete strDLLSearch;
+}
