mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Getting closer to functional
This commit is contained in:
parent
299a3b4ae1
commit
b1d7446c27
@ -24,6 +24,7 @@
|
||||
#include "config_gobj.h"
|
||||
#include "config_grutil.h"
|
||||
#include "bamCacheRecord.h"
|
||||
#include "math.h"
|
||||
|
||||
TypeHandle MovieTexture::_type_handle;
|
||||
|
||||
@ -48,7 +49,9 @@ MovieTexture::
|
||||
MovieTexture(PT(MovieVideo) video) :
|
||||
Texture(video->get_name())
|
||||
{
|
||||
do_load_one(video, NULL, 0);
|
||||
// It is necessary to copy the video, because
|
||||
// the cull thread will be accessing it.
|
||||
do_load_one(video->make_copy(), NULL, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -57,7 +60,14 @@ MovieTexture(PT(MovieVideo) video) :
|
||||
// Description: xxx
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MovieTexture::CData::
|
||||
CData()
|
||||
CData() :
|
||||
_video_width(1),
|
||||
_video_height(1),
|
||||
_video_length(1.0),
|
||||
_playing(false),
|
||||
_clock(0.0),
|
||||
_play_rate(1.0),
|
||||
_loop_count(1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -70,7 +80,12 @@ MovieTexture::CData::
|
||||
CData(const CData ©) :
|
||||
_pages(copy._pages),
|
||||
_video_width(copy._video_width),
|
||||
_video_height(copy._video_height)
|
||||
_video_height(copy._video_height),
|
||||
_video_length(copy._video_length),
|
||||
_playing(false),
|
||||
_clock(0.0),
|
||||
_play_rate(1.0),
|
||||
_loop_count(1.0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -120,6 +135,7 @@ MovieTexture(const MovieTexture ©) :
|
||||
cdata->_pages[i]._alpha = color[i]->make_copy();
|
||||
}
|
||||
}
|
||||
recalculate_image_properties(cdata);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,27 +199,31 @@ VideoPage() :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
recalculate_image_properties(CDWriter &cdata) {
|
||||
int x_max = 0;
|
||||
int y_max = 0;
|
||||
int x_max = 1;
|
||||
int y_max = 1;
|
||||
bool alpha = false;
|
||||
double len = 0.0;
|
||||
|
||||
for (int i=0; i<_z_size; i++) {
|
||||
MovieVideo *t = cdata->_pages[i]._color;
|
||||
if (t) {
|
||||
if (t->size_x() > x_max) x_max = t->size_x();
|
||||
if (t->size_y() > y_max) y_max = t->size_y();
|
||||
if (t->length() > len) len = t->length();
|
||||
if (t->get_num_components() == 4) alpha=true;
|
||||
}
|
||||
t = cdata->_pages[i]._alpha;
|
||||
if (t) {
|
||||
if (t->size_x() > x_max) x_max = t->size_x();
|
||||
if (t->size_y() > y_max) y_max = t->size_y();
|
||||
if (t->length() > len) len = t->length();
|
||||
alpha = true;
|
||||
}
|
||||
}
|
||||
|
||||
cdata->_video_width = x_max;
|
||||
cdata->_video_height = y_max;
|
||||
cdata->_video_length = len;
|
||||
|
||||
if (get_texture_type() == TT_cube_map) {
|
||||
// Texture must be square.
|
||||
@ -269,9 +289,13 @@ do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
_primary_file_num_channels = primary_file_num_channels;
|
||||
_alpha_file_channel = alpha_file_channel;
|
||||
|
||||
return do_load_one(color, alpha, z);
|
||||
if (!do_load_one(color, alpha, z)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
set_loaded_from_image();
|
||||
set_loop(true);
|
||||
play();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -287,7 +311,6 @@ do_load_one(PT(MovieVideo) color, PT(MovieVideo) alpha, int z) {
|
||||
cdata->_pages.resize(z+1);
|
||||
cdata->_pages[z]._color = color;
|
||||
cdata->_pages[z]._alpha = alpha;
|
||||
cdata->_pages[z]._base_clock = ClockObject::get_global_clock()->get_frame_time();
|
||||
recalculate_image_properties(cdata);
|
||||
}
|
||||
|
||||
@ -353,25 +376,36 @@ has_cull_callback() const {
|
||||
bool MovieTexture::
|
||||
cull_callback(CullTraverser *, const CullTraverserData &) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
// Calculate the cursor position modulo the length of the movie.
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
double clock = cdata->_clock;
|
||||
if (cdata->_playing) {
|
||||
clock += now * cdata->_play_rate;
|
||||
}
|
||||
double offset;
|
||||
if (clock >= cdata->_video_length * cdata->_loop_count) {
|
||||
offset = cdata->_video_length;
|
||||
} else {
|
||||
offset = fmod(clock, cdata->_video_length);
|
||||
}
|
||||
|
||||
for (int i=0; i<((int)(cdata->_pages.size())); i++) {
|
||||
double delta = now - cdata->_pages[i]._base_clock;
|
||||
MovieVideo *color = cdata->_pages[i]._color;
|
||||
MovieVideo *alpha = cdata->_pages[i]._alpha;
|
||||
if (color) {
|
||||
double offset = delta;
|
||||
if ((offset < color->last_start()) || (offset >= color->next_start())) {
|
||||
if (alpha) {
|
||||
color->fetch_into_texture_rgb(offset, (MovieTexture*)this, i);
|
||||
} else {
|
||||
color->fetch_into_texture(offset, (MovieTexture*)this, i);
|
||||
}
|
||||
if (color && alpha) {
|
||||
if ((offset >= color->next_start())||
|
||||
((offset < color->last_start()) && (color->can_seek()))) {
|
||||
color->fetch_into_texture_rgb(offset, (MovieTexture*)this, i);
|
||||
}
|
||||
}
|
||||
if (alpha) {
|
||||
double offset = delta;
|
||||
if ((offset < alpha->last_start()) || (offset >= alpha->next_start())) {
|
||||
alpha->fetch_into_texture_alpha(offset, (MovieTexture*)this, i, _alpha_file_channel);
|
||||
if ((offset >= alpha->next_start())||
|
||||
((offset < alpha->last_start()) && (alpha->can_seek()))) {
|
||||
alpha->fetch_into_texture_alpha(offset, (MovieTexture*)this, i, _alpha_file_channel);
|
||||
}
|
||||
} else if (color) {
|
||||
if ((offset >= color->next_start())||
|
||||
((offset < color->last_start()) && (color->can_seek()))) {
|
||||
color->fetch_into_texture(offset, (MovieTexture*)this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -404,3 +438,186 @@ reload_ram_image() {
|
||||
// Therefore, this is not needed.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::restart
|
||||
// Access: Published
|
||||
// Description: Start playing the movie from where it was last
|
||||
// paused. Has no effect if the movie is not paused,
|
||||
// or if the movie's cursor is already at the end.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
restart() {
|
||||
CDWriter cdata(_cycler);
|
||||
if (!cdata->_playing) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
cdata->_clock = cdata->_clock - (now * cdata->_play_rate);
|
||||
cdata->_playing = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::stop
|
||||
// Access: Published
|
||||
// Description: Stops a currently playing or looping movie right
|
||||
// where it is. The movie's cursor remains frozen at
|
||||
// the point where it was stopped.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
stop() {
|
||||
CDWriter cdata(_cycler);
|
||||
if (cdata->_playing) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
cdata->_clock = cdata->_clock + (now * cdata->_play_rate);
|
||||
cdata->_playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::play
|
||||
// Access: Published
|
||||
// Description: Plays the movie from the beginning.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
play() {
|
||||
CDWriter cdata(_cycler);
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
cdata->_clock = 0.0 - (now * cdata->_play_rate);
|
||||
cdata->_playing = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::set_time
|
||||
// Access: Published
|
||||
// Description: Sets the movie's cursor. If the movie's loop count
|
||||
// count is greater than one, then its length is
|
||||
// effectively multiplied for the purposes of this
|
||||
// function. In other words, you can set a value in
|
||||
// the range 0.0 to (length * loopcount).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
set_time(double t) {
|
||||
CDWriter cdata(_cycler);
|
||||
t = min(cdata->_video_length * cdata->_loop_count, max(0.0, t));
|
||||
if (cdata->_playing) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
cdata->_clock = t - (now * cdata->_play_rate);
|
||||
} else {
|
||||
cdata->_clock = t;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::get_time
|
||||
// Access: Published
|
||||
// Description: Returns the current value of the movie's cursor.
|
||||
// If the movie's loop count is greater than one, then
|
||||
// its length is effectively multiplied for the
|
||||
// purposes of this function. In other words,
|
||||
// the return value will be in the range 0.0
|
||||
// to (length * loopcount).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double MovieTexture::
|
||||
get_time() const {
|
||||
CDReader cdata(_cycler);
|
||||
double clock = cdata->_clock;
|
||||
if (cdata->_playing) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
clock += (now * cdata->_play_rate);
|
||||
}
|
||||
return min(cdata->_video_length * cdata->_loop_count, clock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::set_loop
|
||||
// Access: Published
|
||||
// Description: If true, sets the movie's loop count to 1 billion.
|
||||
// If false, sets the movie's loop count to one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
set_loop(bool loop) {
|
||||
CDWriter cdata(_cycler);
|
||||
if (loop) {
|
||||
cdata->_loop_count = 1000000000;
|
||||
} else {
|
||||
cdata->_loop_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::get_loop
|
||||
// Access: Published
|
||||
// Description: Returns true if the movie's loop count is not equal
|
||||
// to one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MovieTexture::
|
||||
get_loop() const {
|
||||
CDReader cdata(_cycler);
|
||||
return (cdata->_loop_count != 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::set_loop_count
|
||||
// Access: Published
|
||||
// Description: Sets the movie's loop count to the desired value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
set_loop_count(int n) {
|
||||
CDWriter cdata(_cycler);
|
||||
if (n < 1) n = 1;
|
||||
if (n > 1000000000) n = 1000000000;
|
||||
cdata->_loop_count = n;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::get_loop_count
|
||||
// Access: Published
|
||||
// Description: Returns the movie's loop count.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int MovieTexture::
|
||||
get_loop_count() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_loop_count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::set_play_rate
|
||||
// Access: Published
|
||||
// Description: Sets the movie's play-rate. This is the speed at
|
||||
// which the movie's cursor advances. The default is
|
||||
// to advance 1.0 movie-seconds per real-time second.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieTexture::
|
||||
set_play_rate(double rate) {
|
||||
CDWriter cdata(_cycler);
|
||||
if (cdata->_playing) {
|
||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||
cdata->_clock += (now * cdata->_play_rate);
|
||||
cdata->_play_rate = rate;
|
||||
cdata->_clock -= (now * cdata->_play_rate);
|
||||
} else {
|
||||
cdata->_play_rate = rate;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::get_play_rate
|
||||
// Access: Published
|
||||
// Description: Gets the movie's play-rate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double MovieTexture::
|
||||
get_play_rate() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_play_rate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieTexture::is_playing
|
||||
// Access: Published
|
||||
// Description: Returns true if the movie's cursor is advancing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool MovieTexture::
|
||||
is_playing() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_playing;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,19 @@ PUBLISHED:
|
||||
INLINE int get_video_height() const;
|
||||
INLINE LVecBase2f get_tex_scale() const;
|
||||
|
||||
void restart();
|
||||
void stop();
|
||||
void play();
|
||||
void set_time(double t);
|
||||
double get_time() const;
|
||||
void set_loop(bool enable);
|
||||
bool get_loop() const;
|
||||
void set_loop_count(int count);
|
||||
int get_loop_count() const;
|
||||
void set_play_rate(double play_rate);
|
||||
double get_play_rate() const;
|
||||
bool is_playing() const;
|
||||
|
||||
public:
|
||||
static PT(Texture) make_texture();
|
||||
virtual bool has_cull_callback() const;
|
||||
@ -62,7 +75,6 @@ protected:
|
||||
VideoPage();
|
||||
PT(MovieVideo) _color;
|
||||
PT(MovieVideo) _alpha;
|
||||
double _base_clock;
|
||||
};
|
||||
|
||||
typedef pvector<VideoPage> Pages;
|
||||
@ -79,6 +91,12 @@ protected:
|
||||
Pages _pages;
|
||||
int _video_width;
|
||||
int _video_height;
|
||||
double _video_length;
|
||||
|
||||
double _clock;
|
||||
bool _playing;
|
||||
int _loop_count;
|
||||
double _play_rate;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
|
@ -60,12 +60,12 @@ FfmpegVideo(const Filename &name) :
|
||||
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
|
||||
_video_index = i;
|
||||
_video_ctx = _format_ctx->streams[i]->codec;
|
||||
_video_timebase = av_q2d(_video_ctx->time_base);
|
||||
_video_timebase = av_q2d(_format_ctx->streams[i]->time_base);
|
||||
}
|
||||
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
|
||||
_audio_index = i;
|
||||
_audio_ctx = _format_ctx->streams[i]->codec;
|
||||
_audio_timebase = av_q2d(_audio_ctx->time_base);
|
||||
_audio_timebase = av_q2d(_format_ctx->streams[i]->time_base);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ FfmpegVideo(const Filename &name) :
|
||||
|
||||
_size_x = _video_ctx->width;
|
||||
_size_y = _video_ctx->height;
|
||||
_num_components = (_video_ctx->pix_fmt==PIX_FMT_RGBA32) ? 4:3;
|
||||
_num_components = 3; // Don't know how to implement RGBA movies yet.
|
||||
|
||||
if (_audio_ctx) {
|
||||
AVCodec *pAudioCodec=avcodec_find_decoder(_audio_ctx->codec_id);
|
||||
@ -103,7 +103,7 @@ FfmpegVideo(const Filename &name) :
|
||||
|
||||
_length = (_format_ctx->duration * 1.0) / AV_TIME_BASE;
|
||||
_can_seek = true;
|
||||
_can_seek_zero = true;
|
||||
_can_seek_fast = true;
|
||||
|
||||
memset(_time_corrections, 0, sizeof(_time_corrections));
|
||||
|
||||
@ -135,6 +135,7 @@ FfmpegVideo::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FfmpegVideo::
|
||||
cleanup() {
|
||||
_frame_out->data[0] = 0;
|
||||
if (_format_ctx) {
|
||||
av_close_input_file(_format_ctx);
|
||||
_format_ctx = 0;
|
||||
@ -217,12 +218,13 @@ read_ahead() {
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "Audio: " << dts << " " << real << "\n";
|
||||
cerr << "Audio: " << pkt.dts << "(" << dts << ") " << real << "\n";
|
||||
}
|
||||
|
||||
av_free_packet(&pkt);
|
||||
}
|
||||
|
||||
cerr << "Synthesized dummy frame.\n";
|
||||
_next_start = _next_start + 1.0;
|
||||
}
|
||||
|
||||
@ -232,11 +234,13 @@ read_ahead() {
|
||||
// Description: See MovieVideo::fetch_into_buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void FfmpegVideo::
|
||||
fetch_into_buffer(double time, unsigned char *data, bool rgba) {
|
||||
fetch_into_buffer(double time, unsigned char *data, bool bgra) {
|
||||
|
||||
// If there was an error at any point, fetch black.
|
||||
if (_format_ctx==0) {
|
||||
memset(data,0,size_x()*size_y()*(rgba?4:3));
|
||||
memset(data,0,size_x()*size_y()*(bgra?4:3));
|
||||
_last_start = _next_start;
|
||||
_next_start += 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -244,13 +248,15 @@ fetch_into_buffer(double time, unsigned char *data, bool rgba) {
|
||||
nassertv(ctx->width == size_x());
|
||||
nassertv(ctx->height == size_y());
|
||||
|
||||
if (rgba) {
|
||||
avpicture_fill((AVPicture *)_frame_out, data, PIX_FMT_RGBA32, ctx->width, ctx->height);
|
||||
img_convert((AVPicture *)_frame_out, PIX_FMT_RGBA32,
|
||||
if (bgra) {
|
||||
_frame_out->data[0] = data + ((ctx->height-1) * ctx->width * 4);
|
||||
_frame_out->linesize[0] = ctx->width * -4;
|
||||
img_convert((AVPicture *)_frame_out, PIX_FMT_BGRA,
|
||||
(AVPicture *)_frame, ctx->pix_fmt, ctx->width, ctx->height);
|
||||
} else {
|
||||
avpicture_fill((AVPicture *)_frame_out, data, PIX_FMT_RGB24, ctx->width, ctx->height);
|
||||
img_convert((AVPicture *)_frame_out, PIX_FMT_RGB24,
|
||||
_frame_out->data[0] = data + ((ctx->height-1) * ctx->width * 3);
|
||||
_frame_out->linesize[0] = ctx->width * -3;
|
||||
img_convert((AVPicture *)_frame_out, PIX_FMT_BGR24,
|
||||
(AVPicture *)_frame, ctx->pix_fmt, ctx->width, ctx->height);
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,8 @@ InkblotVideo(int x, int y, int fps) :
|
||||
_cells2 = new unsigned char[padx * pady];
|
||||
memset(_cells, 255, padx * pady);
|
||||
memset(_cells2, 255, padx * pady);
|
||||
|
||||
_can_seek = true;
|
||||
_can_seek_fast = false;
|
||||
_frames_read = 0;
|
||||
}
|
||||
|
||||
@ -93,12 +94,12 @@ InkblotVideo::
|
||||
// Description: See MovieVideo::fetch_into_buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InkblotVideo::
|
||||
fetch_into_buffer(double time, unsigned char *data, bool rgba) {
|
||||
fetch_into_buffer(double time, unsigned char *data, bool bgra) {
|
||||
|
||||
int padx = size_x() + 2;
|
||||
int pady = size_y() + 2;
|
||||
|
||||
if ((time == 0.0)&&(_next_start != 0.0)) {
|
||||
if (time < _next_start) {
|
||||
// Rewind to beginning.
|
||||
memset(_cells, 255, padx * pady);
|
||||
memset(_cells2, 255, padx * pady);
|
||||
@ -139,10 +140,10 @@ fetch_into_buffer(double time, unsigned char *data, bool rgba) {
|
||||
color &c1 = colormap[(val>>4)+0];
|
||||
color &c2 = colormap[(val>>4)+1];
|
||||
int lerp = val & 15;
|
||||
data[0] = (c1.r * (16-lerp) + c2.r * lerp) / 16;
|
||||
data[0] = (c1.b * (16-lerp) + c2.b * lerp) / 16;
|
||||
data[1] = (c1.g * (16-lerp) + c2.g * lerp) / 16;
|
||||
data[2] = (c1.b * (16-lerp) + c2.b * lerp) / 16;
|
||||
if (rgba) {
|
||||
data[2] = (c1.r * (16-lerp) + c2.r * lerp) / 16;
|
||||
if (bgra) {
|
||||
data[3] = 255;
|
||||
data += 4;
|
||||
} else {
|
||||
|
@ -76,7 +76,14 @@ length() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieAudio::can_seek
|
||||
// Access: Public
|
||||
// Description: See method 'seek' for an explanation.
|
||||
// Description: Returns true if the movie can seek. If this is
|
||||
// true, seeking is still not guaranteed to be fast:
|
||||
// for some movies, seeking is implemented by rewinding
|
||||
// to the beginning and then fast-forwarding to the
|
||||
// desired location. Even if the movie cannot seek,
|
||||
// the seek method can still advance to an arbitrary
|
||||
// location by reading samples and discarding them.
|
||||
// However, to move backward, can_seek must return true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool MovieAudio::
|
||||
can_seek() const {
|
||||
@ -84,13 +91,13 @@ can_seek() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieAudio::can_seek_zero
|
||||
// Function: MovieAudio::can_seek_fast
|
||||
// Access: Public
|
||||
// Description: See method 'seek' for an explanation.
|
||||
// Description: Returns true if seek operations are constant time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool MovieAudio::
|
||||
can_seek_zero() const {
|
||||
return _can_seek_zero;
|
||||
can_seek_fast() const {
|
||||
return _can_seek_fast;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -35,7 +35,7 @@ MovieAudio(const string &name) :
|
||||
_audio_channels(1),
|
||||
_length(1.0E10),
|
||||
_can_seek(true),
|
||||
_can_seek_zero(true),
|
||||
_can_seek_fast(true),
|
||||
_aborted(false),
|
||||
_samples_read(0)
|
||||
{
|
||||
@ -77,22 +77,26 @@ read_samples(int n, PN_int16 *data) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieAudio::seek
|
||||
// Access: Published, Virtual
|
||||
// Description: Skips to the specified point in the movie. After
|
||||
// Description: Skips to the specified sample number. After
|
||||
// calling seek, samples_read will be equal to the
|
||||
// offset times the sample rate.
|
||||
// specified value. If the movie reports that it
|
||||
// cannot seek, then this method can still advance
|
||||
// by reading samples and discarding them. However,
|
||||
// to move backward, can_seek must be true.
|
||||
//
|
||||
// If the movie reports that it can_seek, it doesn't
|
||||
// mean that it can do so quickly. It may have to
|
||||
// rewind the movie and then fast forward to the
|
||||
// desired location. Only if can_seek_fast returns
|
||||
// true can seek operations be done in constant time.
|
||||
//
|
||||
// Seeking may not be precise, because AVI files
|
||||
// often have inaccurate indices. However, it is
|
||||
// usually pretty close (ie, 0.05 seconds).
|
||||
//
|
||||
// It is an error to call seek with a nonzero offset
|
||||
// if can_seek() reports false. It is an error to
|
||||
// call seek with a zero offset if can_seek_zero
|
||||
// reports false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieAudio::
|
||||
seek(double offset) {
|
||||
_samples_read = offset * audio_rate();
|
||||
seek(int sr) {
|
||||
_samples_read = sr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -45,11 +45,11 @@ PUBLISHED:
|
||||
INLINE int audio_channels() const;
|
||||
INLINE double length() const;
|
||||
INLINE bool can_seek() const;
|
||||
INLINE bool can_seek_zero() const;
|
||||
INLINE bool can_seek_fast() const;
|
||||
INLINE bool aborted() const;
|
||||
INLINE int samples_read() const;
|
||||
INLINE void skip_samples(int n);
|
||||
virtual void seek(double offset);
|
||||
virtual void seek(int sr);
|
||||
virtual PT(MovieAudio) make_copy() const;
|
||||
static PT(MovieAudio) load(const Filename &name);
|
||||
|
||||
@ -61,7 +61,7 @@ protected:
|
||||
int _audio_channels;
|
||||
double _length;
|
||||
bool _can_seek;
|
||||
bool _can_seek_zero;
|
||||
bool _can_seek_fast;
|
||||
bool _aborted;
|
||||
int _samples_read;
|
||||
|
||||
|
@ -86,7 +86,14 @@ length() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieVideo::can_seek
|
||||
// Access: Published
|
||||
// Description: See explanation in fetch_to_buffer.
|
||||
// Description: Returns true if the movie can seek. If this is
|
||||
// true, seeking is still not guaranteed to be fast:
|
||||
// for some movies, seeking is implemented by rewinding
|
||||
// to the beginning and then fast-forwarding to the
|
||||
// desired location. Even if the movie cannot seek,
|
||||
// the fetch methods can still advance to an arbitrary
|
||||
// location by reading frames and discarding them.
|
||||
// However, to move backward, can_seek must return true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool MovieVideo::
|
||||
can_seek() const {
|
||||
@ -94,13 +101,13 @@ can_seek() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MovieVideo::can_seek_zero
|
||||
// Function: MovieVideo::can_seek_fast
|
||||
// Access: Published
|
||||
// Description: See explanation in fetch_to_buffer.
|
||||
// Description: Returns true if seek operations are constant time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool MovieVideo::
|
||||
can_seek_zero() const {
|
||||
return _can_seek_zero;
|
||||
can_seek_fast() const {
|
||||
return _can_seek_fast;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -38,7 +38,7 @@ MovieVideo(const string &name) :
|
||||
_num_components(3),
|
||||
_length(1.0E10),
|
||||
_can_seek(true),
|
||||
_can_seek_zero(true),
|
||||
_can_seek_fast(true),
|
||||
_aborted(false),
|
||||
_last_start(-1.0),
|
||||
_next_start(0.0)
|
||||
@ -242,19 +242,22 @@ fetch_into_texture_rgb(double time, Texture *t, int page) {
|
||||
// Function: MovieVideo::fetch_into_buffer
|
||||
// Access: Published, Virtual
|
||||
// Description: Reads the specified video frame into the supplied
|
||||
// RGB8 or RGBA8 buffer. The frame's begin and end
|
||||
// BGR or BGRA buffer. The frame's begin and end
|
||||
// times are stored in last_start and next_start.
|
||||
//
|
||||
// You may always specify a timestamp greater than or
|
||||
// equal to next_start --- ie, read forward through the
|
||||
// movie. If the movie reports that it can_seek_zero,
|
||||
// you may also specify a timestamp of 0.0 --- ie,
|
||||
// rewind the movie. If the movie reports that it
|
||||
// can_seek, you may specify any timestamp. It is
|
||||
// generally much faster to read frames sequentially.
|
||||
// If the movie reports that it can_seek, you may
|
||||
// also specify a timestamp less than next_start.
|
||||
// Otherwise, you may only specify a timestamp
|
||||
// greater than or equal to next_start.
|
||||
//
|
||||
// If the movie reports that it can_seek, it doesn't
|
||||
// mean that it can do so quickly. It may have to
|
||||
// rewind the movie and then fast forward to the
|
||||
// desired location. Only if can_seek_fast returns
|
||||
// true can it seek rapidly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MovieVideo::
|
||||
fetch_into_buffer(double time, unsigned char *data, bool rgba) {
|
||||
fetch_into_buffer(double time, unsigned char *data, bool bgra) {
|
||||
|
||||
// The following is the implementation of the null video stream, ie,
|
||||
// a stream of blinking red and blue frames. This method must be
|
||||
@ -272,7 +275,7 @@ fetch_into_buffer(double time, unsigned char *data, bool rgba) {
|
||||
data[1] = 128;
|
||||
data[2] = 255;
|
||||
}
|
||||
if (rgba) {
|
||||
if (bgra) {
|
||||
data[3] = 255;
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public
|
||||
INLINE int get_num_components() const;
|
||||
INLINE int length() const;
|
||||
INLINE bool can_seek() const;
|
||||
INLINE bool can_seek_zero() const;
|
||||
INLINE bool can_seek_fast() const;
|
||||
INLINE bool aborted() const;
|
||||
INLINE double last_start() const;
|
||||
INLINE double next_start() const;
|
||||
@ -57,7 +57,7 @@ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public
|
||||
static PT(MovieVideo) load(const Filename &name);
|
||||
|
||||
public:
|
||||
virtual void fetch_into_buffer(double time, unsigned char *block, bool rgba);
|
||||
virtual void fetch_into_buffer(double time, unsigned char *block, bool bgra);
|
||||
|
||||
private:
|
||||
void allocate_conversion_buffer();
|
||||
@ -69,7 +69,7 @@ class EXPCL_PANDA_MOVIES MovieVideo : public TypedWritableReferenceCount, public
|
||||
int _num_components;
|
||||
double _length;
|
||||
bool _can_seek;
|
||||
bool _can_seek_zero;
|
||||
bool _can_seek_fast;
|
||||
bool _aborted;
|
||||
double _last_start;
|
||||
double _next_start;
|
||||
|
Loading…
x
Reference in New Issue
Block a user