diff --git a/panda/src/movies/config_movies.cxx b/panda/src/movies/config_movies.cxx index 98295e2f02..91e609d2cf 100644 --- a/panda/src/movies/config_movies.cxx +++ b/panda/src/movies/config_movies.cxx @@ -44,5 +44,6 @@ init_libmovies() { MovieVideo::init_type(); MovieAudio::init_type(); + Movie::init_type(); } diff --git a/panda/src/movies/movie.I b/panda/src/movies/movie.I new file mode 100644 index 0000000000..a4eef1541b --- /dev/null +++ b/panda/src/movies/movie.I @@ -0,0 +1,55 @@ +// Filename: movie.I +// Created by: jyelon (02Jul07) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// Function: Movie::ignores_offset +// Access: Published +// Description: The methods get_video and get_audio both accept +// an offset parameter, which allow you to seek +// to a particular location within the movie. Not +// all movies can do this, though. For instance, an +// internet TV station cannot be fast-forwarded. In +// these cases, the offset parameter is ignored. +//////////////////////////////////////////////////////////////////// +INLINE bool Movie:: +ignores_offset() const { + return _ignores_offset; +} + +//////////////////////////////////////////////////////////////////// +// Function: Movie::dummy_video +// Access: Published +// Description: If you open a sound file as a movie, a dummy video +// stream will be synthesized. Returns true in this case. +//////////////////////////////////////////////////////////////////// +INLINE bool Movie:: +dummy_video() const { + return _dummy_video; +} + +//////////////////////////////////////////////////////////////////// +// Function: Movie::dummy_audio +// Access: Published +// Description: If you open a movie with no sound, a dummy sound +// stream will be synthesized. Returns true in this case. +//////////////////////////////////////////////////////////////////// +INLINE bool Movie:: +dummy_audio() const { + return _dummy_audio; +} + diff --git a/panda/src/movies/movie.cxx b/panda/src/movies/movie.cxx new file mode 100644 index 0000000000..4264bc23e7 --- /dev/null +++ b/panda/src/movies/movie.cxx @@ -0,0 +1,73 @@ +// Filename: movie.cxx +// Created by: jyelon (02Jul07) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "movieVideo.h" +#include "movieAudio.h" +#include "movie.h" +#include "config_movies.h" + +TypeHandle Movie::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: Movie::Constructor +// Access: Published +// Description: This constructor returns a null/dummy movie --- +// the video is plain blue, and the audio is silent. +// To get more interesting movie, you need to construct +// a subclass of this class. +//////////////////////////////////////////////////////////////////// +Movie:: +Movie(const string &name, double len) : + Namable(name), + _ignores_offset(true), + _dummy_video(true), + _dummy_audio(true), + _dummy_len(len) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: Movie::Destructor +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +Movie:: +~Movie() { +} + +//////////////////////////////////////////////////////////////////// +// Function: Movie::get_video +// Access: Published, Virtual +// Description: Fetch a video stream. Always constructs a new +// MovieVideo or subclass of MovieVideo. +//////////////////////////////////////////////////////////////////// +PT(MovieVideo) Movie:: +get_video(double offset) { + return new MovieVideo(get_name(), _dummy_len); +} + +//////////////////////////////////////////////////////////////////// +// Function: Movie::get_audio +// Access: Published, Virtual +// Description: Fetch an audio stream. Always constructs a new +// MovieAudio or subclass of MovieAudio. +//////////////////////////////////////////////////////////////////// +PT(MovieAudio) Movie:: +get_audio(double offset) { + return new MovieAudio(get_name(), _dummy_len); +} diff --git a/panda/src/movies/movie.h b/panda/src/movies/movie.h new file mode 100644 index 0000000000..cbd222756e --- /dev/null +++ b/panda/src/movies/movie.h @@ -0,0 +1,74 @@ +// Filename: movie.h +// Created by: jyelon (02Jul07) +// +//////////////////////////////////////////////////////////////////// +// +// 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 . +// +//////////////////////////////////////////////////////////////////// + +#ifndef MOVIE_H +#define MOVIE_H + +#include "pandabase.h" +#include "texture.h" +#include "pointerTo.h" +#include "movieVideo.h" +#include "movieAudio.h" + +//////////////////////////////////////////////////////////////////// +// Class : Movie +// Description : A "movie" is actually any source that provides +// an audio and a video stream. So that could include +// an AVI file, or an internet TV station. It could +// also be an MP3 file paired with a dummy video stream. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDASKEL Movie : public TypedWritableReferenceCount, public Namable{ + +PUBLISHED: + Movie(const string &name, double len); + INLINE bool ignores_offset() const; + INLINE bool dummy_video() const; + INLINE bool dummy_audio() const; + virtual PT(MovieVideo) get_video(double offset=0.0); + virtual PT(MovieAudio) get_audio(double offset=0.0); + +public: + virtual ~Movie(); + +private: + bool _ignores_offset; + bool _dummy_video; + bool _dummy_audio; + double _dummy_len; + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + TypedWritableReferenceCount::init_type(); + register_type(_type_handle, "Movie", + TypedWritableReferenceCount::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +#include "movie.I" + +#endif diff --git a/panda/src/movies/movieAudio.I b/panda/src/movies/movieAudio.I index bb48da499c..e7bdce12ad 100644 --- a/panda/src/movies/movieAudio.I +++ b/panda/src/movies/movieAudio.I @@ -49,16 +49,33 @@ samples_read() const { } //////////////////////////////////////////////////////////////////// -// Function: MovieAudio::approx_time_remaining +// Function: MovieAudio::skip_samples +// Access: Published +// Description: Skip audio samples from the stream. This is mostly +// for debugging purposes. +//////////////////////////////////////////////////////////////////// +INLINE int MovieAudio:: +skip_samples(int n) { + return read_samples(n, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: MovieAudio::approx_len // Access: Public -// Description: Returns a "best guess" amount of time left on the -// stream. For ffmpeg streams, this is usually a -// pretty close approximation --- ie, off by a few -// hundred samples. For infinite streams, always -// returns the constant value 1.0E10. +// Description: Returns a "best guess" amount of the stream length. +// For ffmpeg streams, this is usually a pretty close +// approximation --- ie, off by a few hundred samples. +// For infinite streams, always returns the constant +// value 1.0E10. Caution: it is legal for a stream to +// periodically update its estimate of the length! +// +// Stream lengths cannot be determined with accuracy, +// because the lengths encoded in AVI files are +// generally inaccurate, and some streams (ie, streaming +// internet audio) have no knowable length. //////////////////////////////////////////////////////////////////// INLINE double MovieAudio:: -approx_time_remaining() const { - return _approx_time_remaining; +approx_len() const { + return _approx_len; } diff --git a/panda/src/movies/movieAudio.cxx b/panda/src/movies/movieAudio.cxx index 4f2419c4db..95bb18106d 100644 --- a/panda/src/movies/movieAudio.cxx +++ b/panda/src/movies/movieAudio.cxx @@ -23,14 +23,18 @@ TypeHandle MovieAudio::_type_handle; //////////////////////////////////////////////////////////////////// // Function: MovieAudio::Constructor // Access: Protected -// Description: +// Description: This constructor returns a null audio stream --- a +// stream of total silence, at 8000 samples per second. +// To get more interesting audio, you need to construct +// a subclass of this class. //////////////////////////////////////////////////////////////////// MovieAudio:: -MovieAudio(const string &name) : +MovieAudio(const string &name, double len) : Namable(name), - _rate(44100), + _rate(8000), + _channels(1), _samples_read(0), - _approx_time_remaining(1.0E10) + _approx_len(len) { } @@ -52,30 +56,40 @@ MovieAudio:: // Multiple-channel audio will be interleaved. Returns // the actual number of samples read. This will always // be equal to N unless end-of-stream has been reached. +// It is legal to pass a null pointer, in this case, +// the samples are discarded. //////////////////////////////////////////////////////////////////// int MovieAudio:: read_samples(int n, PN_int16 *data) { - // This is a dummy implementation. This method should be overridden. - nassertr(n > 0, 0); - for (int i=0; i remain) { + n = remain; + } + if (data) { + for (int i=0; i 0, 0); - PN_int16 *data = new PN_int16[n]; - int res = read_samples(n, data); - delete data; - return res; -} - diff --git a/panda/src/movies/movieAudio.h b/panda/src/movies/movieAudio.h index 26c2857e3e..1e7a79cc1b 100644 --- a/panda/src/movies/movieAudio.h +++ b/panda/src/movies/movieAudio.h @@ -29,15 +29,14 @@ // Description : A stream that generates a sequence of audio samples. //////////////////////////////////////////////////////////////////// class EXPCL_PANDASKEL MovieAudio : public TypedWritableReferenceCount, public Namable { -protected: - MovieAudio(const string &name); PUBLISHED: + MovieAudio(const string &name, double len); INLINE int rate() const; INLINE int channels() const; INLINE int samples_read() const; - INLINE double approx_time_remaining() const; - virtual int skip_samples(int n); + INLINE double approx_len() const; + INLINE int skip_samples(int n); public: virtual int read_samples(int n, PN_int16 *data); @@ -47,7 +46,7 @@ private: int _rate; int _channels; int _samples_read; - double _approx_time_remaining; + double _approx_len; public: static TypeHandle get_class_type() { diff --git a/panda/src/movies/movieVideo.I b/panda/src/movies/movieVideo.I index 80683b93d9..1def69421d 100644 --- a/panda/src/movies/movieVideo.I +++ b/panda/src/movies/movieVideo.I @@ -69,12 +69,12 @@ frame_end() const { } //////////////////////////////////////////////////////////////////// -// Function: MovieVideo::approx_time_remaining +// Function: MovieVideo::approx_len // Access: Published // Description: Get the vertical size of the movie. //////////////////////////////////////////////////////////////////// INLINE double MovieVideo:: -approx_time_remaining() const { - return _approx_time_remaining; +approx_len() const { + return _approx_len; } diff --git a/panda/src/movies/movieVideo.cxx b/panda/src/movies/movieVideo.cxx index f58d8b313e..e63bb6be8d 100644 --- a/panda/src/movies/movieVideo.cxx +++ b/panda/src/movies/movieVideo.cxx @@ -23,14 +23,27 @@ TypeHandle MovieVideo::_type_handle; //////////////////////////////////////////////////////////////////// // Function: MovieVideo::Constructor -// Access: Protected -// Description: Normally, the MovieVideo constructor is not -// called directly; these are created by calling -// the MoviePool::load functions. Furthermore, -// MovieVideo itself is just an abstract base class. +// Access: Published +// Description: This constructor returns a null video stream --- a +// stream of plain blue frames that last 1 second each. +// To get more interesting video, you need to construct +// a subclass of this class. //////////////////////////////////////////////////////////////////// MovieVideo:: -MovieVideo() { +MovieVideo(const string &name, double len) : + Namable(name), + _size_x(1), + _size_y(1), + _approx_len(len), + _frame_start(0.0), + _frame_end(1.0) +{ + if (len <= 0.0) { + _approx_len = 1.0; + } + if (_frame_end > _approx_len) { + _frame_end = _approx_len; + } } //////////////////////////////////////////////////////////////////// @@ -49,7 +62,21 @@ MovieVideo:: //////////////////////////////////////////////////////////////////// void MovieVideo:: load_image(Texture *t) { - movies_cat.error() << "load_image: this virtual method must be overridden."; + + // The following is the implementation of the null video + // stream --- a stream of solid blue frames. Normally, + // this method will be overridden by the subclass. + + if (_ram_image==0) { + _ram_image = PTA_uchar::empty_array(4); + _ram_image.set_element(0,128); + _ram_image.set_element(1,128); + _ram_image.set_element(2,255); + _ram_image.set_element(3,255); + } + t->setup_texture(Texture::TT_2d_texture, 1, 1, 1, + Texture::T_unsigned_byte, Texture::F_rgba); + t->set_ram_image(_ram_image); } //////////////////////////////////////////////////////////////////// @@ -59,5 +86,14 @@ load_image(Texture *t) { //////////////////////////////////////////////////////////////////// void MovieVideo:: next_frame() { - movies_cat.error() << "next_frame: this virtual method must be overridden."; + + // The following is the implementation of the null video + // stream --- a stream of solid blue frames. Normally, + // this method will be overridden by the subclass. + + _frame_start = _frame_end; + _frame_end = _frame_end + 1.0; + if (_frame_end > _approx_len) { + _frame_end = _approx_len; + } } diff --git a/panda/src/movies/movieVideo.h b/panda/src/movies/movieVideo.h index bd8e6e0342..883efd69e4 100644 --- a/panda/src/movies/movieVideo.h +++ b/panda/src/movies/movieVideo.h @@ -28,15 +28,14 @@ // Description : A stream that generates a series of images. //////////////////////////////////////////////////////////////////// class EXPCL_PANDASKEL MovieVideo : public TypedWritableReferenceCount, public Namable { -protected: - MovieVideo(); PUBLISHED: + MovieVideo(const string &name, double len); INLINE int size_x() const; INLINE int size_y() const; INLINE double frame_start() const; INLINE double frame_end() const; - INLINE double approx_time_remaining() const; + INLINE double approx_len() const; virtual void load_image(Texture *t); virtual void next_frame(); @@ -48,7 +47,8 @@ protected: int _size_y; double _frame_start; double _frame_end; - double _approx_time_remaining; + double _approx_len; + PTA_uchar _ram_image; public: static TypeHandle get_class_type() { diff --git a/panda/src/movies/movies_composite.cxx b/panda/src/movies/movies_composite.cxx index 44d42c77ab..1a25017ebe 100644 --- a/panda/src/movies/movies_composite.cxx +++ b/panda/src/movies/movies_composite.cxx @@ -1,3 +1,4 @@ #include "movieVideo.cxx" #include "movieAudio.cxx" +#include "movie.cxx" #include "config_movies.cxx"