integrate with latest ffmpeg

This commit is contained in:
David Rose 2011-06-16 20:23:30 +00:00
parent 43763f0b87
commit 830bfcb056
8 changed files with 110 additions and 34 deletions

View File

@ -1229,18 +1229,25 @@ load_image_as_model(const Filename &filename) {
// Choose the dimensions of the polygon appropriately.
float left,right,top,bottom;
static const float scale = 10.0;
if (x_size > y_size) {
float scale = 10.0;
left = -scale;
right = scale;
top = (scale * y_size) / x_size;
bottom = -(scale * y_size) / x_size;
} else {
float scale = 10.0;
} else if (y_size != 0) {
left = -(scale * x_size) / y_size;
right = (scale * x_size) / y_size;
top = scale;
bottom = -scale;
} else {
framework_cat.warning()
<< "Texture size is 0 0: " << *tex << "\n";
left = -scale;
right = scale;
top = scale;
bottom = -scale;
}
PT(GeomNode) card_node = new GeomNode("card");

View File

@ -24,6 +24,10 @@
TypeHandle FFMpegTexture::_type_handle;
#if LIBAVFORMAT_VERSION_MAJOR < 53
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
#endif
////////////////////////////////////////////////////////////////////
// Function: FFMpegTexture::Constructor
// Access: Published
@ -271,9 +275,8 @@ update_frame(int frame) {
source -= source_row_width;
}
}
}
++_image_modified;
}
if (page._alpha.is_valid()) {
@ -301,8 +304,8 @@ update_frame(int frame) {
dest += dest_row_width;
source -= source_row_width;
}
}
++_image_modified;
}
}
}
@ -513,12 +516,12 @@ get_frame_data(int frame_number) {
if (frame_number > coming_from) {
// Ok, we do have to skip a few frames.
_codec_context->hurry_up = true;
_codec_context->skip_frame = AVDISCARD_BIDIR;
while (frame_number > coming_from) {
int err = read_video_frame(&packet);
if (err < 0) {
return false;
}
#if LIBAVCODEC_VERSION_INT < 3414272
avcodec_decode_video(_codec_context, _frame, &got_frame, packet.data, packet.size);
@ -528,7 +531,7 @@ get_frame_data(int frame_number) {
av_free_packet(&packet);
++coming_from;
}
_codec_context->hurry_up = false;
_codec_context->skip_frame = AVDISCARD_DEFAULT;
}
// Now we're ready to read a frame.
@ -550,7 +553,7 @@ get_frame_data(int frame_number) {
// Okay, now we're at the nearest keyframe behind our timestamp.
// Hurry up and move through frames until we find a frame just after it.
_codec_context->hurry_up = true;
_codec_context->skip_frame = AVDISCARD_BIDIR;
do {
int err = read_video_frame(&packet);
if (err < 0) {
@ -564,15 +567,15 @@ get_frame_data(int frame_number) {
}
#if LIBAVCODEC_VERSION_INT < 3414272
avcodec_decode_video(_codec_context, _frame, &got_frame, packet.data, packet.size);
avcodec_decode_video(_codec_context, _frame, &got_frame, packet.data, packet.size);
#else
avcodec_decode_video2(_codec_context, _frame, &got_frame, &packet);
avcodec_decode_video2(_codec_context, _frame, &got_frame, &packet);
#endif
av_free_packet(&packet);
} while (true);
_codec_context->hurry_up = false;
_codec_context->skip_frame = AVDISCARD_DEFAULT;
// Now near frame with Packet ready for decode (and free)
}
@ -584,9 +587,9 @@ get_frame_data(int frame_number) {
if (packet.stream_index == _stream_number) {
// Decode video frame
#if LIBAVCODEC_VERSION_INT < 3414272
avcodec_decode_video(_codec_context, _frame, &frame_finished, packet.data, packet.size);
avcodec_decode_video(_codec_context, _frame, &frame_finished, packet.data, packet.size);
#else
avcodec_decode_video2(_codec_context, _frame, &frame_finished, &packet);
avcodec_decode_video2(_codec_context, _frame, &frame_finished, &packet);
#endif
// Did we get a video frame?
@ -603,9 +606,10 @@ get_frame_data(int frame_number) {
} else {
dst_format = PIX_FMT_RGB32;
}
struct SwsContext *convert_ctx = sws_getContext(_codec_context->width, _codec_context->height,
_codec_context->pix_fmt, _codec_context->width, _codec_context->height,
dst_format, 2, NULL, NULL, NULL);
struct SwsContext *convert_ctx =
sws_getContext(_codec_context->width, _codec_context->height,
_codec_context->pix_fmt, _codec_context->width, _codec_context->height,
dst_format, SWS_FAST_BILINEAR, NULL, NULL, NULL);
nassertr(convert_ctx != NULL, false);
sws_scale(convert_ctx, _frame->data, _frame->linesize,
0, _codec_context->height, _frame_out->data, _frame_out->linesize);
@ -663,7 +667,7 @@ read(const Filename &filename) {
_stream_number = -1;
for(int i = 0; i < _format_context->nb_streams; i++) {
if ((*_format_context->streams[i]->codec).codec_type == CODEC_TYPE_VIDEO) {
if ((*_format_context->streams[i]->codec).codec_type == AVMEDIA_TYPE_VIDEO) {
_stream_number = i;
break;
}
@ -671,7 +675,7 @@ read(const Filename &filename) {
if (_stream_number == -1) {
grutil_cat.error()
<< "ffmpeg: no stream found with codec of type CODEC_TYPE_VIDEO" << endl;
<< "ffmpeg: no stream found with codec of type AVMEDIA_TYPE_VIDEO" << endl;
clear();
return false;
}
@ -796,6 +800,10 @@ clear() {
int FFMpegTexture::VideoStream::
read_video_frame(AVPacket *packet) {
int err = av_read_frame(_format_context, packet);
if (grutil_cat.is_spam()) {
grutil_cat.spam()
<< "av_read_frame() = " << err << "\n";
}
if (err < 0) {
return err;
}
@ -805,9 +813,15 @@ read_video_frame(AVPacket *packet) {
av_free_packet(packet);
err = av_read_frame(_format_context, packet);
if (grutil_cat.is_spam()) {
grutil_cat.spam()
<< "av_read_frame() = " << err << "\n";
}
if (err < 0) {
grutil_cat.debug()
<< "Got error " << err << " reading frame.\n";
if (grutil_cat.is_debug()) {
grutil_cat.debug()
<< "Got error " << err << " reading frame.\n";
}
return err;
}
}

View File

@ -23,6 +23,7 @@ extern "C" {
ConfigureDef(config_movies);
NotifyCategoryDef(movies, "");
NotifyCategoryDef(ffmpeg, "movies");
ConfigureFn(config_movies) {
init_libmovies();

View File

@ -38,6 +38,7 @@
ConfigureDecl(config_movies, EXPCL_PANDA_MOVIES, EXPTP_PANDA_MOVIES);
NotifyCategoryDecl(movies, EXPCL_PANDA_MOVIES, EXPTP_PANDA_MOVIES);
NotifyCategoryDecl(ffmpeg, EXPCL_PANDA_MOVIES, EXPTP_PANDA_MOVIES);
extern EXPCL_PANDA_MOVIES void init_libmovies();

View File

@ -22,6 +22,10 @@ extern "C" {
TypeHandle FfmpegAudioCursor::_type_handle;
#if LIBAVFORMAT_VERSION_MAJOR < 53
#define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
#endif
////////////////////////////////////////////////////////////////////
// Function: FfmpegAudioCursor::Constructor
// Access: Protected
@ -51,8 +55,8 @@ FfmpegAudioCursor(FfmpegAudio *src) :
}
// Find the audio stream
for(int i=0; i<_format_ctx->nb_streams; i++) {
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
for(int i = 0; i < (int)_format_ctx->nb_streams; i++) {
if(_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
_audio_index = i;
_audio_ctx = _format_ctx->streams[i]->codec;
_audio_timebase = av_q2d(_format_ctx->streams[i]->time_base);

View File

@ -28,6 +28,11 @@ extern "C" {
TypeHandle FfmpegVideoCursor::_type_handle;
#if LIBAVFORMAT_VERSION_MAJOR < 53
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
#endif
////////////////////////////////////////////////////////////////////
// Function: FfmpegVideoCursor::Constructor
// Access: Public
@ -58,8 +63,8 @@ FfmpegVideoCursor(FfmpegVideo *src) :
}
// Find the video stream
for(int i=0; i<_format_ctx->nb_streams; i++) {
if(_format_ctx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
for(int i = 0; i < (int)_format_ctx->nb_streams; i++) {
if(_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
_video_index = i;
_video_ctx = _format_ctx->streams[i]->codec;
_video_timebase = av_q2d(_format_ctx->streams[i]->time_base);

View File

@ -50,9 +50,13 @@ extern "C" {
static int
pandavfs_open(URLContext *h, const char *filename, int flags) {
if (flags != 0) {
movies_cat.error() << "ffmpeg is trying to write to the VFS.\n";
return -1;
if (movies_cat.is_debug()) {
movies_cat.debug()
<< "ffmpeg is trying to write to the VFS.\n";
}
// We'll allow this, but just fail any actual writes.
}
filename += 9; // Skip over "pandavfs:"
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
istream *s = vfs->open_read_file(filename, true);
@ -98,7 +102,8 @@ pandavfs_write(URLContext *h, unsigned char *buf, int size) {
#else
pandavfs_write(URLContext *h, const unsigned char *buf, int size) {
#endif
movies_cat.error() << "ffmpeg is trying to write to the VFS.\n";
movies_cat.warning()
<< "ffmpeg is trying to write to the VFS.\n";
return -1;
}
@ -177,9 +182,46 @@ register_protocol() {
protocol.url_close = pandavfs_close;
#if LIBAVFORMAT_VERSION_INT < 3415296
::register_protocol(&protocol);
#else
#elif LIBAVFORMAT_VERSION_MAJOR < 53
av_register_protocol(&protocol);
#else
av_register_protocol2(&protocol, sizeof(protocol));
#endif
// Let's also register the logging to Panda's notify callback.
av_log_set_callback(&log_callback);
}
////////////////////////////////////////////////////////////////////
// Function: FfmpegVirtualFile::log_callback
// Access: Private, Static
// Description: These callbacks are made when ffmpeg wants to write a
// log entry; it redirects into Panda's notify.
////////////////////////////////////////////////////////////////////
void FfmpegVirtualFile::
log_callback(void *ptr, int level, const char *fmt, va_list v1) {
NotifySeverity severity;
if (level <= AV_LOG_PANIC) {
severity = NS_fatal;
} else if (level <= AV_LOG_ERROR) {
severity = NS_error;
} else if (level <= AV_LOG_WARNING) {
severity = NS_warning;
} else if (level <= AV_LOG_INFO) {
severity = NS_info;
} else if (level <= AV_LOG_VERBOSE) {
severity = NS_debug;
} else /* level <= AV_LOG_DEBUG */ {
severity = NS_spam;
}
if (ffmpeg_cat.is_on(severity)) {
static const size_t buffer_size = 4096;
static char buffer[buffer_size];
vsnprintf(buffer, buffer_size, fmt, v1);
ffmpeg_cat.out(severity, true)
<< buffer;
}
}
#endif // HAVE_FFMPEG

View File

@ -17,15 +17,14 @@
#ifdef HAVE_FFMPEG
#include "config_movies.h"
#include <stdarg.h>
////////////////////////////////////////////////////////////////////
// Class : FfmpegVirtualFile
// Description : Enables ffmpeg to access panda's VFS.
//
// This class only has one public method,
// register_hooks. Once the hooks are registered,
// ffmpeg will be able to open "URLs" that look
// like this:
// Once register_protocol() is called, ffmpeg will be
// able to open "URLs" that look like this:
//
// pandavfs:/c/mygame/foo.avi
//
@ -33,6 +32,9 @@
class EXPCL_PANDA_MOVIES FfmpegVirtualFile {
public:
static void register_protocol();
private:
static void log_callback(void *ptr, int level, const char *fmt, va_list v1);
};
#include "ffmpegVirtualFile.I"