diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-21 22:49:44 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-21 22:49:44 +0000 |
commit | a6fb2d6387b558db727f7c3d421cde0e1e092aa7 (patch) | |
tree | d82af5b1f6c8429eb0e748c6c906b373002cfda4 /media/base/media_posix.cc | |
parent | 6892d42b987764bc802c3782ad47e877e8e56da7 (diff) | |
download | chromium_src-a6fb2d6387b558db727f7c3d421cde0e1e092aa7.zip chromium_src-a6fb2d6387b558db727f7c3d421cde0e1e092aa7.tar.gz chromium_src-a6fb2d6387b558db727f7c3d421cde0e1e092aa7.tar.bz2 |
Hacked up delay load code for ffmpeg in posix systems. This is
a temporary solution. We need to find a more sustainable way to
do this.
Review URL: http://codereview.chromium.org/87018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14150 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/media_posix.cc')
-rw-r--r--[-rwxr-xr-x] | media/base/media_posix.cc | 214 |
1 files changed, 213 insertions, 1 deletions
diff --git a/media/base/media_posix.cc b/media/base/media_posix.cc index 664f9f8..331a143 100755..100644 --- a/media/base/media_posix.cc +++ b/media/base/media_posix.cc @@ -4,15 +4,227 @@ #include "media/base/media.h" +#include <string> + +#include <dlfcn.h> + +#include "base/file_path.h" #include "base/logging.h" #include "base/path_service.h" +#include "media/filters/ffmpeg_common.h" + +// We create stub references to dynamically loaded functions in ffmpeg +// for ease of linking. +// +// TODO(ajwong): We need to find a more maintainable way to have this work. +// Also, this code should really be in the ffmpeg wrapper, and not here +// in the media level. The concept of "weak symbols" looks like it might +// be promising, but I don't quite understand it yet. +extern "C" { + +void (*avcodec_init_ptr)(void) = NULL; +void avcodec_init(void) { + avcodec_init_ptr(); +} + +AVCodec* (*avcodec_find_decoder_ptr)(enum CodecID id) = NULL; +AVCodec* avcodec_find_decoder(enum CodecID id) { + return avcodec_find_decoder_ptr(id); +} + +int (*avcodec_thread_init_ptr)(AVCodecContext* s, int thread_count) = NULL; +int avcodec_thread_init(AVCodecContext* s, int thread_count) { + return avcodec_thread_init_ptr(s, thread_count); +} + +int (*avcodec_open_ptr)(AVCodecContext* avctx, AVCodec* codec) = NULL; +int avcodec_open(AVCodecContext* avctx, AVCodec* codec) { + return avcodec_open_ptr(avctx, codec); +} + +AVFrame* (*avcodec_alloc_frame_ptr)(void) = NULL; +AVFrame* avcodec_alloc_frame(void) { + return avcodec_alloc_frame_ptr(); +} + +int (*avcodec_decode_audio2_ptr)(AVCodecContext* avctx, int16_t* samples, + int* frame_size_ptr, const uint8_t* buf, + int buf_size) = NULL; +int avcodec_decode_audio2(AVCodecContext* avctx, int16_t* samples, + int* frame_size_ptr, + const uint8_t* buf, int buf_size) { + + return avcodec_decode_audio2_ptr(avctx, samples, frame_size_ptr, buf, + buf_size); +} + + +int (*avcodec_decode_video_ptr)(AVCodecContext* avctx, AVFrame* picture, + int* got_picture_ptr, const uint8_t* buf, + int buf_size) = NULL; +int avcodec_decode_video(AVCodecContext* avctx, AVFrame* picture, + int* got_picture_ptr, const uint8_t* buf, + int buf_size) { + return avcodec_decode_video_ptr(avctx, picture, got_picture_ptr, buf, + buf_size); +} + + +void (*av_register_all_ptr)(void); +void av_register_all(void) { + av_register_all_ptr(); +} + +int (*av_open_input_file_ptr)(AVFormatContext** ic_ptr, const char* filename, + AVInputFormat* fmt, int buf_size, + AVFormatParameters* ap) = NULL; +int av_open_input_file(AVFormatContext** ic_ptr, const char* filename, + AVInputFormat* fmt, int buf_size, + AVFormatParameters* ap) { + return av_open_input_file_ptr(ic_ptr, filename, fmt, buf_size, ap); +} + +int (*av_find_stream_info_ptr)(AVFormatContext* ic) = NULL; +int av_find_stream_info(AVFormatContext* ic) { + return av_find_stream_info_ptr(ic); +} + +int (*av_read_frame_ptr)(AVFormatContext* s, AVPacket* pkt) = NULL; +int av_read_frame(AVFormatContext* s, AVPacket* pkt) { + return av_read_frame_ptr(s, pkt); +} + + +void* (*av_malloc_ptr)(unsigned int size) = NULL; +void* av_malloc(unsigned int size) { + return av_malloc_ptr(size); +} + +} // extern "C" + namespace media { +namespace { + +enum FFmpegDSOKeys { + FILE_LIBAVCODEC, // full path to libavcodec media decoding library. + FILE_LIBAVFORMAT, // full path to libavformat media parsing library. + FILE_LIBAVUTIL, // full path to libavutil media utility library. +}; + +// Retrieves the DLLName for the given key. +std::string GetDSOName(FFmpegDSOKeys dso_key) { + // TODO(ajwong): Do we want to lock to a specific ffmpeg version? + // TODO(port): These library names are incorrect for mac. We need .dynlib + // suffixes. + switch (dso_key) { + case FILE_LIBAVCODEC: + return FILE_PATH_LITERAL("libavcodec.so.52"); + case FILE_LIBAVFORMAT: + return FILE_PATH_LITERAL("libavformat.so.52"); + case FILE_LIBAVUTIL: + return FILE_PATH_LITERAL("libavutil.so.50"); + default: + LOG(DFATAL) << "Invalid DSO key requested: " << dso_key; + return FILE_PATH_LITERAL(""); + } +} + +} // namespace + // Attempts to initialize the media library (loading DLLs, DSOs, etc.). // Returns true if everything was successfully initialized, false otherwise. bool InitializeMediaLibrary(const FilePath& module_dir) { - NOTIMPLEMENTED(); + // TODO(ajwong): We need error resolution. + FFmpegDSOKeys path_keys[] = { + FILE_LIBAVCODEC, + FILE_LIBAVFORMAT, + FILE_LIBAVUTIL + }; + void* libs[arraysize(path_keys)] = {}; + for (size_t i = 0; i < arraysize(path_keys); ++i) { + FilePath path = module_dir.Append(GetDSOName(path_keys[i])); + libs[i] = dlopen(path.value().c_str(), RTLD_LAZY); + if (!libs[i]) + break; + } + + // Check that we loaded all libraries successfully. We only need to check the + // last array element because the loop above breaks on any failure. + if (libs[arraysize(libs)-1] == NULL) { + // Free any loaded libraries if we weren't successful. + for (size_t i = 0; i < arraysize(libs) && libs[i] != NULL; ++i) { + dlclose(libs[i]); + libs[i] = NULL; // Just to be safe. + } + return false; + } + + // TODO(ajwong): Extract this to somewhere saner, and hopefully + // autogenerate the bindings from the .def files. Having all this + // code here is incredibly ugly. + avcodec_init_ptr = + reinterpret_cast<void(*)(void)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_init")); + avcodec_find_decoder_ptr = + reinterpret_cast<AVCodec* (*)(enum CodecID)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_find_decoder")); + avcodec_thread_init_ptr = + reinterpret_cast<int (*)(AVCodecContext*, int)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_thread_init")); + avcodec_open_ptr = + reinterpret_cast<int (*)(AVCodecContext*, AVCodec*)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_open")); + avcodec_alloc_frame_ptr = + reinterpret_cast<AVFrame* (*)(void)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_alloc_frame")); + avcodec_decode_audio2_ptr = + reinterpret_cast<int (*)(AVCodecContext*, int16_t*, int*, + const uint8_t*, int)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_audio2")); + avcodec_decode_video_ptr = + reinterpret_cast<int (*)(AVCodecContext*, AVFrame*, int*, + const uint8_t*, int)>( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_video")); + + av_register_all_ptr = + reinterpret_cast<void(*)(void)>( + dlsym(libs[FILE_LIBAVFORMAT], "av_register_all")); + av_open_input_file_ptr = + reinterpret_cast<int (*)(AVFormatContext**, const char*, + AVInputFormat*, int, + AVFormatParameters*)>( + dlsym(libs[FILE_LIBAVFORMAT], "av_open_input_file")); + av_find_stream_info_ptr = + reinterpret_cast<int (*)(AVFormatContext*)>( + dlsym(libs[FILE_LIBAVFORMAT], "av_find_stream_info")); + av_read_frame_ptr = + reinterpret_cast<int (*)(AVFormatContext*, AVPacket*)>( + dlsym(libs[FILE_LIBAVFORMAT], "av_read_frame")); + + av_malloc_ptr = + reinterpret_cast<void* (*)(unsigned int)>( + dlsym(libs[FILE_LIBAVUTIL], "av_malloc")); + + // Check that all the symbols were loaded correctly before returning true. + if (avcodec_init_ptr && + avcodec_find_decoder_ptr && + avcodec_thread_init_ptr && + avcodec_open_ptr && + avcodec_alloc_frame_ptr && + avcodec_decode_audio2_ptr && + avcodec_decode_video_ptr && + + av_register_all_ptr && + av_open_input_file_ptr && + av_find_stream_info_ptr && + av_read_frame_ptr && + + av_malloc_ptr) { + return true; + } + return false; } |