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
+181 -26
View File
@@ -5,6 +5,7 @@
* Authors:
* Marcus Overhagen
* Axel Dörfler
* Stephan Aßmus <[email protected]>
*/
@@ -13,20 +14,21 @@
#include <stdio.h>
#include <string.h>
#include <FindDirectory.h>
#include <Path.h>
#include <Entry.h>
#include <Directory.h>
#include <Autolock.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <image.h>
#include <Path.h>
#include <safemode_defs.h>
#include <syscalls.h>
#include "debug.h"
#include "media_server.h"
#include "FormatManager.h"
#include "MetaFormat.h"
#include "media_server.h"
#include "debug.h"
// #pragma mark - ImageLoader
@@ -60,7 +62,8 @@ private:
AddOnManager::AddOnManager()
:
fLock("add-on manager")
fLock("add-on manager"),
fNextWriterFormatFamilyID(0)
{
}
@@ -73,7 +76,7 @@ AddOnManager::~AddOnManager()
void
AddOnManager::LoadState()
{
RegisterAddOns();
_RegisterAddOns();
}
@@ -90,8 +93,9 @@ AddOnManager::GetDecoderForFormat(xfer_entry_ref* _decoderRef,
if ((format.type == B_MEDIA_ENCODED_VIDEO
|| format.type == B_MEDIA_ENCODED_AUDIO
|| format.type == B_MEDIA_MULTISTREAM)
&& format.Encoding() == 0)
&& 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;
@@ -137,7 +141,76 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount,
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);
@@ -146,7 +219,7 @@ AddOnManager::RegisterAddOn(BEntry& entry)
if (status < B_OK)
return status;
printf("AddOnManager::RegisterAddOn(): trying to load \"%s\"\n",
printf("AddOnManager::_RegisterAddOn(): trying to load \"%s\"\n",
path.Path());
ImageLoader loader(path);
@@ -157,27 +230,35 @@ AddOnManager::RegisterAddOn(BEntry& entry)
if (get_image_symbol(loader.Image(), "instantiate_plugin",
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());
return B_BAD_TYPE;
}
MediaPlugin* plugin = (*instantiate_plugin_func)();
if (plugin == NULL) {
printf("AddOnManager::RegisterAddOn(): instantiate_plugin in \"%s\" "
printf("AddOnManager::_RegisterAddOn(): instantiate_plugin in \"%s\" "
"returned NULL\n", path.Path());
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);
if (reader != NULL)
RegisterReader(reader, ref);
_RegisterReader(reader, ref);
DecoderPlugin* decoder = dynamic_cast<DecoderPlugin*>(plugin);
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;
@@ -186,7 +267,7 @@ AddOnManager::RegisterAddOn(BEntry& entry)
void
AddOnManager::RegisterAddOns()
AddOnManager::_RegisterAddOns()
{
class CodecHandler : public AddOnMonitorHandler {
private:
@@ -209,7 +290,7 @@ AddOnManager::RegisterAddOns()
entryInfo->dir_nref.node, entryInfo->name, &ref);
BEntry entry(&ref, false);
if (entry.InitCheck() == B_OK)
fManager->RegisterAddOn(entry);
fManager->_RegisterAddOn(entry);
}
virtual void AddOnDisabled(const add_on_entry_info* entryInfo)
@@ -261,7 +342,7 @@ AddOnManager::RegisterAddOns()
void
AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref)
AddOnManager::_RegisterReader(ReaderPlugin* reader, const entry_ref& ref)
{
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;
info.ref = ref;
@@ -283,7 +364,7 @@ AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref)
void
AddOnManager::RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref)
AddOnManager::_RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref)
{
BAutolock locker(fLock);
@@ -295,22 +376,96 @@ 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;
info.ref = ref;
media_format* formats = 0;
size_t count = 0;
if (plugin->GetSupportedFormats(&formats,&count) != B_OK) {
printf("AddOnManager::RegisterDecoder(): plugin->GetSupportedFormats"
if (plugin->GetSupportedFormats(&formats, &count) != B_OK) {
printf("AddOnManager::_RegisterDecoder(): plugin->GetSupportedFormats"
"(...) failed!\n");
return;
}
for (uint i = 0 ; i < count ; i++) {
for (uint i = 0 ; i < count ; i++)
info.formats.Insert(formats[i]);
}
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:
* Marcus Overhagen
* Axel Dörfler
* Stephan Aßmus <[email protected]>
*/
#ifndef _ADD_ON_MANAGER_H
#define _ADD_ON_MANAGER_H
@@ -15,13 +16,15 @@
*/
#include "ReaderPlugin.h"
#include "DecoderPlugin.h"
#include "DataExchange.h"
#include "TList.h"
#include "AddOnMonitor.h"
#include "AddOnMonitorHandler.h"
#include "DecoderPlugin.h"
#include "EncoderPlugin.h"
#include "ReaderPlugin.h"
#include "WriterPlugin.h"
class AddOnManager {
@@ -38,13 +41,24 @@ public:
status_t GetReaders(xfer_entry_ref* _ref,
int32* _count, int32 maxCount);
private:
status_t RegisterAddOn(BEntry& entry);
void RegisterAddOns();
status_t GetEncoderForFormat(xfer_entry_ref* _ref,
const media_format& format);
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);
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);
private:
@@ -53,6 +67,7 @@ private:
};
struct writer_info {
entry_ref ref;
List<media_file_format> fileFormats;
};
struct decoder_info {
entry_ref ref;
@@ -60,6 +75,7 @@ private:
};
struct encoder_info {
entry_ref ref;
List<media_format> formats;
};
BLocker fLock;
@@ -68,7 +84,7 @@ private:
List<decoder_info> fDecoderList;
List<encoder_info> fEncoderList;
decoder_info* fCurrentDecoder;
uint32 fNextWriterFormatFamilyID;
AddOnMonitorHandler* fHandler;
AddOnMonitor* fAddOnMonitor;
+22
View File
@@ -886,6 +886,28 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
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:
printf("media_server: received unknown message code %#08lx\n",
code);