24 #include <libavcodec/avcodec.h>
25 #include <libavformat/avformat.h>
29 #define AVSEEK_SIZE 0x10000
38 _format_context(nullptr),
41 _buffer_size(ffmpeg_read_buffer_size)
62 if (ffmpeg_cat.is_debug()) {
64 <<
"ffmpeg open_vfs(" << filename <<
")\n";
71 if (vfile ==
nullptr) {
75 _in = vfile->open_read_file(
true);
82 _size = vfile->get_file_size(_in);
88 unsigned char *buffer = (
unsigned char*) av_malloc(_buffer_size);
89 _io_context = avio_alloc_context(buffer, _buffer_size, 0, (
void*)
this,
90 &read_packet,
nullptr, &seek);
92 _format_context = avformat_alloc_context();
93 _format_context->pb = _io_context;
97 avformat_open_input(&_format_context,
"",
nullptr,
nullptr);
115 Filename fname = info.get_filename();
120 if (ffmpeg_cat.is_debug()) {
122 <<
"ffmpeg open_subfile(" << fname <<
")\n";
127 _start = info.get_start();
128 _size = info.get_size();
136 unsigned char *buffer = (
unsigned char*) av_malloc(_buffer_size);
137 _io_context = avio_alloc_context(buffer, _buffer_size, 0, (
void*)
this,
138 &read_packet,
nullptr, &seek);
140 _format_context = avformat_alloc_context();
141 _format_context->pb = _io_context;
145 avformat_open_input(&_format_context, fname.c_str(),
nullptr,
nullptr);
160 if (_format_context !=
nullptr) {
161 avformat_close_input(&_format_context);
164 if (_io_context !=
nullptr) {
165 if (_io_context->buffer !=
nullptr) {
166 av_free(_io_context->buffer);
168 av_free(_io_context);
169 _io_context =
nullptr;
173 nassertv(_in !=
nullptr);
186 static bool initialized =
false;
193#if LIBAVFORMAT_VERSION_MICRO < 100 || LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
198 avformat_network_init();
201 av_log_set_callback(&log_callback);
207int FfmpegVirtualFile::
208read_packet(
void *opaque, uint8_t *buf,
int size) {
209 streampos ssize = (streampos)size;
211 std::istream *in = self->_in;
215 streampos remaining = self->_start + (streampos)self->_size - in->tellg();
216 if (remaining < ssize) {
217 if (remaining <= 0) {
224 in->read((
char *)buf, ssize);
225 streamsize gc = in->gcount();
234int64_t FfmpegVirtualFile::
235seek(
void *opaque, int64_t pos,
int whence) {
237 std::istream *in = self->_in;
241 in->seekg(self->_start + (streampos)pos, std::ios::beg);
245 in->seekg(pos, std::ios::cur);
251 in->seekg(self->_start + (streampos)self->_size + (streampos)pos, std::ios::beg);
259 <<
"Illegal parameter to seek in FfmpegVirtualFile\n";
265 return in->tellg() - self->_start;
272void FfmpegVirtualFile::
273log_callback(
void *ptr,
int level,
const char *fmt, va_list v1) {
274 NotifySeverity severity;
276 if (level <= AV_LOG_PANIC) {
280 if (level <= AV_LOG_ERROR) {
283 }
else if (level <= AV_LOG_WARNING) {
284 severity = NS_warning;
286 }
else if (level <= AV_LOG_INFO) {
289 }
else if (level <= AV_LOG_VERBOSE) {
296 if (ffmpeg_cat.is_on(severity)) {
297 static const size_t buffer_size = 4096;
298 char *buffer = (
char *)alloca(buffer_size);
299 vsnprintf(buffer, buffer_size, fmt, v1);
300 nassertv(strlen(buffer) < buffer_size);
301 ffmpeg_cat.out(severity,
true)
Enables ffmpeg to access panda's VFS.
static void register_protocol()
Should be called at startup to attach the appropriate hooks between Panda and FFMpeg.
bool open_vfs(const Filename &filename)
Opens the movie file via Panda's VFS.
bool open_subfile(const SubfileInfo &info)
Opens the movie file directly from a file on disk (does not go through the VFS).
void close()
Explicitly closes the opened file.
The name of a file, such as a texture file or an Egg file.
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
void set_binary()
Indicates that the filename represents a binary file.
This class records a particular byte sub-range within an existing file on disk.
A hierarchy of directories and files that appears to be one continuous file system,...
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
PointerTo< VirtualFile > get_file(const Filename &filename, bool status_only=false) const
Looks up the file by the indicated name in the file system.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
The abstract base class for a file or directory within the VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.