From 30678653058f62beda7ac3f3ac94bc830b6db85e Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期三, 03 十二月 2025 10:49:35 +0800
Subject: [PATCH] 1.新开进程camera2 2.未测试验证 H264EncodeService2
---
app/src/main/java/com/anyun/h264/H264EncodeService.java | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 163 insertions(+), 13 deletions(-)
diff --git a/app/src/main/java/com/anyun/h264/H264EncodeService.java b/app/src/main/java/com/anyun/h264/H264EncodeService.java
index 67ce31f..a798418 100644
--- a/app/src/main/java/com/anyun/h264/H264EncodeService.java
+++ b/app/src/main/java/com/anyun/h264/H264EncodeService.java
@@ -1,7 +1,10 @@
package com.anyun.h264;
import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import timber.log.Timber;
@@ -19,6 +22,8 @@
import java.util.Date;
import java.util.List;
import java.util.Locale;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* H264缂栫爜鏈嶅姟
@@ -31,6 +36,11 @@
private H264FileTransmitter h264FileTransmitter; // H264鏂囦欢浼犺緭鍣�
private String outputFileDirectory; // H264鏂囦欢杈撳嚭鐩綍
private WatermarkInfo currentWatermarkInfo; // 褰撳墠姘村嵃淇℃伅
+
+ // 澶氳繘绋嬫敮鎸侊細绗簩涓憚鍍忓ご鐨勬湇鍔¤繛鎺�
+ private IH264EncodeService camera2Service;
+ private ServiceConnection camera2Connection;
+ private boolean isCamera2Bound = false;
// 榛樿缂栫爜鍙傛暟
private static final int DEFAULT_WIDTH = 640;
@@ -91,6 +101,18 @@
// 鍋滄骞堕噴鏀剧紪鐮佸櫒鍜屾枃浠朵紶杈撳櫒
stopEncoder();
stopFileTransmitter();
+
+ // 瑙g粦绗簩涓繘绋嬬殑鏈嶅姟
+ if (isCamera2Bound && camera2Connection != null) {
+ try {
+ unbindService(camera2Connection);
+ } catch (Exception e) {
+ Timber.e(e, "Error unbinding camera2 service");
+ }
+ isCamera2Bound = false;
+ camera2Service = null;
+ camera2Connection = null;
+ }
}
/**
@@ -103,6 +125,7 @@
int height;
int framerate;
String simPhone;
+ Integer cameraId; // 鎽勫儚澶碔D锛�1鎴�2锛岀敤浜庡杩涚▼鏂规锛�
// 浠嶫SON瑙f瀽閰嶇疆
static EncodeConfig fromJson(String jsonConfig) throws JSONException {
@@ -115,6 +138,7 @@
config.ip = null;
config.port = 0;
config.simPhone = null;
+ config.cameraId = 1; // 榛樿浣跨敤绗竴涓憚鍍忓ご
return config;
}
@@ -125,6 +149,13 @@
config.ip = json.optString("ip", null);
config.port = json.optInt("port", 0);
config.simPhone = json.optString("simPhone", null);
+
+ // 瑙f瀽cameraId锛堝鏋滄湭鎸囧畾锛岄粯璁や负1锛�
+ if (json.has("cameraId")) {
+ config.cameraId = json.optInt("cameraId", 1);
+ } else {
+ config.cameraId = 1; // 榛樿浣跨敤绗竴涓憚鍍忓ご
+ }
return config;
}
@@ -171,15 +202,34 @@
* 4-寮�濮嬩紶杈揌264鏂囦欢锛堜粠鏂囦欢璇诲彇骞剁綉缁滄帹閫侊級锛�
* 5-鍋滄H264鏂囦欢浼犺緭
* @param jsonConfig JSON鏍煎紡鐨勯厤缃弬鏁�
- * action 0/2: 鍖呭惈锛歩p銆乸ort銆亀idth銆乭eight銆乫ramerate銆乻imPhone
+ * action 0/2: 鍖呭惈锛歩p銆乸ort銆亀idth銆乭eight銆乫ramerate銆乻imPhone銆乧ameraId锛堝彲閫夛紝1鎴�2锛岄粯璁�1锛�
* action 4: 鍖呭惈锛歩p銆乸ort銆乫ramerate銆乻imPhone銆乫ilePath銆乸rotocolType锛堝彲閫夛紝1-UDP锛�2-TCP锛岄粯璁CP锛�
- * action 1/3/5: 姝ゅ弬鏁板彲涓虹┖鎴杗ull
+ * action 1/3/5: 姝ゅ弬鏁板彲涓虹┖鎴杗ull锛屾垨鍖呭惈cameraId鏉ユ寚瀹氳鍋滄鐨勬憚鍍忓ご
* @return 0-鎴愬姛锛�1-澶辫触
*/
private synchronized int controlEncode(int action, String jsonConfig) {
Timber.d("controlEncode called with action: %d, jsonConfig: %s", action, jsonConfig);
try {
+ // 瑙f瀽cameraId锛堝鏋滈厤缃腑鏈夛級
+ Integer cameraId = null;
+ if (jsonConfig != null && !jsonConfig.trim().isEmpty()) {
+ try {
+ JSONObject json = new JSONObject(jsonConfig);
+ if (json.has("cameraId")) {
+ cameraId = json.optInt("cameraId", 1);
+ }
+ } catch (JSONException e) {
+ // 蹇界暐瑙f瀽閿欒锛岀户缁娇鐢ㄥ綋鍓嶈繘绋�
+ }
+ }
+
+ // 濡傛灉鎸囧畾浜哻ameraId=2锛岃矾鐢卞埌绗簩涓繘绋�
+ if (cameraId != null && cameraId == 2) {
+ return controlEncodeInProcess2(action, jsonConfig);
+ }
+
+ // 鍚﹀垯鍦ㄥ綋鍓嶈繘绋嬶紙cameraId=1锛夊鐞�
switch (action) {
case 0: // 寮�鍚痟264鏂囦欢鍐欏叆
try {
@@ -191,6 +241,10 @@
}
case 1: // 鍋滄h264缂栫爜骞跺仠姝㈠啓鍏ユ枃浠�
+ // 妫�鏌ユ槸鍚︽寚瀹氫簡cameraId=2
+ if (cameraId != null && cameraId == 2) {
+ return controlEncodeInProcess2(action, jsonConfig);
+ }
return stopEncoder();
case 2: // 寮�鍚綉缁滄帹閫乭264锛堜笉鍐欏叆鏂囦欢锛�
@@ -203,6 +257,10 @@
}
case 3: // 鍋滄h264缂栫爜骞跺仠姝㈢綉缁滄帹閫�
+ // 妫�鏌ユ槸鍚︽寚瀹氫簡cameraId=2
+ if (cameraId != null && cameraId == 2) {
+ return controlEncodeInProcess2(action, jsonConfig);
+ }
return stopEncoder();
case 4: // 寮�濮嬩紶杈揌264鏂囦欢
@@ -216,6 +274,10 @@
case 5: // 鍋滄H264鏂囦欢浼犺緭
Timber.i("瀹㈡埛绔姹傚仠姝㈣棰戞枃浠朵笂浼�");
+ // 妫�鏌ユ槸鍚︽寚瀹氫簡cameraId=2
+ if (cameraId != null && cameraId == 2) {
+ return controlEncodeInProcess2(action, jsonConfig);
+ }
return stopFileTransmitter();
default:
@@ -226,6 +288,85 @@
Timber.e(e, "Error in controlEncode");
return 1; // 澶辫触
}
+ }
+
+ /**
+ * 鍦ㄧ浜屼釜杩涚▼锛坈amera2锛変腑鎵ц缂栫爜鎺у埗
+ */
+ private int controlEncodeInProcess2(int action, String jsonConfig) {
+ Timber.d("Routing to process 2 (camera2) for action: %d", action);
+
+ try {
+ // 纭繚绗簩涓繘绋嬬殑鏈嶅姟宸茬粦瀹�
+ if (!ensureCamera2ServiceBound()) {
+ Timber.e("Failed to bind camera2 service");
+ return 1;
+ }
+
+ // 璋冪敤绗簩涓繘绋嬬殑鏈嶅姟
+ if (camera2Service != null) {
+ return camera2Service.controlEncode(action, jsonConfig);
+ } else {
+ Timber.e("Camera2 service is null");
+ return 1;
+ }
+ } catch (RemoteException e) {
+ Timber.e(e, "Error calling camera2 service");
+ return 1;
+ }
+ }
+
+ /**
+ * 纭繚绗簩涓繘绋嬬殑鏈嶅姟宸茬粦瀹�
+ */
+ private synchronized boolean ensureCamera2ServiceBound() {
+ if (isCamera2Bound && camera2Service != null) {
+ return true;
+ }
+
+ Timber.d("Binding to camera2 service...");
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ final boolean[] success = {false};
+
+ camera2Connection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ Timber.d("Camera2 service connected");
+ camera2Service = IH264EncodeService.Stub.asInterface(service);
+ isCamera2Bound = true;
+ success[0] = true;
+ latch.countDown();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Timber.w("Camera2 service disconnected");
+ camera2Service = null;
+ isCamera2Bound = false;
+ }
+ };
+
+ Intent intent = new Intent(this, H264EncodeService2.class);
+ boolean bound = bindService(intent, camera2Connection, Context.BIND_AUTO_CREATE);
+
+ if (!bound) {
+ Timber.e("Failed to bind camera2 service");
+ return false;
+ }
+
+ // 绛夊緟鏈嶅姟杩炴帴锛堟渶澶�5绉掞級
+ try {
+ if (!latch.await(5, TimeUnit.SECONDS)) {
+ Timber.e("Timeout waiting for camera2 service connection");
+ return false;
+ }
+ } catch (InterruptedException e) {
+ Timber.e(e, "Interrupted while waiting for camera2 service");
+ return false;
+ }
+
+ return success[0];
}
/**
@@ -245,9 +386,9 @@
h264Encoder = new H264Encoder();
// 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
- int width = config != null ? config.width : DEFAULT_WIDTH;
- int height = config != null ? config.height : DEFAULT_HEIGHT;
- int framerate = config != null ? config.framerate : DEFAULT_FRAME_RATE;
+ int width = config != null && config.width > 0 ? config.width : DEFAULT_WIDTH;
+ int height = config != null && config.height > 0 ? config.height : DEFAULT_HEIGHT;
+ int framerate = config != null && config.framerate > 0 ? config.framerate : DEFAULT_FRAME_RATE;
h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
long timeFile = System.currentTimeMillis()/1000*1000;//Date鏄锛屾墍浠ヤ负浜嗚窡涓嬪彂鐨凞ate starttime涓�鑷达紝姝ゅ闄や互1000 绉�
@@ -264,8 +405,14 @@
h264Encoder.setEnableNetworkTransmission(false);
// 鍒濆鍖栧苟鍚姩锛堜娇鐢ㄩ厤缃腑鐨勫垎杈ㄧ巼锛�
+ // 鏍规嵁cameraId閫夋嫨鎽勫儚澶磋寖鍥�
+ int[] cameraIdRange = DEFAULT_CAMERA_ID_RANGE;
+ if (config != null && config.cameraId != null) {
+ // 濡傛灉鎸囧畾浜哻ameraId锛屼娇鐢ㄥ搴旂殑鎽勫儚澶�
+ cameraIdRange = new int[]{config.cameraId, config.cameraId};
+ }
int[] resolution = {width, height};
- if (h264Encoder.initialize(DEFAULT_CAMERA_ID_RANGE, null, resolution, false)) {
+ if (h264Encoder.initialize(cameraIdRange, null, resolution, false)) {
// 搴旂敤宸蹭繚瀛樼殑姘村嵃淇℃伅锛堝鏋滄湁锛�
if (currentWatermarkInfo != null) {
h264Encoder.setWatermarkInfo(currentWatermarkInfo);
@@ -310,12 +457,9 @@
h264Encoder = new H264Encoder();
// 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
-
-
- // 璁剧疆缂栫爜鍙傛暟锛堜娇鐢ㄩ厤缃腑鐨勫弬鏁帮級
- int width = DEFAULT_WIDTH;
- int height = DEFAULT_HEIGHT;
- int framerate = DEFAULT_FRAME_RATE;
+ int width = config != null && config.width > 0 ? config.width : DEFAULT_WIDTH;
+ int height = config != null && config.height > 0 ? config.height : DEFAULT_HEIGHT;
+ int framerate = config != null && config.framerate > 0 ? config.framerate : DEFAULT_FRAME_RATE;
h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
long timeFile = System.currentTimeMillis()/1000*1000;
@@ -339,8 +483,14 @@
h264Encoder.setProtocolParams(simPhone, (byte)1);
// 鍒濆鍖栧苟鍚姩锛堜娇鐢ㄩ厤缃腑鐨勫垎杈ㄧ巼锛�
+ // 鏍规嵁cameraId閫夋嫨鎽勫儚澶磋寖鍥�
+ int[] cameraIdRange = DEFAULT_CAMERA_ID_RANGE;
+ if (config != null && config.cameraId != null) {
+ // 濡傛灉鎸囧畾浜哻ameraId锛屼娇鐢ㄥ搴旂殑鎽勫儚澶�
+ cameraIdRange = new int[]{config.cameraId, config.cameraId};
+ }
int[] resolution = {width, height};
- if (h264Encoder.initialize(DEFAULT_CAMERA_ID_RANGE, null, resolution, false)) {
+ if (h264Encoder.initialize(cameraIdRange, null, resolution, false)) {
// 搴旂敤宸蹭繚瀛樼殑姘村嵃淇℃伅锛堝鏋滄湁锛�
if (currentWatermarkInfo != null) {
h264Encoder.setWatermarkInfo(currentWatermarkInfo);
--
Gitblit v1.8.0