private void convertToNV21(int k) {		
		byte[] buffer = new byte[3*mSize/2];

		int stride = mWidth, sliceHeight = mHeight;
		int colorFormat = mDecoderColorFormat;
		boolean planar = false;

		if (mDecOutputFormat != null) {
			MediaFormat format = mDecOutputFormat;
			if (format != null) {
				if (format.containsKey("slice-height")) {
					sliceHeight = format.getInteger("slice-height");
					if (sliceHeight<mHeight) sliceHeight = mHeight;
				}
				if (format.containsKey("stride")) {
					stride = format.getInteger("stride");
					if (stride<mWidth) stride = mWidth;
				}
				if (format.containsKey(MediaFormat.KEY_COLOR_FORMAT) && format.getInteger(MediaFormat.KEY_COLOR_FORMAT)>0) {
					colorFormat = format.getInteger(MediaFormat.KEY_COLOR_FORMAT);
				}
			}
		}

		switch (colorFormat) {
		case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
		case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
		case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
			planar = false;
			break;	
		case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
		case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
			planar = true;
			break;
		}

		for (int i=0;i<mSize;i++) {
			if (i%mWidth==0) i+=stride-mWidth;
			buffer[i] = mDecodedVideo[k][i];
		}

		if (!planar) {
			for (int i=0,j=0;j<mSize/4;i+=1,j+=1) {
				if (i%mWidth/2==0) i+=(stride-mWidth)/2;
				buffer[mSize+2*j+1] = mDecodedVideo[k][stride*sliceHeight+2*i];
				buffer[mSize+2*j] = mDecodedVideo[k][stride*sliceHeight+2*i+1];
			}
		} else {
			for (int i=0,j=0;j<mSize/4;i+=1,j+=1) {
				if (i%mWidth/2==0) i+=(stride-mWidth)/2;
				buffer[mSize+2*j+1] = mDecodedVideo[k][stride*sliceHeight+i];
				buffer[mSize+2*j] = mDecodedVideo[k][stride*sliceHeight*5/4+i];
			}
		}

		mDecodedVideo[k] = buffer;

	}
Converts the image obtained from the decoder to NV21.
src/net/majorkernelpanic/streaming/hw/EncoderDebugger.java