If you think the Android project streamvid listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
Java Source Code
/*
* Copyright (C) 2011-2014 GUIGUI Simon, fyhertz@gmail.com
* /*fromwww.java2s.com*/
* This file is part of Spydroid (http://code.google.com/p/spydroid-ipcamera/)
*
* Spydroid is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/package net.majorkernelpanic.streaming.hw;
import java.nio.ByteBuffer;
import android.media.MediaCodecInfo;
/**
* Converts from NV21 to YUV420 semi planar or planar.
*/publicclass NV21Convertor {
privateint mSliceHeight, mHeight;
privateint mStride, mWidth;
privateint mSize;
privateboolean mPlanar, mPanesReversed = false;
privateint mYPadding;
privatebyte[] mBuffer;
ByteBuffer mCopy;
publicvoid setSize(int width, int height) {
mHeight = height;
mWidth = width;
mSliceHeight = height;
mStride = width;
mSize = mWidth*mHeight;
}
publicvoid setStride(int width) {
mStride = width;
}
publicvoid setSliceHeigth(int height) {
mSliceHeight = height;
}
publicvoid setPlanar(boolean planar) {
mPlanar = planar;
}
publicvoid setYPadding(int padding) {
mYPadding = padding;
}
publicint getBufferSize() {
return 3*mSize/2;
}
publicvoid setEncoderColorFormat(int colorFormat) {
switch (colorFormat) {
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
setPlanar(false);
break;
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
setPlanar(true);
break;
}
}
publicvoid setColorPanesReversed(boolean b) {
mPanesReversed = b;
}
publicint getStride() {
return mStride;
}
publicint getSliceHeigth() {
return mSliceHeight;
}
publicint getYPadding() {
return mYPadding;
}
publicboolean getPlanar() {
return mPlanar;
}
publicboolean getUVPanesReversed() {
return mPanesReversed;
}
publicvoid convert(byte[] data, ByteBuffer buffer) {
byte[] result = convert(data);
buffer.put(result, 0, result.length);
}
publicbyte[] convert(byte[] data) {
// A buffer large enough for every case
if (mBuffer==null || mBuffer.length != 3*mSliceHeight*mStride/2+mYPadding) {
mBuffer = newbyte[3*mSliceHeight*mStride/2+mYPadding];
}
if (!mPlanar) {
if (mSliceHeight==mHeight && mStride==mWidth) {
// Swaps U and V
if (!mPanesReversed) {
for (int i = mSize; i < mSize+mSize/2; i += 2) {
mBuffer[0] = data[i+1];
data[i+1] = data[i];
data[i] = mBuffer[0];
}
}
if (mYPadding>0) {
System.arraycopy(data, 0, mBuffer, 0, mSize);
System.arraycopy(data, mSize, mBuffer, mSize+mYPadding, mSize/2);
return mBuffer;
}
return data;
}
} else {
if (mSliceHeight==mHeight && mStride==mWidth) {
// De-interleave U and V
if (!mPanesReversed) {
for (int i = 0; i < mSize/4; i+=1) {
mBuffer[i] = data[mSize+2*i+1];
mBuffer[mSize/4+i] = data[mSize+2*i];
}
} else {
for (int i = 0; i < mSize/4; i+=1) {
mBuffer[i] = data[mSize+2*i];
mBuffer[mSize/4+i] = data[mSize+2*i+1];
}
}
if (mYPadding == 0) {
System.arraycopy(mBuffer, 0, data, mSize, mSize/2);
} else {
System.arraycopy(data, 0, mBuffer, 0, mSize);
System.arraycopy(mBuffer, 0, mBuffer, mSize+mYPadding, mSize/2);
return mBuffer;
}
return data;
}
}
return data;
}
}