From 76fee359897066db51d58bc5d992ad450863b9a2 Mon Sep 17 00:00:00 2001
From: melpon <shigemasa7watanabe+github@gmail.com>
Date: Thu, 11 Apr 2024 13:13:22 +0900
Subject: [PATCH] =?UTF-8?q?NV12=20=E3=81=AE=20fake=20=E3=82=92=E5=88=A9?=
 =?UTF-8?q?=E7=94=A8=E5=8F=AF=E8=83=BD=E3=81=AB=E3=81=99=E3=82=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 examples/sumomo/fake_capturer.cpp | 31 +++++++++++++++++++++----------
 examples/sumomo/fake_capturer.h   | 13 ++++++++++---
 examples/sumomo/option.c          | 10 ++++++----
 examples/sumomo/option.h          |  3 ++-
 examples/sumomo/sumomo.c          |  5 ++++-
 5 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/examples/sumomo/fake_capturer.cpp b/examples/sumomo/fake_capturer.cpp
index 1acefef..fa659f9 100644
--- a/examples/sumomo/fake_capturer.cpp
+++ b/examples/sumomo/fake_capturer.cpp
@@ -13,8 +13,8 @@ namespace sumomo {
 
 class FakeCapturer : public SumomoCapturer {
  public:
-  FakeCapturer(int width, int height, int fps)
-      : width_(width), height_(height), fps_(fps) {
+  FakeCapturer(int width, int height, int fps, SumomoFakeCapturerFormat format)
+      : width_(width), height_(height), fps_(fps), format_(format) {
     this->destroy = [](SumomoCapturer* p) { delete (sumomo::FakeCapturer*)p; };
     this->set_frame_callback = [](SumomoCapturer* p,
                                   sumomo_capturer_on_frame_func on_frame,
@@ -48,12 +48,19 @@ class FakeCapturer : public SumomoCapturer {
       std::uniform_int_distribution<int> dist(0, width_ * height_ - 1);
       sorac::VideoFrame frame;
       frame.timestamp = timestamp;
-      frame.i420_buffer = sorac::VideoFrameBufferI420::Create(width_, height_);
-      frame.i420_buffer->y[dist(*engine_)] = 0xff;
-      frame.i420_buffer->y[dist(*engine_)] = 0xff;
-      frame.i420_buffer->y[dist(*engine_)] = 0xff;
-      frame.i420_buffer->y[dist(*engine_)] = 0xff;
-      frame.i420_buffer->y[dist(*engine_)] = 0xff;
+      if (format_ == SUMOMO_FAKE_CAPTURER_FORMAT_I420) {
+        frame.i420_buffer =
+            sorac::VideoFrameBufferI420::Create(width_, height_);
+        for (int i = 0; i < width_ / 100; i++) {
+          frame.i420_buffer->y[dist(*engine_)] = 0xff;
+        }
+      } else if (format_ == SUMOMO_FAKE_CAPTURER_FORMAT_NV12) {
+        frame.nv12_buffer =
+            sorac::VideoFrameBufferNV12::Create(width_, height_);
+        for (int i = 0; i < width_ / 100; i++) {
+          frame.nv12_buffer->y[dist(*engine_)] = 0xff;
+        }
+      }
       frame.base_width = width_;
       frame.base_height = height_;
       callback_(frame);
@@ -66,6 +73,7 @@ class FakeCapturer : public SumomoCapturer {
   int width_;
   int height_;
   int fps_;
+  SumomoFakeCapturerFormat format_;
   std::function<void(const sorac::VideoFrame& frame)> callback_;
   SteadyFrameThread th_;
   std::unique_ptr<std::mt19937> engine_;
@@ -75,7 +83,10 @@ class FakeCapturer : public SumomoCapturer {
 
 extern "C" {
 
-SumomoCapturer* sumomo_fake_capturer_create(int width, int height, int fps) {
-  return new sumomo::FakeCapturer(width, height, fps);
+SumomoCapturer* sumomo_fake_capturer_create(int width,
+                                            int height,
+                                            int fps,
+                                            SumomoFakeCapturerFormat format) {
+  return new sumomo::FakeCapturer(width, height, fps, format);
 }
 }
diff --git a/examples/sumomo/fake_capturer.h b/examples/sumomo/fake_capturer.h
index 8dc4f5c..e95dcce 100644
--- a/examples/sumomo/fake_capturer.h
+++ b/examples/sumomo/fake_capturer.h
@@ -9,9 +9,16 @@
 extern "C" {
 #endif
 
-extern SumomoCapturer* sumomo_fake_capturer_create(int width,
-                                                   int height,
-                                                   int fps);
+typedef enum {
+  SUMOMO_FAKE_CAPTURER_FORMAT_I420 = 0,
+  SUMOMO_FAKE_CAPTURER_FORMAT_NV12 = 1,
+} SumomoFakeCapturerFormat;
+
+extern SumomoCapturer* sumomo_fake_capturer_create(
+    int width,
+    int height,
+    int fps,
+    SumomoFakeCapturerFormat format);
 
 #ifdef __cplusplus
 }
diff --git a/examples/sumomo/option.c b/examples/sumomo/option.c
index 75a6487..fe17320 100644
--- a/examples/sumomo/option.c
+++ b/examples/sumomo/option.c
@@ -44,7 +44,7 @@ int sumomo_option_parse(SumomoOption* option,
   }
   *error = 0;
   memset(option, 0, sizeof(SumomoOption));
-  option->capture_type = SUMOMO_OPTION_CAPTURE_TYPE_FAKE;
+  option->capture_type = SUMOMO_OPTION_CAPTURE_TYPE_FAKE_I420;
 #if defined(__linux__)
   option->capture_device_name = "/dev/video0";
 #elif defined(__APPLE__)
@@ -120,8 +120,10 @@ int sumomo_option_parse(SumomoOption* option,
         } else if (OPT_IS("audio")) {
           SET_OPTBOOL(option->audio);
         } else if (OPT_IS("capture-type")) {
-          if (strcmp(optarg, "fake") == 0) {
-            option->capture_type = SUMOMO_OPTION_CAPTURE_TYPE_FAKE;
+          if (strcmp(optarg, "fake-i420") == 0) {
+            option->capture_type = SUMOMO_OPTION_CAPTURE_TYPE_FAKE_I420;
+          } else if (strcmp(optarg, "fake-nv12") == 0) {
+            option->capture_type = SUMOMO_OPTION_CAPTURE_TYPE_FAKE_NV12;
           } else if (strcmp(optarg, "v4l2") == 0) {
             option->capture_type = SUMOMO_OPTION_CAPTURE_TYPE_V4L2;
           } else if (strcmp(optarg, "mac") == 0) {
@@ -200,7 +202,7 @@ int sumomo_option_parse(SumomoOption* option,
       fprintf(stdout, "  --metadata=JSON\n");
       fprintf(stdout, "  --video=true,false,none\n");
       fprintf(stdout, "  --audio=true,false,none\n");
-      fprintf(stdout, "  --capture-type=fake,v4l2,mac\n");
+      fprintf(stdout, "  --capture-type=fake-i420,fake-nv12,v4l2,mac\n");
       fprintf(stdout, "  --capture-device-name=NAME\n");
       fprintf(stdout, "  --capture-device-width=WIDTH\n");
       fprintf(stdout, "  --capture-device-height=HEIGHT\n");
diff --git a/examples/sumomo/option.h b/examples/sumomo/option.h
index 666fb78..ab628fc 100644
--- a/examples/sumomo/option.h
+++ b/examples/sumomo/option.h
@@ -10,7 +10,8 @@ typedef enum SumomoOptionalBool {
 } SumomoOptionalBool;
 
 typedef enum SumomoOptionCaptureType {
-  SUMOMO_OPTION_CAPTURE_TYPE_FAKE,
+  SUMOMO_OPTION_CAPTURE_TYPE_FAKE_I420,
+  SUMOMO_OPTION_CAPTURE_TYPE_FAKE_NV12,
   SUMOMO_OPTION_CAPTURE_TYPE_V4L2,
   SUMOMO_OPTION_CAPTURE_TYPE_MAC,
 } SumomoOptionCaptureType;
diff --git a/examples/sumomo/sumomo.c b/examples/sumomo/sumomo.c
index 418d911..f4921a3 100644
--- a/examples/sumomo/sumomo.c
+++ b/examples/sumomo/sumomo.c
@@ -100,7 +100,10 @@ void on_track(SoracTrack* track, void* userdata) {
     } else {
       state->capturer = sumomo_fake_capturer_create(
           state->opt->capture_device_width, state->opt->capture_device_height,
-          state->opt->capture_device_fps);
+          state->opt->capture_device_fps,
+          state->opt->capture_type == SUMOMO_OPTION_CAPTURE_TYPE_FAKE_I420
+              ? SUMOMO_FAKE_CAPTURER_FORMAT_I420
+              : SUMOMO_FAKE_CAPTURER_FORMAT_NV12);
     }
     sumomo_capturer_set_frame_callback(state->capturer, on_capture_frame,
                                        state);