From 1210ab70ac360af3e24f04ef2a1fa5bdef4f0b70 Mon Sep 17 00:00:00 2001 From: beveloper Date: Fri, 5 Dec 2003 01:18:51 +0000 Subject: [PATCH] Huge hack to load the mp3 reader and decoder. Soundplay loads it and can play a crackling mp3, but MediaPlayer doesn't git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5572 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/media/PluginManager.h | 32 +++ .../plugins/mp3_decoder/mp3DecoderPlugin.cpp | 1 + src/kits/media/DecoderPlugin.cpp | 16 +- src/kits/media/MediaExtractor.cpp | 29 ++- src/kits/media/MediaFile.cpp | 1 + src/kits/media/MediaFormats.cpp | 8 +- src/kits/media/MediaTrack.cpp | 2 +- src/kits/media/PluginManager.cpp | 206 ++++++++++++++++++ 8 files changed, 274 insertions(+), 21 deletions(-) diff --git a/headers/private/media/PluginManager.h b/headers/private/media/PluginManager.h index 3925db8498..ec56bf39c8 100644 --- a/headers/private/media/PluginManager.h +++ b/headers/private/media/PluginManager.h @@ -3,6 +3,8 @@ #include "ReaderPlugin.h" #include "DecoderPlugin.h" +#include +#include status_t _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BDataIO *source); status_t _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *format); @@ -10,4 +12,34 @@ status_t _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_fo void _DestroyReader(Reader *reader); void _DestroyDecoder(Decoder *decoder); +status_t _PublishDecoder(DecoderPlugin *decoderplugin, + const char *meta_description, + const char *short_name, + const char *pretty_name, + const char *default_mapping /* = 0 */); + +class PluginManager +{ +public: + PluginManager(); + ~PluginManager(); + + MediaPlugin * GetPlugin(const char *name); + void PutPlugin(MediaPlugin *plugin); + +private: + bool LoadPlugin(const char *name, MediaPlugin **plugin, image_id *image); + + struct plugin_info + { + char name[260]; + int usecount; + MediaPlugin *plugin; + image_id image; + }; + + List *fPluginList; + BLocker *fLocker; +}; + #endif diff --git a/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp b/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp index 56c31b0916..597e8072bf 100644 --- a/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp +++ b/src/add-ons/media/plugins/mp3_decoder/mp3DecoderPlugin.cpp @@ -114,6 +114,7 @@ mp3DecoderPlugin::RegisterPlugin() PublishDecoder("audiocodec/mpeg2.5layer1", "mp3", "MPEG 2.5 audio layer 1 decoder, based on mpeg123 mpglib"); PublishDecoder("audiocodec/mpeg2.5layer2", "mp3", "MPEG 2.5 audio layer 2 decoder, based on mpeg123 mpglib"); PublishDecoder("audiocodec/mpeg2.5layer3", "mp3", "MPEG 2.5 audio layer 3 decoder, based on mpeg123 mpglib"); + return B_OK; } diff --git a/src/kits/media/DecoderPlugin.cpp b/src/kits/media/DecoderPlugin.cpp index eaf707f607..841efb69e5 100644 --- a/src/kits/media/DecoderPlugin.cpp +++ b/src/kits/media/DecoderPlugin.cpp @@ -1,4 +1,5 @@ #include "DecoderPlugin.h" +#include "PluginManager.h" #include #include #include @@ -35,18 +36,5 @@ DecoderPlugin::PublishDecoder(const char *meta_description, const char *pretty_name, const char *default_mapping /* = 0 */) { -/* - media_format fmt; - memset(&fmt, 0, sizeof(fmt)); - fmt.type = fmt_type; - BMediaFormats formats; - if (B_OK != formats.MakeFormatFor(&fmt_desc, 1, &fmt)) - return B_ERROR; - - char s[1024]; - string_for_format(fmt, s, sizeof(s)); - printf("DecoderPlugin::PublishDecoder: short_name \"%s\", pretty_name \"%s\", format %s\n", - short_name, pretty_name, s); -*/ - return B_OK; + return _PublishDecoder(this, meta_description, short_name, pretty_name, default_mapping); } diff --git a/src/kits/media/MediaExtractor.cpp b/src/kits/media/MediaExtractor.cpp index 7ae81a5968..424480add8 100644 --- a/src/kits/media/MediaExtractor.cpp +++ b/src/kits/media/MediaExtractor.cpp @@ -1,10 +1,12 @@ #include "MediaExtractor.h" #include "PluginManager.h" +#include "debug.h" #include #include MediaExtractor::MediaExtractor(BDataIO * source, int32 flags) { + CALLED(); fSource = source; fStreamInfo = 0; fStreamCount = 0; @@ -47,13 +49,27 @@ MediaExtractor::MediaExtractor(BDataIO * source, int32 flags) fStreamInfo[i].status = B_ERROR; printf("MediaExtractor::MediaExtractor: GetStreamInfo for stream %ld failed\n", i); } + + char sz[1024]; + string_for_format(fStreamInfo[i].encodedFormat, sz, sizeof(sz)); + printf("MediaExtractor::MediaExtractor: stream %d has format %s\n", i, sz); + fStreamInfo[i].encodedFormat.type = B_MEDIA_ENCODED_AUDIO; + fStreamInfo[i].encodedFormat.u.encoded_audio.encoding = (enum media_encoded_audio_format::audio_encoding) 1; + fStreamInfo[i].encodedFormat.u.encoded_audio.bit_rate = 128000; + fStreamInfo[i].encodedFormat.u.encoded_audio.frame_size = 3000; + fStreamInfo[i].encodedFormat.u.encoded_audio.output.frame_rate = 44100; + fStreamInfo[i].encodedFormat.u.encoded_audio.output.channel_count = 2; + fStreamInfo[i].encodedFormat.u.encoded_audio.output.format = 2; + fStreamInfo[i].encodedFormat.u.encoded_audio.output.byte_order = B_MEDIA_LITTLE_ENDIAN; + fStreamInfo[i].encodedFormat.u.encoded_audio.output.buffer_size = 8 * 1024; + string_for_format(fStreamInfo[i].encodedFormat, sz, sizeof(sz)); + printf("MediaExtractor::MediaExtractor: stream %d has new format %s\n", i, sz); } - - } MediaExtractor::~MediaExtractor() { + CALLED(); // free all stream cookies for (int32 i = 0; i < fStreamCount; i++) { if (fStreamInfo[i].cookie) @@ -70,18 +86,21 @@ MediaExtractor::~MediaExtractor() status_t MediaExtractor::InitCheck() { + CALLED(); return fErr; } void MediaExtractor::GetFileFormatInfo(media_file_format *mfi) const { + CALLED(); *mfi = fMff; } int32 MediaExtractor::StreamCount() { + CALLED(); return fStreamCount; } @@ -94,6 +113,7 @@ MediaExtractor::EncodedFormat(int32 stream) int64 MediaExtractor::CountFrames(int32 stream) const { + CALLED(); int64 frameCount; bigtime_t duration; media_format format; @@ -108,6 +128,7 @@ MediaExtractor::CountFrames(int32 stream) const bigtime_t MediaExtractor::Duration(int32 stream) const { + CALLED(); int64 frameCount; bigtime_t duration; media_format format; @@ -135,12 +156,14 @@ status_t MediaExtractor::Seek(int32 stream, uint32 seekTo, int64 *frame, bigtime_t *time) { + CALLED(); status_t result; result = fReader->Seek(fStreamInfo[stream].cookie, seekTo, frame, time); if (result != B_OK) return result; // clear buffered chunks + return B_OK; } status_t @@ -148,6 +171,7 @@ MediaExtractor::GetNextChunk(int32 stream, void **chunkBuffer, int32 *chunkSize, media_header *mediaHeader) { + CALLED(); // get buffered chunk // XXX this should be done in a different thread, and double buffered for each stream @@ -157,6 +181,7 @@ MediaExtractor::GetNextChunk(int32 stream, status_t MediaExtractor::CreateDecoder(int32 stream, Decoder **decoder, media_codec_info *mci) { + CALLED(); if (fStreamInfo[stream].status != B_OK) { printf("MediaExtractor::CreateDecoder can't create decoder for stream %ld\n", stream); return B_ERROR; diff --git a/src/kits/media/MediaFile.cpp b/src/kits/media/MediaFile.cpp index e974a7c75d..87e4c00ca3 100644 --- a/src/kits/media/MediaFile.cpp +++ b/src/kits/media/MediaFile.cpp @@ -137,6 +137,7 @@ BMediaFile::ReleaseTrack(BMediaTrack *track) return B_OK; } } + printf("BMediaFile::ReleaseTrack track %p not found\n", track); return B_ERROR; } diff --git a/src/kits/media/MediaFormats.cpp b/src/kits/media/MediaFormats.cpp index 18b8d0b61e..45eef777ec 100644 --- a/src/kits/media/MediaFormats.cpp +++ b/src/kits/media/MediaFormats.cpp @@ -305,8 +305,8 @@ _get_format_for_description(media_format *out_format, const media_format_descrip request.description = in_desc; - if (B_OK != QueryServer(SERVER_GET_FORMAT_FOR_DESCRIPTION, &request, sizeof(request), &reply, sizeof(reply))) - return B_ERROR; +// if (B_OK != QueryServer(SERVER_GET_FORMAT_FOR_DESCRIPTION, &request, sizeof(request), &reply, sizeof(reply))) +// return B_ERROR; *out_format = reply.format; return B_OK; @@ -320,8 +320,8 @@ _get_meta_description_for_format(media_format_description *out_desc, const media request.format = in_format; - if (B_OK != QueryServer(SERVER_GET_META_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply))) - return B_ERROR; +// if (B_OK != QueryServer(SERVER_GET_META_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply))) +// return B_ERROR; *out_desc = reply.description; return B_OK; diff --git a/src/kits/media/MediaTrack.cpp b/src/kits/media/MediaTrack.cpp index f631ebedea..608005aba5 100644 --- a/src/kits/media/MediaTrack.cpp +++ b/src/kits/media/MediaTrack.cpp @@ -54,7 +54,7 @@ BMediaTrack::EncodedFormat(media_format *out_format) const return B_NO_INIT; out_format = fExtractor->EncodedFormat(fStream); - +printf("encoded format\n"); return B_OK; } diff --git a/src/kits/media/PluginManager.cpp b/src/kits/media/PluginManager.cpp index e2749329f7..f27b70233e 100644 --- a/src/kits/media/PluginManager.cpp +++ b/src/kits/media/PluginManager.cpp @@ -1,15 +1,77 @@ +#include +#include +#include + #include "PluginManager.h" +PluginManager _plugin_manager; status_t _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BDataIO *source) { + printf("_CreateReader enter\n"); + + MediaPlugin *plugin; + ReaderPlugin *readerplugin; + + plugin = _plugin_manager.GetPlugin("mp3_reader"); + if (!plugin) { + printf("_CreateReader: GetPlugin failed\n"); + return B_ERROR; + } + + readerplugin = dynamic_cast(plugin); + if (!readerplugin) { + printf("_CreateReader: dynamic_cast failed\n"); + return B_ERROR; + } + + *reader = readerplugin->NewReader(); + if (! *reader) { + printf("_CreateReader: NewReader failed\n"); + return B_ERROR; + } + + (*reader)->Setup(source); + + if (B_OK != (*reader)->Sniff(streamCount)) { + printf("_CreateReader: Sniff failed\n"); + return B_ERROR; + } + + printf("_CreateReader leave\n"); + return B_OK; } status_t _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *format) { + printf("_CreateDecoder enter\n"); + + MediaPlugin *plugin; + DecoderPlugin *decoderplugin; + + plugin = _plugin_manager.GetPlugin("mp3_decoder"); + if (!plugin) { + printf("_CreateDecoder: GetPlugin failed\n"); + return B_ERROR; + } + + decoderplugin = dynamic_cast(plugin); + if (!decoderplugin) { + printf("_CreateDecoder: dynamic_cast failed\n"); + return B_ERROR; + } + + *decoder = decoderplugin->NewDecoder(); + if (! *decoder) { + printf("_CreateDecoder: NewReader failed\n"); + return B_ERROR; + } + + printf("_CreateDecoder leave\n"); + return B_OK; } @@ -23,3 +85,147 @@ void _DestroyDecoder(Decoder *decoder) { } + +status_t +_PublishDecoder(DecoderPlugin *decoderplugin, + const char *meta_description, + const char *short_name, + const char *pretty_name, + const char *default_mapping /* = 0 */) +{ + printf("_PublishDecoder: meta_description \"%s\", short_name \"%s\", pretty_name \"%s\", default_mapping \"%s\"\n", + meta_description, short_name, pretty_name, default_mapping); + + return B_OK; +} + + + +PluginManager::PluginManager() +{ + fLocker = new BLocker; + fPluginList = new List; +} + + +PluginManager::~PluginManager() +{ + while (!fPluginList->IsEmpty()) { + plugin_info *info; + fPluginList->Get(fPluginList->CountItems() - 1, &info); + printf("PluginManager: Error, unloading PlugIn %s with usecount %d\n", info->name, info->usecount); + delete info->plugin; + unload_add_on(info->image); + fPluginList->Remove(fPluginList->CountItems() - 1); + } + delete fLocker; +} + + +MediaPlugin * +PluginManager::GetPlugin(const char *name) +{ + fLocker->Lock(); + + MediaPlugin *plugin; + plugin_info *pinfo; + plugin_info info; + + for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) { + if (0 == strcmp(name, pinfo->name)) { + plugin = pinfo->plugin; + pinfo->usecount++; + fLocker->Unlock(); + return plugin; + } + } + + if (!LoadPlugin(name, &info.plugin, &info.image)) { + printf("PluginManager: Error, loading PlugIn %s failed\n", name); + fLocker->Unlock(); + return 0; + } + + strcpy(info.name, name); + info.usecount = 1; + fPluginList->Insert(info); + + printf("PluginManager: PlugIn %s loaded\n", name); + + plugin = info.plugin; + + fLocker->Unlock(); + return plugin; +} + + +void +PluginManager::PutPlugin(MediaPlugin *plugin) +{ + fLocker->Lock(); + + plugin_info *pinfo; + + for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) { + if (plugin == pinfo->plugin) { + pinfo->usecount--; + if (pinfo->usecount == 0) { + delete pinfo->plugin; + unload_add_on(pinfo->image); + } + fPluginList->RemoveCurrent(); + fLocker->Unlock(); + return; + } + } + + printf("PluginManager: Error, can't put PlugIn %p\n", plugin); + + fLocker->Unlock(); +} + + +bool +PluginManager::LoadPlugin(const char *name, MediaPlugin **plugin, image_id *image) +{ + const char *searchdir[] = { + "/boot/home/config/add-ons/media/plugins", + "/boot/beos/system/add-ons/media/plugins", + "/boot/home/develop/openbeos/current/distro/x86.R1/beos/system/add-ons/media/plugins", + NULL + }; + + for (int i = 0; searchdir[i]; i++) { + BPath p(searchdir[i], name); + + printf("PluginManager: LoadPlugin trying to load %s\n", p.Path()); + + image_id id; + id = load_add_on(p.Path()); + if (id < 0) + continue; + + MediaPlugin *(*instantiate_plugin_func)(); + + if (get_image_symbol(id, "instantiate_plugin", B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) { + printf("PluginManager: Error, LoadPlugin can't find instantiate_plugin in %s\n", p.Path()); + unload_add_on(id); + continue; + } + + MediaPlugin *pl; + + pl = (*instantiate_plugin_func)(); + if (pl == 0) { + printf("PluginManager: Error, LoadPlugin instantiate_plugin in %s returned 0\n", p.Path()); + unload_add_on(id); + continue; + } + + *plugin = pl; + *image = id; + return true; + } + + return false; +}