/*
* Copyright (C) 2016-2017 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bytedeco.javacv;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.indexer.UByteIndexer;
import org.junit.Test;
import static org.bytedeco.javacpp.avutil.*;
import static org.junit.Assert.*;
/**
* Test cases for FrameGrabber classes. Also uses other classes from JavaCV.
*
* @author Samuel Audet
*/
public class FrameGrabberTest {
@Test public void testFFmpegFrameGrabber() {
System.out.println("FFmpegFrameGrabber");
File tempFile = new File(Loader.getTempDir(), "test.mkv");
try {
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new FileOutputStream(tempFile), 640, 480, 2);
recorder.setFormat("matroska"); // mp4 doesn't support streaming
recorder.setPixelFormat(AV_PIX_FMT_BGR24);
recorder.setVideoCodecName("libx264rgb");
recorder.setVideoQuality(0); // lossless
recorder.setSampleFormat(AV_SAMPLE_FMT_S16);
recorder.setSampleRate(44100);
recorder.setAudioCodecName("pcm_s16le");
recorder.start();
Frame[] frames = new Frame[1000];
for (int n = 0; n < frames.length; n++) {
Frame frame = new Frame(640, 480, Frame.DEPTH_UBYTE, 3);
UByteIndexer frameIdx = frame.createIndexer();
for (int i = 0; i < frameIdx.rows(); i++) {
for (int j = 0; j < frameIdx.cols(); j++) {
for (int k = 0; k < frameIdx.channels(); k++) {
frameIdx.put(i, j, k, n + i + j + k);
}
}
}
recorder.record(frame);
frames[n] = frame;
}
Frame audioFrame = new Frame();
ShortBuffer audioBuffer = ShortBuffer.allocate(64 * 1024);
audioFrame.sampleRate = 44100;
audioFrame.audioChannels = 2;
audioFrame.samples = new ShortBuffer[] {audioBuffer};
for (int i = 0; i < audioBuffer.capacity(); i++) {
audioBuffer.put(i, (short)i);
}
recorder.record(audioFrame);
recorder.stop();
recorder.release();
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new FileInputStream(tempFile));
grabber.setSampleMode(FrameGrabber.SampleMode.FLOAT);
grabber.start();
int n = 0, m = 0;
Frame frame2;
while ((frame2 = grabber.grab()) != null) {
if (frame2.image != null) {
Frame frame = frames[n++];
assertEquals(frame.imageWidth, frame2.imageWidth);
assertEquals(frame.imageHeight, frame2.imageHeight);
assertEquals(frame.imageChannels, frame2.imageChannels);
UByteIndexer frameIdx = frame.createIndexer();
UByteIndexer frame2Idx = frame2.createIndexer();
for (int i = 0; i < frameIdx.rows(); i++) {
for (int j = 0; j < frameIdx.cols(); j++) {
for (int k = 0; k < frameIdx.channels(); k++) {
int b = frameIdx.get(i, j, k);
assertEquals(b, frame2Idx.get(i, j, k));
}
}
}
} else {
FloatBuffer audioBuffer2 = (FloatBuffer)frame2.samples[0];
while (audioBuffer2.hasRemaining()) {
assertEquals((float)audioBuffer.get(m++) / (Short.MAX_VALUE + 1), audioBuffer2.get(), 0);
}
}
}
assertEquals(frames.length, n);
assertEquals(null, grabber.grab());
grabber.restart();
grabber.stop();
grabber.release();
} catch (Exception e) {
fail("Exception should not have been thrown: " + e);
} finally {
tempFile.delete();
}
}
}