26 #if defined(OPENCV_VER_3)    28 #include <opencv2/core.hpp>    29 #include <opencv2/videoio/videoio_c.h>    32 #elif defined(OPENCV_VER_23)    34 #include <opencv2/core/core.hpp>    35 #include <opencv2/highgui/highgui.hpp>    44 #endif  // OPENCV_VER_3    52 OpenCVTexture(
const std::string &name) :
    70   if (this_frame != _last_frame_update) {
    71     int frame = get_frame();
    72     if (_current_frame != frame) {
    74       do_update_frame(cdata, frame);
    75       _current_frame = frame;
    79       int max_z = std::max(cdata->_z_size, (
int)_pages.size());
    80       for (
int z = 0; z < max_z; ++z) {
    81         VideoPage &page = _pages[z];
    82         if (!page._color.is_from_file() || !page._alpha.is_from_file()) {
    83           do_update_frame(cdata, frame, z);
    87     _last_frame_update = this_frame;
   101 make_copy_impl()
 const {
   103   PT(OpenCVTexture) copy = 
new OpenCVTexture(get_name());
   105   copy->do_assign(cdata_copy_tex, 
this, cdata_tex);
   114 do_assign(Texture::CData *cdata_tex, 
const OpenCVTexture *copy,
   115           const Texture::CData *cdata_copy_tex) {
   116   VideoTexture::do_assign(cdata_tex, copy, cdata_copy_tex);
   117   _pages = copy->_pages;
   130 from_camera(
int camera_index, 
int z, 
int alpha_file_channel,
   133   if (!do_reconsider_z_size(cdata, z, options)) {
   136   nassertr(z >= 0 && z < cdata->_z_size, 
false);
   138   cdata->_alpha_file_channel = alpha_file_channel;
   140   VideoPage &page = do_modify_page(cdata, z);
   141   if (alpha_file_channel == 0) {
   144     if (!page._color.from_camera(camera_index)) {
   148     if (!do_reconsider_video_properties(cdata, page._color, 3, z, options)) {
   155     if (!page._alpha.from_camera(camera_index)) {
   159     if (!do_reconsider_video_properties(cdata, page._alpha, 1, z, options)) {
   163     do_set_format(cdata, F_alpha);
   166   cdata->_loaded_from_image = 
true;
   167   clear_current_frame();
   168   do_update_frame(cdata, 0);
   177 OpenCVTexture::VideoPage &OpenCVTexture::
   178 do_modify_page(
const Texture::CData *cdata, 
int z) {
   179   nassertr(z < cdata->_z_size, _pages[0]);
   180   while (z >= (
int)_pages.size()) {
   181     _pages.push_back(VideoPage());
   191 do_reconsider_video_properties(Texture::CData *cdata,
   192                                const OpenCVTexture::VideoStream &stream,
   193                                int num_components, 
int z,
   195   double frame_rate = 0.0f;
   198   if (stream.is_from_file()) {
   199     frame_rate = cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FPS);
   200     num_frames = (int)cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FRAME_COUNT);
   201     if (vision_cat.is_debug()) {
   203         << 
"Loaded " << stream._filename << 
", " << num_frames << 
" frames at "   204         << frame_rate << 
" fps\n";
   209     if (vision_cat.is_debug()) {
   211         << 
"Loaded camera stream\n";
   215   int width = (int)cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FRAME_WIDTH);
   216   int height = (int)cvGetCaptureProperty(stream._capture, CV_CAP_PROP_FRAME_HEIGHT);
   220   do_adjust_this_size(cdata, x_size, y_size, get_name(), 
true);
   222   if (vision_cat.is_debug()) {
   224       << 
"Video stream is " << width << 
" by " << height
   225       << 
" pixels; fitting in texture " << x_size << 
" by "   226       << y_size << 
" texels.\n";
   229   if (!do_reconsider_image_properties(cdata, x_size, y_size, num_components,
   230                                       T_unsigned_byte, z, options)) {
   234   if (cdata->_loaded_from_image &&
   235       (get_video_width() != width || get_video_height() != height ||
   236        get_num_frames() != num_frames || get_frame_rate() != frame_rate)) {
   238       << 
"Video properties have changed for texture " << get_name()
   239       << 
" level " << z << 
".\n";
   243   set_frame_rate(frame_rate);
   244   set_num_frames(num_frames);
   245   set_video_size(width, height);
   259   return new OpenCVTexture;
   266 do_update_frame(Texture::CData *cdata, 
int frame) {
   267   int max_z = std::max(cdata->_z_size, (
int)_pages.size());
   268   for (
int z = 0; z < max_z; ++z) {
   269     do_update_frame(cdata, frame, z);
   277 do_update_frame(Texture::CData *cdata, 
int frame, 
int z) {
   278   if (vision_cat.is_spam()) {
   280       << 
"Updating OpenCVTexture page " << z << 
"\n";
   283   VideoPage &page = _pages[z];
   284   if (page._color.is_valid() || page._alpha.is_valid()) {
   285     do_modify_ram_image(cdata);
   286     ++(cdata->_image_modified);
   288   int dest_x_pitch = cdata->_num_components * cdata->_component_width;
   289   int dest_y_pitch = cdata->_x_size * dest_x_pitch;
   291   if (page._color.is_valid()) {
   292     nassertv(get_num_components() >= 3 && get_component_width() == 1);
   294     const unsigned char *r, *g, *b;
   295     int x_pitch, y_pitch;
   296     if (page._color.get_frame_data(frame, r, g, b, x_pitch, y_pitch)) {
   297       nassertv(get_video_width() <= cdata->_x_size && get_video_height() <= cdata->_y_size);
   298       nassertv(!cdata->_ram_images.empty())
   299       unsigned char *dest = cdata->_ram_images[0]._image.p() + do_get_expected_ram_page_size(cdata) * z;
   301       if (cdata->_num_components == 3 && x_pitch == 3) {
   303         int copy_bytes = get_video_width() * dest_x_pitch;
   304         nassertv(copy_bytes <= dest_y_pitch && copy_bytes <= abs(y_pitch));
   306         for (
int y = 0; y < get_video_height(); ++y) {
   307           memcpy(dest, r, copy_bytes);
   308           dest += dest_y_pitch;
   316         for (
int y = 0; y < get_video_height(); ++y) {
   319           for (
int x = 0; x < get_video_width(); ++x) {
   321             dest[dx + 1] = g[sx];
   322             dest[dx + 2] = b[sx];
   326           dest += dest_y_pitch;
   334   if (page._alpha.is_valid()) {
   335     nassertv(get_component_width() == 1);
   337     const unsigned char *source[3];
   338     int x_pitch, y_pitch;
   339     if (page._alpha.get_frame_data(frame, source[0], source[1], source[2],
   341       nassertv(get_video_width() <= cdata->_x_size && get_video_height() <= cdata->_y_size);
   342       nassertv(!cdata->_ram_images.empty())
   343       unsigned char *dest = cdata->_ram_images[0]._image.p() + do_get_expected_ram_page_size(cdata) * z;
   348       const unsigned char *sch = source[0];
   349       if (cdata->_alpha_file_channel >= 1 && cdata->_alpha_file_channel <= 3) {
   350         sch = source[cdata->_alpha_file_channel - 1];
   353       for (
int y = 0; y < get_video_height(); ++y) {
   356         int dx = (cdata->_num_components - 1) * cdata->_component_width;
   358         for (
int x = 0; x < get_video_width(); ++x) {
   363         dest += dest_y_pitch;
   375 do_read_one(Texture::CData *cdata,
   377             int z, 
int n, 
int primary_file_num_channels, 
int alpha_file_channel,
   380   if (record != 
nullptr) {
   384   nassertr(n == 0, 
false);
   385   nassertr(z >= 0 && z < cdata->_z_size, 
false);
   387   VideoPage &page = do_modify_page(cdata, z);
   388   if (!page._color.read(fullpath)) {
   390       << 
"OpenCV couldn't read " << fullpath << 
" as video.\n";
   393   if (!alpha_fullpath.empty()) {
   394     if (!page._alpha.read(alpha_fullpath)) {
   396         << 
"OpenCV couldn't read " << alpha_fullpath << 
" as video.\n";
   407     if (cdata->_filename.empty()) {
   408       cdata->_filename = fullpath;
   409       cdata->_alpha_filename = alpha_fullpath;
   412     cdata->_fullpath = fullpath;
   413     cdata->_alpha_fullpath = alpha_fullpath;
   416   cdata->_primary_file_num_channels = 3;
   417   cdata->_alpha_file_channel = 0;
   419   if (alpha_fullpath.empty()) {
   421     if (!do_reconsider_video_properties(cdata, page._color, 3, z, options)) {
   428     cdata->_alpha_file_channel = alpha_file_channel;
   430     if (!do_reconsider_video_properties(cdata, page._color, 4, z, options)) {
   436     if (!do_reconsider_video_properties(cdata, page._alpha, 4, z, options)) {
   443   set_loaded_from_image();
   444   clear_current_frame();
   445   do_update_frame(cdata, 0);
   454 do_load_one(Texture::CData *cdata,
   455             const PNMImage &pnmimage, 
const std::string &name,
   457   if (z <= (
int)_pages.size()) {
   458     VideoPage &page = do_modify_page(cdata, z);
   463   return Texture::do_load_one(cdata, pnmimage, name, z, n, options);
   470 register_with_read_factory() {
   486 OpenCVTexture::VideoStream::
   497 OpenCVTexture::VideoStream::
   498 VideoStream(
const OpenCVTexture::VideoStream ©) :
   504   if (copy.is_valid()) {
   505     if (copy.is_from_file()) {
   506       read(copy._filename);
   508       from_camera(copy._camera_index);
   516 OpenCVTexture::VideoStream::
   536 bool OpenCVTexture::VideoStream::
   537 get_frame_data(
int frame,
   538                const unsigned char *&r,
   539                const unsigned char *&g,
   540                const unsigned char *&b,
   541                int &x_pitch, 
int &y_pitch) {
   542   nassertr(is_valid(), 
false);
   544   if (is_from_file() && _next_frame != frame) {
   545     cvSetCaptureProperty(_capture, CV_CAP_PROP_POS_FRAMES, frame);
   548   _next_frame = frame + 1;
   549   IplImage *image = cvQueryFrame(_capture);
   550   if (image == 
nullptr) {
   554   r = (
const unsigned char *)image->imageData;
   558   y_pitch = image->widthStep;
   560   if (image->dataOrder == 1) {
   564     g = r + image->height * y_pitch;
   565     b = g + image->height * y_pitch;
   568   if (image->origin == 0) {
   573     r += (image->height - 1) * y_pitch;
   574     g += (image->height - 1) * y_pitch;
   575     b += (image->height - 1) * y_pitch;
   586 bool OpenCVTexture::VideoStream::
   591   _capture = cvCaptureFromFile(os_specific.c_str());
   592   if (_capture == 
nullptr) {
   595   _filename = filename;
   603 bool OpenCVTexture::VideoStream::
   604 from_camera(
int camera_index) {
   607   _capture = cvCaptureFromCAM(camera_index);
   608   if (_capture == 
nullptr) {
   611   _camera_index = camera_index;
   618 void OpenCVTexture::VideoStream::
   620   if (_capture != 
nullptr) {
   621     cvReleaseCapture(&_capture);
   629 #endif  // HAVE_OPENCV static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
 
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
Specifies parameters that may be passed to the loader.
 
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
 
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
The base class for a family of animated Textures that take their input from a video source,...
 
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
get_frame_count
Returns the number of times tick() has been called since the ClockObject was created,...
 
The name of a file, such as a texture file or an Egg file.
 
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
 
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
 
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
 
void add_dependent_file(const Filename &pathname)
Adds the indicated file to the list of files that will be loaded to generate the data in this record.
 
TypeHandle is the identifier used to differentiate C++ class types.
 
std::string to_os_specific() const
Converts the filename from our generic Unix-like convention (forward slashes starting with the root a...