In theory, I added management of WriterPlugins and EncoderPlugins. When looking

at media_file_format.id, I wonder if this could work without having to get an
entry_ref from the server for a WriterPlugin, added TODOs to this effect.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31936 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-07-29 19:14:04 +00:00
parent 6e64586530
commit c74bdf0919
3 changed files with 227 additions and 34 deletions
+180 -25
View File
@@ -5,6 +5,7 @@
* Authors: * Authors:
* Marcus Overhagen * Marcus Overhagen
* Axel Dörfler * Axel Dörfler
* Stephan Aßmus <[email protected]>
*/ */
@@ -13,20 +14,21 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <FindDirectory.h>
#include <Path.h>
#include <Entry.h>
#include <Directory.h>
#include <Autolock.h> #include <Autolock.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <image.h> #include <image.h>
#include <Path.h>
#include <safemode_defs.h> #include <safemode_defs.h>
#include <syscalls.h> #include <syscalls.h>
#include "debug.h"
#include "media_server.h"
#include "FormatManager.h" #include "FormatManager.h"
#include "MetaFormat.h" #include "MetaFormat.h"
#include "media_server.h"
#include "debug.h"
// #pragma mark - ImageLoader // #pragma mark - ImageLoader
@@ -60,7 +62,8 @@ private:
AddOnManager::AddOnManager() AddOnManager::AddOnManager()
: :
fLock("add-on manager") fLock("add-on manager"),
fNextWriterFormatFamilyID(0)
{ {
} }
@@ -73,7 +76,7 @@ AddOnManager::~AddOnManager()
void void
AddOnManager::LoadState() AddOnManager::LoadState()
{ {
RegisterAddOns(); _RegisterAddOns();
} }
@@ -90,8 +93,9 @@ AddOnManager::GetDecoderForFormat(xfer_entry_ref* _decoderRef,
if ((format.type == B_MEDIA_ENCODED_VIDEO if ((format.type == B_MEDIA_ENCODED_VIDEO
|| format.type == B_MEDIA_ENCODED_AUDIO || format.type == B_MEDIA_ENCODED_AUDIO
|| format.type == B_MEDIA_MULTISTREAM) || format.type == B_MEDIA_MULTISTREAM)
&& format.Encoding() == 0) && format.Encoding() == 0) {
return B_MEDIA_BAD_FORMAT; return B_MEDIA_BAD_FORMAT;
}
if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE) if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE)
return B_MEDIA_BAD_FORMAT; return B_MEDIA_BAD_FORMAT;
@@ -137,7 +141,76 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount,
status_t status_t
AddOnManager::RegisterAddOn(BEntry& entry) AddOnManager::GetEncoderForFormat(xfer_entry_ref* _encoderRef,
const media_format& format)
{
if ((format.type == B_MEDIA_ENCODED_VIDEO
|| format.type == B_MEDIA_ENCODED_AUDIO
|| format.type == B_MEDIA_MULTISTREAM)
&& format.Encoding() == 0) {
return B_MEDIA_BAD_FORMAT;
}
if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE)
return B_MEDIA_BAD_FORMAT;
BAutolock locker(fLock);
printf("AddOnManager::GetEncoderForFormat: searching encoder for encoding "
"%ld\n", format.Encoding());
encoder_info* info;
for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) {
media_format* encoderFormat;
for (info->formats.Rewind(); info->formats.GetNext(&encoderFormat);) {
// check if the encoder matches the supplied format
if (!encoderFormat->Matches(&format))
continue;
printf("AddOnManager::GetEncoderForFormat: found encoder %s for "
"encoding %ld\n", info->ref.name, encoderFormat->Encoding());
*_encoderRef = info->ref;
return B_OK;
}
}
return B_ENTRY_NOT_FOUND;
}
status_t
AddOnManager::GetWriter(xfer_entry_ref* _ref, const media_file_format& format)
{
BAutolock locker(fLock);
writer_info* info;
for (fWriterList.Rewind(); fWriterList.GetNext(&info);) {
media_file_format* fileFormat;
for (info->fileFormats.Rewind();
info->fileFormats.GetNext(&fileFormat);) {
// Check if the writer matches the supplied file format
// TODO: There must be a trick here which makes all this
// much simpler and probably lets us create a Writer client
// side...
if (fileFormat->id.internal_id != format.id.internal_id)
continue;
printf("AddOnManager::GetWriter: found writer %s for "
"file format %s\n", info->ref.name, format.pretty_name);
*_ref = info->ref;
return B_OK;
}
}
return B_ERROR;
}
// #pragma mark -
status_t
AddOnManager::_RegisterAddOn(BEntry& entry)
{ {
BPath path(&entry); BPath path(&entry);
@@ -146,7 +219,7 @@ AddOnManager::RegisterAddOn(BEntry& entry)
if (status < B_OK) if (status < B_OK)
return status; return status;
printf("AddOnManager::RegisterAddOn(): trying to load \"%s\"\n", printf("AddOnManager::_RegisterAddOn(): trying to load \"%s\"\n",
path.Path()); path.Path());
ImageLoader loader(path); ImageLoader loader(path);
@@ -157,27 +230,35 @@ AddOnManager::RegisterAddOn(BEntry& entry)
if (get_image_symbol(loader.Image(), "instantiate_plugin", if (get_image_symbol(loader.Image(), "instantiate_plugin",
B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) { B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) {
printf("AddOnManager::RegisterAddOn(): can't find instantiate_plugin " printf("AddOnManager::_RegisterAddOn(): can't find instantiate_plugin "
"in \"%s\"\n", path.Path()); "in \"%s\"\n", path.Path());
return B_BAD_TYPE; return B_BAD_TYPE;
} }
MediaPlugin* plugin = (*instantiate_plugin_func)(); MediaPlugin* plugin = (*instantiate_plugin_func)();
if (plugin == NULL) { if (plugin == NULL) {
printf("AddOnManager::RegisterAddOn(): instantiate_plugin in \"%s\" " printf("AddOnManager::_RegisterAddOn(): instantiate_plugin in \"%s\" "
"returned NULL\n", path.Path()); "returned NULL\n", path.Path());
return B_ERROR; return B_ERROR;
} }
// ToDo: remove any old formats describing this add-on!! // TODO: Remove any old formats describing this add-on!!
ReaderPlugin* reader = dynamic_cast<ReaderPlugin*>(plugin); ReaderPlugin* reader = dynamic_cast<ReaderPlugin*>(plugin);
if (reader != NULL) if (reader != NULL)
RegisterReader(reader, ref); _RegisterReader(reader, ref);
DecoderPlugin* decoder = dynamic_cast<DecoderPlugin*>(plugin); DecoderPlugin* decoder = dynamic_cast<DecoderPlugin*>(plugin);
if (decoder != NULL) if (decoder != NULL)
RegisterDecoder(decoder, ref); _RegisterDecoder(decoder, ref);
WriterPlugin* writer = dynamic_cast<WriterPlugin*>(plugin);
if (writer != NULL)
_RegisterWriter(writer, ref);
EncoderPlugin* encoder = dynamic_cast<EncoderPlugin*>(plugin);
if (encoder != NULL)
_RegisterEncoder(encoder, ref);
delete plugin; delete plugin;
@@ -186,7 +267,7 @@ AddOnManager::RegisterAddOn(BEntry& entry)
void void
AddOnManager::RegisterAddOns() AddOnManager::_RegisterAddOns()
{ {
class CodecHandler : public AddOnMonitorHandler { class CodecHandler : public AddOnMonitorHandler {
private: private:
@@ -209,7 +290,7 @@ AddOnManager::RegisterAddOns()
entryInfo->dir_nref.node, entryInfo->name, &ref); entryInfo->dir_nref.node, entryInfo->name, &ref);
BEntry entry(&ref, false); BEntry entry(&ref, false);
if (entry.InitCheck() == B_OK) if (entry.InitCheck() == B_OK)
fManager->RegisterAddOn(entry); fManager->_RegisterAddOn(entry);
} }
virtual void AddOnDisabled(const add_on_entry_info* entryInfo) virtual void AddOnDisabled(const add_on_entry_info* entryInfo)
@@ -261,7 +342,7 @@ AddOnManager::RegisterAddOns()
void void
AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref) AddOnManager::_RegisterReader(ReaderPlugin* reader, const entry_ref& ref)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
@@ -273,7 +354,7 @@ AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref)
} }
} }
printf("AddOnManager::RegisterReader, name %s\n", ref.name); printf("AddOnManager::_RegisterReader, name %s\n", ref.name);
reader_info info; reader_info info;
info.ref = ref; info.ref = ref;
@@ -283,7 +364,7 @@ AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref)
void void
AddOnManager::RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref) AddOnManager::_RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
@@ -295,7 +376,7 @@ AddOnManager::RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref)
} }
} }
printf("AddOnManager::RegisterDecoder, name %s\n", ref.name); printf("AddOnManager::_RegisterDecoder, name %s\n", ref.name);
decoder_info info; decoder_info info;
info.ref = ref; info.ref = ref;
@@ -303,14 +384,88 @@ AddOnManager::RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref)
media_format* formats = 0; media_format* formats = 0;
size_t count = 0; size_t count = 0;
if (plugin->GetSupportedFormats(&formats, &count) != B_OK) { if (plugin->GetSupportedFormats(&formats, &count) != B_OK) {
printf("AddOnManager::RegisterDecoder(): plugin->GetSupportedFormats" printf("AddOnManager::_RegisterDecoder(): plugin->GetSupportedFormats"
"(...) failed!\n"); "(...) failed!\n");
return; return;
} }
for (uint i = 0 ; i < count ; i++) { for (uint i = 0 ; i < count ; i++)
info.formats.Insert(formats[i]); info.formats.Insert(formats[i]);
}
fDecoderList.Insert(info); fDecoderList.Insert(info);
} }
void
AddOnManager::_RegisterWriter(WriterPlugin* writer, const entry_ref& ref)
{
BAutolock locker(fLock);
writer_info* pinfo;
for (fWriterList.Rewind(); fWriterList.GetNext(&pinfo);) {
if (!strcmp(pinfo->ref.name, ref.name)) {
// we already know this writer
return;
}
}
printf("AddOnManager::_RegisterWriter, name %s\n", ref.name);
writer_info info;
info.ref = ref;
// Get list of support media_file_formats...
media_file_format* fileFormats = NULL;
size_t count = 0;
if (writer->GetSupportedFileFormats(&fileFormats, &count) != B_OK) {
printf("AddOnManager::_RegisterWriter(): "
"plugin->GetSupportedFileFormats(...) failed!\n");
return;
}
for (uint i = 0 ; i < count ; i++) {
// Generate a proper ID before inserting this format, this encodes
// the specific plugin in the media_file_format.
media_file_format fileFormat = fileFormats[i];
fileFormat.id.node = ref.directory;
fileFormat.id.device = ref.device;
fileFormat.id.internal_id = fNextWriterFormatFamilyID++;
info.fileFormats.Insert(fileFormat);
}
fWriterList.Insert(info);
}
void
AddOnManager::_RegisterEncoder(EncoderPlugin* plugin, const entry_ref& ref)
{
BAutolock locker(fLock);
encoder_info* pinfo;
for (fEncoderList.Rewind(); fEncoderList.GetNext(&pinfo);) {
if (!strcmp(pinfo->ref.name, ref.name)) {
// we already know this encoder
return;
}
}
printf("AddOnManager::_RegisterEncoder, name %s\n", ref.name);
encoder_info info;
info.ref = ref;
// Get list of support media_formats...
media_format* formats = NULL;
size_t count = 0;
if (plugin->GetSupportedFormats(&formats, &count) != B_OK) {
printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedFormats"
"(...) failed!\n");
return;
}
for (uint i = 0 ; i < count ; i++)
info.formats.Insert(formats[i]);
fEncoderList.Insert(info);
}
+24 -8
View File
@@ -5,6 +5,7 @@
* Authors: * Authors:
* Marcus Overhagen * Marcus Overhagen
* Axel Dörfler * Axel Dörfler
* Stephan Aßmus <[email protected]>
*/ */
#ifndef _ADD_ON_MANAGER_H #ifndef _ADD_ON_MANAGER_H
#define _ADD_ON_MANAGER_H #define _ADD_ON_MANAGER_H
@@ -15,13 +16,15 @@
*/ */
#include "ReaderPlugin.h"
#include "DecoderPlugin.h"
#include "DataExchange.h" #include "DataExchange.h"
#include "TList.h" #include "TList.h"
#include "AddOnMonitor.h" #include "AddOnMonitor.h"
#include "AddOnMonitorHandler.h" #include "AddOnMonitorHandler.h"
#include "DecoderPlugin.h"
#include "EncoderPlugin.h"
#include "ReaderPlugin.h"
#include "WriterPlugin.h"
class AddOnManager { class AddOnManager {
@@ -38,13 +41,24 @@ public:
status_t GetReaders(xfer_entry_ref* _ref, status_t GetReaders(xfer_entry_ref* _ref,
int32* _count, int32 maxCount); int32* _count, int32 maxCount);
private: status_t GetEncoderForFormat(xfer_entry_ref* _ref,
status_t RegisterAddOn(BEntry& entry); const media_format& format);
void RegisterAddOns();
void RegisterReader(ReaderPlugin* reader, status_t GetWriter(xfer_entry_ref* _ref,
const media_file_format& format);
private:
status_t _RegisterAddOn(BEntry& entry);
void _RegisterAddOns();
void _RegisterReader(ReaderPlugin* reader,
const entry_ref& ref); const entry_ref& ref);
void RegisterDecoder(DecoderPlugin* decoder, void _RegisterDecoder(DecoderPlugin* decoder,
const entry_ref& ref);
void _RegisterWriter(WriterPlugin* writer,
const entry_ref& ref);
void _RegisterEncoder(EncoderPlugin* encoder,
const entry_ref& ref); const entry_ref& ref);
private: private:
@@ -53,6 +67,7 @@ private:
}; };
struct writer_info { struct writer_info {
entry_ref ref; entry_ref ref;
List<media_file_format> fileFormats;
}; };
struct decoder_info { struct decoder_info {
entry_ref ref; entry_ref ref;
@@ -60,6 +75,7 @@ private:
}; };
struct encoder_info { struct encoder_info {
entry_ref ref; entry_ref ref;
List<media_format> formats;
}; };
BLocker fLock; BLocker fLock;
@@ -68,7 +84,7 @@ private:
List<decoder_info> fDecoderList; List<decoder_info> fDecoderList;
List<encoder_info> fEncoderList; List<encoder_info> fEncoderList;
decoder_info* fCurrentDecoder; uint32 fNextWriterFormatFamilyID;
AddOnMonitorHandler* fHandler; AddOnMonitorHandler* fHandler;
AddOnMonitor* fAddOnMonitor; AddOnMonitor* fAddOnMonitor;
+22
View File
@@ -886,6 +886,28 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
break; break;
} }
case SERVER_GET_WRITER_FOR_FORMAT_FAMILY:
{
const server_get_writer_request *request
= reinterpret_cast<const server_get_writer_request *>(data);
server_get_writer_reply reply;
rv = gAddOnManager->GetWriter(&reply.ref, request->file_format);
request->SendReply(rv, &reply, sizeof(reply));
break;
}
case SERVER_GET_ENCODER_FOR_FORMAT:
{
const server_get_encoder_for_format_request *request
= reinterpret_cast<
const server_get_encoder_for_format_request *>(data);
server_get_encoder_for_format_reply reply;
rv = gAddOnManager->GetEncoderForFormat(&reply.ref,
request->format);
request->SendReply(rv, &reply, sizeof(reply));
break;
}
default: default:
printf("media_server: received unknown message code %#08lx\n", printf("media_server: received unknown message code %#08lx\n",
code); code);