From d9927380ed7c8366f762049be9f3fee225860833 Mon Sep 17 00:00:00 2001
From: liyujie <2352380935@qq.com>
Date: Thu, 28 Aug 2025 12:04:16 +0000
Subject: [PATCH] [2/4]解决USB摄像头打开相机预览界面绿屏

---
 android/hardware/aw/camera/3_4/v4l2_stream.cpp |  277 ++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 232 insertions(+), 45 deletions(-)

diff --git a/android/hardware/aw/camera/3_4/v4l2_stream.cpp b/android/hardware/aw/camera/3_4/v4l2_stream.cpp
index f662f37..affd6f1 100755
--- a/android/hardware/aw/camera/3_4/v4l2_stream.cpp
+++ b/android/hardware/aw/camera/3_4/v4l2_stream.cpp
@@ -55,6 +55,7 @@
 static int eb_yuv_count  = 0;
 static int eb_jpeg_count = 0;
 static int dq_yuv_count  = 0;
+static int cb_yuv_count  = 0;
 const  int output_counts = 10;
 #endif
 
@@ -64,12 +65,16 @@
 V4L2Stream* V4L2Stream::NewV4L2Stream(
     const int id,
     const std::string device_path,
-    std::shared_ptr<CCameraConfig> pCameraCfg) {
-  return new V4L2Stream(id, device_path, pCameraCfg);
+    std::shared_ptr<CCameraConfig> pCameraCfg,
+    int merge_status
+    ) {
+  return new V4L2Stream(id, device_path, pCameraCfg, merge_status);
 }
 
 V4L2Stream::V4L2Stream(const int id, const std::string device_path,
-                       std::shared_ptr<CCameraConfig> pCameraCfg)
+                       std::shared_ptr<CCameraConfig> pCameraCfg,
+                       int merge_status
+                       )
     : mCameraConfig(pCameraCfg),
       device_path_(std::move(device_path)),
       device_fd_(-1),
@@ -87,7 +92,14 @@
   HAL_LOG_ENTER();
   int pipefd[2];
   int ret = -1;
-  if (device_path_.compare(MAIN_STREAM_PATH) == 0) {
+  if (merge_status) {
+    if (device_path_.compare(MAIN_MERGE_STREAM_PATH) == 0) {
+      device_ss_ = MAIN_STREAM;
+    } else if (device_path_.compare(SUB_0_MERGE_STREAM_PATH) == 0) {
+      device_ss_ = SUB_0_STREAM;
+    }
+  } else {
+    if (device_path_.compare(MAIN_STREAM_PATH) == 0) {
       device_ss_ = MAIN_STREAM;
   } else if (device_path_.compare(SUB_0_STREAM_PATH) == 0) {
       device_ss_ = SUB_0_STREAM;
@@ -95,9 +107,15 @@
       device_ss_ = MAIN_STREAM;
   } else if (device_path_.compare(SUB_0_FRONT_STREAM_PATH) == 0) {
       device_ss_ = SUB_0_STREAM;
+    }
   }
 
   memset(&jpeg_crop_rect, 0, sizeof(cam_crop_rect_t));
+  reduce_call_num = 0;
+  reducecallnum_dst_width = 0;
+  reducecallnum_dst_height = 0;
+  reducecallnum_src_width = 0;
+  reducecallnum_src_height = 0;
   ret = pipe(pipefd);
   if (ret == -1) {
       ALOGE("V4L2Stream create pipe failed");
@@ -116,7 +134,7 @@
   close(write_fd_);
 }
 
-int V4L2Stream::Connect() {
+int V4L2Stream::Connect(int merge_status) {
   HAL_LOG_ENTER();
   std::lock_guard<std::mutex> lock(connection_lock_);
 
@@ -146,6 +164,25 @@
 
   device_fd_ = fd;
   ++connection_count_;
+
+  struct dma_merge picture_merge;
+  HAL_LOGE("bill merge_status = %d", merge_status);
+  if(device_id_ == 0 && merge_status) {
+      picture_merge.en = 1;
+  } else if(device_id_ == 0 && !merge_status) {
+      picture_merge.en = 2;
+  } else {
+      picture_merge.en = 0;
+  }
+
+  HAL_LOGD("device_id_:%d picture_merge.en:%d", device_id_, picture_merge.en);
+
+  if (TEMP_FAILURE_RETRY(
+        ioctl(fd, VIDIOC_SET_DMA_MERGE, &picture_merge)) != 0) {
+     HAL_LOGE("VIDIOC_SET_DMA_MERGE on %d error: %s.",
+         picture_merge.en,
+         strerror(errno));
+  }
 
   HAL_LOGV("Detect camera stream %s, stream serial:%d.",
       device_path_.c_str(), device_ss_);
@@ -268,12 +305,55 @@
   if (getSingleCameraId() < 0) {
     mIspId = mAWIspApi->awIspGetIspId(mDevice_id);
   }
-  if (mIspId >= 0) {
-    mAWIspApi->awIspStart(mIspId);
-    HAL_LOGD("ISP turned on.");
+  //if (mIspId >= 0) {
+  //  mAWIspApi->awIspStart(mIspId);
+  //  HAL_LOGD("ISP turned on.");
+  //} else {
+  //  HAL_LOGE("ISP turned on failed!");
+  //}
+
+  if(device_id_ == 0 &&
+      device_path_.compare(MAIN_MERGE_STREAM_PATH) == 0) {
+      mDevice_id = 0;
+      mIspId = mAWIspApi->awIspGetIspId(mDevice_id);
+      if (mIspId >= 0) {
+          mAWIspApi->awIspStart(mIspId);
+          HAL_LOGD("ISP turned on. mDevice_id = %d", mDevice_id);
+      } else {
+          HAL_LOGE("ISP turned on failed!");
+      }
+
+  } else if(device_id_ == 0 &&
+      device_path_.compare(SUB_0_MERGE_STREAM_PATH) == 0) {
+      mDevice_id = 1;
+      mIspId = mAWIspApi->awIspGetIspId(mDevice_id);
+      if (mIspId >= 0) {
+          mAWIspApi->awIspStart(mIspId);
+          HAL_LOGD("ISP turned on. mDevice_id = %d", mDevice_id);
+      } else {
+          HAL_LOGE("ISP turned on failed!");
+      }
+
+  } else if(device_id_ == 1 && format_->GetMergeStreamFlag()) {
+      mDevice_id = 0;
+      mIspId = mAWIspApi->awIspGetIspId(mDevice_id);
+      if (mIspId >= 0) {
+          mAWIspApi->awIspStart(mIspId);
+          HAL_LOGD("ISP turned on. mDevice_id = %d", mDevice_id);
+      } else {
+          HAL_LOGE("ISP turned on failed!");
+      }
+
   } else {
-    HAL_LOGE("ISP turned on failed!");
-  }
+      mIspId = mAWIspApi->awIspGetIspId(mDevice_id);
+      if (mIspId >= 0) {
+          mAWIspApi->awIspStart(mIspId);
+          HAL_LOGD("ISP turned on. mDevice_id = %d", mDevice_id);
+      } else {
+          HAL_LOGE("ISP turned on failed!");
+      }
+   }
+
 #endif
 
   return 0;
@@ -614,13 +694,17 @@
   s.r.width = cam_crop_rect.width;
   s.r.height = cam_crop_rect.height;
 
-  ret = IoctlLocked(VIDIOC_S_SELECTION, &s);
-  HAL_LOGV("ret:%d device_fd_:%d left:%d top:%d width:%d height:%d",
-      ret, device_fd_, s.r.left, s.r.top, s.r.width, s.r.height);
-  if (ret < 0) {
-    HAL_LOGE("failed, %s", strerror(errno));
-  } else {
-    HAL_LOGV("ok, %s", strerror(errno));
+  if (mCameraConfig->supportReducecallnumSize()) {
+      HAL_LOGV("####SetCropRect supportReducecallnumSize!~");
+  }else {
+      ret = IoctlLocked(VIDIOC_S_SELECTION, &s);
+      HAL_LOGV("ret:%d device_fd_:%d left:%d top:%d width:%d height:%d",
+          ret, device_fd_, s.r.left, s.r.top, s.r.width, s.r.height);
+      if (ret < 0) {
+          HAL_LOGE("failed, %s", strerror(errno));
+      } else {
+          HAL_LOGV("ok, %s", strerror(errno));
+      }
   }
   return ret;
 }
@@ -669,17 +753,39 @@
   return 0;
 }
 
-int V4L2Stream::SetParm(int mCapturemode) {
+int V4L2Stream::SetParm(int mCapturemode, uint32_t width, uint32_t height) {
   HAL_LOG_ENTER();
 
   struct v4l2_streamparm params;
   memset(&params, 0, sizeof(params));
 
   params.parm.capture.timeperframe.numerator = 1;
-  params.parm.capture.timeperframe.denominator = 30;
+  
+
   params.parm.capture.reserved[0] = 0;
   params.type = V4L2_CAPTURE_TYPE;
   params.parm.capture.capturemode = mCapturemode;
+
+  if (width * height > 2112*1568) {
+    HAL_LOGV("SetParm %dx%d",width,height);
+    params.parm.capture.timeperframe.denominator = 25;
+  } else {
+    params.parm.capture.timeperframe.denominator = 30;
+  }
+  if (width * height > 4000*3000) {
+    params.parm.capture.timeperframe.denominator = 24;
+    params.parm.capture.reserved[2] = 3;
+  } else {
+    if (device_id_ == 0 &&
+        device_path_.compare(SUB_0_MERGE_STREAM_PATH) == 0) {
+      params.parm.capture.timeperframe.denominator = 24;
+      params.parm.capture.reserved[2] = 3;
+    } else {
+      params.parm.capture.reserved[2] = 0;
+    }
+  }
+  HAL_LOGI("params.parm.capture.timeperframe.denominator:%d reserved:%d",
+      params.parm.capture.timeperframe.denominator, params.parm.capture.reserved[2]);
 
   if (IoctlLocked(VIDIOC_S_PARM, &params) < 0) {
     HAL_LOGE("S_PARM fails: %s", strerror(errno));
@@ -800,7 +906,8 @@
 }
 
 int V4L2Stream::SetFormat(const StreamFormat& desired_format,
-    uint32_t* result_max_buffers) {
+                          uint32_t* result_max_buffers,
+                          bool merge_stream_flag) {
   HAL_LOG_ENTER();
 
   if (format_ && desired_format == *format_) {
@@ -856,7 +963,31 @@
       new_format.fmt.pix_mp.width = interpolation_src_width;
       new_format.fmt.pix_mp.height = interpolation_src_height;
       setFormatFlag = 1;
-    }
+      }
+
+  }
+
+  if(mCameraConfig->supportReducecallnumSize())
+  {
+      char * value;
+      value = mCameraConfig->supportReducecallnumSizeValue();
+      parse_pair(value, &reducecallnum_src_width, &reducecallnum_src_height, 'x');
+
+      char *reduce_call_num_char;
+      reduce_call_num_char = mCameraConfig->ReduceCallNumValue();
+      reduce_call_num = atoi(reduce_call_num_char);
+
+      new_format.fmt.pix_mp.width = reducecallnum_src_width;
+      new_format.fmt.pix_mp.height = reducecallnum_src_height;
+
+      struct buf_merge buf_merge;
+      buf_merge.en = 1;
+      buf_merge.buffer_num = reduce_call_num;
+
+      if (IoctlLocked(VIDIOC_SET_BUFFER_MERGE, &buf_merge) < 0) {
+          HAL_LOGE("VIDIOC_SET_BUFFER_MERGE failed: %s", strerror(errno));
+          return -ENODEV;
+      }
   }
 
   // TODO(b/29334616): When async, this will need to check if the stream
@@ -871,8 +1002,18 @@
     return -ENODEV;
   }
 
+  if(mCameraConfig->supportReducecallnumSize())
+  {
+      char * value1;
+      value1 = mCameraConfig->defaultReducecallnumSizeValue();
+      parse_pair(value1, &reducecallnum_dst_width, &reducecallnum_dst_height, 'x');
+
+      new_format.fmt.pix_mp.width = reducecallnum_dst_width;
+      new_format.fmt.pix_mp.height = reducecallnum_dst_height;
+  }
+
   // Check that the driver actually set to the requested values.
-  if (desired_format != StreamFormat(new_format)) {
+  if (desired_format != StreamFormat(new_format, merge_stream_flag)) {
     HAL_LOGE("Device doesn't support desired stream configuration.");
   }
 
@@ -881,7 +1022,7 @@
     new_format.fmt.pix_mp.height = cur_height;
   }
   // Keep track of our new format.
-  format_.reset(new StreamFormat(new_format));
+  format_.reset(new StreamFormat(new_format, merge_stream_flag));
 
   // Format changed, request new buffers.
   int res = RequestBuffers(*result_max_buffers);
@@ -1169,7 +1310,10 @@
 #if DBG_SAVE_OUTPUT
   char yuv_path[100];
   dq_yuv_count = dq_yuv_count % output_counts;
-  sprintf(yuv_path, "/data/camera/dq_yuv_%d.bin", dq_yuv_count++);
+  sprintf(yuv_path, "/data/camera/dq_yuv_%dx%d_%d.bin",
+      format_->width(),
+      format_->height(),
+      dq_yuv_count++);
   int copy_size = ALIGN_16B(format_->width())*ALIGN_16B(format_->height())*3/2;
   saveBuffers(yuv_path, *src_addr_, copy_size, true);
 #endif
@@ -1264,9 +1408,43 @@
     }
   }
 
-  memcpy(dst_addr_ycbcr->y, src_addr, width*height);
-  memcpy(dst_addr_ycbcr->cr,
-      reinterpret_cast<char*>(src_addr) + width*height, width*height/2);
+  if(mCameraConfig->supportReducecallnumSize())
+  {
+      int i,cur_width,cur_height;
+      cur_width = reducecallnum_src_width;
+      cur_height = reducecallnum_src_height;
+
+      for(i = 0 ;i < reduce_call_num; i++)
+      {
+          memcpy((char *)dst_addr_ycbcr->y + i*(cur_width * cur_height),
+              (char *)src_addr + i*(cur_width * cur_height * 3 / 2),
+              cur_width*cur_height);
+          /*memcpy((char *)dst_addr_ycbcr->cr + i*(cur_width * cur_height / 2),
+              (char *)src_addr + (i + 1)*(cur_width * cur_height) + i * (cur_width*cur_height / 2),
+              cur_width*cur_height / 2);*/
+      }
+      memcpy(dst_addr_ycbcr->cr, (char*)src_addr + width*height, width*height/2);
+  }
+  else {
+      memcpy(dst_addr_ycbcr->y, src_addr, width*height);
+      memcpy(dst_addr_ycbcr->cr, (char*)src_addr + width*height, width*height/2);
+  }
+
+#if DBG_SAVE_OUTPUT
+  char yuv_path[100];
+  sprintf(yuv_path, "/data/camera/yuv_preview_%dx%d_%d.bin",
+      width, height,
+      (cb_yuv_count++) % 10);
+  int y_size = width * height;
+  int cr_size = width * height/2;
+  saveBuffers(yuv_path,
+      dst_addr_ycbcr->y,
+      dst_addr_ycbcr->cr,
+      y_size,
+      cr_size,
+      true);
+#endif
+
   return 0;
 }
 
@@ -1372,7 +1550,11 @@
   if (mCameraConfig->supportInterpolationSize()) {
     jpeg_enc.quality  = 100;
     sjpegInfo.quality = 100;
-  } else {
+  } else if (format_->width() * format_->height() > 3264 * 2448) {
+    jpeg_enc.quality  = 100;
+    sjpegInfo.quality = 100;
+  } 
+  else {
     sjpegInfo.quality = jpeg_enc.quality;
   }
 
@@ -1509,44 +1691,49 @@
     return false;
   }
 
+  int isp_3a_param_size = 0;
+  int isp_debug_msg_size = 0;
+
   camera3_jpeg_3a_blob_t jpeg_3a_header;
   jpeg_3a_header.jpeg_3a_header_id = CAMERA3_JPEG_3A_PARAM_BLOB_ID;
-  jpeg_3a_header.jpeg_3a_size = sizeof(camera3_jpeg_3a_blob_t) +
-    ISP_3A_PARAM_SIZE;
-  ALOGV("3a jpeg_3a_size = %d sizeof struct = %zu",
-      jpeg_3a_header.jpeg_3a_size, sizeof(camera3_jpeg_3a_blob_t));
   strncpy(jpeg_3a_header.magic_str, ISP_DEBUG_MAGIC_STR, 8);
 
   camera3_jpeg_isp_msg_blob_t jpeg_isp_msg_header;
   jpeg_isp_msg_header.jpeg_isp_msg_header_id = CAMERA3_JPEG_ISP_MSG_BLOB_ID;
-  jpeg_isp_msg_header.jpeg_isp_msg_size =
-    sizeof(camera3_jpeg_isp_msg_blob_t) + ISP_DEBUG_MSG_SIZE;
-  ALOGV("isp jpeg_isp_size = %d sizeof struct = %zu",
-      jpeg_isp_msg_header.jpeg_isp_msg_size,
-      sizeof(camera3_jpeg_isp_msg_blob_t));
   strncpy(jpeg_isp_msg_header.magic_str, ISP_DEBUG_MAGIC_STR, 8);
 
   camera3_jpeg_blob_t jpegHeader;
   jpegHeader.jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
-  jpegHeader.jpeg_size =
-    bufSize + jpeg_3a_header.jpeg_3a_size +
-    jpeg_isp_msg_header.jpeg_isp_msg_size;
 
   unsigned long jpeg_eof_offset =
     (unsigned long)(mJpegBufferSizes - (unsigned long)sizeof(jpegHeader));
   char *jpeg_eof = reinterpret_cast<char *>(jpeg_buf) + jpeg_eof_offset;
-  memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader));
 
   char *jpeg_isp_3a_params = reinterpret_cast<char *>(jpeg_buf + bufSize);
+  isp_3a_param_size =
+      mAWIspApi->awIspGet3AParameters(reinterpret_cast<void*>(
+          jpeg_isp_3a_params + sizeof(jpeg_3a_header)));
+  jpeg_3a_header.jpeg_3a_size = sizeof(camera3_jpeg_3a_blob_t) +
+      isp_3a_param_size;
   memcpy(jpeg_isp_3a_params, &jpeg_3a_header, sizeof(jpeg_3a_header));
-  mAWIspApi->awIspGet3AParameters(reinterpret_cast<void*>(
-        jpeg_isp_3a_params + sizeof(jpeg_3a_header)));
 
   char *jpeg_isp_debug_msg = reinterpret_cast<char *>(jpeg_buf + bufSize +
       jpeg_3a_header.jpeg_3a_size);
+  isp_debug_msg_size =
+      mAWIspApi->awIspGetDebugMessage(reinterpret_cast<void*>(
+          jpeg_isp_debug_msg + sizeof(jpeg_isp_msg_header)));
+  jpeg_isp_msg_header.jpeg_isp_msg_size =
+      sizeof(camera3_jpeg_isp_msg_blob_t) + isp_debug_msg_size;
   memcpy(jpeg_isp_debug_msg, &jpeg_isp_msg_header, sizeof(jpeg_isp_msg_header));
-  mAWIspApi->awIspGetDebugMessage(reinterpret_cast<void*>(
-        jpeg_isp_debug_msg + sizeof(jpeg_isp_msg_header)));
+
+  jpegHeader.jpeg_size =
+      bufSize + jpeg_3a_header.jpeg_3a_size +
+      jpeg_isp_msg_header.jpeg_isp_msg_size;
+  memcpy(jpeg_eof, &jpegHeader, sizeof(jpegHeader));
+
+  HAL_LOGV("####jpeg_size:%d jpeg_3a_size:%d jpeg_isp_msg_size:%d",
+      jpegHeader.jpeg_size,jpeg_3a_header.jpeg_3a_size,
+      jpeg_isp_msg_header.jpeg_isp_msg_size);
 
   return 0;
 }

--
Gitblit v1.6.2