From 8432db83ab4e9146c1e8ee8869e8e25e83e721da Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 14 May 2024 10:27:26 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DOSD=E9=97=AA=E7=83=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mpapp/v2/Camera2VideoActivity.java | 59 ++++++++++++++++--- .../gpuv/egl/filter/GlWatermarkFilter.java | 24 +++++++- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java b/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java index 1e6c52c6..dab65330 100644 --- a/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java +++ b/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java @@ -52,6 +52,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.concurrent.Semaphore; public class Camera2VideoActivity extends AppCompatActivity { @@ -94,6 +95,9 @@ public class Camera2VideoActivity extends AppCompatActivity { private int mTimeMask = 0; private int mStatusBarHeight = -1; + private long mOsdTs = 0; + private Semaphore mOSDSemaphore = new Semaphore(0); + private Thread mOsdThread = null; private static class OSD_ITEM { @@ -134,12 +138,17 @@ public class Camera2VideoActivity extends AppCompatActivity { } // updateOSD(ts); - initOSD(ts); + Bitmap bitmap = mBitmap; + mBitmap = null; + mOSDFilter.updateBitmap(bitmap); + + mBitmap = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888); + mOsdTs = ts; + mOSDSemaphore.release(); mHandler.postDelayed(this, 1000 - ms); } }; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -261,6 +270,7 @@ public class Camera2VideoActivity extends AppCompatActivity { mTimeMask |= TIME_MASK_RB_ML; } } + if (!TextUtils.isEmpty(mOSDLeftBottom)) { mOSDLeftBottom = mOSDLeftBottom.replace("\r\n", "\n"); mOSDLeftBottom = mOSDLeftBottom.replace("\n\r", "\n"); @@ -278,10 +288,42 @@ public class Camera2VideoActivity extends AppCompatActivity { mHandler = new Handler(); + mOsdThread = new Thread(new Runnable() { + @Override + public void run() { + while (true) { + try { + mOSDSemaphore.acquire(); + } catch (Exception ex) { + + } + + if (mOsdTs == -1) { + break; + } + + updateOSD(mOsdTs); + } + } + }); + + mOsdThread.start(); + mHandler.postDelayed(new Runnable() { @Override public void run() { mNextVideoAbsolutePath = getVideoFilePath(); + + if (mTimeMask != 0) { + long ts = System.currentTimeMillis(); + long ms = ts % 1000; + initOSD(ts - ms); + + mOsdTs = ts + 1000; + mOSDSemaphore.release(); + mHandler.postDelayed(mTimerRunnable, 1000 - ms); + } + mGPUCameraRecorder.start(mNextVideoAbsolutePath); } }, 200); @@ -291,7 +333,7 @@ public class Camera2VideoActivity extends AppCompatActivity { public void run() { mGPUCameraRecorder.stop(); } - }, 200 + mDuration * 1000); + }, 210 + mDuration * 1000); // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); } @@ -644,6 +686,8 @@ public class Camera2VideoActivity extends AppCompatActivity { mNextVideoAbsolutePath = getVideoFilePath(this); } + + mGPUCameraRecorder = new GPUCameraRecorderBuilder(this, mPreviewView) //.recordNoFilter(true) .cameraRecordListener(new CameraRecordListener() { @@ -655,6 +699,8 @@ public class Camera2VideoActivity extends AppCompatActivity { @Override public void onRecordComplete() { mHandler.removeCallbacks(mTimerRunnable); + mOsdTs = -1; + mOSDSemaphore.release(); exportMp4ToGallery(getApplicationContext(), mNextVideoAbsolutePath); broadcastVideoFile(true, mNextVideoAbsolutePath); mHandler.postDelayed(new Runnable() { @@ -668,12 +714,7 @@ public class Camera2VideoActivity extends AppCompatActivity { @Override public void onRecordStart() { - if (mTimeMask != 0) { - long ts = System.currentTimeMillis(); - long ms = ts % 1000; - initOSD(ts - ms); - mHandler.postDelayed(mTimerRunnable, 1000 - ms); - } + } diff --git a/gpuv/src/main/java/com/xypower/gpuv/egl/filter/GlWatermarkFilter.java b/gpuv/src/main/java/com/xypower/gpuv/egl/filter/GlWatermarkFilter.java index 6a265971..07f0da9a 100644 --- a/gpuv/src/main/java/com/xypower/gpuv/egl/filter/GlWatermarkFilter.java +++ b/gpuv/src/main/java/com/xypower/gpuv/egl/filter/GlWatermarkFilter.java @@ -9,7 +9,9 @@ import android.util.Log; public class GlWatermarkFilter extends GlOverlayFilter { + private Object mLocker = new Object(); private Bitmap bitmap; + private boolean invalidated = true; private Position position = Position.LEFT_TOP; public GlWatermarkFilter(Bitmap bitmap) { @@ -22,12 +24,28 @@ public class GlWatermarkFilter extends GlOverlayFilter { this.position = position; } + public void updateBitmap(Bitmap bm) { + Bitmap oldBitmap = null; + synchronized (mLocker) { + invalidated = true; + oldBitmap = bitmap; + bitmap = bm; + } + + if (oldBitmap != null) { + // oldBitmap.recycle(); + } + } + @Override protected void drawCanvas(Canvas canvas) { - synchronized (bitmap) { + synchronized (mLocker) { Log.d("OSD", "drawCanvas"); - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - canvas.drawBitmap(bitmap, null, canvas.getClipBounds(), null); + if (invalidated) { + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + canvas.drawBitmap(bitmap, null, canvas.getClipBounds(), null); + invalidated = false; + } } /*