* Deleted useless com.jme3.video package

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8318 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..rd 13 years ago
parent 3f95a0ca2f
commit b1e46de5ee
  1. 43
      engine/src/jheora/com/jme3/video/Clock.java
  2. 177
      engine/src/jheora/com/jme3/video/RingBuffer.java
  3. 59
      engine/src/jheora/com/jme3/video/SystemClock.java
  4. 203
      engine/src/jheora/com/jme3/video/TestVideoPlayer.java
  5. 62
      engine/src/jheora/com/jme3/video/VFrame.java
  6. 82
      engine/src/jheora/com/jme3/video/VQueue.java
  7. 278
      engine/src/jheora/com/jme3/video/plugins/jheora/ADecoder.java
  8. 223
      engine/src/jheora/com/jme3/video/plugins/jheora/AVThread.java
  9. 184
      engine/src/jheora/com/jme3/video/plugins/jheora/VDecoder.java
  10. 143
      engine/src/jheora/com/jme3/video/plugins/jheora/YUVConv.java

@ -1,43 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video;
@Deprecated
public interface Clock {
public static final long MILLIS_TO_NANOS = 1000000;
public static final long SECONDS_TO_NANOS = 1000000000;
public long getTime();
public double getTimeSeconds();
}

@ -1,177 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video;
@Deprecated
public final class RingBuffer {
private final int bufSize;
private final byte[] buf;
private final Object lock = new Object();
private volatile int writePos;
private volatile int readPos;
// private volatile boolean eof;
private volatile long totalRead = 0,
totalWritten = 0;
public RingBuffer(int size) {
bufSize = size;
buf = new byte[size];
}
public int remainingForWrite() {
if (writePos < readPos) return readPos - writePos - 1;
if (writePos == readPos) return bufSize - 1;
return bufSize - (writePos - readPos) - 1;
}
public void write(byte[] data, int offset, int length) {
if (length == 0) return;
synchronized (lock) {
while (remainingForWrite() < length) {
System.out.println("Warning: Audio decoder starved, waiting for player");
try {
lock.wait();
} catch (InterruptedException ex) {
}
}
// copy data
if (writePos >= readPos) {
int l = Math.min(length, bufSize - writePos);
System.arraycopy(data, offset, buf, writePos, l);
writePos += l;
if (writePos >= bufSize) writePos = 0;
if (length > l) write(data, offset + l, length - l);
} else {
int l = Math.min(length, readPos - writePos - 1);
System.arraycopy(data, offset, buf, writePos, l);
writePos += l;
if (writePos >= bufSize) writePos = 0;
}
totalWritten += length;
}
}
public int remainingForRead() {
if (writePos < readPos) return bufSize - (readPos - writePos);
if (writePos == readPos) return 0;
return writePos - readPos;
}
public int skip(int amount){
if (amount <= 0) return 0;
int dataLen = 0;
synchronized (lock){
if (remainingForRead() <= 0)
return 0;
amount = Math.min(amount, remainingForRead());
// copy data
if (readPos < writePos) {
int l = Math.min(amount, writePos - readPos);
readPos += l;
if (readPos >= bufSize) readPos = 0;
dataLen = l;
} else {
int l = Math.min(amount, bufSize - readPos);
readPos += l;
if (readPos >= bufSize) readPos = 0;
dataLen = l;
if (amount > l) dataLen += skip(amount - l);
}
lock.notifyAll();
}
totalRead += dataLen;
return dataLen;
}
public int read(byte[] data, int offset, int len) {
if (len == 0) return 0;
int dataLen = 0;
synchronized (lock) {
// see if we have enough data
if (remainingForRead() <= 0){
System.out.println("Warning: Audio starved. Not enough data.");
return 0;
}
len = Math.min(len, remainingForRead());
// copy data
if (readPos < writePos) {
int l = Math.min(len, writePos - readPos);
System.arraycopy(buf, readPos, data, offset, l);
readPos += l;
if (readPos >= bufSize) readPos = 0;
dataLen = l;
} else {
int l = Math.min(len, bufSize - readPos);
System.arraycopy(buf, readPos, data, offset, l);
readPos += l;
if (readPos >= bufSize) readPos = 0;
dataLen = l;
if (len > l) dataLen += read(data, offset + l, len - l);
}
lock.notifyAll();
}
totalRead += dataLen;
return dataLen;
}
public long getTotalRead(){
return totalRead;
}
public long getTotalWritten(){
return totalWritten;
}
// public boolean isEOF() {
// return eof;
// }
//
// public void setEOF(boolean eof) {
// this.eof = eof;
// }
}

@ -1,59 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video;
@Deprecated
public class SystemClock implements Clock {
private long startTime = 0;
public SystemClock(){
}
public boolean needReset(){
return startTime == 0;
}
public void reset(){
startTime = System.nanoTime();
}
public long getTime() {
return System.nanoTime() - startTime;
}
public double getTimeSeconds(){
return (double) getTime() / Clock.SECONDS_TO_NANOS;
}
}

@ -1,203 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video;
import com.jme3.app.SimpleApplication;
import com.jme3.audio.AudioNode;
import com.jme3.system.AppSettings;
import com.jme3.texture.Image;
import com.jme3.ui.Picture;
import com.jme3.video.plugins.jheora.AVThread;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@Deprecated
public class TestVideoPlayer extends SimpleApplication {
private Picture picture;
private AVThread decoder;
private Thread videoThread;
private VQueue videoQueue;
private long lastFrameTime = 0;
private Clock masterClock;
private AudioNode source;
private float waitTime = 0;
private VFrame frameToDraw = null;
public static void main(String[] args){
TestVideoPlayer app = new TestVideoPlayer();
AppSettings settings = new AppSettings(true);
settings.setFrameRate(60);
app.setSettings(settings);
app.start();
}
private void createVideo(){
try {
// uncomment to play video from harddrive
// FileInputStream fis = new FileInputStream("E:\\bunny.ogg");
InputStream fis = new URL("http://mirrorblender.top-ix.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_stereo.ogg").openStream();
// increasing queued frames value from 5 will make web streamed
// playback smoother at the cost of memory.
videoQueue = new VQueue(5);
decoder = new AVThread(fis, videoQueue);
videoThread = new Thread(decoder, "Jheora Video Decoder");
videoThread.setDaemon(true);
videoThread.start();
masterClock = decoder.getMasterClock();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void simpleInitApp() {
picture = new Picture("VideoPicture", true);
picture.setPosition(0, 0);
picture.setWidth(settings.getWidth());
picture.setHeight(settings.getHeight());
picture.setImage(assetManager, "Interface/Logo/Monkey.jpg", false);
// attach geometry to orthoNode
rootNode.attachChild(picture);
// start video playback
createVideo();
}
private void drawFrame(VFrame frame){
Image image = frame.getImage();
frame.setImage(image);
picture.setTexture(assetManager, frame, false);
// note: this forces renderer to upload frame immediately,
// since it is going to be returned to the video queue pool
// it could be used again.
renderer.setTexture(0, frame);
videoQueue.returnFrame(frame);
lastFrameTime = frame.getTime();
}
private void waitNanos(long time){
long millis = (long) (time / Clock.MILLIS_TO_NANOS);
int nanos = (int) (time - (millis * Clock.MILLIS_TO_NANOS));
try {
Thread.sleep(millis, nanos);
}catch (InterruptedException ex){
stop();
return;
}
}
@Override
public void simpleUpdate(float tpf){
if (source == null){
if (decoder.getAudioStream() != null){
source = new AudioNode(audioRenderer, decoder.getAudioStream(), null);
source.setPositional(false);
source.setReverbEnabled(false);
audioRenderer.playSource(source);
}else{
// uncomment this statement to be able to play videos
// without audio.
return;
}
}
if (waitTime > 0){
waitTime -= tpf;
if (waitTime > 0)
return;
else{
waitTime = 0;
drawFrame(frameToDraw);
frameToDraw = null;
}
}else{
VFrame frame;
try {
frame = videoQueue.take();
} catch (InterruptedException ex){
stop();
return;
}
if (frame.getTime() < lastFrameTime){
videoQueue.returnFrame(frame);
return;
}
if (frame.getTime() == -2){
// end of stream
System.out.println("End of stream");
stop();
return;
}
long AV_SYNC_THRESHOLD = 1 * Clock.MILLIS_TO_NANOS;
long delay = frame.getTime() - lastFrameTime;
// delay -= tpf * Clock.SECONDS_TO_NANOS;
long diff = frame.getTime() - masterClock.getTime();
long syncThresh = delay > AV_SYNC_THRESHOLD ? delay : AV_SYNC_THRESHOLD;
// if difference is more than 1 second, synchronize.
if (Math.abs(diff) < Clock.SECONDS_TO_NANOS){
if(diff <= -syncThresh) {
delay = 0;
} else if(diff >= syncThresh) {
delay = 2 * delay;
}
}
// delay = diff;
System.out.println("M: "+decoder.getSystemClock().getTimeSeconds()+
", V: "+decoder.getVideoClock().getTimeSeconds()+
", A: "+decoder.getAudioClock().getTimeSeconds());
if (delay > 0){
waitNanos(delay);
drawFrame(frame);
// waitTime = (float) ((double) delay / Clock.SECONDS_TO_NANOS);
// frameToDraw = frame;
}else{
videoQueue.returnFrame(frame);
lastFrameTime = frame.getTime();
}
}
}
}

@ -1,62 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture2D;
import com.jme3.util.BufferUtils;
@Deprecated
public class VFrame extends Texture2D {
private long time;
public VFrame(int width, int height){
super(width, height, Format.RGBA8);
getImage().setData(BufferUtils.createByteBuffer(width*height*4));
}
public long getTime(){
return time;
}
public void setTime(long time){
this.time = time;
}
@Override
public String toString(){
return super.toString() + "[Time="+time+"]";
}
}

@ -1,82 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
@Deprecated
public class VQueue extends ArrayBlockingQueue<VFrame> {
// private final ArrayList<VFrame> returnedFrames;
private final ArrayBlockingQueue<VFrame> returnedFrames;
public VQueue(int bufferedFrames){
super(bufferedFrames);
// returnedFrames = new ArrayList<VFrame>(remainingCapacity());
returnedFrames = new ArrayBlockingQueue<VFrame>(bufferedFrames * 3);
}
public VFrame nextReturnedFrame(boolean waitForIt){
// synchronized (returnedFrames){
// while (returnedFrames.size() == 0){
// if (!waitForIt)
// return null;
//
// try {
// returnedFrames.wait();
// } catch (InterruptedException ex) {
// }
// }
// }
// }
try {
return returnedFrames.take();
} catch (InterruptedException ex) {
ex.printStackTrace();
return null;
}
}
public void returnFrame(VFrame frame){
returnedFrames.add(frame);
// synchronized (returnedFrames){
// returnedFrames.add(frame);
// returnedFrames.notifyAll();
// }
}
}

@ -1,278 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video.plugins.jheora;
import com.jcraft.jogg.Packet;
import com.jcraft.jorbis.Block;
import com.jcraft.jorbis.Comment;
import com.jcraft.jorbis.DspState;
import com.jcraft.jorbis.Info;
import com.jme3.audio.AudioStream;
import com.jme3.video.Clock;
import com.jme3.video.RingBuffer;
import com.jme3.video.SystemClock;
import java.io.InputStream;
@Deprecated
public class ADecoder extends InputStream implements Clock {
private int packetIndex = 0;
private final DspState dsp;
private Block block;
private Info info;
private Comment comment;
private float[][][] pcmAll = new float[1][][];
private int[] index;
private AudioStream stream;
private RingBuffer ringBuffer = new RingBuffer(48000 * 2 * 2 * 2);
private int UNCOMP_BUFSIZE = 4096;
private byte[] uncompBuf = new byte[UNCOMP_BUFSIZE];
private long lastPts = 0;
private long lastWritten = 0;
private long lastRead = 0;
private long lastPtsRead = 0;
private long lastPtsWrite = 0;
private long timeDiffSum = 0;
private int timesDesynced = 0;
private Clock masterClock;
public ADecoder(){
info = new Info();
info.init();
comment = new Comment();
comment.init();
dsp = new DspState();
block = new Block(dsp);
}
public void setMasterClock(Clock masterClock) {
this.masterClock = masterClock;
}
public AudioStream getAudioStream(){
return stream;
}
public long getTime(){
long bytesRead = ringBuffer.getTotalRead();
if (bytesRead == 0)
return 0;
//long diff = bytesRead - lastWritten;
long diff = bytesRead;
long diffNs = (diff * Clock.SECONDS_TO_NANOS) / (2 * info.channels * info.rate);
long timeSinceLastRead = System.nanoTime() - lastPtsRead;
return /*lastPts +*/ diffNs + timeSinceLastRead;
}
public double getTimeSeconds(){
return (double) getTime() / Clock.SECONDS_TO_NANOS;
}
public int read(){
byte[] buf = new byte[1];
int read = read(buf, 0, 1);
if (read < 0)
return -1;
else
return buf[0] & 0xff;
}
private static final long NOSYNC_THRESH = 3 * Clock.SECONDS_TO_NANOS,
AUDIO_DIFF_THRESH = Clock.SECONDS_TO_NANOS / 2;
private static final int NUM_DIFFS_FOR_SYNC = 5;
private static final double PRODUCT_FOR_PREV = 6.0 / 10.0,
PRODUCT_FOR_PREV_INV = 4.0 / 10.0;
private int needToSkip = 0;
/**
* Only useful if audio is synced to something else.
*/
private void sync(){
if (needToSkip > 0){
int skipped = ringBuffer.skip(needToSkip);
System.out.println("Skipped: "+skipped);
needToSkip -= skipped;
}
long masterTime = masterClock.getTime();
long audioTime = getTime();
long diff = audioTime - masterTime;
if (diff < NOSYNC_THRESH){
timeDiffSum = diff + (long) (timeDiffSum * PRODUCT_FOR_PREV);
if (timesDesynced < NUM_DIFFS_FOR_SYNC){
timesDesynced ++;
}else{
long avgDiff = (long) (timeDiffSum * PRODUCT_FOR_PREV_INV);
if (Math.abs(avgDiff) >= AUDIO_DIFF_THRESH){
if (diff < 0){
int toSkip = (int) ((-diff * 2 * info.channels * info.rate) / Clock.SECONDS_TO_NANOS);
int skipped = ringBuffer.skip(toSkip);
System.out.println("Skipped: "+skipped);
if (skipped < toSkip)
needToSkip = toSkip - skipped;
timeDiffSum = 0;
timesDesynced = 0;
}
}
}
}else{
timesDesynced = 0;
timeDiffSum = 0;
}
}
@Override
public int read(byte[] buf, int offset, int length){
// int diff = (int) (ringBuffer.getTotalWritten() - ringBuffer.getTotalRead());
// if ( diff > info.rate * info.channels * 2){
// System.out.println("Warning: more than 1 second lag for audio. Adjusting..");
// ringBuffer.skip( diff );
// }
// if (masterClock != null)
// sync();
int r = ringBuffer.read(buf, offset, length);
if (r <= 0){
// // put silence
for (int i = 0; i < length; i++){
buf[offset + i] = 0x0;
}
return length;
}else{
lastPtsRead = System.nanoTime();
}
return r;
}
public void decodeDsp(Packet packet){
if (block.synthesis(packet) == 0) {
dsp.synthesis_blockin(block);
}
int samplesAvail;
int channels = info.channels;
while ((samplesAvail = dsp.synthesis_pcmout(pcmAll, index)) > 0) {
float[][] pcm = pcmAll[0];
int samplesCanRead = UNCOMP_BUFSIZE / (channels*2);
int samplesToRead = (samplesAvail < samplesCanRead ? samplesAvail : samplesCanRead);
// convert floats to 16 bit signed ints and interleave
for (int i = 0; i < channels; i++) {
// each sample is two bytes, the sample for the 2nd
// channel is at index 2, etc.
int writeOff = i * 2;
int readOff = index[i];
for (int j = 0; j < samplesToRead; j++) {
int val = (int) (pcm[i][readOff + j] * 32767.0);
// guard against clipping
if (val > 32767) {
val = 32767;
}if (val < -32768) {
val = -32768;
}
uncompBuf[writeOff] = (byte) (val);
uncompBuf[writeOff + 1] = (byte) (val >> 8);
writeOff += 2 * channels; // each sample is 2 bytes
}
}
ringBuffer.write(uncompBuf, 0, samplesToRead * channels * 2);
// tell vorbis how many samples were actualy consumed
dsp.synthesis_read(samplesToRead);
}
}
@Override
public void close(){
}
public void decode(Packet packet){
if (packetIndex < 3) {
if (info.synthesis_headerin(comment, packet) < 0) {
// error case; not a Vorbis header
System.err.println("does not contain Vorbis audio data.");
return;
}
if (packetIndex == 2) {
dsp.synthesis_init(info);
block.init(dsp);
System.out.println("vorbis: "+info);
System.out.println(comment.toString());
index = new int[info.channels];
if (stream == null){
stream = new AudioStream();
stream.setupFormat(info.channels, 16, info.rate);
stream.updateData(this, -1);
}
if (masterClock instanceof SystemClock){
SystemClock clock = (SystemClock) masterClock;
if (clock.needReset()){
clock.reset();
System.out.println("Note: master clock was reset by audio");
}
}
}
} else {
long gp = packet.granulepos;
if (gp != -1){
lastPts = (gp * Clock.SECONDS_TO_NANOS) / info.rate;
lastWritten = ringBuffer.getTotalWritten();
lastRead = ringBuffer.getTotalRead();
lastPtsWrite = System.nanoTime();
}
decodeDsp(packet);
}
packetIndex++;
}
}

@ -1,223 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video.plugins.jheora;
import com.jcraft.jogg.Packet;
import com.jcraft.jogg.Page;
import com.jcraft.jogg.StreamState;
import com.jcraft.jogg.SyncState;
import com.jme3.audio.AudioStream;
import com.jme3.util.IntMap;
import com.jme3.video.Clock;
import com.jme3.video.SystemClock;
import com.jme3.video.VQueue;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
@Deprecated
public class AVThread implements Runnable {
private static final Logger logger = Logger.getLogger(AVThread.class.getName());
private static final int BUFFSIZE = 8192;
/**
* OggPage.
*/
private Page page;
/**
* OggPacket, constructed from OggPages.
*/
private Packet packet;
/**
* SyncState.
*/
private SyncState syncState;
/**
* Stream of .ogg file.
*/
private InputStream oggStream;
private AtomicBoolean cancel = new AtomicBoolean(false);
private IntMap<StreamState> streams = new IntMap<StreamState>();
private int theoraSerial, vorbisSerial;
private ADecoder audioDecoder;
private VDecoder videoDecoder;
private Clock masterClock;
private Clock systemClock;
public AVThread(InputStream oggStream, VQueue videoQueue){
this.oggStream = oggStream;
videoDecoder = new VDecoder(videoQueue);
audioDecoder = new ADecoder();
systemClock = new SystemClock();
// masterClock = systemClock;//audioDecoder;
masterClock = audioDecoder;
audioDecoder.setMasterClock(masterClock);
videoDecoder.setMasterClock(masterClock);
// masterClock = videoDecoder;
// masterClock = systemClock;
// audioDecoder.setMasterClock(masterClock);
}
public AudioStream getAudioStream(){
return audioDecoder.getAudioStream();
}
public void stop(){
cancel.set(true);
}
private void done(){
videoDecoder.close();
audioDecoder.close();
try {
oggStream.close();
} catch (IOException ex) {
logger.log(Level.SEVERE, "Error while closing Ogg Video", ex);
}
}
public Clock getMasterClock(){
return masterClock;
}
public Clock getSystemClock(){
return systemClock;
}
public Clock getVideoClock(){
return videoDecoder;
}
public Clock getAudioClock(){
return audioDecoder;
}
public void run(){
page = new Page();
packet = new Packet();
syncState = new SyncState();
while (!cancel.get()) {
int index = syncState.buffer(BUFFSIZE);
// Read from stream into syncState's buffer.
int read;
try {
read = oggStream.read(syncState.data, index, BUFFSIZE);
} catch (IOException ex){
logger.log(Level.SEVERE, "Error while decoding Ogg Video", ex);
return;
}
if (read < 0){
// EOF
break;
}
syncState.wrote(read);
while (!cancel.get()) {
// Acquire page from syncState
int res = syncState.pageout(page);
if (res == 0)
break; // need more data
if (res == -1) {
// missing or corrupt data at this page position
// no reason to complain; already complained above
} else {
int serial = page.serialno();
StreamState state = streams.get(serial);
boolean newStream = false;
if (state == null){
state = new StreamState();
state.init(serial);
state.reset();
streams.put(serial, state);
newStream = true;
}
// Give StreamState the page
res = state.pagein(page);
if (res < 0) {
// error; stream version mismatch perhaps
System.err.println("Error reading first page of Ogg bitstream data.");
return;
}
while (!cancel.get()) {
// Get a packet out of the stream state
res = state.packetout(packet);
if (res == 0)
break;
if (res == -1) {
// missing or corrupt data at this page position
// no reason to complain; already complained above
} else {
// Packet acquired!
if (newStream) {
// typefind
int packetId = packet.packet;
byte[] packetBase = packet.packet_base;
if (packetBase[packetId + 1] == 0x76) {
vorbisSerial = serial;
} else if (packet.packet_base[packet.packet + 1] == 0x73) {
// smoke video! ignored
logger.log(Level.WARNING, "Smoke video detected. Unsupported!");
} else if (packet.packet_base[packet.packet + 1] == 0x74) {
theoraSerial = serial;
}
}
if (serial == theoraSerial){
videoDecoder.decode(packet);
}else if (serial == vorbisSerial){
audioDecoder.decode(packet);
}
}
}
}
}
}
done();
}
}

@ -1,184 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video.plugins.jheora;
import com.fluendo.jheora.Comment;
import com.fluendo.jheora.Info;
import com.fluendo.jheora.State;
import com.fluendo.jheora.YUVBuffer;
import com.jcraft.jogg.Packet;
import com.jme3.video.Clock;
import com.jme3.video.SystemClock;
import com.jme3.video.VFrame;
import com.jme3.video.VQueue;
import java.nio.ByteBuffer;
@Deprecated
public class VDecoder implements Clock {
private int packetIndex = 0;
private Info info;
private Comment comment;
private State state;
private YUVBuffer yuv;
private int xOff, yOff, width, height;
private YUVConv conv = new YUVConv();
private VQueue videoQueue;
private long lastTs = -1;
private long lastUpdateTime = 0;
private Clock masterClock;
public VDecoder(VQueue queue) {
info = new Info();
comment = new Comment();
state = new State();
yuv = new YUVBuffer();
videoQueue = queue;
}
public void setMasterClock(Clock masterClock) {
this.masterClock = masterClock;
}
public long getTime(){
if (lastTs == -1)
return 0;
long timeDiff = System.nanoTime() - lastUpdateTime;
return lastTs + timeDiff;
}
public double getTimeSeconds(){
return (double) getTime() / Clock.SECONDS_TO_NANOS;
}
private void initializeFrames(){
for (int i = 0; i < videoQueue.remainingCapacity(); i++){
videoQueue.returnFrame(new VFrame(width, height));
}
}
private void decodeRgbFromBuffer(long time){
VFrame frame = videoQueue.nextReturnedFrame(true);
conv.convert(yuv, xOff, yOff, width, height);
int[] rgb = conv.getRGBData();
frame.setTime(time);
ByteBuffer data = frame.getImage().getData(0);
data.clear();
data.asIntBuffer().put(rgb);
try {
// if it throws an exception someone
// else modified it. "unknown error"..
videoQueue.put(frame);
} catch (InterruptedException ex) {
}
}
public void close(){
// enqueue a frame with time == -2 to indicate end of stream
VFrame frame = videoQueue.nextReturnedFrame(true);
frame.setTime(-2);
try {
videoQueue.put(frame);
} catch (InterruptedException ex) {
}
}
public void decode(Packet packet) {
//System.out.println ("creating packet");
if (packetIndex < 3) {
//System.out.println ("decoding header");
if (info.decodeHeader(comment, packet) < 0) {
// error case; not a theora header
System.err.println("does not contain Theora video data.");
return;
}
if (packetIndex == 2) {
state.decodeInit(info);
System.out.println("theora frame: " + info.frame_width + "x" + info.frame_height);
System.out.println("theora resolution: " + info.width + "x" + info.height);
System.out.println("theora aspect: " + info.aspect_numerator + "x" + info.aspect_denominator);
System.out.println("theora framerate: " + info.fps_numerator + "x" + info.fps_denominator);
xOff = info.offset_x;
yOff = info.offset_y;
width = info.frame_width;
height = info.frame_height;
initializeFrames();
if (masterClock instanceof SystemClock){
SystemClock clock = (SystemClock) masterClock;
if (clock.needReset()){
clock.reset();
System.out.println("Note: master clock was reset by video");
}
}
}
} else {
// convert to nanos
long granulePos = packet.granulepos;
long time = (long) (state.granuleTime(granulePos) * Clock.SECONDS_TO_NANOS);
long oneFrameTime = (long) ((Clock.SECONDS_TO_NANOS * info.fps_denominator) / info.fps_numerator);
if (time >= 0){
lastTs = time;
}else{
lastTs += oneFrameTime;
time = lastTs;
}
lastUpdateTime = System.nanoTime();
if (state.decodePacketin(packet) != 0) {
System.err.println("Error Decoding Theora.");
return;
}
// if (time >= 0){
if (state.decodeYUVout(yuv) != 0) {
System.err.println("Error getting the picture.");
return;
}
decodeRgbFromBuffer( time );
// }
}
packetIndex++;
}
}

@ -1,143 +0,0 @@
/*
* Copyright (c) 2009-2010 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.video.plugins.jheora;
import com.fluendo.jheora.YUVBuffer;
@Deprecated
public final class YUVConv {
private int[] pixels;
private static final int VAL_RANGE = 256;
private static final int SHIFT = 16;
private static final int CR_FAC = (int) (1.402 * (1 << SHIFT));
private static final int CB_FAC = (int) (1.772 * (1 << SHIFT));
private static final int CR_DIFF_FAC = (int) (0.71414 * (1 << SHIFT));
private static final int CB_DIFF_FAC = (int) (0.34414 * (1 << SHIFT));
private static int[] r_tab = new int[VAL_RANGE * 3];
private static int[] g_tab = new int[VAL_RANGE * 3];
private static int[] b_tab = new int[VAL_RANGE * 3];
static {
setupRgbYuvAccelerators();
}
private static final short clamp255(int val) {
val -= 255;
val = -(255 + ((val >> (31)) & val));
return (short) -((val >> 31) & val);
}
private static void setupRgbYuvAccelerators() {
for (int i = 0; i < VAL_RANGE * 3; i++) {
r_tab[i] = clamp255(i - VAL_RANGE);
g_tab[i] = clamp255(i - VAL_RANGE) << 8;
b_tab[i] = clamp255(i - VAL_RANGE) << 16;
}
}
public YUVConv(){
}
public int[] getRGBData(){
return pixels;
}
public void convert(YUVBuffer yuv, int xOff, int yOff, int width, int height) {
if (pixels == null){
pixels = new int[width*height];
}
// Set up starting values for YUV pointers
int YPtr = yuv.y_offset + xOff + yOff * (yuv.y_stride);
int YPtr2 = YPtr + yuv.y_stride;
int UPtr = yuv.u_offset + xOff/2 + (yOff/2)*(yuv.uv_stride);
int VPtr = yuv.v_offset + xOff/2 + (yOff/2)*(yuv.uv_stride);
int RGBPtr = 0;
int RGBPtr2 = width;
int width2 = width / 2;
int height2 = height / 2;
// Set the line step for the Y and UV planes and YPtr2
int YStep = yuv.y_stride * 2 - (width2) * 2;
int UVStep = yuv.uv_stride - (width2);
int RGBStep = width;
for (int i = 0; i < height2; i++) {
for (int j = 0; j < width2; j++) {
// groups of four pixels
int UFactor = yuv.data[UPtr++] - 128;
int VFactor = yuv.data[VPtr++] - 128;
int GFactor = UFactor * CR_DIFF_FAC + VFactor * CB_DIFF_FAC - (VAL_RANGE<<SHIFT);
UFactor = UFactor * CR_FAC + (VAL_RANGE<<SHIFT);
VFactor = VFactor * CB_FAC + (VAL_RANGE<<SHIFT);
int YVal = yuv.data[YPtr] << SHIFT;
pixels[RGBPtr] = r_tab[(YVal + VFactor)>>SHIFT] |
b_tab[(YVal + UFactor)>>SHIFT] |
g_tab[(YVal - GFactor)>>SHIFT];
YVal = yuv.data[YPtr+1] << SHIFT;
pixels[RGBPtr+1] = r_tab[(YVal + VFactor)>>SHIFT] |
b_tab[(YVal + UFactor)>>SHIFT] |
g_tab[(YVal - GFactor)>>SHIFT];
YVal = yuv.data[YPtr2] << SHIFT;
pixels[RGBPtr2] = r_tab[(YVal + VFactor)>>SHIFT] |
b_tab[(YVal + UFactor)>>SHIFT] |
g_tab[(YVal - GFactor)>>SHIFT];
YVal = yuv.data[YPtr2+1] << SHIFT;
pixels[RGBPtr2+1] = r_tab[(YVal + VFactor)>>SHIFT] |
b_tab[(YVal + UFactor)>>SHIFT] |
g_tab[(YVal - GFactor)>>SHIFT];
YPtr += 2;
YPtr2 += 2;
RGBPtr += 2;
RGBPtr2 += 2;
}
// Increment the various pointers
YPtr += YStep;
YPtr2 += YStep;
UPtr += UVStep;
VPtr += UVStep;
RGBPtr += RGBStep;
RGBPtr2 += RGBStep;
}
}
}
Loading…
Cancel
Save