package com.github.sarxos.webcam.ds.gst1.impl;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.concurrent.Exchanger;
import org.freedesktop.gstreamer.Buffer;
import org.freedesktop.gstreamer.FlowReturn;
import org.freedesktop.gstreamer.Sample;
import org.freedesktop.gstreamer.Structure;
import org.freedesktop.gstreamer.elements.AppSink;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.sarxos.webcam.WebcamException;
/**
* This class is a sample {@link AppSink} listener which is invoked when a new buffer is ready.
*
* @author Bartosz Firyn (sarxos)
*/
public class AppSinkNewSampleListener implements AppSink.NEW_SAMPLE {
/**
* Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(AppSinkNewSampleListener.class);
private final Exchanger<BufferedImage> exchanger;
public AppSinkNewSampleListener(Exchanger<BufferedImage> exchanger) {
this.exchanger = exchanger;
}
public void rgbFrame(boolean isPrerollFrame, int width, int height, IntBuffer rgb) {
LOG.trace("RGB frame ({}x{}), preroll is {}", width, height, isPrerollFrame);
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
rgb.get(pixels, 0, width * height);
try {
exchanger.exchange(image);
} catch (InterruptedException e) {
throw new WebcamException("Exchange has been interrupted", e);
}
}
@Override
public FlowReturn newSample(AppSink elem) {
LOG.trace("New sample ready in {}", elem);
final Sample sample = elem.pullSample();
final Structure capsStruct = sample.getCaps().getStructure(0);
final int w = capsStruct.getInteger("width");
final int h = capsStruct.getInteger("height");
final Buffer buffer = sample.getBuffer();
final ByteBuffer bb = buffer.map(false);
if (bb != null) {
rgbFrame(false, w, h, bb.asIntBuffer());
buffer.unmap();
}
sample.dispose();
return FlowReturn.OK;
}
}