Warning: session_start(): open(/var/lib/php/sessions/sess_61e6dtd41557agu6jqa5pvsatc, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
import org.jcodec.api.awt.AWTSequenceEncoder8Bit;
static int framesToEncode = 100000;
p {
inputFilePath("Video to modify", voidfunc(final File video) {
thread {
invertVideo(video);
}
});
}
svoid invertVideo(File video) {
File outFile = prepareProgramFile(addSuffix("inverted-" + video.getName(), ".mp4"));
final LeftQueue lq = new LeftQueue(video);
final RightQueue rq = new RightQueue(outFile);
lq.rightQueue = rq;
stepThreads(1, lq, rq);
}
svoid stepThreads(final int interval, Steppable... engines) {
final EngineGroup group = new EngineGroup(asList(engines));
new L threads;
for (final Steppable s : engines) {
Thread thread = new Thread("Stepper Thread") {
public void run() ctex {
s.step();
while licensed {
while (s.shouldStep) {
s.shouldStep = false;
s.step();
}
synchronized(s) { s.wait(interval); }
}
}
};
s.thread = thread;
threads.add(thread);
}
for (Thread t : threads) t.start();
}
sclass EngineGroup {
L engines;
*(L *engines) {
for (Steppable engine : engines)
engine.group = this;
}
void shouldStep {
for (Steppable engine : engines)
engine.shouldStepLocally();
}
}
abstract sclass Steppable {
volatile bool shouldStep;
Thread thread;
EngineGroup group;
void shouldStep() {
if (group != null)
group.shouldStep();
else
shouldStepLocally();
}
void shouldStepLocally {
shouldStep = true;
synchronized(this) { notifyAll(); }
}
abstract void step();
}
// decoding part
Steppable > LeftQueue {
Iterator stream;
RightQueue rightQueue;
*(File video) {
stream = framesFromVideo_reordering(video);
}
void step {
if (stream != null && rightQueue.needImage())
if (stream.hasNext()) {
rightQueue.receive(stream.next());
shouldStep();
} else {
stream = null;
rightQueue.close();
}
}
}
// encoding part
Steppable > RightQueue {
File outMP4;
AWTSequenceEncoder8Bit enc;
volatile BufferedImage img;
int frames;
volatile bool shouldClose;
*(File *outMP4) ctex {
enc = AWTSequenceEncoder8Bit.create25Fps(outMP4);
enc.getEncoder().setKeyInterval(25);
}
void receive(BufferedImage img) {
if (this.img != null) fail();
this.img = img;
shouldStep();
}
bool needImage() { ret img == null; }
void step ctex {
if (shouldClose) {
shouldClose = false;
close();
}
if (img != null) {
img = invertedImage(img);
enc.encodeImage(img);
img = null;
++frames;
print("Frames: " + frames + "/" + framesToEncode);
if (frames >= framesToEncode) shouldClose = true;
else shouldStep();
}
}
void close ctex {
if (enc != null) {
enc.finish();
enc = null;
print("Wrote " + f2s(outMP4) + " (" + frames + " frames)");
}
}
}