关于Camera补帧处理
程序员文章站
2022-09-02 18:03:25
帧处理相关相关Camera获取帧接口camera.addCallbackBuffer(ByteArray(mWidth * mHeight * ImageFormat.getBitsPerPixel(dataFormat) / 8))camera.setPreviewCallbackWithBuffer { data, camera -> //此处处理帧数据 关于多少帧处理需要根据实际情况来确定 存入循环queue copybyte = Byte....
帧处理相关
相关Camera获取帧接口
camera.addCallbackBuffer(ByteArray(mWidth * mHeight * ImageFormat.getBitsPerPixel(dataFormat) / 8)) camera.setPreviewCallbackWithBuffer { data, camera -> //此处处理帧数据 关于多少帧处理需要根据实际情况来确定 存入循环queue
copybyte = ByteArray(data.size) copybyte = data.copyOf()
ringbufferTool.put(data)//4 }
新起线程 开启循环读取队列(注意 "单列" 线程里边最好不要出现break 、return 之类的词,否则触发后会导致线程直接关闭)
new Thread{
//将数据读取出来
ringbufferTool!!.get()
}.start()
循环queue队列实现(遵循先进先出,出了后补的原则)
package com.sunchip.pointreadingpen.util; import android.util.Log; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Created by Li on 2020/9/16. */ public class RingBuffTool<T> { private final static int DEFAULT_SIZE = 550; private Object[] buffer; private int head = 0; private int tail = 0; private int bufferSize; public RingBuffTool(){ this.bufferSize = DEFAULT_SIZE; this.buffer = new Object[bufferSize]; // Byte[] data = new Byte[1024]; // buffer[0] = data; cameraBuffers = new ArrayList<>(); } public RingBuffTool(int initSize){ this.bufferSize = initSize; this.buffer = new Object[bufferSize]; } private Boolean empty() { return head == tail; } private Boolean full() { return (tail + 1) % bufferSize == head; } public void clear(){ Arrays.fill(buffer,null); this.head = 0; this.tail = 0; } public Boolean put(byte[] v) { if (full()) { return false; } Log.w("bufferNumber","put number buffer ..... tail "+tail); buffer[tail] = v; tail = (tail + 1) % bufferSize; return true; } public Boolean put(int v) { if (full()) { return false; } Log.w("bufferNumber","put number buffer ..... tail "+tail); buffer[tail] = v; tail = (tail + 1) % bufferSize; return true; } public Object get() { if (empty()) { //Log.w("bufferNumber","判空 ..."); return null; } Object result = buffer[head]; Log.w("bufferNumber","get + head"+head); head = (head + 1) % bufferSize; return result; } public Object[] getAll() { if (empty()) { return new Object[0]; } int copyTail = tail; int cnt = head < copyTail ? copyTail - head : bufferSize - head + copyTail; Object[] result = new String[cnt]; if (head < copyTail) { for (int i = head; i < copyTail; i++) { result[i - head] = buffer[i]; } } else { for (int i = head; i < bufferSize; i++) { result[i - head] = buffer[i]; } for (int i = 0; i < copyTail; i++) { result[bufferSize - head + i] = buffer[i]; } } head = copyTail; return result; } //********************************************************************************************** private final static int DEFAULT_SIZES = 200; private List<byte[]>cameraBuffers; private int headbuffer = 0; private int tailbuffer = 0; private int databufferSize; public RingBuffTool(boolean nothing){ } public interface OnPutListener{ } }
顺带实现一下单列线程池实现
package com.sunchip.pointreadingpen.util; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * Created by Li on 2020/2/28. */ public class ThreadPoolManager<T> { /** * 根据cpu的数量动态的配置核心线程数和最大线程数 */ private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); /** * 核心线程数 = CPU核心数 + 1 */ private static final int CORE_POOL_SIZE = CPU_COUNT + 1; /** * 线程池最大线程数 = CPU核心数 * 2 + 1 */ private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; /** * 非核心线程闲置时超时1s */ private static final int KEEP_ALIVE = 1; /** * 线程池的对象 */ private ThreadPoolExecutor executor; /** * 要确保该类只有一个实例对象,避免产生过多对象消费资源,所以采用单例模式 */ private ThreadPoolManager() { } private static ThreadPoolManager sInstance; public synchronized static ThreadPoolManager getsInstance() { if (sInstance == null) { sInstance = new ThreadPoolManager(); } return sInstance; } /** * 开启一个无返回结果的线程 * @param r */ public void execute(Runnable r) { if (executor == null) { /** * corePoolSize:核心线程数 * maximumPoolSize:线程池所容纳最大线程数(workQueue队列满了之后才开启) * keepAliveTime:非核心线程闲置时间超时时长 * unit:keepAliveTime的单位 * workQueue:等待队列,存储还未执行的任务 * threadFactory:线程创建的工厂 * handler:异常处理机制 * */ //四种相对锁 // new ArrayBlockingQueue<Runnable>(20) // new LinkedBlockingQueue<Runnable>(20); // new SynchronousQueue(); // new DelayQueue(); executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); } // 把一个任务丢到了线程池中 executor.execute(r); } /** * 开启一个有返回结果的线程 * @param r * @return */ public Future<T> submit(Callable<T> r) { if (executor == null) { /** * corePoolSize:核心线程数 * maximumPoolSize:线程池所容纳最大线程数(workQueue队列满了之后才开启) * keepAliveTime:非核心线程闲置时间超时时长 * unit:keepAliveTime的单位 * workQueue:等待队列,存储还未执行的任务 * threadFactory:线程创建的工厂 * handler:异常处理机制 * */ executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); } // 把一个任务丢到了线程池中 return executor.submit(r); } /** * 把任务移除等待队列 * @param r */ public void cancel(Runnable r) { if (r != null) { executor.getQueue().remove(r); } } }
害,搞搞又是一天
本文地址:https://blog.csdn.net/qq_32216895/article/details/108714683
上一篇: jb51用的ubb转换 原创
下一篇: 微信小程序通过保存图片分享到朋友圈功能
推荐阅读