mirror of
https://github.com/Team-Resurgent/XBMC4Xbox.git
synced 2026-08-15 11:18:13 -07:00
If ever adding the XBMC4Xbox source to GitHub use "git add -f -A" or it wont add all the files.
186 lines
4.3 KiB
C++
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;
|
|
}
|