diff --git a/panda/src/movies/Sources.pp b/panda/src/movies/Sources.pp index 259039afda..10b6c57e98 100644 --- a/panda/src/movies/Sources.pp +++ b/panda/src/movies/Sources.pp @@ -14,18 +14,33 @@ movie.h movie.I \ movieAudio.h movieAudio.I \ movieVideo.h movieVideo.I \ + inkblotMovie.h inkblotMovie.I \ + inkblotVideo.h inkblotVideo.I \ + ffmpegMovie.h ffmpegMovie.I \ + ffmpegVideo.h ffmpegVideo.I \ + ffmpegAudio.h ffmpegAudio.I \ config_movies.h #define INCLUDED_SOURCES \ movieVideo.cxx \ movieAudio.cxx \ movie.cxx \ + inkblotVideo.cxx \ + inkblotMovie.cxx \ + ffmpegVideo.cxx \ + ffmpegAudio.cxx \ + ffmpegMovie.cxx \ config_movies.cxx #define INSTALL_HEADERS \ movie.h movie.I \ movieAudio.h movieAudio.I \ movieVideo.h movieVideo.I \ + inkblotMovie.h inkblotMovie.I \ + inkblotVideo.h inkblotVideo.I \ + ffmpegMovie.h ffmpegMovie.I \ + ffmpegVideo.h ffmpegVideo.I \ + ffmpegAudio.h ffmpegAudio.I \ config_movies.h #define IGATESCAN all diff --git a/panda/src/movies/config_movies.cxx b/panda/src/movies/config_movies.cxx index 91e609d2cf..e2e543eb9d 100644 --- a/panda/src/movies/config_movies.cxx +++ b/panda/src/movies/config_movies.cxx @@ -45,5 +45,10 @@ init_libmovies() { MovieVideo::init_type(); MovieAudio::init_type(); Movie::init_type(); + InkblotVideo::init_type(); + InkblotMovie::init_type(); + FfmpegVideo::init_type(); + FfmpegAudio::init_type(); + FfmpegMovie::init_type(); } diff --git a/panda/src/movies/config_movies.h b/panda/src/movies/config_movies.h index b46deb0785..f90ae90e62 100644 --- a/panda/src/movies/config_movies.h +++ b/panda/src/movies/config_movies.h @@ -24,6 +24,10 @@ #include "configVariableEnum.h" #include "configVariableDouble.h" #include "dconfig.h" +#include "movie.h" +#include "movieVideo.h" +#include "movieAudio.h" +#include "inkblotVideo.h" ConfigureDecl(config_movies, EXPCL_PANDA_MOVIES, EXPTP_PANDA_MOVIES); NotifyCategoryDecl(movies, EXPCL_PANDA_MOVIES, EXPTP_PANDA_MOVIES); diff --git a/panda/src/movies/ffmpegAudio.I b/panda/src/movies/ffmpegAudio.I new file mode 100644 index 0000000000..43941fd9f5 --- /dev/null +++ b/panda/src/movies/ffmpegAudio.I @@ -0,0 +1,18 @@ +// Filename: ffmpegAudio.I +// Created by: jyelon (01Aug2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + diff --git a/panda/src/movies/ffmpegAudio.cxx b/panda/src/movies/ffmpegAudio.cxx new file mode 100644 index 0000000000..289086d344 --- /dev/null +++ b/panda/src/movies/ffmpegAudio.cxx @@ -0,0 +1,67 @@ +// Filename: ffmpegAudio.cxx +// Created by: jyelon (01Aug2007) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2007, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net +// +//////////////////////////////////////////////////////////////////// + +#include "ffmpegAudio.h" + +TypeHandle FfmpegAudio::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: FfmpegAudio::Constructor +// Access: Protected +// Description: xxx +//////////////////////////////////////////////////////////////////// +FfmpegAudio:: +FfmpegAudio(CPT(FfmpegMovie) source, double offset) : + MovieAudio((const FfmpegMovie *)source), + _sourcep(source) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: FfmpegAudio::Destructor +// Access: Protected, Virtual +// Description: xxx +//////////////////////////////////////////////////////////////////// +FfmpegAudio:: +~FfmpegAudio() { +} + +//////////////////////////////////////////////////////////////////// +// Function: FfmpegAudio::read_samples +// Access: Public, Virtual +// Description: Read audio samples from the stream. N is the +// number of samples you wish to read. Your buffer +// must be equal in size to N * channels. +// Multiple-channel audio will be interleaved. +//////////////////////////////////////////////////////////////////// +void FfmpegAudio:: +read_samples(int n, PN_int16 *data) { + + // This is the null implementation, which generates pure silence. + // Normally, this method will be overridden by a subclass. + + if (n <= 0) { + return; + } + + for (int i=0; iget_name()), _source(source), _samples_read(0) { diff --git a/panda/src/movies/movieAudio.h b/panda/src/movies/movieAudio.h index ee1199ece6..d3a01c8376 100644 --- a/panda/src/movies/movieAudio.h +++ b/panda/src/movies/movieAudio.h @@ -32,7 +32,6 @@ class EXPCL_PANDA_MOVIES MovieAudio : public TypedWritableReferenceCount, public Namable { PUBLISHED: - MovieAudio(const string &name, CPT(Movie) source); INLINE CPT(Movie) get_source() const; INLINE int audio_rate() const; INLINE int audio_channels() const; @@ -41,8 +40,9 @@ PUBLISHED: INLINE void skip_samples(int n); public: - virtual void read_samples(int n, PN_int16 *data); + MovieAudio(CPT(Movie) source); virtual ~MovieAudio(); + virtual void read_samples(int n, PN_int16 *data); protected: CPT(Movie) _source; diff --git a/panda/src/movies/movieVideo.cxx b/panda/src/movies/movieVideo.cxx index cb30b6feec..27340fec28 100644 --- a/panda/src/movies/movieVideo.cxx +++ b/panda/src/movies/movieVideo.cxx @@ -23,25 +23,25 @@ TypeHandle MovieVideo::_type_handle; //////////////////////////////////////////////////////////////////// // Function: MovieVideo::Constructor -// Access: Published +// Access: Public // Description: This constructor returns a null video stream --- a // stream of plain blue and white frames that last one // second each. To get more interesting video, you need // to construct a subclass of this class. //////////////////////////////////////////////////////////////////// MovieVideo:: -MovieVideo(const string &name, CPT(Movie) source) : - Namable(name), +MovieVideo(CPT(Movie) source) : + Namable(source->get_name()), _source(source), _aborted(false), - _curr_start(-1.0), + _last_start(-1.0), _next_start(0.0) { } //////////////////////////////////////////////////////////////////// // Function: MovieVideo::Destructor -// Access: Published, Virtual +// Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// MovieVideo:: @@ -65,40 +65,17 @@ allocate_conversion_buffer() { } } -//////////////////////////////////////////////////////////////////// -// Function: MovieVideo::seek_ahead -// Access: Published, Virtual -// Description: Seeks forward until the next frame contains time t. -// Also updates last_start and next_start. -// It is an error to pass in a value less than -// next_start (that would be a backward seek). -// -// Arbitrary seeking (both forward and backward) can -// be accomplished by fetching the original Movie -// object, and then calling get_video with an offset. -// However, unlike seek_ahead, the result is not -// guaranteed to be quite precise, because AVI files -// often have inaccurate indices. -//////////////////////////////////////////////////////////////////// -void MovieVideo:: -seek_ahead(double t) { - - // The following is the implementation of the null video stream, ie, - // a stream of blinking red and blue frames. This method must be - // overridden by the subclass. - - nassertv(t >= _next_start); - _next_start = floor(t); - _last_start = _next_start - 1.0; -} - //////////////////////////////////////////////////////////////////// // Function: MovieVideo::fetch_into_texture // Access: Published, Virtual -// Description: Fetch the next frame into a page of a texture. +// Description: Reads frames from the stream until the specified +// time is reached. The last frame read is stored in +// the supplied texture. +// +// See fetch_into_buffer for more details. //////////////////////////////////////////////////////////////////// void MovieVideo:: -fetch_into_texture(Texture *t, int page) { +fetch_into_texture(double time, Texture *t, int page) { // This generic implementation is layered on fetch_into_buffer. // It will work for any derived class, so it is never necessary to @@ -117,10 +94,10 @@ fetch_into_texture(Texture *t, int page) { unsigned char *data = img.p() + page * t->get_expected_ram_page_size(); if (t->get_x_size() == size_x()) { - fetch_into_buffer(data, t->get_num_components() == 4); + fetch_into_buffer(time, data, t->get_num_components() == 4); } else { allocate_conversion_buffer(); - fetch_into_buffer(_conversion_buffer, t->get_num_components() == 4); + fetch_into_buffer(time, _conversion_buffer, t->get_num_components() == 4); int src_stride = size_x() * t->get_num_components(); int dst_stride = t->get_x_size() * t->get_num_components(); unsigned char *p = _conversion_buffer; @@ -135,11 +112,15 @@ fetch_into_texture(Texture *t, int page) { //////////////////////////////////////////////////////////////////// // Function: MovieVideo::fetch_into_texture_alpha // Access: Published, Virtual -// Description: Fetch the next frame into the alpha channel -// of a texture. +// Description: Reads frames from the stream until the specified +// time is reached. The last frame read is stored in +// the alpha channel of the supplied texture. The +// RGB channels of the texture are not touched. +// +// See fetch_into_buffer for more details. //////////////////////////////////////////////////////////////////// void MovieVideo:: -fetch_into_texture_alpha(Texture *t, int page, int alpha_src) { +fetch_into_texture_alpha(double time, Texture *t, int page, int alpha_src) { // This generic implementation is layered on fetch_into_buffer. // It will work for any derived class, so it is never necessary to @@ -156,7 +137,7 @@ fetch_into_texture_alpha(Texture *t, int page, int alpha_src) { allocate_conversion_buffer(); - fetch_into_buffer(_conversion_buffer, true); + fetch_into_buffer(time, _conversion_buffer, true); PTA_uchar img = t->modify_ram_image(); @@ -187,23 +168,87 @@ fetch_into_texture_alpha(Texture *t, int page, int alpha_src) { } //////////////////////////////////////////////////////////////////// -// Function: MovieVideo::fetch_into_buffer +// Function: MovieVideo::fetch_into_texture_rgb // Access: Published, Virtual -// Description: Fetch the next frame into a supplied RGB8 or RGBA8 -// buffer. +// Description: Reads frames from the stream until the specified +// time is reached. The last frame read is stored in +// the RGB channels of the supplied texture. The alpha +// channel of the texture is not touched. +// +// See fetch_into_buffer for more details. //////////////////////////////////////////////////////////////////// void MovieVideo:: -fetch_into_buffer(unsigned char *data, bool rgba) { +fetch_into_texture_rgb(double time, Texture *t, int page) { + + // This generic implementation is layered on fetch_into_buffer. + // It will work for any derived class, so it is never necessary to + // redefine this. However, it may be possible to make a faster + // implementation that uses fewer intermediate copies, depending + // on the capabilities of the underlying codec software. + + nassertv(t->get_x_size() >= size_x()); + nassertv(t->get_y_size() >= size_y()); + nassertv(t->get_num_components() == 4); + nassertv(t->get_component_width() == 1); + nassertv(page < t->get_z_size()); + + allocate_conversion_buffer(); + + fetch_into_buffer(time, _conversion_buffer, true); + + PTA_uchar img = t->modify_ram_image(); + + unsigned char *data = img.p() + page * t->get_expected_ram_page_size(); + + int src_stride = size_x() * 4; + int dst_stride = t->get_x_size() * 4; + unsigned char *p = _conversion_buffer; + for (int y=0; y= length()) { + if (time < _next_start) time = _next_start; + _last_start = floor(time); + _next_start = _last_start + 1; + + if (_last_start >= length()) { data[0] = 0; data[1] = 0; data[2] = 0; - } else if (((int)_next_start) & 1) { + } else if (((int)_last_start) & 1) { data[0] = 255; data[1] = 128; data[2] = 128; @@ -215,8 +260,5 @@ fetch_into_buffer(unsigned char *data, bool rgba) { if (rgba) { data[3] = 255; } - - _curr_start = _next_start; - _next_start = _next_start + 1.0; } diff --git a/panda/src/movies/movieVideo.h b/panda/src/movies/movieVideo.h index 2f36f3aa80..e0507b2cfe 100644 --- a/panda/src/movies/movieVideo.h +++ b/panda/src/movies/movieVideo.h @@ -31,8 +31,6 @@ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public Namable { PUBLISHED: - MovieVideo(const string &name, CPT(Movie) source); - virtual ~MovieVideo(); INLINE CPT(Movie) get_source() const; INLINE int size_x() const; INLINE int size_y() const; @@ -41,11 +39,15 @@ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public INLINE bool aborted() const; INLINE double last_start() const; INLINE double next_start() const; - virtual void seek_ahead(double t); - virtual void fetch_into_texture(Texture *t, int page); - virtual void fetch_into_texture_alpha(Texture *t, int page, int alpha_src); - virtual void fetch_into_buffer(unsigned char *block, bool rgba); + virtual void fetch_into_texture(double time, Texture *t, int page); + virtual void fetch_into_texture_rgb(double time, Texture *t, int page); + virtual void fetch_into_texture_alpha(double time, Texture *t, int page, int alpha_src); + public: + MovieVideo(CPT(Movie) source); + virtual ~MovieVideo(); + virtual void fetch_into_buffer(double time, unsigned char *block, bool rgba); + private: void allocate_conversion_buffer(); unsigned char *_conversion_buffer; @@ -54,7 +56,6 @@ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public CPT(Movie) _source; bool _aborted; double _last_start; - double _curr_start; double _next_start; public: diff --git a/panda/src/movies/movies_composite1.cxx b/panda/src/movies/movies_composite1.cxx index 1a25017ebe..4491f8586f 100644 --- a/panda/src/movies/movies_composite1.cxx +++ b/panda/src/movies/movies_composite1.cxx @@ -1,4 +1,9 @@ +#include "movie.cxx" #include "movieVideo.cxx" #include "movieAudio.cxx" -#include "movie.cxx" +#include "inkblotMovie.cxx" +#include "inkblotVideo.cxx" +#include "ffmpegMovie.cxx" +#include "ffmpegAudio.cxx" +#include "ffmpegVideo.cxx" #include "config_movies.cxx"