tahoma2d/toonz/sources/t32bitsrv/t32movmsg.cpp

621 lines
15 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13: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 stuff
2016-03-19 06:57:51 +13:00
#include "tiio.h"
#include "timage_io.h"
#include "tlevel_io.h"
#include "trasterimage.h"
#include "traster.h"
#include "tstream.h"
#include "movsettings.h"
#include "tproperty.h"
#include "tsound.h"
#if defined(_WIN32)
2016-03-19 06:57:51 +13:00
#include "../image/mov/tiio_mov.h"
#elif defined(MACOSX)
2016-03-19 06:57:51 +13:00
#include "../image/mov/tiio_movM.h"
#include <ApplicationServices/ApplicationServices.h>
#endif
2016-06-15 18:43:10 +12:00
// Qt stuff
2016-03-19 06:57:51 +13:00
#include <QString>
#include <QHash>
#include <QSharedMemory>
#include <QDebug>
#include <QLocalSocket>
#include <QDataStream>
2016-06-15 18:43:10 +12:00
// tipc includes
2016-03-19 06:57:51 +13:00
#include "tipc.h"
#include "tipcmsg.h"
#include "tipcsrv.h"
#include "t32bitsrv_wrap.h"
#include "t32movmsg.h"
//---------------------------------------------------
// Diagnostics stuff
//#define TIPC_DEBUG
#ifdef TIPC_DEBUG
#define tipc_debug(expr) expr
#else
#define tipc_debug(expr)
#endif
#ifdef TIPC_DEBUG
#include <QTime>
#endif
//---------------------------------------------------
// Local namespace stuff
2016-06-15 18:43:10 +12:00
namespace {
2016-03-19 06:57:51 +13:00
QHash<unsigned int, TLevelReaderP> readers;
QHash<unsigned int, TLevelWriterP> writers;
}
//---------------------------------------------------
using namespace tipc;
2016-06-15 18:43:10 +12:00
namespace mov_io {
void addParsers(tipc::Server *srv) {
srv->addParser(new IsQTInstalledParser);
srv->addParser(new DefaultMovPropsParser);
srv->addParser(new OpenMovSettingsPopupParser);
srv->addParser(new InitLWMovParser);
srv->addParser(new LWSetFrameRateParser);
srv->addParser(new LWImageWriteParser);
srv->addParser(new LWSaveSoundTrackParser);
srv->addParser(new CloseLWMovParser);
srv->addParser(new InitLRMovParser);
srv->addParser(new LRLoadInfoParser);
srv->addParser(new LREnableRandomAccessReadParser);
srv->addParser(new LRImageReadParser);
srv->addParser(new LRImageReadSHMParser);
srv->addParser(new CloseLRMovParser);
2016-03-19 06:57:51 +13:00
#ifdef WIN32
2016-06-15 18:43:10 +12:00
srv->addParser(new LRSetYMirrorParser);
srv->addParser(new LRSetLoadTimecodeParser);
srv->addParser(new LRTimecodeParser);
2016-03-19 06:57:51 +13:00
#endif
}
//************************************************************************
// IsQTInstalled Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void IsQTInstalledParser::operator()(Message &msg) {
bool ret = Tiio::isQuicktimeInstalled();
msg << clr << QString((ret) ? "yes" : "no");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// DefaultMovProps Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void DefaultMovPropsParser::operator()(Message &msg) {
// Ensure the file path was passed - and retrieve it
QString reply;
msg >> reply >> clr;
if (reply.isEmpty()) goto err;
2016-03-19 06:57:51 +13:00
#ifdef WIN32
2016-06-15 18:43:10 +12:00
// Ensure that QuickTime is correctly running
if (InitializeQTML(0) != noErr) goto err;
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
// Success - retrieve the props
{
TPropertyGroup movProps;
{
// Low-level QuickTime stuff
ComponentInstance ci = OpenDefaultComponent(StandardCompressionType,
StandardCompressionSubType);
QTAtomContainer settings;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (SCGetSettingsAsAtomContainer(ci, &settings) != noErr) assert(false);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
fromAtomsToProperties(settings, movProps);
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Write the retrieved properties
TFilePath tfp(reply.toStdWString());
TOStream os(tfp);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
movProps.saveData(os);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return;
2016-03-19 06:57:51 +13:00
err:
2016-06-15 18:43:10 +12:00
msg << QString("err");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// OpenMovSettingsPopup Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void OpenMovSettingsPopupParser::operator()(Message &msg) {
// Open the properties file
QString fp;
msg >> fp >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Retrieve the properties
TPropertyGroup *props = new TPropertyGroup;
TFilePath tfp(fp.toStdWString());
{
TIStream is(tfp);
props->loadData(is);
}
2016-03-19 06:57:51 +13:00
#ifdef MACOSX
2016-06-15 18:43:10 +12:00
ProcessSerialNumber psn = {0, kCurrentProcess};
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
openMovSettingsPopup(props, true);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
{
TOStream os(tfp); // Should NOT append
props->saveData(os);
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
delete props;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// InitLWMov Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void InitLWMovParser::operator()(Message &msg) {
unsigned int id;
QString fp, propsFp;
msg >> id >> fp >> propsFp >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TFilePath tfp(fp.toStdWString()), propsTFp(propsFp.toStdWString());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
try {
TPropertyGroup *props = 0;
if (!propsTFp.isEmpty()) {
props = new TPropertyGroup;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TIStream is(propsTFp);
props->loadData(is);
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
writers.insert(id, TLevelWriterP(tfp, props));
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
} catch (...) {
msg << QString("err");
}
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LWsetFrameRate Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LWSetFrameRateParser::operator()(Message &msg) {
unsigned int id;
double fps;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg >> id >> fps >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
writers.find(id).value()->setFrameRate(fps);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LWImageWrite Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LWImageWriteParser::operator()(Message &msg) {
unsigned int id;
int frameIdx, lx, ly;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg >> id >> frameIdx >> lx >> ly;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Read the data through a shared memory segment
TRaster32P ras(lx, ly);
t32bitsrv::RasterExchanger<TPixel32> exch(ras);
tipc::readShMemBuffer(*stream(), msg, &exch);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Save the image
try {
TImageWriterP iw(writers.find(id).value()->getFrameWriter(frameIdx + 1));
iw->save(TRasterImageP(ras));
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
} catch (...) {
msg << QString("err");
}
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LWSaveSoundTrack Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LWSaveSoundTrackParser::operator()(Message &msg) {
unsigned int id;
QString shMemId;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TUINT32 sampleRate;
TINT32 sCount;
int bps, chanCount;
bool signedSample;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg >> id >> sampleRate >> bps >> chanCount >> sCount >> signedSample;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Retrieve the soundtrack buffer
TSoundTrackP st =
TSoundTrack::create(sampleRate, bps, chanCount, sCount, signedSample);
t32bitsrv::BufferExchanger exch((UCHAR *)st->getRawData());
tipc::readShMemBuffer(*stream(), msg, &exch);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Write the soundtrack
try {
writers.find(id).value()->saveSoundTrack(st.getPointer());
msg << QString("ok");
} catch (...) {
msg << QString("err");
}
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// CloseLWMov Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void CloseLWMovParser::operator()(Message &msg) {
unsigned int id;
msg >> id >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
try {
writers.take(id);
msg << QString("ok");
} catch (...) {
msg << QString("err");
}
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// InitLRMov Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void InitLRMovParser::operator()(Message &msg) {
unsigned int id;
QString fp, propsFp;
msg >> id >> fp >> clr;
assert(!fp.isEmpty());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TFilePath tfp(fp.toStdWString());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
try {
TLevelReaderP lrm(tfp);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Extract some info to be returned
const TImageInfo *info = lrm->getImageInfo();
if (!info) throw TImageException(tfp, "Couldn't retrieve image properties");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int lx = info->m_lx, ly = info->m_ly;
double frameRate = info->m_frameRate;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc_debug(qDebug() << "Inserted image"
<< QString::fromStdWString(tfp.getWideString()));
readers.insert(id, lrm);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok") << lx << ly << frameRate;
} catch (...) {
msg << QString("err");
}
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LRLoadInfo Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LRLoadInfoParser::operator()(Message &msg) {
// Read command data
unsigned int id;
QString shMemId;
msg >> id >> shMemId >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) goto err;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Read level infos
{
TLevelP level;
try {
level = it.value()->loadInfo();
} catch (...) {
goto err;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int frameCount = level->getFrameCount();
if (!shMemId.isEmpty()) {
// Create a shared memory segment to transfer the infos to
tipc::DefaultMessageParser<SHMEM_REQUEST> msgParser;
Message shMsg;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
shMsg << shMemId << frameCount * (int)sizeof(int) << reset;
msgParser(shMsg);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QString str;
shMsg >> reset >> str;
if (str != QString("ok")) goto err;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Copy level data to 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
TLevel::Table *table = level->getTable();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TLevel::Table::const_iterator jt;
int *f = (int *)shmem.data();
for (jt = table->begin(); jt != table->end(); ++jt, ++f)
*f = jt->first.getNumber();
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
msg << QString("ok") << frameCount;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return;
2016-03-19 06:57:51 +13:00
err:
2016-06-15 18:43:10 +12:00
msg << QString("err");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LREnableRandomAccessRead Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LREnableRandomAccessReadParser::operator()(Message &msg) {
unsigned int id;
QString str;
msg >> id >> str >> clr;
bool enable = (str == "true");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) {
msg << QString("err");
return;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
it.value()->enableRandomAccessRead(enable);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LRSetYMirror Parser
//************************************************************************
#ifdef WIN32
2016-06-15 18:43:10 +12:00
void LRSetYMirrorParser::operator()(Message &msg) {
unsigned int id;
QString str;
msg >> id >> str >> clr;
bool enable = (str == "true");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) {
msg << QString("err");
return;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
static_cast<TLevelReaderMov *>(it.value().getPointer())->setYMirror(enable);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LRSetLoadTimecode Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LRSetLoadTimecodeParser::operator()(Message &msg) {
unsigned int id;
QString str;
msg >> id >> str >> clr;
bool enable = (str == "true");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) {
msg << QString("err");
return;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
static_cast<TLevelReaderMov *>(it.value().getPointer())
->setLoadTimecode(enable);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LRTimecode Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LRTimecodeParser::operator()(Message &msg) {
unsigned int id;
int frameIdx;
QString str;
msg >> id >> frameIdx >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) {
msg << QString("err");
return;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
UCHAR hh, mm, ss, ff;
static_cast<TLevelReaderMov *>(it.value().getPointer())
->timecode(frameIdx, hh, mm, ss, ff);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg << QString("ok") << hh << mm << ss << ff;
2016-03-19 06:57:51 +13:00
}
#endif
//************************************************************************
// LRImageRead Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LRImageReadParser::operator()(Message &msg) {
tipc_debug(QTime fTime; QTime irTime; QTime shTime; fTime.start(););
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
{
unsigned int id;
int lx, ly, pixSize, frameIdx, x, y, shrinkX, shrinkY;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
msg >> id >> lx >> ly >> pixSize >> frameIdx >> x >> y >> shrinkX >>
shrinkY >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (pixSize != 4) goto err;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) goto err;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc_debug(irTime.start());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Load the raster
TRaster32P ras(lx, ly);
try {
TImageReaderP ir(it.value()->getFrameReader(frameIdx + 1));
ir->load(ras, TPoint(x, y), shrinkX, shrinkY);
} catch (...) {
goto err;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc_debug(qDebug() << "load time:" << irTime.elapsed());
tipc_debug(shTime.start());
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
t32bitsrv::RasterExchanger<TPixel32> exch(ras);
if (!tipc::writeShMemBuffer(*stream(), msg << clr,
lx * ly * sizeof(TPixel32), &exch))
goto err;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc_debug(qDebug() << "exchange time:" << shTime.elapsed());
tipc_debug(qDebug() << "TLevelReaderMov::loadImage time:"
<< fTime.elapsed());
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return;
2016-03-19 06:57:51 +13:00
err:
2016-06-15 18:43:10 +12:00
msg << QString("err");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// LRImageReadSHM Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void LRImageReadSHMParser::operator()(Message &msg) {
tipc_debug(QTime fTime; QTime irTime; fTime.start(););
unsigned int id;
int lx, ly, frameIdx;
QString shMemId;
msg >> id >> lx >> ly >> frameIdx >> shMemId >> clr;
tipc_debug(qDebug() << "LoadImageSHM data:" << id << lx << ly << frameIdx
<< shMemId);
QHash<unsigned int, TLevelReaderP>::iterator it = readers.find(id);
if (it == readers.end()) goto err;
// Attach the shared memory segment the raster
{
QSharedMemory shm(shMemId);
shm.attach();
if (!shm.isAttached()) goto err;
// Load the raster
TRaster32P ras(lx, ly, lx, (TPixel32 *)shm.data());
try {
tipc_debug(qDebug() << "loading image...");
tipc_debug(irTime.start());
shm.lock();
TImageReaderP ir(it.value()->getFrameReader(frameIdx + 1));
ir->load(ras, TPoint(), 1, 1);
shm.unlock();
tipc_debug(qDebug() << "load time:" << irTime.elapsed());
} catch (TImageException e) {
shm.unlock();
tipc_debug(qDebug() << "Image Read Error:"
<< QString::fromStdWString(e.getMessage()));
goto err;
} catch (...) {
shm.unlock();
tipc_debug(qDebug() << "Unknown Image Read Error");
goto err;
}
}
msg << QString("ok");
2016-03-19 06:57:51 +13:00
#ifdef WIN32
2016-06-15 18:43:10 +12:00
UCHAR hh, mm, ss, ff;
TLevelReaderMov *lrm =
static_cast<TLevelReaderMov *>(it.value().getPointer());
lrm->loadedTimecode(hh, mm, ss, ff);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
tipc_debug(qDebug() << "TLevelReaderMov::loadImage time:" << fTime.elapsed());
msg << hh << mm << ss << ff;
2016-03-19 06:57:51 +13:00
#endif
2016-06-15 18:43:10 +12:00
return;
2016-03-19 06:57:51 +13:00
err:
2016-06-15 18:43:10 +12:00
msg << QString("err");
2016-03-19 06:57:51 +13:00
}
//************************************************************************
// CloseLRMov Parser
//************************************************************************
2016-06-15 18:43:10 +12:00
void CloseLRMovParser::operator()(Message &msg) {
unsigned int id;
msg >> id >> clr;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
readers.take(id);
msg << QString("ok");
2016-03-19 06:57:51 +13:00
}
2016-06-15 18:43:10 +12:00
} // namespace mov_io
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
#endif // !x64 && !__LP64__