diff --git a/app/app.iml b/app/app.iml
index e03e0af..836541a 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -9,7 +9,6 @@
-
@@ -23,7 +22,7 @@
-
+
@@ -47,7 +46,6 @@
-
@@ -55,7 +53,6 @@
-
@@ -63,25 +60,22 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -100,37 +94,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java
index 0da2000..7a71ae4 100644
--- a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java
+++ b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java
@@ -2,19 +2,14 @@ package com.jiangdg.usbcamera.view;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
import android.support.annotation.Nullable;
-import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
-import android.util.Log;
import android.view.Surface;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
-import com.jiangdg.usbcamera.FileUtils;
+import com.jiangdg.usbcamera.utils.FileUtils;
import com.jiangdg.usbcamera.R;
import com.jiangdg.usbcamera.USBCameraManager;
import com.serenegiant.usb.CameraDialog;
@@ -24,12 +19,6 @@ import com.serenegiant.usb.common.AbstractUVCCameraHandler;
import com.serenegiant.usb.encoder.RecordParams;
import com.serenegiant.usb.widget.CameraViewInterface;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/task/SaveYuvImageTask.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/task/SaveYuvImageTask.java
new file mode 100644
index 0000000..567ee19
--- /dev/null
+++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/task/SaveYuvImageTask.java
@@ -0,0 +1,82 @@
+package com.jiangdg.usbcamera.task;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.os.AsyncTask;
+
+import com.jiangdg.usbcamera.utils.YUVBean;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**保存YUV格式(NV21)图片
+ *
+ * Created by jiangdongguo on 2017-12-25下午9:13:01
+ */
+public class SaveYuvImageTask extends AsyncTask {
+ private static final String TAG = "SaveYuvImageTask";
+ private YUVBean yuvBean;
+ private Context mContext;
+ //转换结果回调接口
+ private OnSaveYuvResultListener mListener;
+
+ public interface OnSaveYuvResultListener{
+ void onSaveResult(String savePath);
+ }
+
+ public SaveYuvImageTask(YUVBean yuvBean, OnSaveYuvResultListener mListener) {
+ this.yuvBean = yuvBean;
+ this.mListener = mListener;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ if (yuvBean == null || yuvBean.getWidth() == 0
+ || yuvBean.getHeight() == 0 || yuvBean.getYuvData() == null) {
+ return null;
+ }
+ saveYuv2Jpeg(yuvBean.getYuvData(),yuvBean.getWidth(),yuvBean.getHeight());
+ return null;
+ }
+
+ private void saveYuv2Jpeg(byte[] data,int width,int height){
+ YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
+ boolean result = yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, bos);
+ if(result){
+ byte[] buffer = bos.toByteArray();
+ Bitmap bmp = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
+ bmp.recycle();
+ String savPath = yuvBean.getPicPath();
+ File file = new File(savPath);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(file);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
+ try {
+ fos.flush();
+ fos.close();
+ //传递转换结果给调用者
+ mListener.onSaveResult(savPath);
+ } catch (IOException e) {
+ e.printStackTrace();
+ mListener.onSaveResult(null);
+ }
+ }
+ try {
+ bos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/FileUtils.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java
similarity index 97%
rename from libusbcamera/src/main/java/com/jiangdg/usbcamera/FileUtils.java
rename to libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java
index 4467c38..6d1637d 100644
--- a/libusbcamera/src/main/java/com/jiangdg/usbcamera/FileUtils.java
+++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java
@@ -1,4 +1,4 @@
-package com.jiangdg.usbcamera;
+package com.jiangdg.usbcamera.utils;
import android.os.Environment;
diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/YUVBean.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/YUVBean.java
new file mode 100644
index 0000000..ded8df4
--- /dev/null
+++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/YUVBean.java
@@ -0,0 +1,45 @@
+package com.jiangdg.usbcamera.utils;
+
+/** NV21数据类
+ *
+ * Created by jiangdongguo on 2018/1/26.
+ */
+
+public class YUVBean {
+ private int width;
+ private int height;
+ private byte[] yuvData;
+ private String picPath;
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public byte[] getYuvData() {
+ return yuvData;
+ }
+
+ public void setYuvData(byte[] yuvData) {
+ this.yuvData = yuvData;
+ }
+
+ public String getPicPath() {
+ return picPath;
+ }
+
+ public void setPicPath(String picPath) {
+ this.picPath = picPath;
+ }
+}
diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java
index 75de3fc..14d5df8 100644
--- a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java
+++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java
@@ -16,12 +16,10 @@ import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
-import com.jiangdg.usbcamera.FileUtils;
import com.serenegiant.usb.IFrameCallback;
import com.serenegiant.usb.Size;
import com.serenegiant.usb.USBMonitor;
import com.serenegiant.usb.UVCCamera;
-import com.serenegiant.usb.encoder.MediaAudioEncoder;
import com.serenegiant.usb.encoder.MediaEncoder;
import com.serenegiant.usb.encoder.MediaMuxerWrapper;
import com.serenegiant.usb.encoder.MediaSurfaceEncoder;
@@ -41,8 +39,6 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
-import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -536,6 +532,9 @@ public abstract class AbstractUVCCameraHandler extends Handler {
if(mPreviewListener != null){
mPreviewListener.onPreviewResult(true);
}
+ // 获取USB Camera预览数据
+ mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21);
+
} catch (final IllegalArgumentException e) {
// 添加分辨率参数合法性检测
if(mPreviewListener != null){
@@ -586,7 +585,7 @@ public abstract class AbstractUVCCameraHandler extends Handler {
if (parent == null) return;
// mSoundPool.play(mSoundId, 0.2f, 0.2f, 0, 0, 1.0f); // play shutter sound
try {
- final Bitmap bitmap = mWeakCameraView.get().captureStillImage();
+ final Bitmap bitmap = mWeakCameraView.get().captureStillImage(mWidth,mHeight);
// get buffered output stream for saving a captured still image as a file on external storage.
// the file name is came from current time.
// You should use extension name as same as CompressFormat when calling Bitmap#compress.
@@ -662,8 +661,8 @@ public abstract class AbstractUVCCameraHandler extends Handler {
return;
if (params == null)
throw new NullPointerException("RecordParams can not be null!");
- // 获取USB Camera预览数据
- mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21);
+// // 获取USB Camera预览数据
+// mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21);
// 初始化混合器
videoPath = params.getRecordPath();
mMuxer = new Mp4MediaMuxer(params.getRecordPath(),
@@ -774,30 +773,7 @@ public abstract class AbstractUVCCameraHandler extends Handler {
// isAudioThreadStart = false;
}
- // 停止录制视频
-// public void handleStopRecording2() {
-// if (DEBUG) Log.v(TAG_THREAD, "handleStopRecording:mMuxer=" + mMuxer);
-// final MediaMuxerWrapper muxer;
-// synchronized (mSync) {
-// muxer = mMuxer;
-// mMuxer = null;
-// mVideoEncoder = null;
-// if (mUVCCamera != null) {
-// mUVCCamera.stopCapture();
-// }
-// }
-// try {
-// mWeakCameraView.get().setVideoEncoder(null);
-// } catch (final Exception e) {
-// // ignore
-// }
-// if (muxer != null) {
-// muxer.stopRecording();
-// mUVCCamera.setFrameCallback(null, 0);
-// // you should not wait here
-// callOnStopRecording();
-// }
-// }
+ private boolean isCaptureStill;
private final IFrameCallback mIFrameCallback = new IFrameCallback() {
@Override
@@ -813,6 +789,11 @@ public abstract class AbstractUVCCameraHandler extends Handler {
int len = frame.capacity();
byte[] yuv = new byte[len];
frame.get(yuv);
+ // 捕获图片
+ if(isCaptureStill) {
+
+ }
+ // 视频
if(mH264Consumer != null){
// 修改分辨率参数
mH264Consumer.setRawYuv(yuv,mWidth,mHeight);
diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/MediaEncoder.java b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/MediaEncoder.java
index 633255e..d2b99c1 100644
--- a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/MediaEncoder.java
+++ b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/MediaEncoder.java
@@ -3,18 +3,13 @@ package com.serenegiant.usb.encoder;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Build;
-import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
-import com.jiangdg.usbcamera.FileUtils;
+import com.jiangdg.usbcamera.utils.FileUtils;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
-import java.nio.Buffer;
import java.nio.ByteBuffer;
public abstract class MediaEncoder implements Runnable {
diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java
index f35ae4e..01f860d 100644
--- a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java
+++ b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/H264EncodeConsumer.java
@@ -14,12 +14,6 @@ import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
-import com.jiangdg.usbcamera.FileUtils;
-
-import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar;
-import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar;
-import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
-
/** 对YUV视频流进行编码
* Created by jiangdongguo on 2017/5/6.
*/
diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/widget/AspectRatioTextureView.java b/libusbcamera/src/main/java/com/serenegiant/usb/widget/AspectRatioTextureView.java
index 1599519..076758d 100644
--- a/libusbcamera/src/main/java/com/serenegiant/usb/widget/AspectRatioTextureView.java
+++ b/libusbcamera/src/main/java/com/serenegiant/usb/widget/AspectRatioTextureView.java
@@ -56,6 +56,7 @@ public class AspectRatioTextureView extends TextureView // API >= 14
super(context, attrs, defStyle);
}
+ // 设置屏幕宽高比
@Override
public void setAspectRatio(final double aspectRatio) {
if (aspectRatio < 0) {
diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/widget/CameraViewInterface.java b/libusbcamera/src/main/java/com/serenegiant/usb/widget/CameraViewInterface.java
index 53b9741..af903d6 100644
--- a/libusbcamera/src/main/java/com/serenegiant/usb/widget/CameraViewInterface.java
+++ b/libusbcamera/src/main/java/com/serenegiant/usb/widget/CameraViewInterface.java
@@ -43,5 +43,5 @@ public interface CameraViewInterface extends IAspectRatioView {
public Surface getSurface();
public boolean hasSurface();
public void setVideoEncoder(final IVideoEncoder encoder);
- public Bitmap captureStillImage();
+ public Bitmap captureStillImage(int width,int height);
}
diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/widget/UVCCameraTextureView.java b/libusbcamera/src/main/java/com/serenegiant/usb/widget/UVCCameraTextureView.java
index 42529e7..b1880b9 100644
--- a/libusbcamera/src/main/java/com/serenegiant/usb/widget/UVCCameraTextureView.java
+++ b/libusbcamera/src/main/java/com/serenegiant/usb/widget/UVCCameraTextureView.java
@@ -60,6 +60,9 @@ public class UVCCameraTextureView extends AspectRatioTextureView // API >= 14
private Bitmap mTempBitmap;
private boolean mReqesutCaptureStillImage;
private Callback mCallback;
+ // Camera分辨率宽度
+
+
/** for calculation of frame rate */
private final FpsCounter mFpsCounter = new FpsCounter();
@@ -169,7 +172,7 @@ public class UVCCameraTextureView extends AspectRatioTextureView // API >= 14
* you should change this method(copy and return)
*/
@Override
- public Bitmap captureStillImage() {
+ public Bitmap captureStillImage(int width,int height) {
synchronized (mCaptureSync) {
mReqesutCaptureStillImage = true;
try {