Skip to content

Commit

Permalink
修复大于2G视频seek失败的问题, 详细见 Jackarain#8
Browse files Browse the repository at this point in the history
Signed-off-by: Jack <[email protected]>
  • Loading branch information
Jackarain committed Apr 15, 2013
1 parent 9a2aa85 commit 4c8777a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 60 deletions.
2 changes: 1 addition & 1 deletion libtorrent/src/torrent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ namespace libtorrent

if (rdf)
{
rdf(rp->piece_data.get(), r.piece * m_torrent_file->piece_length(), size);
rdf(rp->piece_data.get(), r.piece * boost::int64_t(m_torrent_file->piece_length()), size);
}

// delete rp;
Expand Down
80 changes: 26 additions & 54 deletions source/file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,17 @@
#include "internal.h"
#include "file_source.h"

static const int BUFFER_SIZE = (1 << 21);
static const int AVG_READ_SIZE = (BUFFER_SIZE >> 1);

#ifndef AVSEEK_SIZE
#define AVSEEK_SIZE 0x10000
#endif

#ifdef WIN32
static
uint64_t file_size(const char *filename)
{
WIN32_FILE_ATTRIBUTE_DATA fad = { 0 };

if (!::GetFileAttributesExA(filename, ::GetFileExInfoStandard, &fad))
return -1;
return (static_cast<uint64_t>(fad.nFileSizeHigh)
<< (sizeof(fad.nFileSizeLow) * 8)) + fad.nFileSizeLow;
}
#else
static
uint64_t file_size(const char *sFileName)
{
struct stat buf;
if(stat(sFileName, &buf) != 0)
return(-1);
return (buf.st_size);
}
#endif // WIN32

file_source::file_source()
: m_file(NULL)
, m_file_size(0)
{
pthread_mutex_init(&m_mutex, NULL);
}
{}

file_source::~file_source()
{
close();
pthread_mutex_destroy(&m_mutex);
if (m_open_data)
delete m_open_data;
}
Expand All @@ -52,72 +23,73 @@ bool file_source::open(boost::any ctx)
// 保存ctx.
m_open_data = boost::any_cast<open_file_data*>(ctx);

// 打开文件.
if (access(m_open_data->filename.c_str(), 0) == -1)
// 文件是否存在.
if (!boost::filesystem::exists(m_open_data->filename))
return false;

// 获得文件大小.
m_file_size = file_size(m_open_data->filename.c_str());

// 打开文件.
m_file = fopen(m_open_data->filename.c_str(), "rb");
if (!m_file)
m_file.open(m_open_data->filename, std::ios::binary|std::ios::in);
if (!m_file.is_open())
return false;

// 设置缓冲区大小.
setvbuf(m_file, NULL, _IOFBF, BUFFER_SIZE);

return true;
}

bool file_source::read_data(char* data, size_t size, size_t &read_size)
{
// 根据参数加锁.
if (m_open_data->is_multithread)
pthread_mutex_lock(&m_mutex);
m_mutex.lock();

if (!m_file)
{
if (m_open_data->is_multithread)
pthread_mutex_unlock(&m_mutex);
m_mutex.unlock();
return false;
}

// 开始读取数据.
read_size = fread(data, 1, size, m_file);
m_file.read(data, size);
read_size = m_file.gcount();

if (m_open_data->is_multithread)
pthread_mutex_unlock(&m_mutex);
m_mutex.unlock();

return true;
}

int64_t file_source::read_seek(uint64_t offset, int whence)
{
// 参数检查.
if (offset > m_file_size || !m_file)
int64_t ret = boost::filesystem::file_size(m_open_data->filename);

if (offset > ret || !m_file.is_open())
return false;

if (m_open_data->is_multithread)
pthread_mutex_lock(&m_mutex);
m_mutex.lock();

int64_t ret = m_file_size;
std::ios_base::seekdir way = (std::ios_base::seekdir)whence;

// 进行seek操作.
if (whence != AVSEEK_SIZE)
ret = fseek(m_file, offset, whence);
{
m_file.clear();
m_file.seekg(offset, way);
if (m_file.good())
ret = 0;
else
ret = -1;
}

if (m_open_data->is_multithread)
pthread_mutex_unlock(&m_mutex);
m_mutex.unlock();

return ret;
}

void file_source::close()
{
if (m_file)
{
fclose(m_file);
m_file = NULL;
}
if (m_file.is_open())
m_file.close();
}
11 changes: 6 additions & 5 deletions source/file_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
#endif

#include <string>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread/mutex.hpp>

#include "av_source.h"


struct open_file_data
{
// 是否是多线程访问.
Expand Down Expand Up @@ -50,13 +54,10 @@ class file_source
open_file_data *m_open_data;

// 文件指针.
FILE *m_file;

// 文件大小.
uint64_t m_file_size;
boost::filesystem::fstream m_file;

// 线程安全锁.
mutable pthread_mutex_t m_mutex;
mutable boost::mutex m_mutex;
};

#endif // __FILE_SOURCE_H__
Expand Down

0 comments on commit 4c8777a

Please sign in to comment.