zl程序教程

您现在的位置是:首页 >  Java

当前栏目

从零开发一款相机APP 第十五篇: YUV流处理

2023-02-18 16:35:34 时间
本课程内容由 @公众号:小驰笔记出品,欢迎关注公众号,获取更多交流信息~
欢迎访问个人博客:www.xiaochibiji.com

一、如何获取实时预览流?

1)camera1 api 如何获取?

//1) 设置preview callback
Camera.setPreviewCallback(mPreviewCallback);

//2)回调数据是nv21格式yuv数据
public PreviewCallback mPreviewCallback = new PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
            }
        };

2)camera2 api如何获取?

private ImageReader mImageReader;
//1) 创建ImageReader
mImageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, MAX_REQUIRED_IMAGE_NUM);

//2) 设置数据回调监听
mImageReader.setOnImageAvailableListener(mImageReaderAvailableListener, mBackgroundHandler);

//3) 讲ImageReader 的surface设置到target
surfaces.add(mImageReader.getSurface());
mPreviewBuilder.addTarget(mImageReader.getSurface());

//4) 创建的session中,携带imageReader的surface
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {}

// 5)回调数据中解析y、u、v 数据
private class MyImageReaderAvailableListener implements ImageReader.OnImageAvailableListener {
        private byte[] y;
        private byte[] u;
        private byte[] v;
        private ReentrantLock lock = new ReentrantLock();

        @Override
        public void onImageAvailable(ImageReader reader) {
                Image image = reader.acquireLatestImage();

               synchronized (mImageReaderLock) {

                   if (ImageFormat.YUV_420_888 == image.getFormat()) {
                        Image.Plane[] planes = image.getPlanes();

                        // 加锁确保y、u、v来源于同一个Image
                        lock.lock();

                        if (y == null) {
                            y = new byte[planes[0].getBuffer().limit() - planes[0].getBuffer().position()];
                            u = new byte[planes[1].getBuffer().limit() - planes[1].getBuffer().position()];
                            v = new byte[planes[2].getBuffer().limit() - planes[2].getBuffer().position()];
                        }

                        if (mHasSetImageReaderTarget && mPreviewListener != null && image.getPlanes()[0].getBuffer().remaining() == y.length) {
                            planes[0].getBuffer().get(y);
                            planes[1].getBuffer().get(u);
                            planes[2].getBuffer().get(v);
                        }
                        lock.unlock();
                    }
                }
                image.close();
        }
}

二、如何一边本地录像,一边后台推流?

深圳上班,

从事Android Camera相关软件开发工作,

公众号记录生活和工作的点滴,