From e5112c69dbf8ce4c3b723b5d6b80f9e3c0bc1deb Mon Sep 17 00:00:00 2001 From: "ajwong@chromium.org" Date: Sat, 6 Jun 2009 01:52:13 +0000 Subject: Reverting r17820 and r17819 due to mac breakage. Review URL: http://codereview.chromium.org/119276 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17821 0039d316-1c4b-4281-b951-d872f2087c98 --- media/DEPS | 2 +- media/base/media_posix.cc | 290 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 275 insertions(+), 17 deletions(-) (limited to 'media') diff --git a/media/DEPS b/media/DEPS index 3d2daa9..2b2d7d8 100644 --- a/media/DEPS +++ b/media/DEPS @@ -1,3 +1,3 @@ include_rules = [ - "+third_party/ffmpeg", + "+third_party/ffmpeg/include", ] diff --git a/media/base/media_posix.cc b/media/base/media_posix.cc index 51efbca..9a964dd 100644 --- a/media/base/media_posix.cc +++ b/media/base/media_posix.cc @@ -11,46 +11,304 @@ #include "base/file_path.h" #include "base/logging.h" #include "base/path_service.h" -#include "third_party/ffmpeg/ffmpeg_stubs.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. +// +// TODO(scherkus): I am *this close* to writing the world's coolest macro to +// make modifying this file easier. +extern "C" { + +// libavcodec functions. +void (*av_free_packet_ptr)(AVPacket* pkt) = NULL; +void av_free_packet(AVPacket* pkt) { + av_free_packet_ptr(pkt); +} + +int (*av_get_bits_per_sample_format_ptr)(enum SampleFormat sample_fmt) = NULL; +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt) { + return av_get_bits_per_sample_format_ptr(sample_fmt); +} + +void (*av_init_packet_ptr)(AVPacket* pkt) = NULL; +void av_init_packet(AVPacket* pkt) { + av_init_packet_ptr(pkt); +} + +int (*av_new_packet_ptr)(AVPacket* pkt, int size) = NULL; +int av_new_packet(AVPacket* pkt, int size) { + return av_new_packet_ptr(pkt, size); +} + +AVFrame* (*avcodec_alloc_frame_ptr)(void) = NULL; +AVFrame* avcodec_alloc_frame(void) { + return avcodec_alloc_frame_ptr(); +} + +int (*avcodec_decode_audio3_ptr)(AVCodecContext* avctx, int16_t* samples, + int* frame_size_ptr, AVPacket* avpkt) = NULL; +int avcodec_decode_audio3(AVCodecContext* avctx, int16_t* samples, + int* frame_size_ptr, AVPacket* avpkt) { + return avcodec_decode_audio3_ptr(avctx, samples, frame_size_ptr, avpkt); +} + +int (*avcodec_decode_video2_ptr)(AVCodecContext* avctx, AVFrame* picture, + int* got_picture_ptr, AVPacket* avpkt) = NULL; +int avcodec_decode_video2(AVCodecContext* avctx, AVFrame* picture, + int* got_picture_ptr, AVPacket* avpkt) { + return avcodec_decode_video2_ptr(avctx, picture, got_picture_ptr, avpkt); +} + +AVCodec* (*avcodec_find_decoder_ptr)(enum CodecID id) = NULL; +AVCodec* avcodec_find_decoder(enum CodecID id) { + return avcodec_find_decoder_ptr(id); +} + +void (*avcodec_flush_buffers_ptr)(AVCodecContext *avctx) = NULL; +void avcodec_flush_buffers(AVCodecContext *avctx) { + avcodec_flush_buffers_ptr(avctx); +} + +void (*avcodec_init_ptr)(void) = NULL; +void avcodec_init(void) { + avcodec_init_ptr(); +} + +int (*avcodec_open_ptr)(AVCodecContext* avctx, AVCodec* codec) = NULL; +int avcodec_open(AVCodecContext* avctx, AVCodec* codec) { + return avcodec_open_ptr(avctx, codec); +} + +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); +} + + +// libavformat functions. +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_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_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_register_all_ptr)(void) = NULL; +void av_register_all(void) { + av_register_all_ptr(); +} + +int (*av_register_protocol_ptr)(URLProtocol* protocol) = NULL; +int av_register_protocol(URLProtocol* protocol) { + return av_register_protocol_ptr(protocol); +} + +int (*av_seek_frame_ptr)(AVFormatContext* s, int stream_index, + int64_t timestamp, int flags) = NULL; +int av_seek_frame(AVFormatContext* s, int stream_index, + int64_t timestamp, int flags) { + return av_seek_frame_ptr(s, stream_index, timestamp, flags); +} + + +// libavutil functions. +void (*av_free_ptr)(void* ptr) = NULL; +void av_free(void* ptr) { + return av_free_ptr(ptr); +} + +void* (*av_malloc_ptr)(unsigned int size) = NULL; +void* av_malloc(unsigned int size) { + return av_malloc_ptr(size); +} + +int64_t (*av_rescale_q_ptr)(int64_t a, AVRational bq, AVRational cq) = NULL; +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) { + return av_rescale_q_ptr(a, bq, cq); +} + +} // extern "C" -namespace tp_ffmpeg = third_party_ffmpeg; namespace media { namespace { -// Retrieves the DSOName for the given key. -std::string GetDSOName(tp_ffmpeg::StubModules stub_key) { +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 (stub_key) { - case tp_ffmpeg::kModuleAvcodec52: + switch (dso_key) { + case FILE_LIBAVCODEC: return FILE_PATH_LITERAL("libavcodec.so.52"); - case tp_ffmpeg::kModuleAvformat52: + case FILE_LIBAVFORMAT: return FILE_PATH_LITERAL("libavformat.so.52"); - case tp_ffmpeg::kModuleAvutil50: + case FILE_LIBAVUTIL: return FILE_PATH_LITERAL("libavutil.so.50"); default: - LOG(DFATAL) << "Invalid stub module requested: " << stub_key; + LOG(DFATAL) << "Invalid DSO key requested: " << dso_key; return FILE_PATH_LITERAL(""); } } } // namespace -// Attempts to initialize the media library (loading DSOs, etc.). +// 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) { // TODO(ajwong): We need error resolution. - tp_ffmpeg::StubPathMap paths; - for (int i = 0; i < static_cast(tp_ffmpeg::kNumStubModules); ++i) { - tp_ffmpeg::StubModules module = static_cast(i); - FilePath path = module_dir.Append(GetDSOName(module)); - paths[module].push_back(path.value()); + 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. + + // libavcodec functions. + av_free_packet_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "av_free_packet")); + av_get_bits_per_sample_format_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "av_get_bits_per_sample_format")); + av_init_packet_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "av_init_packet")); + av_new_packet_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "av_new_packet")); + avcodec_alloc_frame_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_alloc_frame")); + avcodec_decode_audio3_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_audio3")); + avcodec_decode_video2_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_video2")); + avcodec_find_decoder_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_find_decoder")); + avcodec_flush_buffers_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_flush_buffers")); + avcodec_init_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_init")); + avcodec_open_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_open")); + avcodec_thread_init_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVCODEC], "avcodec_thread_init")); + + // libavformat functions. + av_find_stream_info_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVFORMAT], "av_find_stream_info")); + av_open_input_file_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVFORMAT], "av_open_input_file")); + av_read_frame_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVFORMAT], "av_read_frame")); + av_register_all_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVFORMAT], "av_register_all")); + av_register_protocol_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVFORMAT], "av_register_protocol")); + av_seek_frame_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVFORMAT], "av_seek_frame")); + + // libavutil functions. + av_free_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVUTIL], "av_free")); + av_malloc_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVUTIL], "av_malloc")); + av_rescale_q_ptr = + reinterpret_cast( + dlsym(libs[FILE_LIBAVUTIL], "av_rescale_q")); + + // Check that all the symbols were loaded correctly before returning true. + if (av_free_packet_ptr && + av_get_bits_per_sample_format_ptr && + av_init_packet_ptr && + av_new_packet_ptr && + avcodec_alloc_frame_ptr && + avcodec_decode_audio3_ptr && + avcodec_decode_video2_ptr && + avcodec_find_decoder_ptr && + avcodec_flush_buffers_ptr && + avcodec_init_ptr && + avcodec_open_ptr && + avcodec_thread_init_ptr && + + av_find_stream_info_ptr && + av_open_input_file_ptr && + av_read_frame_ptr && + av_register_all_ptr && + av_register_protocol_ptr && + av_seek_frame_ptr && + + av_free_ptr && + av_malloc_ptr && + av_rescale_q_ptr) { + return true; } - return tp_ffmpeg::InitializeStubs(paths); + return false; } } // namespace media -- cgit v1.1