Explorar o código

Changes to get OpenCV webcam working

rdb %!s(int64=17) %!d(string=hai) anos
pai
achega
9861d44f82

+ 2 - 2
panda/src/gobj/videoTexture.h

@@ -52,11 +52,11 @@ protected:
   virtual void reconsider_dirty();
   virtual void do_reload_ram_image();
 
-  INLINE void consider_update();
+  virtual INLINE void consider_update();
   INLINE void clear_current_frame();
   virtual void update_frame(int frame)=0;
 
-private:
+protected:
   int _video_width;
   int _video_height;
   int _last_frame_update;

+ 29 - 0
panda/src/grutil/openCVTexture.I

@@ -64,3 +64,32 @@ VideoPage(const OpenCVTexture::VideoPage &copy) :
 INLINE OpenCVTexture::VideoPage::
 ~VideoPage() {
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: OpenCVTexture::consider_update
+//       Access: Protected
+//  Description: Calls update_frame() if the current frame has
+//               changed.
+////////////////////////////////////////////////////////////////////
+INLINE void OpenCVTexture::
+consider_update() {
+  int this_frame = ClockObject::get_global_clock()->get_frame_count();
+  if (this_frame != _last_frame_update) {
+    int frame = get_frame();
+    if (_current_frame != frame) {
+      update_frame(frame);
+      _current_frame = frame;
+    } else {
+      // Loop through the pages to see if there's any camera stream to update.
+      int max_z = max(_z_size, (int)_pages.size());
+      for (int z = 0; z < max_z; ++z) {
+        VideoPage &page = _pages[z];
+        if (!page._color.is_from_file() || !page._alpha.is_from_file()) {
+          update_frame(frame, z);
+        }
+      }
+    }
+    _last_frame_update = this_frame;
+  }
+}
+

+ 67 - 56
panda/src/grutil/openCVTexture.cxx

@@ -224,71 +224,55 @@ make_texture() {
 ////////////////////////////////////////////////////////////////////
 void OpenCVTexture::
 update_frame(int frame) {
-  grutil_cat.spam() << "OpenCVTexture::update_frame called\n";
   int max_z = max(_z_size, (int)_pages.size());
   for (int z = 0; z < max_z; ++z) {
-    VideoPage &page = _pages[z];
-    if (page._color.is_valid() || page._alpha.is_valid()) {
-      modify_ram_image();
-    }
-    if (page._color.is_valid()) {
-      nassertv(get_num_components() >= 3 && get_component_width() == 1);
-
-      const unsigned char *source = page._color.get_frame_data(frame);
-      if (source != NULL) {
-        nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
-        unsigned char *dest = _ram_images[0]._image.p() + get_expected_ram_page_size() * z;
-
-        int dest_row_width = (_x_size * _num_components * _component_width);
-        int source_row_width = get_video_width() * 3;
-
-        if (get_num_components() == 3) {
-          // The easy case--copy the whole thing in, row by row.
-          for (int y = 0; y < get_video_height(); ++y) {
-            memcpy(dest, source, source_row_width);
-            dest += dest_row_width;
-            source += source_row_width;
-          }
+    update_frame(frame, z);
+  }
+}
 
-        } else {
-          // The harder case--interleave the color in with the alpha,
-          // pixel by pixel.
-          nassertv(get_num_components() == 4);
-          for (int y = 0; y < get_video_height(); ++y) {
-            int dx = 0;
-            int sx = 0;
-            for (int x = 0; x < get_video_width(); ++x) {
-              dest[dx] = source[sx];
-              dest[dx + 1] = source[sx + 1];
-              dest[dx + 2] = source[sx + 2];
-              dx += 4;
-              sx += 3;
-            }
-            dest += dest_row_width;
-            source += source_row_width;
-          }
-        }
-      }
-    }
-    if (page._alpha.is_valid()) {
-      nassertv(get_num_components() == 4 && get_component_width() == 1);
+////////////////////////////////////////////////////////////////////
+//     Function: OpenCVTexture::update_frame
+//       Access: Protected, Virtual
+//  Description: This variant of update_frame updates the
+//               indicated page only.
+////////////////////////////////////////////////////////////////////
+void OpenCVTexture::
+update_frame(int frame, int z) {
+  grutil_cat.spam() << "Updating OpenCVTexture page " << z << "\n";
+  VideoPage &page = _pages[z];
+  if (page._color.is_valid() || page._alpha.is_valid()) {
+    modify_ram_image();
+  }
+  if (page._color.is_valid()) {
+    nassertv(get_num_components() >= 3 && get_component_width() == 1);
 
-      const unsigned char *source = page._alpha.get_frame_data(frame);
-      if (source != NULL) {
-        nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
-        unsigned char *dest = _ram_images[0]._image.p() + get_expected_ram_page_size() * z;
+    const unsigned char *source = page._color.get_frame_data(frame);
+    if (source != NULL) {
+      nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
+      unsigned char *dest = _ram_images[0]._image.p() + get_expected_ram_page_size() * z;
 
-        int dest_row_width = (_x_size * _num_components * _component_width);
-        int source_row_width = get_video_width() * 3;
+      int dest_row_width = (_x_size * _num_components * _component_width);
+      int source_row_width = get_video_width() * 3;
 
-        // Interleave the alpha in with the color, pixel by pixel.
-        // Even though the alpha will probably be a grayscale video,
-        // the OpenCV library presents it as RGB.
+      if (get_num_components() == 3) {
+        // The easy case--copy the whole thing in, row by row.
         for (int y = 0; y < get_video_height(); ++y) {
-          int dx = 3;
-          int sx = _alpha_file_channel;
+          memcpy(dest, source, source_row_width);
+          dest += dest_row_width;
+          source += source_row_width;
+        }
+
+      } else {
+        // The harder case--interleave the color in with the alpha,
+        // pixel by pixel.
+        nassertv(get_num_components() == 4);
+        for (int y = 0; y < get_video_height(); ++y) {
+          int dx = 0;
+          int sx = 0;
           for (int x = 0; x < get_video_width(); ++x) {
             dest[dx] = source[sx];
+            dest[dx + 1] = source[sx + 1];
+            dest[dx + 2] = source[sx + 2];
             dx += 4;
             sx += 3;
           }
@@ -298,6 +282,33 @@ update_frame(int frame) {
       }
     }
   }
+  if (page._alpha.is_valid()) {
+    nassertv(get_num_components() == 4 && get_component_width() == 1);
+
+    const unsigned char *source = page._alpha.get_frame_data(frame);
+    if (source != NULL) {
+      nassertv(get_video_width() <= _x_size && get_video_height() <= _y_size);
+      unsigned char *dest = _ram_images[0]._image.p() + get_expected_ram_page_size() * z;
+
+      int dest_row_width = (_x_size * _num_components * _component_width);
+      int source_row_width = get_video_width() * 3;
+
+      // Interleave the alpha in with the color, pixel by pixel.
+      // Even though the alpha will probably be a grayscale video,
+      // the OpenCV library presents it as RGB.
+      for (int y = 0; y < get_video_height(); ++y) {
+        int dx = 3;
+        int sx = _alpha_file_channel;
+        for (int x = 0; x < get_video_width(); ++x) {
+          dest[dx] = source[sx];
+          dx += 4;
+          sx += 3;
+        }
+        dest += dest_row_width;
+        source += source_row_width;
+      }
+    }
+  }
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
panda/src/grutil/openCVTexture.h

@@ -46,10 +46,12 @@ public:
   static PT(Texture) make_texture();
 
 protected:
+  virtual INLINE void consider_update();
   virtual PT(Texture) do_make_copy();
   void do_assign(const OpenCVTexture &copy);
 
   virtual void update_frame(int frame);
+  virtual void update_frame(int frame, int z);
 
   virtual bool do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
                            int z, int n, int primary_file_num_channels, int alpha_file_channel,