001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.video.gstreamer;
031
032import org.bridj.Pointer;
033import org.openimaj.image.ImageUtilities;
034import org.openimaj.image.MBFImage;
035import org.openimaj.image.colour.ColourSpace;
036import org.openimaj.video.Video;
037import org.openimaj.video.VideoDisplay;
038
039public class GStreamerVideo extends Video<MBFImage> {
040        private OpenIMAJCapGStreamer gstreamer;
041        private MBFImage frame;
042        private int width;
043        private int height;
044        private boolean isStopped = true;
045
046        /** The timestamp at which the capture (session) was started */
047        private long captureStartedTimestamp = 0;
048
049        /** The timestamp of the current image */
050        private long currentTimestamp = 0;
051        private String pipeline;
052        private double fps;
053
054        public GStreamerVideo(String pipeline) {
055                this.pipeline = pipeline;
056
057                gstreamer = new OpenIMAJCapGStreamer();
058
059                reset();
060        }
061
062        @Override
063        public synchronized MBFImage getNextFrame() {
064                if (isStopped)
065                        return frame;
066
067                final boolean err = gstreamer.nextFrame();
068                if (!err)
069                        throw new RuntimeException(new GStreamerException("Error getting next frame"));
070
071                final Pointer<Byte> data = gstreamer.getImage();
072                if (data == null) {
073                        return frame;
074                }
075
076                if (gstreamer.getBands() == 3) {
077                        final byte[] d = data.getBytes(width * height * 3);
078                        final float[][] r = frame.bands.get(0).pixels;
079                        final float[][] g = frame.bands.get(1).pixels;
080                        final float[][] b = frame.bands.get(2).pixels;
081
082                        for (int i = 0, y = 0; y < height; y++) {
083                                for (int x = 0; x < width; x++, i += 3) {
084                                        final int blue = d[i + 0] & 0xFF;
085                                        final int green = d[i + 1] & 0xFF;
086                                        final int red = d[i + 2] & 0xFF;
087                                        r[y][x] = ImageUtilities.BYTE_TO_FLOAT_LUT[red];
088                                        g[y][x] = ImageUtilities.BYTE_TO_FLOAT_LUT[green];
089                                        b[y][x] = ImageUtilities.BYTE_TO_FLOAT_LUT[blue];
090                                }
091                        }
092                } else {
093                        final byte[] d = data.getBytes(width * height * 3);
094                        final float[][] g = frame.bands.get(0).pixels;
095
096                        for (int i = 0, y = 0; y < height; y++) {
097                                for (int x = 0; x < width; x++, i++) {
098                                        g[y][x] = ImageUtilities.BYTE_TO_FLOAT_LUT[d[i] & 0xFF];
099                                }
100                        }
101                }
102
103                super.currentFrame++;
104
105                if (captureStartedTimestamp == 0)
106                        captureStartedTimestamp = System.currentTimeMillis();
107                currentTimestamp = System.currentTimeMillis() - captureStartedTimestamp;
108
109                return frame;
110        }
111
112        @Override
113        public MBFImage getCurrentFrame() {
114                return frame;
115        }
116
117        @Override
118        public int getWidth() {
119                return width;
120        }
121
122        @Override
123        public int getHeight() {
124                return height;
125        }
126
127        @Override
128        public long getTimeStamp() {
129                return currentTimestamp;
130        }
131
132        @Override
133        public double getFPS() {
134                return fps;
135        }
136
137        @Override
138        public boolean hasNextFrame() {
139                // TODO Auto-generated method stub
140                return false;
141        }
142
143        @Override
144        public long countFrames() {
145                return -1;
146        }
147
148        @Override
149        public void reset() {
150                gstreamer.close();
151
152                // final Pointer<Byte> cpipeline = Pointer.pointerToCString(pipeline +
153                // "\0");
154                final byte[] b = pipeline.getBytes();
155                final byte[] b1 = new byte[b.length + 1];
156                System.arraycopy(b, 0, b1, 0, b.length);
157                b1[b.length] = 0;
158                final Pointer<Byte> cpipeline = Pointer.pointerToBytes(b1);
159                if (!gstreamer.open(cpipeline)) {
160                        // cpipeline.release();
161                        throw new RuntimeException(new GStreamerException("Error"));
162                }
163                // cpipeline.release();
164
165                isStopped = false;
166
167                gstreamer.nextFrame();
168                gstreamer.getImage();
169
170                width = gstreamer.getWidth();
171                height = gstreamer.getHeight();
172                final int bands = gstreamer.getBands();
173                this.fps = gstreamer.getProperty(OpenIMAJCapGStreamer.PROP_FPS);
174                frame = new MBFImage(width, height, bands == 3 ? ColourSpace.RGB : ColourSpace.LUMINANCE_AVG);
175                System.out.println("here11");
176        }
177
178        public static void main(String[] args) {
179                final GStreamerVideo gsv = new GStreamerVideo(
180                                "videotestsrc ! video/x-raw,format=GRAY8 ! videoconvert ! appsink");
181                System.out.println("here");
182
183                VideoDisplay.createVideoDisplay(gsv);
184        }
185}