优化OSD中时间的控制

serial
Matthew 1 year ago
parent d23051a10b
commit 13d77624aa

@ -93,7 +93,6 @@
<activity
android:name=".v2.Camera2VideoActivity"
android:exported="false"
android:hardwareAccelerated="true"
android:screenOrientation="landscape"
/>

@ -10,7 +10,6 @@ import android.graphics.Insets;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.net.Uri;
import android.opengl.GLException;
@ -23,12 +22,10 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.WindowMetrics;
import android.widget.FrameLayout;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@ -85,7 +82,9 @@ public class Camera2VideoActivity extends AppCompatActivity {
private Paint mPaint;
private Paint mPaintStroker;
private Bitmap mBitmap;
GlWatermarkFilter mOSDFilter = null;
private GlWatermarkFilter mOSDFilter = null;
private Object mBitmapLocker = new Object();
private SimpleDateFormat mDateFormater;
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
@ -97,7 +96,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
private int mStatusBarHeight = -1;
private long mOsdTs = 0;
private Semaphore mOSDSemaphore = new Semaphore(0);
private Thread mOsdThread = null;
private static class OSD_ITEM
{
@ -130,32 +129,53 @@ public class Camera2VideoActivity extends AppCompatActivity {
private Runnable mTimerRunnable = new Runnable() {
@Override
public void run() {
synchronized (mBitmapLocker) {
if (mBitmap != null) {
Bitmap bitmap = mBitmap;
mBitmap = null;
mOSDFilter.updateBitmap(bitmap);
}
}
long ts = System.currentTimeMillis();
mOsdTs = ts + 1000; // next second
long ms = ts % 1000;
if (ms > 900) {
ts += 1000 - ms;
ms = 0;
}
// updateOSD(ts);
Bitmap bitmap = mBitmap;
mBitmap = null;
mOSDFilter.updateBitmap(bitmap);
Log.d("OSD", "Cur TS=" + Long.toString(ts / 1000) + " Timer=" + Long.toString(1000 - ms));
mBitmap = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
mOsdTs = ts;
mOSDSemaphore.release();
mHandler.postDelayed(this, 1000 - ms);
}
};
private Thread mOsdThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
mOSDSemaphore.acquire();
} catch (Exception ex) {
}
if (mOsdTs == -1) {
break;
}
updateOSD(mOsdTs);
}
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Window win = getWindow();
// win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
/*
@ -206,9 +226,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
}
protected void onCreateActivity() {
//
// SysApi.setCam3V3Enable(true);
Intent intent = getIntent();
@ -288,27 +305,11 @@ 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();
long ts = 0;
long zeroTs = 0;
if (!TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop)) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.FILL);
@ -327,33 +328,46 @@ public class Camera2VideoActivity extends AppCompatActivity {
Canvas canvas = new Canvas(mBitmap);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
mOSDFilter = new GlWatermarkFilter(mBitmap);
long ts = System.currentTimeMillis();
ts = System.currentTimeMillis();
zeroTs = ts - (ts % 1000);
initOSD(zeroTs);
initOSD(ts);
mOSDFilter = new GlWatermarkFilter(mBitmap);
mOsdTs = ts + 1000;
long ms = ts % 1000;
mOSDSemaphore.release();
mHandler.postDelayed(mTimerRunnable, 1000 - ms);
mBitmap = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
updateOSD(zeroTs + 1000);
}
final long prevZeroTs = zeroTs;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mNextVideoAbsolutePath = getVideoFilePath();
mGPUCameraRecorder.start(mNextVideoAbsolutePath);
long ts2 = System.currentTimeMillis();
long zeroTs2 = ts2 - (ts2 % 1000);
if (zeroTs2 > prevZeroTs) {
// Next second
mOSDFilter.updateBitmap(mBitmap);
mBitmap = null;
mOsdTs = zeroTs2 + 1000;
mOSDSemaphore.release();
}
Log.d("OSD", "Cur TS=" + Long.toString(ts2 / 1000) + " Timer=" + Long.toString(1000 - (ts2 - zeroTs2)));
mHandler.postDelayed(mTimerRunnable, 1000 - (ts2 - zeroTs2));
}
}, 32);
}, 0);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mGPUCameraRecorder.stop();
}
}, 48 + mDuration * 1000);
}, 16 + mDuration * 1000);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@ -372,11 +386,13 @@ public class Camera2VideoActivity extends AppCompatActivity {
private void initOSD(long ts) {
Log.d("OSD", "INIT OSD " + Long.toString(ts / 1000));
if (mStatusBarHeight == -1) {
mStatusBarHeight = getStatusBarHeight(this);
}
int statusHeight = mStatusBarHeight;
synchronized (mBitmap) {
synchronized (mBitmapLocker) {
int bmWidth = mBitmap.getWidth();
int bmHeight = mBitmap.getHeight();
int margin = mOSDMargin;
@ -416,7 +432,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
} else {
String newText = updateOSDTime(item, ts);
Log.d("OSD", "INIT OSD x=" + origin.x + " y=" + origin.y);
canvas.drawText(newText, origin.x, origin.y, mPaint);
canvas.drawText(newText, origin.x, origin.y, mPaintStroker);
@ -556,72 +571,67 @@ public class Camera2VideoActivity extends AppCompatActivity {
private void updateOSD(long ts) {
Log.d("OSD", "prepareOSD " + Long.toString(ts / 1000));
if (mStatusBarHeight == -1) {
mStatusBarHeight = getStatusBarHeight(this);
}
int statusHeight = mStatusBarHeight;
synchronized (mBitmap) {
int bmWidth = mBitmap.getWidth();
int bmHeight = mBitmap.getHeight();
int margin = mOSDMargin;
Canvas canvas = new Canvas(mBitmap);
boolean aa = canvas.isHardwareAccelerated();
Rect textBounds = new Rect();
Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
// mBitmap.eraseColor(Color.argb(0, 0, 0, 0));
// bitmap.eraseColor(Color.argb(0, 0, 0, 0));
Canvas canvas = new Canvas(bm);
boolean aa = canvas.isHardwareAccelerated();
Rect textBounds = new Rect();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
for (OSD_ITEM osdItem : mOSDItems) {
String text = updateOSDTime(osdItem.text, ts);
int x = osdItem.previousRect.left;
int y = osdItem.previousRect.top;
if ((osdItem.mask & TIME_MASK_LT) != 0) {
// canvas.drawRect(osdItem.previousRect, mEmptyPaint);
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
Log.d("OSD", "UPD OSD x=" + x + " y=" + y);
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
osdItem.previousRect.set(x, y, x + textBounds.width(), y + textBounds.height());
} else if ((osdItem.mask & TIME_MASK_LB) != 0) {
// canvas.drawRect(osdItem.previousRect, mEmptyPaint);
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
y = osdItem.origin.y - textBounds.height();
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
osdItem.previousRect.set(x, y, x + textBounds.width(), y + textBounds.height());
} else if ((osdItem.mask & TIME_MASK_RT) != 0) {
// canvas.drawRect(osdItem.previousRect, mEmptyPaint);
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
x = osdItem.origin.x - textBounds.width();
canvas.drawText(text, x, osdItem.origin.y, mPaint);
canvas.drawText(text, x, osdItem.origin.y, mPaintStroker);
osdItem.previousRect.set(x, osdItem.origin.y, x + textBounds.width(), osdItem.origin.y + textBounds.height());
} else if ((osdItem.mask & TIME_MASK_RB) != 0) {
// canvas.drawRect(osdItem.previousRect, mEmptyPaint);
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
x = osdItem.origin.x - textBounds.width();
y = osdItem.origin.y - textBounds.height();
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
osdItem.previousRect.set(x, y, x + textBounds.width(), y + textBounds.height());
} else {
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
}
for (OSD_ITEM osdItem : mOSDItems) {
String text = updateOSDTime(osdItem.text, ts);
int x = osdItem.previousRect.left;
int y = osdItem.previousRect.top;
if ((osdItem.mask & TIME_MASK_LT) != 0) {
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
// Log.d("OSD", "UPD OSD x=" + x + " y=" + y);
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
osdItem.previousRect.set(x, y, x + textBounds.width(), y + textBounds.height());
} else if ((osdItem.mask & TIME_MASK_LB) != 0) {
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
y = osdItem.origin.y - textBounds.height();
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
osdItem.previousRect.set(x, y, x + textBounds.width(), y + textBounds.height());
} else if ((osdItem.mask & TIME_MASK_RT) != 0) {
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
x = osdItem.origin.x - textBounds.width();
canvas.drawText(text, x, osdItem.origin.y, mPaint);
canvas.drawText(text, x, osdItem.origin.y, mPaintStroker);
osdItem.previousRect.set(x, osdItem.origin.y, x + textBounds.width(), osdItem.origin.y + textBounds.height());
} else if ((osdItem.mask & TIME_MASK_RB) != 0) {
mPaintStroker.getTextBounds(text, 0, text.length(), textBounds);
x = osdItem.origin.x - textBounds.width();
y = osdItem.origin.y - textBounds.height();
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
osdItem.previousRect.set(x, y, x + textBounds.width(), y + textBounds.height());
} else {
canvas.drawText(text, x, y, mPaint);
canvas.drawText(text, x, y, mPaintStroker);
}
}
synchronized (mBitmapLocker) {
mBitmap = bm;
}
}
private String updateOSDTime(String osd, long ts) {
@ -640,7 +650,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
return newOSD;
}
private void releaseCamera() {
if (mPreviewView != null) {
mPreviewView.onPause();
@ -685,8 +694,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
mNextVideoAbsolutePath = getVideoFilePath(this);
}
mGPUCameraRecorder = new GPUCameraRecorderBuilder(this, mPreviewView)
//.recordNoFilter(true)
.cameraRecordListener(new CameraRecordListener() {
@ -712,9 +719,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
@Override
public void onRecordStart() {
}
@Override
@ -729,7 +733,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
@Override
public void onVideoFileReady() {
}
})
.videoSize(mVideoWidth, mVideoHeight)
@ -740,7 +743,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
if (mOSDFilter != null) {
mGPUCameraRecorder.setFilter(mOSDFilter);
}
}
// private void changeFilter(Filters filters) {
@ -846,7 +848,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
}
}
public static void exportMp4ToGallery(Context context, String filePath) {
final ContentValues values = new ContentValues(2);
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");

@ -90,7 +90,6 @@ public class GPUCameraRecorder {
});
}
private synchronized void startPreview(SurfaceTexture surfaceTexture) {
if (cameraHandler == null) {
final CameraThread thread = new CameraThread(cameraRecordListener, new CameraThread.OnStartPreviewListener() {
@ -132,7 +131,6 @@ public class GPUCameraRecorder {
cameraHandler.startPreview(cameraWidth, cameraHeight);
}
public void setFilter(final GlFilter filter) {
if (filter == null) return;
glPreviewRenderer.setGlFilter(filter);
@ -153,7 +151,6 @@ public class GPUCameraRecorder {
}
}
public void switchFlashMode() {
if (!flashSupport) return;
if (cameraHandler != null) {
@ -171,7 +168,6 @@ public class GPUCameraRecorder {
return flashSupport;
}
private void destroyPreview() {
if (glPreviewRenderer != null) {
glPreviewRenderer.release();

@ -73,7 +73,6 @@ public abstract class GlOverlayFilter extends GlFilter {
createBitmap();
}
// bitmap.eraseColor(Color.argb(0, 0, 0, 0));
Canvas bitmapCanvas = new Canvas(bitmap);
bitmapCanvas.scale(1, -1, bitmapCanvas.getWidth() / 2, bitmapCanvas.getHeight() / 2);
drawCanvas(bitmapCanvas);

@ -4,32 +4,32 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.util.Log;
public class GlWatermarkFilter extends GlOverlayFilter {
private Object mLocker = new Object();
private Bitmap bitmap;
private Bitmap mBitmap;
private boolean invalidated = true;
private Position position = Position.LEFT_TOP;
private Position mPosition = Position.LEFT_TOP;
public GlWatermarkFilter(Bitmap bitmap) {
this.bitmap = bitmap;
this.mBitmap = bitmap;
}
public GlWatermarkFilter(Bitmap bitmap, Position position) {
this.bitmap = bitmap;
this.position = position;
mBitmap = bitmap;
mPosition = position;
}
public void updateBitmap(Bitmap bm) {
Bitmap oldBitmap = null;
Log.d("OSD", "updateBitmap");
synchronized (mLocker) {
invalidated = true;
oldBitmap = bitmap;
bitmap = bm;
oldBitmap = mBitmap;
mBitmap = bm;
}
if (oldBitmap != null) {
@ -40,10 +40,10 @@ public class GlWatermarkFilter extends GlOverlayFilter {
@Override
protected void drawCanvas(Canvas canvas) {
synchronized (mLocker) {
Log.d("OSD", "drawCanvas");
// Log.d("OSD", "drawCanvas invalidated=" + Boolean.toString(invalidated));
if (invalidated) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawBitmap(bitmap, null, canvas.getClipBounds(), null);
canvas.drawBitmap(mBitmap, null, canvas.getClipBounds(), null);
invalidated = false;
}
}

Loading…
Cancel
Save