From 73d06c931a48648805f333a7113686a26764100d Mon Sep 17 00:00:00 2001 From: jiangdongguo <765067602@qq.com> Date: Fri, 26 Jan 2018 17:59:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=8D=E7=85=A7=E5=88=86?= =?UTF-8?q?=E8=BE=A8=E7=8E=87=E4=B8=8D=E6=AD=A3=E7=A1=AE=E9=97=AE=E9=A2=98?= =?UTF-8?q?(=E6=9C=AA=E5=AE=8C=E6=88=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/app.iml | 84 +++++++++---------- .../usbcamera/view/USBCameraActivity.java | 13 +-- .../usbcamera/task/SaveYuvImageTask.java | 82 ++++++++++++++++++ .../usbcamera/{ => utils}/FileUtils.java | 2 +- .../com/jiangdg/usbcamera/utils/YUVBean.java | 45 ++++++++++ .../usb/common/AbstractUVCCameraHandler.java | 43 +++------- .../serenegiant/usb/encoder/MediaEncoder.java | 7 +- .../usb/encoder/biz/H264EncodeConsumer.java | 6 -- .../usb/widget/AspectRatioTextureView.java | 1 + .../usb/widget/CameraViewInterface.java | 2 +- .../usb/widget/UVCCameraTextureView.java | 5 +- 11 files changed, 187 insertions(+), 103 deletions(-) create mode 100644 libusbcamera/src/main/java/com/jiangdg/usbcamera/task/SaveYuvImageTask.java rename libusbcamera/src/main/java/com/jiangdg/usbcamera/{ => utils}/FileUtils.java (97%) create mode 100644 libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/YUVBean.java 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 @@ - + @@ -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 {