Skip to content

Commit

Permalink
Initial version of Capture plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
dkulp committed May 2, 2024
1 parent 656058e commit c3867c4
Show file tree
Hide file tree
Showing 8 changed files with 530 additions and 617 deletions.
899 changes: 282 additions & 617 deletions LICENSE

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
SRCDIR ?= /opt/fpp/src
include $(SRCDIR)/makefiles/common/setup.mk
include $(SRCDIR)/makefiles/platform/*.mk

all: libfpp-Capture.$(SHLIB_EXT)
debug: all

CFLAGS+=-I.
OBJECTS_fpp_capture_so += src/FPPCapture.o
LIBS_fpp_capture_so += -L$(SRCDIR) -lfpp -ljsoncpp -lhttpserver
CXXFLAGS_src/FPPCapture.o += -I$(SRCDIR)


%.o: %.cpp Makefile
$(CCACHE) $(CC) $(CFLAGS) $(CXXFLAGS) $(CXXFLAGS_$@) -c $< -o $@

libfpp-Capture.$(SHLIB_EXT): $(OBJECTS_fpp_capture_so) $(SRCDIR)/libfpp.$(SHLIB_EXT)
$(CCACHE) $(CC) -shared $(CFLAGS_$@) $(OBJECTS_fpp_capture_so) $(LIBS_fpp_capture_so) $(LDFLAGS) -o $@

clean:
rm -f libfpp-Capture.so $(OBJECTS_fpp_capture_so)

29 changes: 29 additions & 0 deletions callbacks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash


for var in "$@"
do
case $var in
-l|--list)
echo "c++";
exit 0;
;;
-h|--help)
usage
exit 0
;;
-v|--version)
printf "%s, version %s\n" "$PROGRAM_NAME" "$PROGRAM_VERSION"
exit 0
;;
--)
# no more arguments to parse
break
;;
*)
printf "Unknown option %s\n" "$var"
exit 1
;;
esac
done

8 changes: 8 additions & 0 deletions scripts/fpp_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

# fpp-Capture install script

BASEDIR=$(dirname $0)
cd $BASEDIR
cd ..
make "SRCDIR=${SRCDIR}"
10 changes: 10 additions & 0 deletions scripts/fpp_uninstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

# fpp-Capture uninstall script
echo "Running fpp-Capture uninstall Script"

BASEDIR=$(dirname $0)
cd $BASEDIR
cd ..
make clean "SRCDIR=${SRCDIR}"

8 changes: 8 additions & 0 deletions scripts/preStart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

echo "Running fpp-Capture PreStart Script"

BASEDIR=$(dirname $0)
cd $BASEDIR
cd ..
make "SRCDIR=${SRCDIR}"
166 changes: 166 additions & 0 deletions src/FPPCapture.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include <fpp-pch.h>

#include <unistd.h>
#include <ifaddrs.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <fstream>
#include <list>
#include <vector>
#include <sstream>
#include <httpserver.hpp>
#include <SysSocket.h>
#include <cmath>


#include "FPPCapture.h"

#include "commands/Commands.h"
#include "common.h"
#include "settings.h"
#include "Plugin.h"
#include "log.h"
#include "channeloutput/ChannelOutputSetup.h"
#include "fseq/FSEQFile.h"


class FPPStartCaptureCommand;
class FPPStopCaptureCommand;

class FPPCapturePlugin : public FPPPlugins::Plugin, public FPPPlugins::ChannelDataPlugin, public FPPPlugins::APIProviderPlugin {
public:

FPPCapturePlugin() : FPPPlugins::Plugin("fpp-Capture"), FPPPlugins::ChannelDataPlugin(), FPPPlugins::APIProviderPlugin () {
LogInfo(VB_PLUGIN, "Initializing FPP Capture Plugin\n");
}
virtual ~FPPCapturePlugin();

virtual void modifyChannelData(int ms, uint8_t* seqData) override {
if (capturing) {
if (frame == 0) {
startMS = GetTimeMS();
}
captureFile->addFrame(frame++, seqData);
}
}
void stopCapturing() {
if (capturing) {
capturing = false;
std::string fname = captureFile->getFilename();
captureFile->finalize();
delete captureFile;
captureFile = nullptr;

if (frame) {
uint64_t endMS = GetTimeMS();
float timing = (endMS - startMS);
timing /= frame;
printf("Frames: %d Timing: %f\n", frame, timing);

FSEQFile *src = FSEQFile::openFSEQFile(fname);
V2FSEQFile *dest = (V2FSEQFile*)FSEQFile::createFSEQFile(fname.substr(0, fname.length() - 8), 2, FSEQFile::CompressionType::zstd, 1);
dest->initializeFromFSEQ(*src);
dest->setStepTime(std::round(timing));
dest->setNumFrames(frame);
dest->enableMinorVersionFeatures(2);
for (auto &r : GetOutputRanges(false)) {
dest->m_sparseRanges.push_back(r);
}
dest->writeHeader();

int max = src->getMaxChannel() + 10;
uint8_t *data = new uint8_t[max];
std::vector<std::pair<uint32_t, uint32_t>> ranges;
src->prepareRead(ranges, 0);
for (int x = 0; x < frame; x++) {
src->getFrame(x)->readFrame(data, max);
dest->addFrame(x, data);
}
dest->finalize();
delete dest;
delete src;
}
}
}
bool startCapturing(const std::string &filename) {
if (capturing) {
return false;
}
frame = 0;
std::string file = FPP_DIR_SEQUENCE("/" + filename + ".capture");
captureFile = (V2FSEQFile*)FSEQFile::createFSEQFile(file, 2, FSEQFile::CompressionType::zstd, -1);
captureFile->enableMinorVersionFeatures(2);
startMS = GetTimeMS();
captureFile->setStepTime(25);
captureFile->setNumFrames(48000); //20 minutes of frames, we'll adjust at end
FSEQFile::VariableHeader header;
header.code[0] = 's';
header.code[1] = 'p';
std::string ver = "FPP Capture Plugin";
int len = strlen(ver.c_str()) + 1;
header.data.resize(len);
strcpy((char *)&header.data[0], ver.c_str());
captureFile->addVariableHeader(header);

uint32_t max = INT32_MAX;
for (auto &r : GetOutputRanges(false)) {
max = std::max(max, r.second);
captureFile->m_sparseRanges.push_back(r);
}
captureFile->setChannelCount(max);
captureFile->writeHeader();
capturing = true;
return true;
}

virtual void addControlCallbacks(std::map<int, std::function<bool(int)>> &callbacks) override;

bool capturing = false;
V2FSEQFile *captureFile;
uint32_t frame;
uint64_t startMS;
};

class FPPStartCaptureCommand : public Command {
public:
FPPStartCaptureCommand(FPPCapturePlugin *p) : Command("FSEQ Capture Start"), plugin(p) {
args.push_back(CommandArg("FSEQ", "string", "FSEQ"));
}

virtual std::unique_ptr<Command::Result> run(const std::vector<std::string> &args) override {
if (!plugin->startCapturing(args[0])) {
return std::make_unique<Command::ErrorResult>("Failed to start capture");
}
return std::make_unique<Command::Result>("FSEQ Capture Started");
}
FPPCapturePlugin *plugin;
};
class FPPStopCaptureCommand : public Command {
public:
FPPStopCaptureCommand(FPPCapturePlugin *p) : Command("FSEQ Capture Stop"), plugin(p) {
}

virtual std::unique_ptr<Command::Result> run(const std::vector<std::string> &args) override {
plugin->stopCapturing();
return std::make_unique<Command::Result>("FSEQ Capture Stopped");
}
FPPCapturePlugin *plugin;
};

FPPCapturePlugin::~FPPCapturePlugin() {
}

void FPPCapturePlugin::addControlCallbacks(std::map<int, std::function<bool(int)>> &callbacks) {
CommandManager::INSTANCE.addCommand(new FPPStartCaptureCommand(this));
CommandManager::INSTANCE.addCommand(new FPPStopCaptureCommand(this));
}


extern "C" {
FPPCapturePlugin *createPlugin() {
return new FPPCapturePlugin();
}
}
5 changes: 5 additions & 0 deletions src/FPPCapture.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#ifndef __FPPCAPTURE__
#define __FPPCAPTURE__


#endif

0 comments on commit c3867c4

Please sign in to comment.