Skip to content

Commit 0a0d546

Browse files
author
Cyrille Favreau
committed
Removed movie making from CircuitExploxer, moved to braynsMediaMaker plugin
1 parent 5da7193 commit 0a0d546

File tree

2 files changed

+3
-268
lines changed

2 files changed

+3
-268
lines changed

plugins/CircuitExplorer/plugin/CircuitExplorerPlugin.cpp

Lines changed: 0 additions & 252 deletions
Original file line numberDiff line numberDiff line change
@@ -410,24 +410,6 @@ void CircuitExplorerPlugin::init()
410410
_attachCircuitSimulationHandler(s);
411411
});
412412

413-
PLUGIN_INFO << "Registering 'export-frames-to-disk' endpoint"
414-
<< std::endl;
415-
_api->getActionInterface()->registerNotification<ExportFramesToDisk>(
416-
"export-frames-to-disk",
417-
[&](const ExportFramesToDisk& s) { _exportFramesToDisk(s); });
418-
419-
PLUGIN_INFO << "Registering 'get-export-frames-progress' endpoint"
420-
<< std::endl;
421-
actionInterface->registerRequest<FrameExportProgress>(
422-
"get-export-frames-progress", [&](void) -> FrameExportProgress {
423-
return _getFrameExportProgress();
424-
});
425-
426-
PLUGIN_INFO << "Registering 'make-movie' endpoint" << std::endl;
427-
actionInterface->registerNotification<MakeMovieParameters>(
428-
"make-movie",
429-
[&](const MakeMovieParameters& params) { _makeMovie(params); });
430-
431413
PLUGIN_INFO << "Registering 'trace-anterograde' endpoint" << std::endl;
432414
_api->getActionInterface()
433415
->registerRequest<AnterogradeTracing, AnterogradeTracingResult>(
@@ -484,43 +466,6 @@ void CircuitExplorerPlugin::preRender()
484466
if (_dirty)
485467
_api->getScene().markModified();
486468
_dirty = false;
487-
488-
if (_exportFramesToDiskDirty && _accumulationFrameNumber == 0)
489-
{
490-
const auto& ai = _exportFramesToDiskPayload.animationInformation;
491-
if (_frameNumber >= ai.size())
492-
_exportFramesToDiskDirty = false;
493-
else
494-
{
495-
const uint64_t i = 11 * _frameNumber;
496-
// Camera position
497-
CameraDefinition cd;
498-
const auto& ci = _exportFramesToDiskPayload.cameraInformation;
499-
cd.origin = {ci[i], ci[i + 1], ci[i + 2]};
500-
cd.direction = {ci[i + 3], ci[i + 4], ci[i + 5]};
501-
cd.up = {ci[i + 6], ci[i + 7], ci[i + 8]};
502-
cd.apertureRadius = ci[i + 9];
503-
cd.focusDistance = ci[i + 10];
504-
_setCamera(cd);
505-
506-
// Animation parameters
507-
_api->getParametersManager().getAnimationParameters().setFrame(
508-
ai[_frameNumber]);
509-
}
510-
}
511-
}
512-
513-
void CircuitExplorerPlugin::postRender()
514-
{
515-
if (_exportFramesToDiskDirty &&
516-
_accumulationFrameNumber == _exportFramesToDiskPayload.spp)
517-
{
518-
_doExportFrameToDisk();
519-
++_frameNumber;
520-
_accumulationFrameNumber = 0;
521-
}
522-
else
523-
++_accumulationFrameNumber;
524469
}
525470

526471
void CircuitExplorerPlugin::_setMaterialExtraAttributes(
@@ -1047,203 +992,6 @@ void CircuitExplorerPlugin::_attachCircuitSimulationHandler(
1047992
}
1048993
}
1049994

1050-
void CircuitExplorerPlugin::_exportFramesToDisk(
1051-
const ExportFramesToDisk& payload)
1052-
{
1053-
_exportFramesToDiskPayload = payload;
1054-
_exportFramesToDiskDirty = true;
1055-
_frameNumber = payload.startFrame;
1056-
_accumulationFrameNumber = 0;
1057-
auto& frameBuffer = _api->getEngine().getFrameBuffer();
1058-
frameBuffer.clear();
1059-
PLUGIN_INFO << "-----------------------------------------------------------"
1060-
"---------------------"
1061-
<< std::endl;
1062-
PLUGIN_INFO << "Movie settings :" << std::endl;
1063-
PLUGIN_INFO << "- Number of frames : "
1064-
<< payload.animationInformation.size() - payload.startFrame
1065-
<< std::endl;
1066-
PLUGIN_INFO << "- Samples per pixel: " << payload.spp << std::endl;
1067-
PLUGIN_INFO << "- Frame size : " << frameBuffer.getSize()
1068-
<< std::endl;
1069-
PLUGIN_INFO << "- Export folder : " << payload.path << std::endl;
1070-
PLUGIN_INFO << "- Start frame : " << payload.startFrame << std::endl;
1071-
PLUGIN_INFO << "-----------------------------------------------------------"
1072-
"---------------------"
1073-
<< std::endl;
1074-
}
1075-
1076-
void CircuitExplorerPlugin::_doExportFrameToDisk()
1077-
{
1078-
auto& frameBuffer = _api->getEngine().getFrameBuffer();
1079-
auto image = frameBuffer.getImage();
1080-
auto fif = _exportFramesToDiskPayload.format == "jpg"
1081-
? FIF_JPEG
1082-
: FreeImage_GetFIFFromFormat(
1083-
_exportFramesToDiskPayload.format.c_str());
1084-
if (fif == FIF_JPEG)
1085-
image.reset(FreeImage_ConvertTo24Bits(image.get()));
1086-
else if (fif == FIF_UNKNOWN)
1087-
throw std::runtime_error("Unknown format: " +
1088-
_exportFramesToDiskPayload.format);
1089-
1090-
int flags = _exportFramesToDiskPayload.quality;
1091-
if (fif == FIF_TIFF)
1092-
flags = TIFF_NONE;
1093-
1094-
brayns::freeimage::MemoryPtr memory(FreeImage_OpenMemory());
1095-
1096-
FreeImage_SaveToMemory(fif, image.get(), memory.get(), flags);
1097-
1098-
BYTE* pixels = nullptr;
1099-
DWORD numPixels = 0;
1100-
FreeImage_AcquireMemory(memory.get(), &pixels, &numPixels);
1101-
1102-
char frame[7];
1103-
sprintf(frame, "%05d", _frameNumber);
1104-
std::string filename = _exportFramesToDiskPayload.path + '/' + frame + "." +
1105-
_exportFramesToDiskPayload.format;
1106-
std::ofstream file;
1107-
file.open(filename, std::ios_base::binary);
1108-
if (!file.is_open())
1109-
PLUGIN_THROW("Failed to create " + filename);
1110-
1111-
file.write((char*)pixels, numPixels);
1112-
file.close();
1113-
1114-
frameBuffer.clear();
1115-
1116-
PLUGIN_INFO << "Frame saved to " << filename << std::endl;
1117-
}
1118-
1119-
FrameExportProgress CircuitExplorerPlugin::_getFrameExportProgress()
1120-
{
1121-
FrameExportProgress result;
1122-
const size_t totalNumberOfFrames =
1123-
(_exportFramesToDiskPayload.animationInformation.size() -
1124-
_exportFramesToDiskPayload.startFrame) *
1125-
_exportFramesToDiskPayload.spp;
1126-
const float currentProgress =
1127-
_frameNumber * _exportFramesToDiskPayload.spp +
1128-
_accumulationFrameNumber;
1129-
1130-
result.progress = currentProgress / float(totalNumberOfFrames);
1131-
return result;
1132-
}
1133-
1134-
void CircuitExplorerPlugin::_makeMovie(const MakeMovieParameters& params)
1135-
{
1136-
// Find ffmpeg executable path
1137-
std::array<char, 256> buffer;
1138-
std::string ffmpegPath;
1139-
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("which ffmpeg", "r"),
1140-
pclose);
1141-
if (!pipe)
1142-
{
1143-
PLUGIN_ERROR << "Could not launch movie creation: ffmpeg not found"
1144-
<< std::endl;
1145-
return;
1146-
}
1147-
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
1148-
{
1149-
ffmpegPath += buffer.data();
1150-
}
1151-
1152-
// Remove new lines
1153-
size_t pos = std::string::npos;
1154-
do
1155-
{
1156-
pos = ffmpegPath.find("\n");
1157-
if (pos != std::string::npos)
1158-
{
1159-
ffmpegPath.replace(pos, pos + 2, "");
1160-
}
1161-
} while (pos != std::string::npos);
1162-
1163-
// Get sanitetized string inputs
1164-
std::string sanitizedFramesFolder = params.framesFolderPath;
1165-
const std::string slash =
1166-
sanitizedFramesFolder[sanitizedFramesFolder.length() - 1] == '/' ? ""
1167-
: "/";
1168-
1169-
std::string sanitizedFramesExt = params.framesFileExtension;
1170-
std::string sanitizedOutputPath = params.outputMoviePath;
1171-
1172-
sanitizedFramesFolder = _sanitizeString(sanitizedFramesFolder);
1173-
sanitizedFramesExt = _sanitizeString(sanitizedFramesExt);
1174-
sanitizedOutputPath = _sanitizeString(sanitizedOutputPath);
1175-
1176-
const std::string inputParam =
1177-
sanitizedFramesFolder + slash + "%05d." + sanitizedFramesExt;
1178-
const std::string filterParam =
1179-
"scale=" + std::to_string(static_cast<int>(params.dimensions[0])) +
1180-
":" + std::to_string(static_cast<int>(params.dimensions[1])) +
1181-
",format=yuv420p";
1182-
const pid_t pid = fork();
1183-
1184-
if (pid == 0)
1185-
{
1186-
execl(ffmpegPath.c_str(), "ffmpeg", "-y", "-hide_banner", "-loglevel",
1187-
"0", "-r", std::to_string(params.fpsRate).c_str(), "-i",
1188-
inputParam.c_str(), "-vf", filterParam.c_str(), "-crf", "0",
1189-
"-codec:v", "libx264", sanitizedOutputPath.c_str(),
1190-
static_cast<char*>(nullptr));
1191-
}
1192-
else
1193-
{
1194-
int status = 0;
1195-
if (waitpid(pid, &status, 0) > 0)
1196-
{
1197-
// If we could not make the movie, inform and stop execution
1198-
if (WIFEXITED(status) && WEXITSTATUS(status))
1199-
{
1200-
if (WEXITSTATUS(status) == 127)
1201-
{
1202-
PLUGIN_ERROR << "Could not create media video file. FFMPEG "
1203-
"returned with error "
1204-
<< status << std::endl;
1205-
return;
1206-
}
1207-
}
1208-
}
1209-
else
1210-
{
1211-
PLUGIN_ERROR << "Could not create media video file. "
1212-
"Could not launch FFMPEG."
1213-
<< std::endl;
1214-
return;
1215-
}
1216-
}
1217-
1218-
if (params.eraseFrames)
1219-
{
1220-
DIR* dir;
1221-
struct dirent* ent;
1222-
const std::regex fileNameRegex("[0-9]{5}." +
1223-
params.framesFileExtension);
1224-
if ((dir = opendir(params.framesFolderPath.c_str())) != nullptr)
1225-
{
1226-
while ((ent = readdir(dir)) != nullptr)
1227-
{
1228-
std::string fileName(ent->d_name);
1229-
if (std::regex_match(fileName, fileNameRegex))
1230-
{
1231-
const std::string fullPath =
1232-
sanitizedFramesFolder + slash + fileName;
1233-
PLUGIN_INFO << "Cleaning frame " << fullPath << std::endl;
1234-
remove(fullPath.c_str());
1235-
}
1236-
}
1237-
closedir(dir);
1238-
}
1239-
else
1240-
{
1241-
PLUGIN_ERROR << "make-movie: Could not clean up frames"
1242-
<< std::endl;
1243-
}
1244-
}
1245-
}
1246-
1247995
AnterogradeTracingResult CircuitExplorerPlugin::_traceAnterogrades(
1248996
const AnterogradeTracing& payload)
1249997
{

plugins/CircuitExplorer/plugin/CircuitExplorerPlugin.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class CircuitExplorerPlugin : public brayns::ExtensionPlugin
4646
* @brief preRender Updates the scene according to latest data load
4747
*/
4848
void preRender() final;
49-
void postRender() final;
5049

5150
private:
5251
// Rendering
@@ -68,26 +67,19 @@ class CircuitExplorerPlugin : public brayns::ExtensionPlugin
6867
void _attachCircuitSimulationHandler(
6968
const AttachCircuitSimulationHandler& payload);
7069

71-
// Movie production
72-
void _exportFramesToDisk(const ExportFramesToDisk& payload);
73-
void _doExportFrameToDisk();
74-
FrameExportProgress _getFrameExportProgress();
75-
void _makeMovie(const MakeMovieParameters& params);
76-
7770
// Anterograde tracing
78-
AnterogradeTracingResult _traceAnterogrades(const AnterogradeTracing& payload);
71+
AnterogradeTracingResult _traceAnterogrades(
72+
const AnterogradeTracing& payload);
7973

8074
// Add geometry
81-
void _createShapeMaterial(brayns::ModelPtr& model,
82-
const size_t id,
75+
void _createShapeMaterial(brayns::ModelPtr& model, const size_t id,
8376
const brayns::Vector3d& color,
8477
const double& opacity);
8578
AddShapeResult _addSphere(const AddSphere& payload);
8679
AddShapeResult _addPill(const AddPill& payload);
8780
AddShapeResult _addCylinder(const AddCylinder& payload);
8881
AddShapeResult _addBox(const AddBox& payload);
8982

90-
9183
// Predefined models
9284
void _addGrid(const AddGrid& payload);
9385
void _addColumn(const AddColumn& payload);
@@ -96,10 +88,5 @@ class CircuitExplorerPlugin : public brayns::ExtensionPlugin
9688
SynapseAttributes _synapseAttributes;
9789

9890
bool _dirty{false};
99-
100-
ExportFramesToDisk _exportFramesToDiskPayload;
101-
bool _exportFramesToDiskDirty{false};
102-
uint16_t _frameNumber{0};
103-
int16_t _accumulationFrameNumber{0};
10491
};
10592
#endif

0 commit comments

Comments
 (0)