Files
Rocky5 921f9fe9f8 Clean Copy
If ever adding the XBMC4Xbox source to GitHub use "git add -f -A" or it wont add all the files.
2024-01-08 19:01:29 +00:00

186 lines
4.3 KiB
C++

/*
* Copyright (C) 2011-2013 Team XBMC
* http://xbmc.org
*
* 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 XBMC; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
#include "utils/log.h"
#include "URL.h"
#include "FileItem.h"
#include "DllHDHomeRun.h"
#include "HDHomeRunFile.h"
#include "Util.h"
#include "utils/URIUtils.h"
using namespace XFILE;
using namespace std;
class CUrlOptions
: public map<CStdString, CStdString>
{
public:
CUrlOptions(const CStdString& data)
{
vector<CStdString> options;
CUtil::Tokenize(data, options, "&");
for(vector<CStdString>::iterator it = options.begin();it != options.end(); it++)
{
CStdString name, value;
unsigned int pos = it->find_first_of('=');
if(pos != CStdString::npos)
{
name = it->substr(0, pos);
value = it->substr(pos+1);
}
else
{
name = *it;
value = "";
}
CURL::Decode(name);
CURL::Decode(value);
insert(value_type(name, value));
}
}
};
// -------------------------------------------
// ------------------ File -------------------
// -------------------------------------------
CHomeRunFile::CHomeRunFile()
{
m_device = NULL;
m_pdll = new DllHdHomeRun;
m_pdll->Load();
}
CHomeRunFile::~CHomeRunFile()
{
Close();
delete m_pdll;
}
bool CHomeRunFile::Exists(const CURL& url)
{
CStdString path(url.GetFileName());
/*
* HDHomeRun URLs are of the form hdhomerun://1014F6D1/tuner0?channel=qam:108&program=10
* The filename starts with "tuner" and has no extension. This check will cover off requests
* for *.tbn, *.jpg, *.jpeg, *.edl etc. that do not exist.
*/
if(path.Left(5) == "tuner"
&& URIUtils::GetExtension(path).IsEmpty())
return true;
return false;
}
int64_t CHomeRunFile::Seek(int64_t iFilePosition, int iWhence)
{
return -1;
}
int CHomeRunFile::Stat(const CURL& url, struct __stat64* buffer)
{
memset(buffer, 0, sizeof(struct __stat64));
return 0;
}
int64_t CHomeRunFile::GetPosition()
{
return 0;
}
int64_t CHomeRunFile::GetLength()
{
return 0;
}
bool CHomeRunFile::Open(const CURL &url)
{
if(!m_pdll->IsLoaded())
return false;
m_device = m_pdll->device_create_from_str(url.GetHostName().c_str());
if(!m_device)
return false;
m_pdll->device_set_tuner_from_str(m_device, url.GetFileName().c_str());
CUrlOptions options(url.GetOptions().Mid(1));
CUrlOptions::iterator it;
if( (it = options.find("channel")) != options.end() )
m_pdll->device_set_tuner_channel(m_device, it->second.c_str());
if( (it = options.find("program")) != options.end() )
m_pdll->device_set_tuner_program(m_device, it->second.c_str());
// start streaming from selected device and tuner
if( m_pdll->device_stream_start(m_device) <= 0 )
return false;
return true;
}
unsigned int CHomeRunFile::Read(void* lpBuf, int64_t uiBufSize)
{
unsigned int datasize;
if(uiBufSize < VIDEO_DATA_PACKET_SIZE)
CLog::Log(LOGWARNING, "CHomeRunFile::Read - buffer size too small, will most likely fail");
// for now, let it it time out after 5 seconds,
// neither of the players can be forced to
// continue even if read return 0 as can happen
// on live streams.
DWORD timestamp = GetTickCount() + 5000;
while(1)
{
datasize = (unsigned int)min((unsigned int) uiBufSize,UINT_MAX);
uint8_t* ptr = m_pdll->device_stream_recv(m_device, datasize, &datasize);
if(ptr)
{
memcpy(lpBuf, ptr, datasize);
return datasize;
}
if(GetTickCount() > timestamp)
return 0;
Sleep(64);
}
return datasize;
}
void CHomeRunFile::Close()
{
if(m_device)
{
m_pdll->device_stream_stop(m_device);
m_pdll->device_destroy(m_device);
m_device = NULL;
}
}
int CHomeRunFile::GetChunkSize()
{
return VIDEO_DATA_PACKET_SIZE;
}