多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android RakNet 系列之五 視頻通訊 OpenCV4Android

Android RakNet 系列之五 視頻通訊 OpenCV4Android

來源:程序員人生   發布時間:2014-12-16 08:37:39 閱讀次數:7938次

簡介

引入OpenCV4Android的目標是在Raknet框架下解決視頻通訊的問題,目前在ubuntu下已成功實現,現在把它援用到Android平臺下。

OpenCV是1個基于開源發行的跨平臺計算機視覺庫,可以在 Windows, Android, Maemo,FreeBSD, OpenBSD, iOS,Linux 和Mac OS等平臺上運行。它輕量級而且高效――由1系列 C 函數和少許 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖象處理和計算機視覺方面的很多通用算法。OpenCV致力于真實世界的實時利用,通過優化的C代碼的編寫對其履行速度帶來了可觀的提升,并且可以通過購買Intel的IPP高性能多媒體函數庫(Integrated Performance Primitives)得到更快的處理速度。

相干網站

http://sourceforge.net/projects/opencvlibrary/files/opencv-android/ 最新版項目源碼下載
http://www.opencv.org.cn/   OpenCV中文論壇
http://opencv.org/?s=+android&x=0&y=0  OpenCV 官網
http://www.code.opencv.org/projects/opencv/issues OpenCV 官網下解決方案
http://docs.opencv.org/platforms/android/service/doc/index.html 或  http://docs.opencv.org/trunk/     OpenCV 官網下介紹文檔

http://www.jayrambhia.com/android/ 相干博客

詳情

項目介紹

官方提供了1個庫項目(OpenCV Library - 2.4.10)和9個Demo項目(OpenCV Manager - 2.4.10、OpenCV Tutorial 1 - Camera Preview、OpenCV Tutorial 2 - Mixed Processing、OpenCV Tutorial 3 - Camera Control、OpenCV Sample - 4 puzzle、OpenCV Sample - camera-calibration、OpenCV Sample - color-blob-detection、OpenCV Sample - face-detection、OpenCV Sample - image-manipulations、OpenCV Sample - native-activity、OpenCV Library - 2.4.10),再加上OpenCV Manager項目總計11個項目,項目如圖:




OpenCV Manager - 2.4.10

官方提供的Demo運行需要OpenCV Manager項目的支持,該項目負責匹配手機加載庫文件,通過服務綁定進行通訊。

如果未安裝它,并運行Demo會出現提示框:OpenCV Manager package was not found! Try to install it?  固然如果直接使用它的庫運行是不會出現此情況的。緣由就是該項目只是做加載庫的工作。


項目如圖:



官方給出解釋:




加載庫的代碼以下:

public class BinderConnector { private static boolean mIsReady = false; private MarketConnector mMarket; static { try { System.loadLibrary("OpenCVEngine"); System.loadLibrary("OpenCVEngine_jni"); mIsReady = true; } catch (UnsatisfiedLinkError localUnsatisfiedLinkError) { mIsReady = false; localUnsatisfiedLinkError.printStackTrace(); } } public BinderConnector(MarketConnector paramMarketConnector) { this.mMarket = paramMarketConnector; } private native void Final(); private native boolean Init(MarketConnector paramMarketConnector); public native IBinder Connect(); public boolean Disconnect() { if (mIsReady) Final(); return mIsReady; } public boolean Init() { boolean bool = false; if (mIsReady) bool = Init(this.mMarket); return bool; } }
public class HardwareDetector { //硬件匹配 public static final int ARCH_ARMv5 = 0x4000000; public static final int ARCH_ARMv6 = 0x8000000; public static final int ARCH_ARMv7 = 0x10000000; public static final int ARCH_ARMv8 = 0x20000000; public static final int ARCH_MIPS = 0x40000000; public static final int ARCH_UNKNOWN = ⑴; public static final int ARCH_X64 = 0x2000000; public static final int ARCH_X86 = 0x1000000; public static final int FEATURES_HAS_GPU = 65536; public static final int FEATURES_HAS_NEON = 8; public static final int FEATURES_HAS_NEON2 = 22; public static final int FEATURES_HAS_SSE = 1; public static final int FEATURES_HAS_SSE2 = 2; public static final int FEATURES_HAS_SSE3 = 4; public static final int FEATURES_HAS_VFPv3 = 2; public static final int FEATURES_HAS_VFPv3d16 = 1; public static final int FEATURES_HAS_VFPv4 = 4; public static final int PLATFORM_TEGRA = 1; public static final int PLATFORM_TEGRA2 = 2; public static final int PLATFORM_TEGRA3 = 3; public static final int PLATFORM_TEGRA4 = 5; public static final int PLATFORM_TEGRA4i = 4; public static final int PLATFORM_TEGRA5 = 6; public static final int PLATFORM_UNKNOWN = ⑴; public static boolean mIsReady = false; static { try { System.loadLibrary("OpenCVEngine"); System.loadLibrary("OpenCVEngine_jni"); mIsReady = true; } catch (UnsatisfiedLinkError localUnsatisfiedLinkError) { mIsReady = false; localUnsatisfiedLinkError.printStackTrace(); } } public static native int DetectKnownPlatforms(); public static native int GetCpuID(); public static native String GetPlatformName(); public static native int GetProcessorCount(); }
public class OpenCVLibraryInfo { private String mLibraryList; private long mNativeObj; private String mPackageName; private String mVersionName; public OpenCVLibraryInfo(String paramString) { mNativeObj = open(paramString + "/libopencv_info.so"); if (this.mNativeObj == 0L) return; this.mPackageName = getPackageName(this.mNativeObj); this.mLibraryList = getLibraryList(this.mNativeObj); this.mVersionName = getVersionName(this.mNativeObj); close(this.mNativeObj); } private native void close(long paramLong); private native String getLibraryList(long paramLong); private native String getPackageName(long paramLong); private native String getVersionName(long paramLong); private native long open(String paramString); public String libraryList() { return this.mLibraryList; } public String packageName() { return this.mPackageName; } public boolean status() { if (mNativeObj == 0L || mLibraryList.length() == 0) return false; return true; } public String versionName() { return this.mVersionName; } }
//關鍵服務 demo中綁定的服務就該服務 該服務就是匹配手機加載庫 public class OpenCVEngineService extends Service { private static final String TAG = "OpenCVEngine/Service"; private IBinder mEngineInterface = null; private MarketConnector mMarket; private BinderConnector mNativeBinder; public void OnDestroy() { Log.i("OpenCVEngine/Service", "OpenCV Engine service destruction"); this.mNativeBinder.Disconnect(); } public IBinder onBind(Intent paramIntent) { Log.i("OpenCVEngine/Service", "Service onBind called for intent " + paramIntent.toString()); return this.mEngineInterface; } public void onCreate() { Log.i("OpenCVEngine/Service", "Service starting"); super.onCreate(); Log.i("OpenCVEngine/Service", "Engine binder component creating"); this.mMarket = new MarketConnector(getBaseContext()); this.mNativeBinder = new BinderConnector(this.mMarket); if (this.mNativeBinder.Init()) { this.mEngineInterface = this.mNativeBinder.Connect(); Log.i("OpenCVEngine/Service", "Service started successfully"); } else { Log.e("OpenCVEngine/Service", "Cannot initialize native part of OpenCV Manager!"); Log.e("OpenCVEngine/Service", "Using stub instead"); return; } this.mEngineInterface = new OpenCVEngineInterface(this); } public boolean onUnbind(Intent paramIntent) { Log.i("OpenCVEngine/Service", "Service onUnbind called for intent " + paramIntent.toString()); return true; } }
它的AndroidManifest.xml 以下:

<?xml version="1.0" encoding="utf⑻"?> <manifest android:versionCode="2191" android:versionName="2.19" package="org.opencv.engine" xmlns:android="http://schemas.android.com/apk/res/android"> <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> <application android:label="@string/app_name" android:icon="@drawable/icon"> <service android:name="OpenCVEngineService" android:exported="true" android:process=":OpenCVEngineProcess"> <intent-filter> <action android:name="org.opencv.engine.BIND" /> </intent-filter> </service> <activity android:label="@string/app_name" android:name="org.opencv.engine.manager.ManagerActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>


OpenCV Tutorial 1 - Camera Preview

Demo就1個文件,使用攝像機預覽,Demo中提供了兩種方法,1種是Java層調用,1種是Native層調用。

如圖:


關鍵控件以下:

<org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:visibility="gone" android:id="@+id/tutorial1_activity_java_surface_view" opencv:show_fps="true" opencv:camera_id="any" /> <org.opencv.android.NativeCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:visibility="gone" android:id="@+id/tutorial1_activity_native_surface_view" opencv:show_fps="true" opencv:camera_id="any" />


OpenCV Tutorial 2 - Mixed Processing

該Demo就1個Java文件和1個C++文件,實現4中混合處理。

如圖:


本地代碼以下:

JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba) { Mat& mGr = *(Mat*)addrGray; Mat& mRgb = *(Mat*)addrRgba; vector<KeyPoint> v; FastFeatureDetector detector(50); detector.detect(mGr, v); for( unsigned int i = 0; i < v.size(); i++ ) { const KeyPoint& kp = v[i]; circle(mRgb, Point(kp.pt.x, kp.pt.y), 10, Scalar(255,0,0,255)); } }

使用的控件以下:

<org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/tutorial2_activity_surface_view" />


OpenCV Tutorial 3 - Camera Control

該Demo就2個Java文件,攝像頭控制,控制色彩顯示、攝像分辨率。

效果如圖:


關鍵代碼:

使用的控件

<org.opencv.samples.tutorial3.Tutorial3View android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" android:id="@+id/tutorial3_activity_java_surface_view" />
public class Tutorial3View extends JavaCameraView implements PictureCallback { private static final String TAG = "Sample::Tutorial3View"; private String mPictureFileName; public Tutorial3View(Context context, AttributeSet attrs) { super(context, attrs); } public List<String> getEffectList() { return mCamera.getParameters().getSupportedColorEffects(); } public boolean isEffectSupported() { return (mCamera.getParameters().getColorEffect() != null); } public String getEffect() { return mCamera.getParameters().getColorEffect(); } public void setEffect(String effect) { Camera.Parameters params = mCamera.getParameters(); params.setColorEffect(effect); mCamera.setParameters(params); } public List<Size> getResolutionList() { return mCamera.getParameters().getSupportedPreviewSizes(); } public void setResolution(Size resolution) { disconnectCamera(); mMaxHeight = resolution.height; mMaxWidth = resolution.width; connectCamera(getWidth(), getHeight()); } public Size getResolution() { return mCamera.getParameters().getPreviewSize(); } public void takePicture(final String fileName) { Log.i(TAG, "Taking picture"); this.mPictureFileName = fileName; // Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture. // Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue mCamera.setPreviewCallback(null); // PictureCallback is implemented by the current class mCamera.takePicture(null, null, this); } @Override public void onPictureTaken(byte[] data, Camera camera) { Log.i(TAG, "Saving a bitmap to file"); // The camera preview was automatically stopped. Start it again. mCamera.startPreview(); mCamera.setPreviewCallback(this); // Write the image in a file (in jpeg format) try { FileOutputStream fos = new FileOutputStream(mPictureFileName); fos.write(data); fos.close(); } catch (java.io.IOException e) { Log.e("PictureDemo", "Exception in photoCallback", e); } } }


OpenCV Sample - 4 puzzle

該Demo就兩個Java文件,實現攝像格式錯亂輸出。

效果如圖:


主要代碼以下:

public class Puzzle15Processor { //攝像圖片轉換 private static final int GRID_SIZE = 4; private static final int GRID_AREA = GRID_SIZE * GRID_SIZE; private static final int GRID_EMPTY_INDEX = GRID_AREA - 1; private static final String TAG = "Puzzle15Processor"; private static final Scalar GRID_EMPTY_COLOR = new Scalar(0x33, 0x33, 0x33, 0xFF); private int[] mIndexes; private int[] mTextWidths; private int[] mTextHeights; private Mat mRgba15; private Mat[] mCells15; private boolean mShowTileNumbers = true; public Puzzle15Processor() { mTextWidths = new int[GRID_AREA]; mTextHeights = new int[GRID_AREA]; mIndexes = new int [GRID_AREA]; for (int i = 0; i < GRID_AREA; i++) mIndexes[i] = i; } /* this method is intended to make processor prepared for a new game */ public synchronized void prepareNewGame() { do { shuffle(mIndexes); } while (!isPuzzleSolvable()); } /* This method is to make the processor know the size of the frames that * will be delivered via puzzleFrame. * If the frames will be different size - then the result is unpredictable */ public synchronized void prepareGameSize(int width, int height) { mRgba15 = new Mat(height, width, CvType.CV_8UC4); mCells15 = new Mat[GRID_AREA]; for (int i = 0; i < GRID_SIZE; i++) { for (int j = 0; j < GRID_SIZE; j++) { int k = i * GRID_SIZE + j; mCells15[k] = mRgba15.submat(i * height / GRID_SIZE, (i + 1) * height / GRID_SIZE, j * width / GRID_SIZE, (j + 1) * width / GRID_SIZE); } } for (int i = 0; i < GRID_AREA; i++) { Size s = Core.getTextSize(Integer.toString(i + 1), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, 2, null); mTextHeights[i] = (int) s.height; mTextWidths[i] = (int) s.width; } } /* this method to be called from the outside. it processes the frame and shuffles * the tiles as specified by mIndexes array */ public synchronized Mat puzzleFrame(Mat inputPicture) { Mat[] cells = new Mat[GRID_AREA]; int rows = inputPicture.rows(); int cols = inputPicture.cols(); rows = rows - rows%4; cols = cols - cols%4; for (int i = 0; i < GRID_SIZE; i++) { for (int j = 0; j < GRID_SIZE; j++) { int k = i * GRID_SIZE + j; cells[k] = inputPicture.submat(i * inputPicture.rows() / GRID_SIZE, (i + 1) * inputPicture.rows() / GRID_SIZE, j * inputPicture.cols()/ GRID_SIZE, (j + 1) * inputPicture.cols() / GRID_SIZE); } } rows = rows - rows%4; cols = cols - cols%4; // copy shuffled tiles for (int i = 0; i < GRID_AREA; i++) { int idx = mIndexes[i]; if (idx == GRID_EMPTY_INDEX) mCells15[i].setTo(GRID_EMPTY_COLOR); else { cells[idx].copyTo(mCells15[i]); if (mShowTileNumbers) { Core.putText(mCells15[i], Integer.toString(1 + idx), new Point((cols / GRID_SIZE - mTextWidths[idx]) / 2, (rows / GRID_SIZE + mTextHeights[idx]) / 2), 3/* CV_FONT_HERSHEY_COMPLEX */, 1, new Scalar(255, 0, 0, 255), 2); } } } for (int i = 0; i < GRID_AREA; i++) cells[i].release(); drawGrid(cols, rows, mRgba15); return mRgba15; } public void toggleTileNumbers() { mShowTileNumbers = !mShowTileNumbers; } public void deliverTouchEvent(int x, int y) { int rows = mRgba15.rows(); int cols = mRgba15.cols(); int row = (int) Math.floor(y * GRID_SIZE / rows); int col = (int) Math.floor(x * GRID_SIZE / cols); if (row < 0 || row >= GRID_SIZE || col < 0 || col >= GRID_SIZE) { Log.e(TAG, "It is not expected to get touch event outside of picture"); return ; } int idx = row * GRID_SIZE + col; int idxtoswap = ⑴; // left if (idxtoswap < 0 && col > 0) if (mIndexes[idx - 1] == GRID_EMPTY_INDEX) idxtoswap = idx - 1; // right if (idxtoswap < 0 && col < GRID_SIZE - 1) if (mIndexes[idx + 1] == GRID_EMPTY_INDEX) idxtoswap = idx + 1; // top if (idxtoswap < 0 && row > 0) if (mIndexes[idx - GRID_SIZE] == GRID_EMPTY_INDEX) idxtoswap = idx - GRID_SIZE; // bottom if (idxtoswap < 0 && row < GRID_SIZE - 1) if (mIndexes[idx + GRID_SIZE] == GRID_EMPTY_INDEX) idxtoswap = idx + GRID_SIZE; // swap if (idxtoswap >= 0) { synchronized (this) { int touched = mIndexes[idx]; mIndexes[idx] = mIndexes[idxtoswap]; mIndexes[idxtoswap] = touched; } } } private void drawGrid(int cols, int rows, Mat drawMat) { for (int i = 1; i < GRID_SIZE; i++) { Core.line(drawMat, new Point(0, i * rows / GRID_SIZE), new Point(cols, i * rows / GRID_SIZE), new Scalar(0, 255, 0, 255), 3); Core.line(drawMat, new Point(i * cols / GRID_SIZE, 0), new Point(i * cols / GRID_SIZE, rows), new Scalar(0, 255, 0, 255), 3); } } private static void shuffle(int[] array) { for (int i = array.length; i > 1; i--) { int temp = array[i - 1]; int randIx = (int) (Math.random() * i); array[i - 1] = array[randIx]; array[randIx] = temp; } } private boolean isPuzzleSolvable() { int sum = 0; for (int i = 0; i < GRID_AREA; i++) { if (mIndexes[i] == GRID_EMPTY_INDEX) sum += (i / GRID_SIZE) + 1; else { int smaller = 0; for (int j = i + 1; j < GRID_AREA; j++) { if (mIndexes[j] < mIndexes[i]) smaller++; } sum += smaller; } } return sum % 2 == 0; } }


OpenCV Sample - camera-calibration

該Demo就4個Java文件,實現攝像校準。

效果如圖:



使用的控件:

<org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/camera_calibration_java_surface_view" />


OpenCV Sample - color-blob-detection
該Demo就兩個Java文件,實現色斑檢測。

效果如圖:



使用的控件:

<org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/color_blob_detection_activity_surface_view" />
public class ColorBlobDetector { //匹配 // Lower and Upper bounds for range checking in HSV color space private Scalar mLowerBound = new Scalar(0); private Scalar mUpperBound = new Scalar(0); // Minimum contour area in percent for contours filtering private static double mMinContourArea = 0.1; // Color radius for range checking in HSV color space private Scalar mColorRadius = new Scalar(25,50,50,0); private Mat mSpectrum = new Mat(); private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>(); // Cache Mat mPyrDownMat = new Mat(); Mat mHsvMat = new Mat(); Mat mMask = new Mat(); Mat mDilatedMask = new Mat(); Mat mHierarchy = new Mat(); public void setColorRadius(Scalar radius) { mColorRadius = radius; } public void setHsvColor(Scalar hsvColor) { double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0; double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255; mLowerBound.val[0] = minH; mUpperBound.val[0] = maxH; mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1]; mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1]; mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2]; mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2]; mLowerBound.val[3] = 0; mUpperBound.val[3] = 255; Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3); for (int j = 0; j < maxH-minH; j++) { byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255}; spectrumHsv.put(0, j, tmp); } Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4); } public Mat getSpectrum() { return mSpectrum; } public void setMinContourArea(double area) { mMinContourArea = area; } public void process(Mat rgbaImage) { Imgproc.pyrDown(rgbaImage, mPyrDownMat); Imgproc.pyrDown(mPyrDownMat, mPyrDownMat); Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_RGB2HSV_FULL); Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask); Imgproc.dilate(mMask, mDilatedMask, new Mat()); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); // Find max contour area double maxArea = 0; Iterator<MatOfPoint> each = contours.iterator(); while (each.hasNext()) { MatOfPoint wrapper = each.next(); double area = Imgproc.contourArea(wrapper); if (area > maxArea) maxArea = area; } // Filter contours by area and resize to fit the original image size mContours.clear(); each = contours.iterator(); while (each.hasNext()) { MatOfPoint contour = each.next(); if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) { Core.multiply(contour, new Scalar(4,4), contour); mContours.add(contour); } } } public List<MatOfPoint> getContours() { return mContours; } }


OpenCV Sample - face-detection
該Demo就兩個Java文件和兩個C++文件,實現匹配臉。

效果如圖:


使用的控件:

<org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/fd_activity_surface_view" />
public class DetectionBasedTracker { public DetectionBasedTracker(String cascadeName, int minFaceSize) { mNativeObj = nativeCreateObject(cascadeName, minFaceSize); } public void start() { nativeStart(mNativeObj); } public void stop() { nativeStop(mNativeObj); } public void setMinFaceSize(int size) { nativeSetFaceSize(mNativeObj, size); } public void detect(Mat imageGray, MatOfRect faces) { nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr()); } public void release() { nativeDestroyObject(mNativeObj); mNativeObj = 0; } private long mNativeObj = 0; private static native long nativeCreateObject(String cascadeName, int minFaceSize); private static native void nativeDestroyObject(long thiz); private static native void nativeStart(long thiz); private static native void nativeStop(long thiz); private static native void nativeSetFaceSize(long thiz, int size); private static native void nativeDetect(long thiz, long inputImage, long faces); }

OpenCV Sample - image-manipulations
該Demo就1個Java文件,實現圖片操作。

效果如圖:


使用的控件:

<org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/image_manipulations_activity_surface_view" />
實現CvCameraViewListener2接口,從而操作圖片。

OpenCV Sample - native-activity

該Demo就1個Java文件和1個C++文件,實現本地界面顯示圖片。

效果如圖:


本地代碼以下:

struct Engine { android_app* app; cv::Ptr<cv::VideoCapture> capture; }; static cv::Size calc_optimal_camera_resolution(const char* supported, int width, int height) { int frame_width = 0; int frame_height = 0; size_t prev_idx = 0; size_t idx = 0; float min_diff = FLT_MAX; do { int tmp_width; int tmp_height; prev_idx = idx; while ((supported[idx] != ' 主站蜘蛛池模板: 欧美亚洲另类久久综合 | 女人18毛片视频一级毛片容 | 亚洲欧洲一区二区三区 | 亚洲精品国产一区二区在线 | 欧美日韩国产亚洲综合不卡 | 精品一区二区三区四区乱码 | 欧美成人性videos | 欧美一级爱操视频 | 免费乱码中文字幕网站 | 欧美日韩久久中文字幕 | 91福利院| 在线视频中文字幕 | 久久成人免费 | 在线亚洲一区二区 | 性欧美高清精品videos | 亚洲成网站www久久九 | 成人黄页网站 | 亚洲视频一区二区三区 | 在线观看国产亚洲 | 伊人免费在线观看高清版 | 综合久久一区二区三区 | 亚洲视频在线视频 | 国产精品国产三级国产普通话对白 | 91福利片| 亚洲 校园 春色 另类 激情 | 中文字幕日韩一区二区不卡 | 婷婷在线观看视频 | 91福利国产在线观看香蕉 | 成人性a激情免费视频 | 国产精品久久久久久免费播放 | 日韩理论片在线看免费观看 | 亚洲美女视频网站 | 欧美三级韩国三级日本一级 | 欧美日韩大片 | 亚洲伊人久久大香线蕉在观 | 中文字幕精品在线 | 国产一级理论免费版 | 亚洲 在线播放 | 一级做a爱片 | 欧美1314www伊人久久香网 | 男人午夜视频在线观看 |