Support YUYV and JPEG formats for Camera 95/320095/12
authorSuhaspoornachandra <s.poornachan@samsung.com>
Thu, 7 Nov 2024 12:22:53 +0000 (17:52 +0530)
committerInsoon Kim <is46.kim@samsung.com>
Tue, 19 Nov 2024 01:26:46 +0000 (01:26 +0000)
This patch adds support for the MJPEG and YUYV formats for
Camera.

It also adds error correction case for OnCameraCaptured libyuv convert
calls and reduces code duplication.

Change-Id: I54924f031a1f17a61b224edc42dcae838937ac22
Signed-off-by: Suhaspoornachandra <s.poornachan@samsung.com>
tizen_src/build/config/BUILD.gn
tizen_src/chromium_impl/media/capture/video/tizen/video_capture_device_tizen.cc

index e86d5276d4d7b4643353dbe3fb21f4db7fbc5dbd..4cca6f3d600f8639f00125d3ed07609be13878ed 100644 (file)
@@ -59,13 +59,14 @@ config("tizen_feature_flags") {
       }
     }
 
+    if (tizen_version >= 60) {
+      defines += [ "TIZEN_MULTIMEDIA_MJPEG_SUPPORT" ]
+    }
+
     if (tizen_product_tv) {
       defines += [ "OS_TIZEN_TV_PRODUCT" ]
       if (tizen_version >= 60) {
-        defines += [
-          "TIZEN_MULTIMEDIA_MJPEG_SUPPORT",
-          "TIZEN_MULTIMEDIA_DRMMANAGER_SUPPORT",
-        ]
+        defines += [ "TIZEN_MULTIMEDIA_DRMMANAGER_SUPPORT" ]
         if (tizen_tv_riscv64) {
           defines += [ "TIZEN_TV_RISCV64" ]
         }
index f6d5708d6a70cc68b1bd25b738ca88ab3e707ad3..5aa93916fe5e487f4fcdef8a655fb2c8560cc8ac 100644 (file)
@@ -363,8 +363,9 @@ void VideoCaptureDeviceTizen::PreviewCameraCaptured(ScopedMediaPacket pkt) {
 
   media_format_get_video_info(format.get(), &mime, &width, &height, &avg_bps,
                               &max_bps);
-  CHECK((mime == MEDIA_FORMAT_I420) || (mime == MEDIA_FORMAT_NV12) ||
-        (mime == MEDIA_FORMAT_H264_SP));
+  DCHECK((mime == MEDIA_FORMAT_I420) || (mime == MEDIA_FORMAT_NV12) ||
+         (mime == MEDIA_FORMAT_YUYV) || (mime == MEDIA_FORMAT_MJPEG) ||
+         (mime == MEDIA_FORMAT_H264_SP));
 
   orientation =
       display::Screen::GetScreen()->GetPrimaryDisplay().RotationAsDegree();
@@ -410,58 +411,86 @@ void VideoCaptureDeviceTizen::PreviewCameraCaptured(ScopedMediaPacket pkt) {
   int src_stride_y = width;
   int src_stride_uv = (src_stride_y + 1) / 2;
 
-  if (mime == MEDIA_FORMAT_NV12) {
-    src_stride_uv = src_stride_y;
+  std::string error_message;
+  void* data_y;
 
-    void *data_y, *data_uv;
-    media_packet_get_video_plane_data_ptr(pkt.get(), 0, &data_y);
-    media_packet_get_video_plane_data_ptr(pkt.get(), 1, &data_uv);
-
-    libyuv::NV12ToI420Rotate(reinterpret_cast<uint8_t*>(data_y), src_stride_y,
-                             reinterpret_cast<uint8_t*>(data_uv), src_stride_uv,
+  switch (mime) {
+    case MEDIA_FORMAT_NV12:
+      src_stride_uv = src_stride_y;
+      void* data_uv;
+      media_packet_get_video_plane_data_ptr(pkt.get(), 0, &data_y);
+      media_packet_get_video_plane_data_ptr(pkt.get(), 1, &data_uv);
+
+      if (libyuv::NV12ToI420Rotate(
+              reinterpret_cast<uint8_t*>(data_y), src_stride_y,
+              reinterpret_cast<uint8_t*>(data_uv), src_stride_uv, y_plane,
+              dest_stride_y, u_plane, dest_stride_uv, v_plane, dest_stride_uv,
+              width, height, mode)) {
+        error_message = "Failed to Convert NV12 to I420";
+      }
+      break;
+    case MEDIA_FORMAT_I420:
+      void *data_u, *data_v;
+      media_packet_get_video_plane_data_ptr(pkt.get(), 0, &data_y);
+      media_packet_get_video_plane_data_ptr(pkt.get(), 1, &data_u);
+      media_packet_get_video_plane_data_ptr(pkt.get(), 2, &data_v);
+
+      if (libyuv::I420Rotate(reinterpret_cast<uint8_t*>(data_y), src_stride_y,
+                             reinterpret_cast<uint8_t*>(data_u), src_stride_uv,
+                             reinterpret_cast<uint8_t*>(data_v), src_stride_uv,
+                             y_plane, dest_stride_y, u_plane, dest_stride_uv,
+                             v_plane, dest_stride_uv, width, height, mode)) {
+        error_message = "Failed to Rotate I420 buffer";
+      }
+      break;
+    case MEDIA_FORMAT_YUYV:
+      void* data_yuv;
+      media_packet_get_video_plane_data_ptr(pkt.get(), 0, &data_yuv);
+      if (libyuv::YUY2ToI420(reinterpret_cast<uint8_t*>(data_yuv), src_stride_y,
                              y_plane, dest_stride_y, u_plane, dest_stride_uv,
-                             v_plane, dest_stride_uv, width, height, mode);
-    base::TimeTicks now = base::TimeTicks::Now();
-    if (first_ref_time_.is_null())
-      first_ref_time_ = now;
-
-    client_->OnIncomingCapturedBuffer(std::move(buffer_), videocaptureformat,
-                                      now, now - first_ref_time_);
-  } else if (mime == MEDIA_FORMAT_H264_SP) {
-    base::TimeTicks now = base::TimeTicks::Now();
-    if (first_ref_time_.is_null())
-      first_ref_time_ = now;
-
-    client_->OnIncomingCapturedBuffer(std::move(buffer_), videocaptureformat,
-                                      now, now - first_ref_time_);
-  } else if (mime == MEDIA_FORMAT_I420) {
-    // FIXME: Verify if I420 format is working.
-    void *data_y, *data_u, *data_v;
-    media_packet_get_video_plane_data_ptr(pkt.get(), 0, &data_y);
-    media_packet_get_video_plane_data_ptr(pkt.get(), 1, &data_u);
-    media_packet_get_video_plane_data_ptr(pkt.get(), 2, &data_v);
-
-    if (libyuv::I420Rotate(reinterpret_cast<uint8_t*>(data_y), src_stride_y,
-                           reinterpret_cast<uint8_t*>(data_u), src_stride_uv,
-                           reinterpret_cast<uint8_t*>(data_v), src_stride_uv,
-                           y_plane, dest_stride_y, u_plane, dest_stride_uv,
-                           v_plane, dest_stride_uv, width, height, mode)) {
-      LOG(ERROR) << "Failed to I420Rotate buffer";
+                             v_plane, dest_stride_uv, width, height)) {
+        error_message = "Failed to Convert YUYV to I420";
+      }
+      break;
+#if defined(TIZEN_MULTIMEDIA_MJPEG_SUPPORT)
+    case MEDIA_FORMAT_MJPEG:
+      void* data;
+      media_packet_get_buffer_data_ptr(pkt.get(), &data);
+      uint64_t buffer_size;
+      media_packet_get_buffer_size(pkt.get(), &buffer_size);
+      if (libyuv::ConvertToI420(reinterpret_cast<uint8_t*>(data), buffer_size,
+                                y_plane, dest_stride_y, u_plane, dest_stride_uv,
+                                v_plane, dest_stride_uv, 0, 0, dest_width,
+                                dest_height, dest_width, dest_height,
+                                libyuv::kRotate0, libyuv::FOURCC_MJPG)) {
+        error_message = "Failed to Convert MJPEG to I420";
+      }
+      break;
+#endif
+    case MEDIA_FORMAT_H264_SP:
+      // If mime is MEDIA_FORMAT_H264_SP simply forward the buffer to
+      // VideoCaptureDeviceClient.
+      break;
+    default:
+      LOG(ERROR) << "frame->format( " << mime
+                 << ") is not implemented or not supported by chromium.";
       ChangeCapturingState(false);
       return;
-    }
+  }
 
-    base::TimeTicks now = base::TimeTicks::Now();
-    if (first_ref_time_.is_null())
-      first_ref_time_ = now;
+  if (!error_message.empty()) {
+    LOG(ERROR) << error_message;
+    ChangeCapturingState(false);
+    return;
+  }
 
-    client_->OnIncomingCapturedBuffer(std::move(buffer_), videocaptureformat,
-                                      now, now - first_ref_time_);
-  } else {
-    LOG(ERROR) << "frame->format( " << mime
-               << ") is not implemented or not supported by chromium.";
+  base::TimeTicks now = base::TimeTicks::Now();
+  if (first_ref_time_.is_null()) {
+    first_ref_time_ = now;
   }
 
+  client_->OnIncomingCapturedBuffer(std::move(buffer_), videocaptureformat, now,
+                                    now - first_ref_time_);
   ChangeCapturingState(false);
 }
 
@@ -471,10 +500,6 @@ constexpr bool IsFormatEncoded(camera_pixel_format_e format) {
   is_format_encoded |= format == CAMERA_PIXEL_FORMAT_VP8;
   is_format_encoded |= format == CAMERA_PIXEL_FORMAT_VP9;
 #endif
-#if defined(TIZEN_MULTIMEDIA_MJPEG_SUPPORT)
-  is_format_encoded |= format == CAMERA_PIXEL_FORMAT_MJPEG;
-#endif
-
   return is_format_encoded;
 }
 
@@ -593,13 +618,18 @@ void VideoCaptureDeviceTizen::OnCameraCaptured(camera_preview_data_s* frame,
     } break;
 
     case CAMERA_PIXEL_FORMAT_H264:
-#if defined(TIZEN_MULTIMEDIA_MJPEG_SUPPORT)
-    case CAMERA_PIXEL_FORMAT_MJPEG:
-#endif
       memcpy(y_plane, frame->data.encoded_plane.data,
              frame->data.encoded_plane.size);
       break;
-
+#if defined(TIZEN_MULTIMEDIA_MJPEG_SUPPORT)
+    case CAMERA_PIXEL_FORMAT_MJPEG:
+      libyuv::ConvertToI420(
+          frame->data.encoded_plane.data, frame->data.encoded_plane.size,
+          y_plane, dest_stride_y, u_plane, dest_stride_uv, v_plane,
+          dest_stride_uv, 0, 0, dest_width, dest_height, dest_width,
+          dest_height, libyuv::kRotate0, libyuv::FOURCC_MJPG);
+      break;
+#endif
     default:
       LOG(INFO) << "Unsupported Format "
                 << CameraPixelFormatToString(frame->format);