コード例 #1
0
    int64_t MultiFileReader::SetCurrentFilePointer(int64_t timeShiftBufferFilePos, long timeshiftBufferFileID)
    {
        RefreshTSBufferFile();

        if (m_TSFileId != timeshiftBufferFileID)
        {
            // We have to switch to a different buffer file
            TSDEBUG(LOG_DEBUG, "Change buffer file from %i to %i", m_TSFileId, timeshiftBufferFileID);

            MultiFileReaderFile *file = NULL;
            std::vector<MultiFileReaderFile *>::iterator it = m_tsFiles.begin();
            for (; it < m_tsFiles.end(); ++it)
            {
                file = *it;
                if (file->filePositionId == timeshiftBufferFileID)
                    break;
            };

            if (!file)
            {
                XBMC->Log(LOG_ERROR, "MultiFileReader::no buffer file with id=%i", timeshiftBufferFileID);
                XBMC->QueueNotification(QUEUE_ERROR, "No buffer file");
                return m_currentPosition;
            }

            if (m_currentPosition < (file->startPosition + timeShiftBufferFilePos))
            {
                m_TSFile.CloseFile();
                m_TSFile.SetFileName(file->filename.c_str());
                m_TSFile.OpenFile();

                m_TSFileId = file->filePositionId;
                m_currentFileStartOffset = file->startPosition;

                TSDEBUG(LOG_DEBUG, "MultiFileReader::Read() Current File Changed to %s TS file id=%i\n", file->filename.c_str(), m_TSFileId);
            }
        }

        // Reposition the read pointer within the current timeshift buffer file
        TSDEBUG(LOG_DEBUG, "Move read pointer within buffer file %i; %I64d -> %i64d", m_TSFileId, m_currentPosition, m_currentFileStartOffset + timeShiftBufferFilePos);
        m_currentPosition = m_currentFileStartOffset + timeShiftBufferFilePos;

        if (m_currentPosition > m_endPosition)
        {
            XBMC->Log(LOG_ERROR, "Seeking beyond the end position: %I64d > %I64d", m_currentPosition, m_endPosition);
            m_currentPosition = m_endPosition;
        }

        return m_currentPosition;
    }
コード例 #2
0
//
// OpenFile
//
long MultiFileReader::OpenFile()
{
  long hr = m_TSBufferFile.OpenFile();

  //For radio the buffer sometimes needs some time to become available, so wait try it more than once
  unsigned long tc=GetTickCount();
  while (RefreshTSBufferFile()==S_FALSE)
  {
    if (GetTickCount()-tc>MAX_BUFFER_TIMEOUT)
    {
      XBMC->Log(LOG_DEBUG, "MultiFileReader: timedout while waiting for buffer file to become available");
      return S_FALSE;
    }
  }

  m_currentPosition = 0;
  m_llBufferPointer = 0;

  return hr;
}
コード例 #3
0
//
// OpenFile
//
HRESULT MultiFileReader::OpenFile()
{
	HRESULT hr = m_TSBufferFile.OpenFile();

	//For radio the buffer sometimes needs some time to become available, so wait try it more than once
	DWORD tc=GetTickCount();
	while (RefreshTSBufferFile()==S_FALSE)
	{
		if (GetTickCount()-tc>MAX_BUFFER_TIMEOUT)
		{
			LogDebug("MultiFileReader: timedout while waiting for buffer file to become available");
			return S_FALSE;
		}
	}
			

	m_currentPosition = 0;
	m_llBufferPointer = 0;	

	return hr;
}
コード例 #4
0
//
// OpenFile
//
HRESULT MultiFileReader::OpenFile()
{
  CAutoLock rLock (m_pAccessLock);
  SetStopping(false);
  
	HRESULT hr = m_TSBufferFile.OpenFile();

	//For radio the buffer sometimes needs some time to become available, so wait try it more than once
	DWORD tc=GetTickCount();
	while (RefreshTSBufferFile()==S_FALSE)
	{
		if (GetTickCount()-tc > MAX_BUFFER_TIMEOUT)
		{
			LogDebug("MultiFileReader: timed out while waiting for buffer file to become available");
			return S_FALSE;
		}
		Sleep(50);
	}
			
	m_currentPosition = 0;
  //LogDebug("MultiFileReader::OpenFile()");

	return hr;
}
コード例 #5
0
HRESULT MultiFileReader::Read(PBYTE pbData, ULONG lDataLength, ULONG *dwReadBytes)
{
	HRESULT hr;

	// If the file has already been closed, don't continue
	if (m_TSBufferFile.IsFileInvalid())
		return S_FALSE;

	RefreshTSBufferFile();
  RefreshFileSize();

	if (m_currentPosition < m_startPosition)
		m_currentPosition = m_startPosition;

	// Find out which file the currentPosition is in.
	MultiFileReaderFile *file = NULL;
	std::vector<MultiFileReaderFile *>::iterator it = m_tsFiles.begin();
	for ( ; it < m_tsFiles.end() ; it++ )
	{
		file = *it;
		if (m_currentPosition < (file->startPosition + file->length))
			break;
	};

	if(!file)
  {
    LogDebug("MultiFileReader::no file");
		return S_FALSE;
  }
	if (m_currentPosition < (file->startPosition + file->length))
	{
		if (m_TSFileId != file->filePositionId)
		{
			m_TSFile.CloseFile();
			m_TSFile.SetFileName(file->filename);
			m_TSFile.OpenFile();

			m_TSFileId = file->filePositionId;

			if (m_bDebugOutput)
			{
				USES_CONVERSION;
				TCHAR sz[MAX_PATH+128];
				wsprintf(sz, TEXT("Current File Changed to %s\n"), W2T(file->filename));
				//::OutputDebugString(sz);
			}
		}

		__int64 seekPosition = m_currentPosition - file->startPosition;

		m_TSFile.SetFilePointer(seekPosition, FILE_BEGIN);
    __int64 posSeeked=m_TSFile.GetFilePointer();
    if (posSeeked!=seekPosition)
    {
      LogDebug("SEEK FAILED");
    }

		ULONG bytesRead = 0;

		__int64 bytesToRead = file->length - seekPosition;
		if (lDataLength > bytesToRead)
		{
			hr = m_TSFile.Read(pbData, (ULONG)bytesToRead, &bytesRead);
      if (FAILED(hr))
      {
        LogDebug("READ FAILED1");
      }
			m_currentPosition += bytesToRead;

			hr = this->Read(pbData + bytesToRead, lDataLength - (ULONG)bytesToRead, dwReadBytes);
      if (FAILED(hr))
      {
        LogDebug("READ FAILED2");
      }
			*dwReadBytes += bytesRead;
		}
		else
		{
			hr = m_TSFile.Read(pbData, lDataLength, dwReadBytes);
      if (FAILED(hr))
      {
        LogDebug("READ FAILED2");
      }
			m_currentPosition += lDataLength;
		}
	}
	else
	{
		// The current position is past the end of the last file
		*dwReadBytes = 0;
	}

	return S_OK;
}
コード例 #6
0
__int64 MultiFileReader::GetFileSize()
{
  CAutoLock rLock (m_pAccessLock);
  RefreshTSBufferFile();
  return m_endPosition - m_startPosition;
}
コード例 #7
0
HRESULT MultiFileReader::ReadNoLock(PBYTE pbData, ULONG lDataLength, ULONG *dwReadBytes, bool refreshFile)
{
	HRESULT hr = S_OK;

	// If the file has already been closed, don't continue
	if (m_TSBufferFile.IsFileInvalid())
	{
    LogDebug("MultiFileReader::Read() - IsFileInvalid() failure");
		*dwReadBytes = 0;
		return E_FAIL;
	}

  hr = RefreshTSBufferFile();
  
	if (hr != S_OK)
	{
    //LogDebug("MultiFileReader::Read() - RefreshTSBufferFile() failure, HRESULT = 0x%x", hr);
		*dwReadBytes = 0;
		return E_FAIL;
	}

	if (m_currentPosition < m_startPosition)
		m_currentPosition = m_startPosition;
		
	__int64 oldCurrentPosn = m_currentPosition;

	// Find out which file the currentPosition is in (and the next file, if it exists)
	MultiFileReaderFile *file = NULL;
	MultiFileReaderFile *fileNext = NULL;
	bool fileFound = false;
	std::vector<MultiFileReaderFile *>::iterator it = m_tsFiles.begin();
	for ( ; it < m_tsFiles.end() ; it++ )
	{
	  if (fileFound)
	  {
	    fileNext = *it; //This is the next file after the file we need to read
	    break;
	  }	 
	  file = *it; 
		if (m_currentPosition < (file->startPosition + file->length))
		{
		  fileFound = true;
	  }
	};

	if(!file)
  {
    LogDebug("MultiFileReader::no file");
		*dwReadBytes = 0;
		return E_FAIL;
  }
  
  if(!fileFound)
  {
		// The current position is past the end of the last file
		*dwReadBytes = 0;
		return S_FALSE;
  }
  
	if (m_TSFileId != file->filePositionId)
	{
  	if (!m_TSFile.IsFileInvalid())
  	{
  		m_TSFile.CloseFile();
  	}
		m_TSFile.SetFileName(file->filename);
		m_TSFile.OpenFile();
		m_TSFileId = file->filePositionId;		
  	if (m_TSFile.IsFileInvalid())
  	{
      LogDebug("MultiFileReader::new data file, OpenFile() failed");
  		*dwReadBytes = 0;
  		m_TSFileId = -1;
  		return E_FAIL;
  	}
	}
	
	if (refreshFile)
	{
  	// try to clear local / remote SMB file cache. This should happen when we close the filehandle
  	if (!m_TSFile.IsFileInvalid())
  	{
  		m_TSFile.CloseFile();
  	}
  	Sleep(5);
		m_TSFile.OpenFile();
  	if (m_TSFile.IsFileInvalid())
  	{
      LogDebug("MultiFileReader::data file refresh, OpenFile() failed");
  		*dwReadBytes = 0;
  		m_TSFileId = -1;
  		return E_FAIL;
  	}
  	Sleep(5);
	}

  //Start of 'file next' SMB data cache workaround processing
	if(!fileNext && !m_TSFileNext.IsFileInvalid())
  {
  	m_TSFileNext.CloseFile();
    m_TSFileIdNext = -1;
  }
  
  if (fileNext && m_bUseFileNext && m_pFileReadNextBuffer)
  {
  	if (m_TSFileIdNext != fileNext->filePositionId)
  	{
    	if (!m_TSFileNext.IsFileInvalid())
    	{
    		m_TSFileNext.CloseFile();
    	}
  		m_TSFileNext.SetFileName(fileNext->filename);
  		m_TSFileNext.OpenFile();
  		m_TSFileIdNext = fileNext->filePositionId;
  		m_currPosnFileNext = 0;
  		
      //char url[MAX_PATH];
      //WideCharToMultiByte(CP_ACP, 0 ,fileNext->filename, -1, url, MAX_PATH, 0, 0);
      //LogDebug("MultiFileReader::FileNext Changed to %s", url);
      
      if (fileNext->length >= NEXT_READ_SIZE)
      {
        //Do a dummy read to try and refresh the SMB cache
        ULONG bytesNextRead = 0;
    		m_TSFileNext.SetFilePointer(m_currPosnFileNext, FILE_BEGIN);
    		m_TSFileNext.Read(m_pFileReadNextBuffer, NEXT_READ_SIZE, &bytesNextRead);
        m_lastFileNextRead = timeGetTime();
        if (bytesNextRead != NEXT_READ_SIZE)
        {
          char url[MAX_PATH];
          WideCharToMultiByte(CP_ACP, 0 ,fileNext->filename, -1, url, MAX_PATH, 0, 0);
          LogDebug("MultiFileReader::FileNext read 1 failed, bytes %d, posn %I64d, file %s", bytesNextRead, m_currPosnFileNext, url);
        }
    		m_currPosnFileNext += NEXT_READ_SIZE;
    		m_currPosnFileNext %= NEXT_READ_ROLLOVER;
      }
  	}  	
    else if ((fileNext->length >= (m_currPosnFileNext+NEXT_READ_SIZE)) && (timeGetTime() > (m_lastFileNextRead+1100)))
    {
      //Do a dummy read to try and refresh the SMB data cache
      ULONG bytesNextRead = 0;
  		m_TSFileNext.SetFilePointer(m_currPosnFileNext, FILE_BEGIN);
  		m_TSFileNext.Read(m_pFileReadNextBuffer, NEXT_READ_SIZE, &bytesNextRead);
      m_lastFileNextRead = timeGetTime();
      if (bytesNextRead != NEXT_READ_SIZE)
      {
        char url[MAX_PATH];
        WideCharToMultiByte(CP_ACP, 0 ,fileNext->filename, -1, url, MAX_PATH, 0, 0);
        LogDebug("MultiFileReader::FileNext read 2 failed, bytes %d, posn %I64d, file %s", bytesNextRead, m_currPosnFileNext, url);
      }
  		m_currPosnFileNext += NEXT_READ_SIZE;
  		m_currPosnFileNext %= NEXT_READ_ROLLOVER;
    }
  }  
  //End of 'file next' SMB data cache workaround processing

	__int64 seekPosition = m_currentPosition - file->startPosition;

	m_TSFile.SetFilePointer(seekPosition, FILE_BEGIN);
  __int64 posSeeked=m_TSFile.GetFilePointer();
  if (posSeeked!=seekPosition)
  {
    LogDebug("MultiFileReader::SEEK FAILED");
		*dwReadBytes = 0;
		m_currentPosition = oldCurrentPosn;
		return E_FAIL;
  }

	ULONG bytesRead = 0;

	__int64 bytesToRead = file->length - seekPosition;
	
	if (lDataLength > bytesToRead)
	{
    //LogDebug("MultiFileReader::multi-read 0, pbData=%d, lDataLength=%d, bytesToRead=%I64d, bytesRead=%d, m_currentPosition=%I64d, fileLength=%I64d", pbData, lDataLength, bytesToRead, bytesRead, m_currentPosition, file->length);
		hr = m_TSFile.Read(pbData, (ULONG)bytesToRead, &bytesRead);
    if (!SUCCEEDED(hr))
    {
      if (!m_bIsStopping)
      {
        LogDebug("MultiFileReader::READ FAILED1");
      }
	    *dwReadBytes = 0;
		  m_currentPosition = oldCurrentPosn;
      return E_FAIL;
    }
		m_currentPosition += (__int64)bytesRead;
    //LogDebug("MultiFileReader::multi-read 1, pbData=%d, lDataLength=%d, bytesToRead=%I64d, bytesRead=%d, m_currentPosition=%I64d, fileLength=%I64d", pbData, lDataLength, bytesToRead, bytesRead, m_currentPosition, file->length);
    
    if ((bytesRead < bytesToRead) || !fileNext)
    {
      //We haven't got all of the current file segment (so we can't read the next segment), 
      //or there is no 'next file' to read so just return the data we have...
      //LogDebug("MultiFileReader::multi-read 1A, pbData=%d, lDataLength=%d, bytesToRead=%I64d, bytesRead=%d, m_currentPosition=%I64d", pbData, lDataLength, bytesToRead, bytesRead, m_currentPosition);
	    *dwReadBytes = bytesRead;
      return S_FALSE;
    }

		hr = this->ReadNoLock(pbData + (ULONG)bytesToRead, lDataLength - (ULONG)bytesToRead, dwReadBytes, refreshFile);
    if (!SUCCEEDED(hr))
    {
      if (!m_bIsStopping)
      {
        LogDebug("MultiFileReader::READ FAILED2");
      }
	    *dwReadBytes = 0;
		  m_currentPosition = oldCurrentPosn;
      return E_FAIL;
    }
    //LogDebug("MultiFileReader::multi-read 2, pbData=%d, lDataLength=%d, bytesRead=%d, m_currentPosition=%I64d", (pbData + (ULONG)bytesToRead), (lDataLength - (ULONG)bytesToRead), *dwReadBytes, m_currentPosition);
		*dwReadBytes += bytesRead;
	}
	else
	{  	
		hr = m_TSFile.Read(pbData, lDataLength, dwReadBytes);
    if (!SUCCEEDED(hr))
    {
      if (!m_bIsStopping)
      {
        LogDebug("MultiFileReader::READ FAILED3");
      }
	    *dwReadBytes = 0;
		  m_currentPosition = oldCurrentPosn;
      return E_FAIL;
    }
		m_currentPosition += (__int64)*dwReadBytes;
    //LogDebug("MultiFileReader::multi-read 3, pbData=%d, lDataLength=%d, dwReadBytes=%d, m_currentPosition=%I64d, fileLength=%I64d", pbData, lDataLength, *dwReadBytes, m_currentPosition, file->length);
	}

	return hr;
}
コード例 #8
0
 int64_t MultiFileReader::GetFileSize()
 {
   RefreshTSBufferFile();
   return m_endPosition - m_startPosition;
 }
コード例 #9
0
  long MultiFileReader::Read(unsigned char* pbData, unsigned long lDataLength, unsigned long *dwReadBytes)
  {
    long hr;

    // If the file has already been closed, don't continue
    if (m_TSBufferFile.IsFileInvalid())
      return S_FALSE;

    RefreshTSBufferFile();

    if (m_currentReadPosition < m_startPosition)
    {
      XBMC->Log(LOG_DEBUG, "%s: current position adjusted from %%I64dd to %%I64dd.", __FUNCTION__, m_currentReadPosition, m_startPosition);
      m_currentReadPosition = m_startPosition;
    }

    // Find out which file the currentPosition is in.
    MultiFileReaderFile *file = NULL;
    std::vector<MultiFileReaderFile *>::iterator it = m_tsFiles.begin();
    for (; it < m_tsFiles.end(); it++)
    {
      file = *it;
      if (m_currentReadPosition < (file->startPosition + file->length))
        break;
    };

    // XBMC->Log(LOG_DEBUG, "%s: reading %ld bytes. File %s, start %d, current %d, end %d.", __FUNCTION__, lDataLength, file->filename.c_str(), m_startPosition, m_currentPosition, m_endPosition);


    if (!file)
    {
      XBMC->Log(LOG_ERROR, "MultiFileReader::no file");
      XBMC->QueueNotification(QUEUE_ERROR, "No buffer file");
      return S_FALSE;
    }
    if (m_currentReadPosition < (file->startPosition + file->length))
    {
      if (m_TSFileId != file->filePositionId)
      {
        m_TSFile.CloseFile();
        m_TSFile.SetFileName(file->filename.c_str());
        m_TSFile.OpenFile();

        m_TSFileId = file->filePositionId;

        if (m_bDebugOutput)
        {
          XBMC->Log(LOG_DEBUG, "MultiFileReader::Read() Current File Changed to %s\n", file->filename.c_str());
        }
      }

      int64_t seekPosition = m_currentReadPosition - file->startPosition;

      int64_t posSeeked = m_TSFile.GetFilePointer();
      if (posSeeked != seekPosition)
      {
        m_TSFile.SetFilePointer(seekPosition, FILE_BEGIN);
        posSeeked = m_TSFile.GetFilePointer();
        if (posSeeked != seekPosition)
        {
          XBMC->Log(LOG_ERROR, "SEEK FAILED");
        }
      }

      unsigned long bytesRead = 0;

      int64_t bytesToRead = file->length - seekPosition;
      if ((int64_t)lDataLength > bytesToRead)
      {
        // XBMC->Log(LOG_DEBUG, "%s: datalength %lu bytesToRead %lli.", __FUNCTION__, lDataLength, bytesToRead);
        hr = m_TSFile.Read(pbData, (unsigned long)bytesToRead, &bytesRead);
        if (FAILED(hr))
        {
          XBMC->Log(LOG_ERROR, "READ FAILED1");
        }
        m_currentReadPosition += bytesToRead;

        hr = this->Read(pbData + bytesToRead, lDataLength - (unsigned long)bytesToRead, dwReadBytes);
        if (FAILED(hr))
        {
          XBMC->Log(LOG_ERROR, "READ FAILED2");
        }
        *dwReadBytes += bytesRead;
      }
      else
      {
        hr = m_TSFile.Read(pbData, lDataLength, dwReadBytes);
        if (FAILED(hr))
        {
          XBMC->Log(LOG_ERROR, "READ FAILED3");
        }
        m_currentReadPosition += lDataLength;
      }
    }
    else
    {
      // The current position is past the end of the last file
      *dwReadBytes = 0;
    }

    // XBMC->Log(LOG_DEBUG, "%s: read %lu bytes. start %lli, current %lli, end %lli.", __FUNCTION__, *dwReadBytes, m_startPosition, m_currentPosition, m_endPosition);
    return S_OK;
  }
コード例 #10
0
long MultiFileReader::Read(unsigned char* pbData, unsigned long lDataLength, unsigned long *dwReadBytes)
{
  long hr;

  // If the file has already been closed, don't continue
  if (m_TSBufferFile.IsFileInvalid())
    return S_FALSE;

  RefreshTSBufferFile();
  RefreshFileSize();

  if (m_currentPosition < m_startPosition)
    m_currentPosition = m_startPosition;

  // Find out which file the currentPosition is in.
  MultiFileReaderFile *file = NULL;
  std::vector<MultiFileReaderFile *>::iterator it = m_tsFiles.begin();
  for ( ; it < m_tsFiles.end() ; it++ )
  {
    file = *it;
    if (m_currentPosition < (file->startPosition + file->length))
      break;
  };

  if(!file)
  {
    XBMC->Log(LOG_DEBUG, "MultiFileReader::no file");
    return S_FALSE;
  }
  if (m_currentPosition < (file->startPosition + file->length))
  {
    if (m_TSFileId != file->filePositionId)
    {
      m_TSFile.CloseFile();
      m_TSFile.SetFileName(file->filename.c_str());
      m_TSFile.OpenFile();

      m_TSFileId = file->filePositionId;

      if (m_bDebugOutput)
      {
        XBMC->Log(LOG_DEBUG, "MultiFileReader::Read() Current File Changed to %s\n", file->filename.c_str());
      }
    }

    int64_t seekPosition = m_currentPosition - file->startPosition;

    m_TSFile.SetFilePointer(seekPosition, FILE_BEGIN);
    int64_t posSeeked=m_TSFile.GetFilePointer();
    if (posSeeked!=seekPosition)
    {
      XBMC->Log(LOG_DEBUG, "SEEK FAILED");
    }

    unsigned long bytesRead = 0;

    int64_t bytesToRead = file->length - seekPosition;
    if (lDataLength > bytesToRead)
    {
      hr = m_TSFile.Read(pbData, (unsigned long)bytesToRead, &bytesRead);
      if (FAILED(hr))
      {
        XBMC->Log(LOG_DEBUG, "READ FAILED1");
      }
      m_currentPosition += bytesToRead;

      hr = this->Read(pbData + bytesToRead, lDataLength - (unsigned long)bytesToRead, dwReadBytes);
      if (FAILED(hr))
      {
        XBMC->Log(LOG_DEBUG, "READ FAILED2");
      }
      *dwReadBytes += bytesRead;
    }
    else
    {
      hr = m_TSFile.Read(pbData, lDataLength, dwReadBytes);
      if (FAILED(hr))
      {
        XBMC->Log(LOG_DEBUG, "READ FAILED2");
      }
      m_currentPosition += lDataLength;
    }
  }
  else
  {
    // The current position is past the end of the last file
    *dwReadBytes = 0;
  }

  return S_OK;
}