Dummy movies now implemented.

This commit is contained in:
Josh Yelon 2007-07-04 08:06:06 +00:00
parent ab69230775
commit 964201d713
11 changed files with 321 additions and 51 deletions

View File

@ -44,5 +44,6 @@ init_libmovies() {
MovieVideo::init_type();
MovieAudio::init_type();
Movie::init_type();
}

55
panda/src/movies/movie.I Normal file
View File

@ -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;
}

View File

@ -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);
}

74
panda/src/movies/movie.h Normal file
View File

@ -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

View File

@ -49,16 +49,33 @@ samples_read() const {
}
////////////////////////////////////////////////////////////////////
// Function: MovieAudio::approx_time_remaining
// 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.
// Function: MovieAudio::skip_samples
// Access: Published
// Description: Skip audio samples from the stream. This is mostly
// for debugging purposes.
////////////////////////////////////////////////////////////////////
INLINE double MovieAudio::
approx_time_remaining() const {
return _approx_time_remaining;
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 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_len() const {
return _approx_len;
}

View File

@ -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<n * _channels; i++) {
// This is the null implementation, which generates pure silence.
// Normally, this method will be overridden by a subclass.
if (n < 0) {
return 0;
}
// Convert length to an integer sample count.
// This could generate an integer-overflow, in this case,
// just set the integer length to maxint (74 hrs).
int ilen;
if (_approx_len < 268000.0) {
ilen = _approx_len * 8000.0;
} else {
ilen = 0x7FFFFFFF;
}
// Generate and return samples.
int remain = ilen - _samples_read;
if (n > remain) {
n = remain;
}
if (data) {
for (int i=0; i<n; i++) {
data[i] = 0;
}
}
_samples_read += n;
return n;
}
////////////////////////////////////////////////////////////////////
// Function: MovieAudio::skip_samples
// Access: Public, Virtual
// Description: Skip audio samples from the stream. This is mostly
// for debugging purposes.
////////////////////////////////////////////////////////////////////
int MovieAudio::
skip_samples(int n) {
nassertr(n > 0, 0);
PN_int16 *data = new PN_int16[n];
int res = read_samples(n, data);
delete data;
return res;
}

View File

@ -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() {

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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() {

View File

@ -1,3 +1,4 @@
#include "movieVideo.cxx"
#include "movieAudio.cxx"
#include "movie.cxx"
#include "config_movies.cxx"