tahoma2d/toonz/sources/image/3gp/tiio_3gp_proxy.cpp

436 lines
13 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
2016-06-17 20:48:03 +12:00
#if (defined(x64) || defined(__LP64__) || defined(LINUX))
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Toonz includes
2016-03-19 06:57:51 +13:00
#include "tfilepath.h"
#include "trasterimage.h"
#include "tstream.h"
#include "timageinfo.h"
#include "trop.h"
#include "tsound.h"
2016-06-15 18:43:10 +12:00
// tipc includes
2016-03-19 06:57:51 +13:00
#include "tipc.h"
#include "t32bitsrv_wrap.h"
2016-06-15 18:43:10 +12:00
// Qt includes
2016-03-19 06:57:51 +13:00
#include <QSharedMemory>
#include <QMutexLocker>
#include <QDataStream>
#include "tiio_3gp_proxy.h"
/*
For a list of supported commands through the 32-bit background server,
see the related "t32libserver" project.
*/
//******************************************************************************
// Generic stuff implementation
//******************************************************************************
/*NOT PRESENT: Inherits the MOV stuff*/
//******************************************************************************
// TImageWriter3gp Proxy implementation
//******************************************************************************
2016-06-15 18:43:10 +12:00
class TImageWriter3gpProxy : public TImageWriter {
TLevelWriter3gp *m_lw;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
int m_frameIndex;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TImageWriter3gpProxy(const TFilePath &fp, int frameIndex,
TLevelWriter3gp *lw);
~TImageWriter3gpProxy();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
bool is64bitOutputSupported() { return false; }
void save(const TImageP &);
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
// not implemented
TImageWriter3gpProxy(const TImageWriter3gpProxy &);
TImageWriter3gpProxy &operator=(const TImageWriter3gpProxy &src);
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TImageWriter3gpProxy::TImageWriter3gpProxy(const TFilePath &fp, int frameIndex,
TLevelWriter3gp *lw)
: TImageWriter(fp), m_lw(lw), m_frameIndex(frameIndex) {
m_lw->addRef();
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TImageWriter3gpProxy::~TImageWriter3gpProxy() { m_lw->release(); }
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TImageWriter3gpProxy::save(const TImageP &img) {
m_lw->save(img, m_frameIndex);
2016-03-19 06:57:51 +13:00
}
//******************************************************************************
// TLevelWriter3gp Proxy implementation
//******************************************************************************
TLevelWriter3gp::TLevelWriter3gp(const TFilePath &path, TPropertyGroup *winfo)
2016-06-15 18:43:10 +12:00
: TLevelWriter(path, winfo) {
static TAtomicVar count;
unsigned int currCount = ++count;
m_id = currCount;
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
tipc::Stream stream(&socket);
tipc::Message msg;
QString res, propsFp;
if (winfo) {
// Request a temporary file to store the infos to
stream << (msg << QString("$tmpfile_request")
<< QString("initLW3") + QString::number(currCount));
if (tipc::readMessage(stream, msg) != "ok") goto err;
msg >> propsFp >> tipc::clr;
assert(!propsFp.isEmpty());
TFilePath propsTfp(propsFp.toStdWString());
{
TOStream os(propsTfp);
winfo->saveData(os);
}
}
// Pass fp to the server
stream << (msg << QString("$initLW3gp") << m_id
<< QString::fromStdWString(path.getWideString()) << propsFp);
if (tipc::readMessage(stream, msg) != "ok") goto err;
if (winfo) {
stream << (msg << tipc::clr << QString("$tmpfile_release")
<< QString("initLW3gp") + QString::number(currCount));
if (tipc::readMessage(stream, msg) != "ok") goto err;
}
return;
2016-03-19 06:57:51 +13:00
err:
2016-06-15 18:43:10 +12:00
throw TException("Unable to write file");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TLevelWriter3gp::~TLevelWriter3gp() {
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
QString res;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
stream << (msg << QString("$closeLW3gp") << m_id);
if (tipc::readMessage(stream, msg) != "ok")
throw TException("Unable to write file");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelWriter3gp::setFrameRate(double fps) {
TLevelWriter::setFrameRate(fps);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
QString res;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
stream << (msg << QString("$LW3gpSetFrameRate") << m_id << fps);
if (tipc::readMessage(stream, msg) != "ok")
throw TException("Unexpected error");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TImageWriterP TLevelWriter3gp::getFrameWriter(TFrameId fid) {
if (fid.getLetter() != 0) return TImageWriterP(0);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int index = fid.getNumber() - 1;
return new TImageWriter3gpProxy(m_path, index, this);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelWriter3gp::save(const TImageP &img, int frameIndex) {
TRasterImageP ri(img);
if (!img) throw TImageException(getFilePath(), "Unsupported image type");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TRasterP ras(ri->getRaster());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int lx = ras->getLx(), ly = ras->getLy(), pixSize = ras->getPixelSize();
if (pixSize != 4)
throw TImageException(getFilePath(), "Unsupported pixel type");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int size = lx * ly * pixSize;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Send messages
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Send the write message.
stream << (msg << QString("$LW3gpImageWrite") << m_id << frameIndex << lx
<< ly);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Send the data through a shared memory segment
{
t32bitsrv::RasterExchanger<TPixel32> exch(ras);
tipc::writeShMemBuffer(stream, msg << tipc::clr, size, &exch);
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (tipc::readMessage(stream, msg) != "ok")
throw TImageException(getFilePath(), "Couln't save image");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelWriter3gp::saveSoundTrack(TSoundTrack *st) {
if (st == 0) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Prepare connection
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
unsigned int size = st->getSampleSize() * st->getSampleCount();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Send the saveSoundTract command to the server
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
stream << (msg << QString("$LW3gpSaveSoundTrack") << m_id
<< st->getSampleRate() << st->getBitPerSample()
<< st->getChannelCount() << st->getSampleCount()
<< st->getFormat().m_signedSample);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
t32bitsrv::BufferExchanger exch((UCHAR *)st->getRawData());
tipc::writeShMemBuffer(stream, msg << tipc::clr, size, &exch);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QString res(tipc::readMessage(stream, msg));
assert(res == "ok");
2016-03-19 06:57:51 +13:00
}
//******************************************************************************
// TImageReaderMov Proxy implementation
//******************************************************************************
2016-06-15 18:43:10 +12:00
class TImageReader3gpProxy : public TImageReader {
TLevelReader3gp *m_lr;
TImageInfo *m_info;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
int m_frameIndex;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TImageReader3gpProxy(const TFilePath &fp, int frameIndex, TLevelReader3gp *lr,
TImageInfo *info);
~TImageReader3gpProxy() { m_lr->release(); }
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TImageP load();
void load(const TRasterP &rasP, const TPoint &pos = TPoint(0, 0),
int shrinkX = 1, int shrinkY = 1);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TDimension getSize() const { return m_lr->getSize(); }
TRect getBBox() const { return m_lr->getBBox(); }
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
const TImageInfo *getImageInfo() const { return m_info; }
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
// not implemented
TImageReader3gpProxy(const TImageReader3gpProxy &);
TImageReader3gpProxy &operator=(const TImageReader3gpProxy &src);
2016-03-19 06:57:51 +13:00
};
//------------------------------------------------------------------
TImageReader3gpProxy::TImageReader3gpProxy(const TFilePath &fp, int frameIndex,
2016-06-15 18:43:10 +12:00
TLevelReader3gp *lr,
TImageInfo *info)
: TImageReader(fp), m_lr(lr), m_frameIndex(frameIndex), m_info(info) {
m_lr->addRef();
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TImageP TImageReader3gpProxy::load() {
TRaster32P ras(m_lr->getSize());
m_lr->load(ras, m_frameIndex, TPointI(), 1, 1);
return TRasterImageP(ras);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TImageReader3gpProxy::load(const TRasterP &rasP, const TPoint &pos,
int shrinkX, int shrinkY) {
// NOTE: The original implementation is different. But is also does not make
// sense...
// I've substituted it with the lrm plain call.
m_lr->load(rasP, m_frameIndex, pos, shrinkX, shrinkY);
2016-03-19 06:57:51 +13:00
}
//******************************************************************************
// TLevelReader3gp Proxy implementation
//******************************************************************************
2016-06-15 18:43:10 +12:00
TLevelReader3gp::TLevelReader3gp(const TFilePath &path) : TLevelReader(path) {
static TAtomicVar count;
unsigned int currCount = ++count;
m_id = currCount;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
stream << (msg << QString("$initLR3gp") << m_id
<< QString::fromStdWString(path.getWideString()));
if (tipc::readMessage(stream, msg) != "ok")
throw TImageException(path, "Couldn't open file");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double frameRate;
msg >> m_lx >> m_ly >> frameRate >> tipc::clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
m_info = new TImageInfo;
m_info->m_lx = m_lx;
m_info->m_ly = m_ly;
m_info->m_frameRate = frameRate;
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TLevelReader3gp::~TLevelReader3gp() {
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
stream << (msg << QString("$closeLR3gp") << m_id);
QString res(tipc::readMessage(stream, msg));
assert(res == "ok");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TImageReaderP TLevelReader3gp::getFrameReader(TFrameId fid) {
if (fid.getLetter() != 0) return TImageReaderP(0);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int index = fid.getNumber() - 1;
return new TImageReader3gpProxy(m_path, index, this, m_info);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TLevelP TLevelReader3gp::loadInfo() {
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TLevelP level;
{
QString shMemId(tipc::uniqueId());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Send the appropriate command
stream << (msg << QString("$LR3gpLoadInfo") << m_id << shMemId);
if (tipc::readMessage(stream, msg) != "ok") goto err;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int frameCount;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg >> frameCount >> tipc::clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Read the data in the shared memory segment
QSharedMemory shmem(shMemId);
shmem.attach();
shmem.lock();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int *f, *fBegin = (int *)shmem.data(), *fEnd = fBegin + frameCount;
assert(fBegin);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
for (f = fBegin; f < fEnd; ++f) level->setFrame(*f, TImageP());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
shmem.unlock();
shmem.detach();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Release the shared memory segment
stream << (msg << QString("$shmem_release") << shMemId);
if (tipc::readMessage(stream, msg) != "ok") goto err;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return level;
2016-03-19 06:57:51 +13:00
err:
2016-06-15 18:43:10 +12:00
throw TException("Couldn't read movie data");
return TLevelP();
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelReader3gp::enableRandomAccessRead(bool enable) {
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
stream << (msg << QString("$LR3gpEnableRandomAccessRead") << m_id
<< QString(enable ? "true" : "false"));
QString res(tipc::readMessage(stream, msg));
assert(res == "ok");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TLevelReader3gp::load(const TRasterP &ras, int frameIndex,
const TPoint &pos, int shrinkX, int shrinkY) {
QLocalSocket socket;
tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
t32bitsrv::srvCmdline());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc::Stream stream(&socket);
tipc::Message msg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
unsigned int size = ras->getLx() * ras->getLy() * ras->getPixelSize();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Send the appropriate command to the 32-bit server
stream << (msg << QString("$LR3gpImageRead") << m_id << ras->getLx()
<< ras->getLy() << ras->getPixelSize() << frameIndex << pos.x
<< pos.y << shrinkX << shrinkY);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
t32bitsrv::RasterExchanger<TPixel32> exch(ras);
if (!tipc::readShMemBuffer(stream, msg << tipc::clr, &exch))
throw TException("Couldn't load image");
2016-03-19 06:57:51 +13:00
}
2016-06-15 18:43:10 +12:00
#endif // x64