39 MovieTexture(
const std::string &name) :
52 do_load_one(cdata_tex, video->open(),
nullptr, 0,
LoaderOptions());
75 CData(
const CData ©) :
77 _video_width(copy._video_width),
78 _video_height(copy._video_height),
79 _video_length(copy._video_length),
93 return new CData(*
this);
118 ensure_loader_type(
const Filename &filename) {
123 PT(
MovieVideo) video = reg->make_video(filename);
132 return new MovieTexture(
"");
142 do_recalculate_image_properties(CData *cdata, Texture::CData *cdata_tex,
const LoaderOptions &options) {
149 for (
size_t i = 0; i < cdata->_pages.size(); ++i) {
152 if (t->size_x() > x_max) x_max = t->size_x();
153 if (t->size_y() > y_max) y_max = t->size_y();
154 if (t->length() > len) len = t->length();
155 if (t->get_num_components() >= 3) rgb=
true;
156 if (t->get_num_components() == 4 || t->get_num_components() == 2) alpha=
true;
158 t = cdata->_pages[i]._alpha;
160 if (t->size_x() > x_max) x_max = t->size_x();
161 if (t->size_y() > y_max) y_max = t->size_y();
162 if (t->length() > len) len = t->length();
167 cdata->_video_width = x_max;
168 cdata->_video_height = y_max;
169 cdata->_video_length = len;
171 do_adjust_this_size(cdata_tex, x_max, y_max, get_name(),
true);
173 int num_components = (rgb ? 3 : 1) + alpha;
174 do_reconsider_image_properties(cdata_tex, x_max, y_max, num_components,
175 T_unsigned_byte, cdata->_pages.size(),
177 cdata_tex->_orig_file_x_size = cdata->_video_width;
178 cdata_tex->_orig_file_y_size = cdata->_video_height;
180 do_set_pad_size(cdata_tex,
181 std::max(cdata_tex->_x_size - cdata_tex->_orig_file_x_size, 0),
182 std::max(cdata_tex->_y_size - cdata_tex->_orig_file_y_size, 0),
191 do_adjust_this_size(
const Texture::CData *cdata_tex,
192 int &x_size,
int &y_size,
const std::string &name,
193 bool for_padding)
const {
194 AutoTextureScale ats = do_get_auto_texture_scale(cdata_tex);
195 if (ats != ATS_none) {
199 return adjust_size(x_size, y_size, name, for_padding, ats);
207 do_read_one(Texture::CData *cdata_tex,
209 int z,
int n,
int primary_file_num_channels,
int alpha_file_channel,
212 nassertr(n == 0,
false);
213 if (!do_reconsider_z_size(cdata_tex, z, options)) {
216 nassertr(z >= 0 && z < cdata_tex->_z_size * cdata_tex->_num_views,
false);
218 if (record !=
nullptr) {
225 color = MovieVideo::get(fullpath)->open();
226 if (color ==
nullptr) {
229 if (!alpha_fullpath.empty()) {
230 alpha = MovieVideo::get(alpha_fullpath)->open();
231 if (alpha ==
nullptr) {
241 if (cdata_tex->_filename.empty()) {
242 cdata_tex->_filename = fullpath;
243 cdata_tex->_alpha_filename = alpha_fullpath;
246 cdata_tex->_fullpath = fullpath;
247 cdata_tex->_alpha_fullpath = alpha_fullpath;
250 cdata_tex->_primary_file_num_channels = primary_file_num_channels;
251 cdata_tex->_alpha_file_channel = alpha_file_channel;
253 if (!do_load_one(cdata_tex, color, alpha, z, options)) {
257 cdata_tex->_loaded_from_image =
true;
267 do_load_one(Texture::CData *cdata_tex,
270 CDWriter cdata(_cycler);
271 cdata->_pages.resize(z + 1);
272 cdata->_pages[z]._color = color;
273 cdata->_pages[z]._alpha = alpha;
274 do_recalculate_image_properties(cdata, cdata_tex, options);
278 PTA_uchar image = make_ram_image();
279 memset(image.p(), 0, image.size());
288 do_load_one(Texture::CData *cdata_tex,
289 const PNMImage &pnmimage,
const std::string &name,
int z,
int n,
291 grutil_cat.error() <<
"You cannot load a static image into a MovieTexture\n";
299 do_load_one(Texture::CData *cdata_tex,
300 const PfmFile &pfm,
const std::string &name,
int z,
int n,
302 grutil_cat.error() <<
"You cannot load a static image into a MovieTexture\n";
313 do_allocate_pages(Texture::CData *cdata_tex) {
324 has_cull_callback()
const {
337 CDReader cdata(_cycler);
339 if (!cdata->_has_offset) {
343 int true_loop_count = 1;
344 if (cdata->_synchronize !=
nullptr) {
345 offset = cdata->_synchronize->get_time();
349 offset = cdata->_clock;
350 if (cdata->_playing) {
351 offset += now * cdata->_play_rate;
353 true_loop_count = cdata->_loop_count;
355 ((CData *)cdata.p())->_offset = offset;
356 ((CData *)cdata.p())->_true_loop_count = true_loop_count;
357 ((CData *)cdata.p())->_has_offset =
true;
360 bool in_sync = do_update_frames(cdata);
364 in_sync = do_update_frames(cdata);
369 Pages::const_iterator pi;
370 for (pi = cdata->_pages.begin(); pi != cdata->_pages.end(); ++pi) {
371 const VideoPage &page = (*pi);
374 size_t i = pi - cdata->_pages.begin();
376 if (color !=
nullptr && alpha !=
nullptr) {
380 }
else if (color !=
nullptr) {
384 ((VideoPage &)page)._cbuffer.clear();
385 ((VideoPage &)page)._abuffer.clear();
389 ((CData *)cdata.p())->_has_offset =
false;
405 make_copy_impl()
const {
407 CDReader cdata(_cycler);
408 PT(MovieTexture) copy =
new MovieTexture(get_name());
410 CDWriter cdata_copy(copy->_cycler,
true);
411 copy->do_assign(cdata_copy, cdata_copy_tex,
this, cdata, cdata_tex);
420 do_assign(CData *cdata, Texture::CData *cdata_tex,
const MovieTexture *copy,
421 const CData *cdata_copy,
const Texture::CData *cdata_copy_tex) {
422 Texture::do_assign(cdata_tex, copy, cdata_copy_tex);
426 color.resize(cdata_copy->_pages.size());
427 alpha.resize(cdata_copy->_pages.size());
428 for (
int i=0; i<(int)(color.size()); i++) {
429 color[i] = cdata_copy->_pages[i]._color;
430 alpha[i] = cdata_copy->_pages[i]._alpha;
433 cdata->_pages.resize(color.size());
434 for (
int i=0; i<(int)(color.size()); i++) {
436 cdata->_pages[i]._color = color[i]->get_source()->open();
439 cdata->_pages[i]._alpha = alpha[i]->get_source()->open();
442 do_recalculate_image_properties(cdata, cdata_tex,
LoaderOptions());
450 do_reload_ram_image(Texture::CData *cdata,
bool allow_compression) {
460 get_keep_ram_image()
const {
471 do_has_bam_rawdata(
const Texture::CData *cdata)
const {
480 do_get_bam_rawdata(Texture::CData *cdata) {
489 do_can_reload(
const Texture::CData *cdata)
const {
499 CDWriter cdata(_cycler);
500 if (!cdata->_playing) {
502 cdata->_clock = cdata->_clock - (now * cdata->_play_rate);
503 cdata->_playing =
true;
513 CDWriter cdata(_cycler);
514 if (cdata->_playing) {
516 cdata->_clock = cdata->_clock + (now * cdata->_play_rate);
517 cdata->_playing =
false;
526 CDWriter cdata(_cycler);
528 cdata->_clock = 0.0 - (now * cdata->_play_rate);
529 cdata->_playing =
true;
537 CDWriter cdata(_cycler);
538 t = std::min(cdata->_video_length, std::max(0.0, t));
539 if (cdata->_playing) {
541 cdata->_clock = t - (now * cdata->_play_rate);
553 double MovieTexture::
555 CDReader cdata(_cycler);
556 double clock = cdata->_clock;
557 if (cdata->_playing) {
559 clock += (now * cdata->_play_rate);
569 set_loop(
bool loop) {
570 set_loop_count(loop ? 0:1);
578 CDReader cdata(_cycler);
579 return (cdata->_loop_count == 0);
586 set_loop_count(
int n) {
587 CDWriter cdata(_cycler);
588 cdata->_loop_count = n;
595 get_loop_count()
const {
596 CDReader cdata(_cycler);
597 return cdata->_loop_count;
606 set_play_rate(
double rate) {
607 CDWriter cdata(_cycler);
608 if (cdata->_playing) {
610 cdata->_clock += (now * cdata->_play_rate);
611 cdata->_play_rate = rate;
612 cdata->_clock -= (now * cdata->_play_rate);
614 cdata->_play_rate = rate;
621 double MovieTexture::
622 get_play_rate()
const {
623 CDReader cdata(_cycler);
624 return cdata->_play_rate;
632 CDReader cdata(_cycler);
633 return cdata->_playing;
642 CDWriter cdata(_cycler);
643 cdata->_synchronize = s;
651 CDWriter cdata(_cycler);
652 cdata->_synchronize =
nullptr;
662 do_update_frames(
const CData *cdata)
const {
666 nassertr(cdata->_has_offset,
false);
669 Pages::const_iterator pi;
670 for (pi = cdata->_pages.begin(); pi != cdata->_pages.end(); ++pi) {
671 const VideoPage &page = (*pi);
675 if (color !=
nullptr && page._cbuffer ==
nullptr) {
676 if (color->
set_time(cdata->_offset, cdata->_true_loop_count)) {
677 ((VideoPage &)page)._cbuffer = color->fetch_buffer();
680 if (alpha !=
nullptr && page._abuffer ==
nullptr) {
681 if (alpha->
set_time(cdata->_offset, cdata->_true_loop_count)) {
682 ((VideoPage &)page)._abuffer = alpha->fetch_buffer();
687 if (!movies_sync_pages) {
695 bool any_frames =
false;
696 bool any_dropped =
false;
698 for (pi = cdata->_pages.begin(); pi != cdata->_pages.end(); ++pi) {
699 const VideoPage &page = (*pi);
700 if (page._cbuffer ==
nullptr) {
701 if (page._color !=
nullptr) {
706 nassertr(page._color !=
nullptr,
true);
708 if (newest ==
nullptr) {
709 newest = page._cbuffer;
711 int ref = newest->compare_timestamp(page._cbuffer);
717 newest = page._cbuffer;
722 if (page._abuffer ==
nullptr) {
723 if (page._alpha !=
nullptr) {
727 nassertr(page._alpha !=
nullptr,
true);
729 if (newest ==
nullptr) {
730 newest = page._abuffer;
732 int ref = newest->compare_timestamp(page._abuffer);
737 newest = page._abuffer;
752 if (newest !=
nullptr) {
753 Pages::const_iterator pi;
754 for (pi = cdata->_pages.begin(); pi != cdata->_pages.end(); ++pi) {
755 const VideoPage &page = (*pi);
756 if (page._cbuffer !=
nullptr && newest->compare_timestamp(page._cbuffer) > 0) {
757 ((VideoPage &)page)._cbuffer.clear();
760 if (page._abuffer !=
nullptr && newest->compare_timestamp(page._abuffer) > 0) {
761 ((VideoPage &)page)._abuffer.clear();
771 ((CData *)cdata)->_offset = newest->get_timestamp();
783 register_with_read_factory() {
792 PT(MovieTexture) dummy =
new MovieTexture(
"");
793 return dummy->make_this_from_bam(params);
804 CDWriter cdata(_cycler);
805 size_t num_pages = cdata->_pages.size();
806 for (
size_t n = 0; n < num_pages; ++n) {
807 VideoPage &page = cdata->_pages[n];
819 do_write_datagram_rawdata(Texture::CData *cdata_tex,
BamWriter *manager,
Datagram &dg) {
820 CDReader cdata(_cycler);
827 nassertv(cdata->_pages.size() == (
size_t)(cdata_tex->_z_size * cdata_tex->_num_views));
828 for (
size_t n = 0; n < cdata->_pages.size(); ++n) {
829 const VideoPage &page = cdata->_pages[n];
841 CDWriter cdata(_cycler);
844 cdata_tex->_num_views = 1;
849 size_t num_pages = (size_t)(cdata_tex->_z_size * cdata_tex->_num_views);
850 cdata->_pages.reserve(num_pages);
851 for (
size_t n = 0; n < num_pages; ++n) {
852 cdata->_pages.push_back(VideoPage());
871 CDWriter cdata(_cycler);
874 size_t num_pages = cdata->_pages.size();
875 for (
size_t n = 0; n < num_pages; ++n) {
876 VideoPage &page = cdata->_pages[n];
881 do_recalculate_image_properties(cdata, cdata_tex,
LoaderOptions());
883 set_loaded_from_image();