Urpdate AddOnManager and FormatManager for Media Kit

* These classes were moved from Media Server, making the use of ports
and messages to communicate with the app irrelevant.
* Split in a separate commit to help git keep track of moved files.

Fixes #4893.
This commit is contained in:
Adrien Destugues
2014-04-02 09:56:34 +02:00
parent 2feaa37f24
commit bf3b475c38
5 changed files with 98 additions and 226 deletions
+26 -88
View File
@@ -22,13 +22,8 @@
#include <image.h> #include <image.h>
#include <Path.h> #include <Path.h>
#include <safemode_defs.h>
#include <syscalls.h>
#include "debug.h" #include "debug.h"
#include "media_server.h"
#include "FormatManager.h"
#include "MetaFormat.h" #include "MetaFormat.h"
@@ -65,38 +60,28 @@ AddOnManager::AddOnManager()
: :
fLock("add-on manager"), fLock("add-on manager"),
fNextWriterFormatFamilyID(0), fNextWriterFormatFamilyID(0),
fNextEncoderCodecInfoID(0), fNextEncoderCodecInfoID(0)
fAddOnMonitorHandler(NULL),
fAddOnMonitor(NULL)
{ {
} }
AddOnManager::~AddOnManager() AddOnManager::~AddOnManager()
{ {
if (fAddOnMonitor != NULL && fAddOnMonitor->Lock()) {
fAddOnMonitor->RemoveHandler(fAddOnMonitorHandler);
delete fAddOnMonitorHandler;
fAddOnMonitor->Quit();
}
} }
void AddOnManager AddOnManager::sInstance;
AddOnManager::LoadState()
{
_RegisterAddOns();
}
void /* static */ AddOnManager*
AddOnManager::SaveState() AddOnManager::GetInstance()
{ {
return &sInstance;
} }
status_t status_t
AddOnManager::GetDecoderForFormat(xfer_entry_ref* _decoderRef, AddOnManager::GetDecoderForFormat(entry_ref* _decoderRef,
const media_format& format) const media_format& format)
{ {
if ((format.type == B_MEDIA_ENCODED_VIDEO if ((format.type == B_MEDIA_ENCODED_VIDEO
@@ -109,6 +94,7 @@ AddOnManager::GetDecoderForFormat(xfer_entry_ref* _decoderRef,
return B_MEDIA_BAD_FORMAT; return B_MEDIA_BAD_FORMAT;
BAutolock locker(fLock); BAutolock locker(fLock);
_RegisterAddOns();
printf("AddOnManager::GetDecoderForFormat: searching decoder for encoding " printf("AddOnManager::GetDecoderForFormat: searching decoder for encoding "
"%" B_PRIu32 "\n", format.Encoding()); "%" B_PRIu32 "\n", format.Encoding());
@@ -140,10 +126,11 @@ AddOnManager::GetDecoderForFormat(xfer_entry_ref* _decoderRef,
status_t status_t
AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount, AddOnManager::GetReaders(entry_ref* outRefs, int32* outCount,
int32 maxCount) int32 maxCount)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
_RegisterAddOns();
*outCount = 0; *outCount = 0;
@@ -170,9 +157,10 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount,
status_t status_t
AddOnManager::GetEncoder(xfer_entry_ref* _encoderRef, int32 id) AddOnManager::GetEncoder(entry_ref* _encoderRef, int32 id)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
_RegisterAddOns();
encoder_info* info; encoder_info* info;
for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) { for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) {
@@ -194,9 +182,10 @@ AddOnManager::GetEncoder(xfer_entry_ref* _encoderRef, int32 id)
status_t status_t
AddOnManager::GetWriter(xfer_entry_ref* _ref, uint32 internalID) AddOnManager::GetWriter(entry_ref* _ref, uint32 internalID)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
_RegisterAddOns();
writer_info* info; writer_info* info;
for (fWriterList.Rewind(); fWriterList.GetNext(&info);) { for (fWriterList.Rewind(); fWriterList.GetNext(&info);) {
@@ -217,6 +206,7 @@ status_t
AddOnManager::GetFileFormat(media_file_format* _fileFormat, int32 cookie) AddOnManager::GetFileFormat(media_file_format* _fileFormat, int32 cookie)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
_RegisterAddOns();
media_file_format* fileFormat; media_file_format* fileFormat;
if (fWriterFileFormats.Get(cookie, &fileFormat)) { if (fWriterFileFormats.Get(cookie, &fileFormat)) {
@@ -234,6 +224,7 @@ AddOnManager::GetCodecInfo(media_codec_info* _codecInfo,
media_format* _inputFormat, media_format* _outputFormat, int32 cookie) media_format* _inputFormat, media_format* _outputFormat, int32 cookie)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
_RegisterAddOns();
encoder_info* info; encoder_info* info;
if (fEncoderList.Get(cookie, &info)) { if (fEncoderList.Get(cookie, &info)) {
@@ -254,56 +245,10 @@ AddOnManager::GetCodecInfo(media_codec_info* _codecInfo,
void void
AddOnManager::_RegisterAddOns() AddOnManager::_RegisterAddOns()
{ {
class CodecHandler : public AddOnMonitorHandler { // Check if add-ons are already registered.
private: if(!fReaderList.IsEmpty() || !fWriterList.IsEmpty()
AddOnManager* fManager; || !fDecoderList.IsEmpty() || !fEncoderList.IsEmpty())
return;
public:
CodecHandler(AddOnManager* manager)
{
fManager = manager;
}
virtual void AddOnCreated(const add_on_entry_info* entryInfo)
{
}
virtual void AddOnEnabled(const add_on_entry_info* entryInfo)
{
entry_ref ref;
make_entry_ref(entryInfo->dir_nref.device,
entryInfo->dir_nref.node, entryInfo->name, &ref);
fManager->_RegisterAddOn(ref);
}
virtual void AddOnDisabled(const add_on_entry_info* entryInfo)
{
entry_ref ref;
make_entry_ref(entryInfo->dir_nref.device,
entryInfo->dir_nref.node, entryInfo->name, &ref);
fManager->_UnregisterAddOn(ref);
}
virtual void AddOnRemoved(const add_on_entry_info* entryInfo)
{
}
};
fAddOnMonitorHandler = new CodecHandler(this);
fAddOnMonitor = new AddOnMonitor(fAddOnMonitorHandler);
// get safemode option for disabling user add-ons
char buffer[16];
size_t size = sizeof(buffer);
bool disableUserAddOns = _kern_get_safemode_option(
B_SAFEMODE_DISABLE_USER_ADD_ONS, buffer, &size) == B_OK
&& (!strcasecmp(buffer, "true")
|| !strcasecmp(buffer, "yes")
|| !strcasecmp(buffer, "on")
|| !strcasecmp(buffer, "enabled")
|| !strcmp(buffer, "1"));
char** directories = NULL; char** directories = NULL;
size_t directoryCount = 0; size_t directoryCount = 0;
@@ -311,22 +256,16 @@ AddOnManager::_RegisterAddOns()
if (find_paths_etc(get_architecture(), B_FIND_PATH_ADD_ONS_DIRECTORY, if (find_paths_etc(get_architecture(), B_FIND_PATH_ADD_ONS_DIRECTORY,
"media/plugins", B_FIND_PATH_EXISTING_ONLY, &directories, "media/plugins", B_FIND_PATH_EXISTING_ONLY, &directories,
&directoryCount) != B_OK) { &directoryCount) != B_OK) {
printf("AddOnManager::RegisterAddOns: failed to locate plugins\n");
return; return;
} }
node_ref nref;
BDirectory directory;
BPath path; BPath path;
for (uint i = 0; i < directoryCount; i++) { for (uint i = 0; i < directoryCount; i++) {
if (disableUserAddOns && i <= 1) BDirectory directory;
continue; if (directory.SetTo(directories[i]) == B_OK) {
entry_ref ref;
if (directory.SetTo(directories[i]) == B_OK while(directory.GetNextRef(&ref) == B_OK)
&& directory.GetNodeRef(&nref) == B_OK) { _RegisterAddOn(ref);
fAddOnMonitorHandler->AddDirectory(&nref);
// NOTE: This may already start registering add-ons in the
// AddOnMonitor looper thread after the call returns!
} }
} }
} }
@@ -410,7 +349,6 @@ printf("removing decoder '%s'\n", decoderInfo->ref.name);
media_format* format; media_format* format;
for (decoderInfo->formats.Rewind(); for (decoderInfo->formats.Rewind();
decoderInfo->formats.GetNext(&format);) { decoderInfo->formats.GetNext(&format);) {
gFormatManager->RemoveFormat(*format);
} }
fDecoderList.RemoveCurrent(); fDecoderList.RemoveCurrent();
break; break;
@@ -591,7 +529,7 @@ AddOnManager::_RegisterEncoder(EncoderPlugin* plugin, const entry_ref& ref)
bool bool
AddOnManager::_FindDecoder(const media_format& format, const BPath& path, AddOnManager::_FindDecoder(const media_format& format, const BPath& path,
xfer_entry_ref* _decoderRef) entry_ref* _decoderRef)
{ {
node_ref nref; node_ref nref;
BDirectory directory; BDirectory directory;
@@ -624,7 +562,7 @@ AddOnManager::_FindDecoder(const media_format& format, const BPath& path,
void void
AddOnManager::_GetReaders(const BPath& path, xfer_entry_ref* outRefs, AddOnManager::_GetReaders(const BPath& path, entry_ref* outRefs,
int32* outCount, int32 maxCount) int32* outCount, int32 maxCount)
{ {
node_ref nref; node_ref nref;
+8 -12
View File
@@ -19,8 +19,6 @@
#include "DataExchange.h" #include "DataExchange.h"
#include "TList.h" #include "TList.h"
#include "AddOnMonitor.h"
#include "AddOnMonitorHandler.h"
#include "DecoderPlugin.h" #include "DecoderPlugin.h"
#include "EncoderPlugin.h" #include "EncoderPlugin.h"
#include "ReaderPlugin.h" #include "ReaderPlugin.h"
@@ -32,18 +30,17 @@ public:
AddOnManager(); AddOnManager();
~AddOnManager(); ~AddOnManager();
void LoadState(); static AddOnManager* GetInstance();
void SaveState();
status_t GetDecoderForFormat(xfer_entry_ref* _ref, status_t GetDecoderForFormat(entry_ref* _ref,
const media_format& format); const media_format& format);
status_t GetReaders(xfer_entry_ref* _ref, status_t GetReaders(entry_ref* _ref,
int32* _count, int32 maxCount); int32* _count, int32 maxCount);
status_t GetEncoder(xfer_entry_ref* _ref, int32 id); status_t GetEncoder(entry_ref* _ref, int32 id);
status_t GetWriter(xfer_entry_ref* _ref, status_t GetWriter(entry_ref* _ref,
uint32 internalID); uint32 internalID);
status_t GetFileFormat(media_file_format* _fileFormat, status_t GetFileFormat(media_file_format* _fileFormat,
@@ -71,9 +68,9 @@ private:
bool _FindDecoder(const media_format& format, bool _FindDecoder(const media_format& format,
const BPath& path, const BPath& path,
xfer_entry_ref* _decoderRef); entry_ref* _decoderRef);
void _GetReaders(const BPath& path, void _GetReaders(const BPath& path,
xfer_entry_ref* outRefs, int32* outCount, entry_ref* outRefs, int32* outCount,
int32 maxCount); int32 maxCount);
private: private:
@@ -108,8 +105,7 @@ private:
uint32 fNextWriterFormatFamilyID; uint32 fNextWriterFormatFamilyID;
uint32 fNextEncoderCodecInfoID; uint32 fNextEncoderCodecInfoID;
AddOnMonitorHandler* fAddOnMonitorHandler; static AddOnManager sInstance;
AddOnMonitor* fAddOnMonitor;
}; };
#endif // _ADD_ON_MANAGER_H #endif // _ADD_ON_MANAGER_H
+10 -52
View File
@@ -134,41 +134,24 @@ FormatManager::~FormatManager()
} }
void
FormatManager::LoadState()
{
}
void
FormatManager::SaveState()
{
}
/*! This method is called when BMediaFormats asks for any updates /*! This method is called when BMediaFormats asks for any updates
made to our format list. made to our format list.
If there were any changes since the last time, the whole If there were any changes since the last time, the whole
list will be sent back. list will be sent back.
*/ */
void void
FormatManager::GetFormats(BMessage& message) FormatManager::GetFormats(bigtime_t lastUpdate, BMessage& reply)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
bigtime_t lastUpdate; if (lastUpdate >= fLastUpdate) {
if (message.FindInt64("last_timestamp", &lastUpdate) == B_OK
&& lastUpdate >= fLastUpdate) {
// There weren't any changes since last time. // There weren't any changes since last time.
BMessage reply;
reply.AddBool("need_update", false); reply.AddBool("need_update", false);
message.SendReply(&reply, (BHandler*)NULL, TIMEOUT);
return; return;
} }
// Add all meta formats to the list // Add all meta formats to the list
BMessage reply;
reply.AddBool("need_update", true); reply.AddBool("need_update", true);
reply.AddInt64("timestamp", system_time()); reply.AddInt64("timestamp", system_time());
@@ -180,30 +163,15 @@ FormatManager::GetFormats(BMessage& message)
reply.AddData("formats", MEDIA_META_FORMAT_TYPE, format, reply.AddData("formats", MEDIA_META_FORMAT_TYPE, format,
sizeof(meta_format)); sizeof(meta_format));
} }
message.SendReply(&reply, (BHandler*)NULL, TIMEOUT);
} }
void status_t
FormatManager::MakeFormatFor(BMessage& message) FormatManager::MakeFormatFor(const media_format_description* descriptions,
int32 descriptionCount, media_format& format, uint32 flags, void* _reserved)
{ {
BAutolock locker(fLock); BAutolock locker(fLock);
media_format format;
const void* data;
ssize_t size;
if (message.FindData("format", B_RAW_TYPE, 0, &data, &size) != B_OK
|| size != sizeof(format)) {
// Couldn't get the format
BMessage reply;
reply.AddInt32("result", B_ERROR);
message.SendReply(&reply, (BHandler*)NULL, TIMEOUT);
return;
}
// Copy the BMessage's data into our format
format = *(media_format*)data;
int codec = fNextCodecID; int codec = fNextCodecID;
switch (format.type) { switch (format.type) {
case B_MEDIA_RAW_AUDIO: case B_MEDIA_RAW_AUDIO:
@@ -246,22 +214,16 @@ FormatManager::MakeFormatFor(BMessage& message)
break; break;
default: default:
// nothing to do // nothing to do
BMessage reply; return B_OK;
reply.AddInt32("result", B_OK);
reply.AddData("format", B_RAW_TYPE, &format, sizeof(format));
message.SendReply(&reply, (BHandler*)NULL, TIMEOUT);
return;
} }
fLastUpdate = system_time(); fLastUpdate = system_time();
status_t result = B_OK; status_t result = B_OK;
// TODO: Support "flags" (B_SET_DEFAULT, B_EXCLUSIVE, B_NO_MERGE)! // TODO: Support "flags" (B_SET_DEFAULT, B_EXCLUSIVE, B_NO_MERGE)!
int32 i = 0; int32 i = 0;
while (message.FindData("description", B_RAW_TYPE, i++, &data, &size) for(i = 0; i < descriptionCount; i++) {
== B_OK && size == sizeof(media_format_description)) { meta_format* metaFormat = new(std::nothrow) meta_format(
meta_format* metaFormat descriptions[i], format, codec);
= new(std::nothrow) meta_format(*(media_format_description*)data,
format, codec);
if (metaFormat == NULL if (metaFormat == NULL
|| !fList.BinaryInsert(metaFormat, meta_format::Compare)) { || !fList.BinaryInsert(metaFormat, meta_format::Compare)) {
delete metaFormat; delete metaFormat;
@@ -270,11 +232,7 @@ FormatManager::MakeFormatFor(BMessage& message)
} }
} }
BMessage reply; return B_OK;
reply.AddInt32("result", result);
if (result == B_OK)
reply.AddData("format", B_RAW_TYPE, &format, sizeof(format));
message.SendReply(&reply, (BHandler*)NULL, TIMEOUT);
} }
+6 -5
View File
@@ -21,11 +21,12 @@ public:
FormatManager(); FormatManager();
~FormatManager(); ~FormatManager();
void LoadState(); void GetFormats(bigtime_t lastUpdate, BMessage& reply);
void SaveState(); status_t MakeFormatFor(
const media_format_description* descriptions,
void GetFormats(BMessage& message); int32 descriptionCount,
void MakeFormatFor(BMessage& message); media_format& format, uint32 flags,
void* _reserved);
void RemoveFormat(const media_format& format); void RemoveFormat(const media_format& format);
private: private:
+48 -69
View File
@@ -8,7 +8,9 @@
*/ */
#include "AddOnManager.h"
#include "DataExchange.h" #include "DataExchange.h"
#include "FormatManager.h"
#include "MetaFormat.h" #include "MetaFormat.h"
#include "debug.h" #include "debug.h"
@@ -40,29 +42,32 @@ get_next_encoder(int32* cookie, const media_file_format* fileFormat,
return B_BAD_VALUE; return B_BAD_VALUE;
while (true) { while (true) {
server_get_codec_info_request request; media_codec_info codec_info;
request.cookie = *cookie; media_format_family format_family;
server_get_codec_info_reply reply; media_format input_format;
status_t ret = QueryServer(SERVER_GET_CODEC_INFO_FOR_COOKIE, &request, media_format output_format;
sizeof(request), &reply, sizeof(reply));
status_t ret = AddOnManager::GetInstance()->GetCodecInfo(&codec_info,
&format_family, &input_format, &output_format, *cookie);
if (ret != B_OK) if (ret != B_OK)
return ret; return ret;
*cookie = *cookie + 1; *cookie = *cookie + 1;
if (fileFormat != NULL && reply.format_family != B_ANY_FORMAT_FAMILY if (fileFormat != NULL && format_family != B_ANY_FORMAT_FAMILY
&& fileFormat->family != B_ANY_FORMAT_FAMILY && fileFormat->family != B_ANY_FORMAT_FAMILY
&& fileFormat->family != reply.format_family) { && fileFormat->family != format_family) {
continue; continue;
} }
if (!reply.input_format.Matches(inputFormat)) if (!input_format.Matches(inputFormat))
continue; continue;
if (_outputFormat != NULL) if (_outputFormat != NULL)
*_outputFormat = reply.output_format; *_outputFormat = output_format;
*_codecInfo = reply.codec_info; *_codecInfo = codec_info;
break; break;
} }
@@ -86,24 +91,27 @@ get_next_encoder(int32* cookie, const media_file_format* fileFormat,
} }
while (true) { while (true) {
server_get_codec_info_request request; media_codec_info codec_info;
request.cookie = *cookie; media_format_family format_family;
server_get_codec_info_reply reply; media_format input_format;
status_t ret = QueryServer(SERVER_GET_CODEC_INFO_FOR_COOKIE, &request, media_format output_format;
sizeof(request), &reply, sizeof(reply));
status_t ret = AddOnManager::GetInstance()->GetCodecInfo(&codec_info,
&format_family, &input_format, &output_format, *cookie);
if (ret != B_OK) if (ret != B_OK)
return ret; return ret;
*cookie = *cookie + 1; *cookie = *cookie + 1;
if (fileFormat != NULL && reply.format_family != B_ANY_FORMAT_FAMILY if (fileFormat != NULL && format_family != B_ANY_FORMAT_FAMILY
&& fileFormat->family != B_ANY_FORMAT_FAMILY && fileFormat->family != B_ANY_FORMAT_FAMILY
&& fileFormat->family != reply.format_family) { && fileFormat->family != format_family) {
continue; continue;
} }
if (!reply.input_format.Matches(inputFormat) if (!input_format.Matches(inputFormat)
|| !reply.output_format.Matches(outputFormat)) { || !output_format.Matches(outputFormat)) {
continue; continue;
} }
@@ -113,11 +121,11 @@ get_next_encoder(int32* cookie, const media_file_format* fileFormat,
// possible, we actually have to instantiate an Encoder here and // possible, we actually have to instantiate an Encoder here and
// ask it to specifiy the format. // ask it to specifiy the format.
if (_acceptedInputFormat != NULL) if (_acceptedInputFormat != NULL)
*_acceptedInputFormat = reply.input_format; *_acceptedInputFormat = input_format;
if (_acceptedOutputFormat != NULL) if (_acceptedOutputFormat != NULL)
*_acceptedOutputFormat = reply.output_format; *_acceptedOutputFormat = output_format;
*_codecInfo = reply.codec_info; *_codecInfo = codec_info;
break; break;
} }
@@ -131,16 +139,18 @@ get_next_encoder(int32* cookie, media_codec_info* _codecInfo)
if (cookie == NULL || _codecInfo == NULL) if (cookie == NULL || _codecInfo == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
server_get_codec_info_request request; media_codec_info codec_info;
request.cookie = *cookie; media_format_family format_family;
server_get_codec_info_reply reply; media_format input_format;
status_t ret = QueryServer(SERVER_GET_CODEC_INFO_FOR_COOKIE, &request, media_format output_format;
sizeof(request), &reply, sizeof(reply));
status_t ret = AddOnManager::GetInstance()->GetCodecInfo(&codec_info,
&format_family, &input_format, &output_format, *cookie);
if (ret != B_OK) if (ret != B_OK)
return ret; return ret;
*cookie = *cookie + 1; *cookie = *cookie + 1;
*_codecInfo = reply.codec_info; *_codecInfo = codec_info;
return B_OK; return B_OK;
} }
@@ -350,22 +360,18 @@ meta_format::Compare(const meta_format* a, const meta_format* b)
* The formats lock has to be hold when you call this function. * The formats lock has to be hold when you call this function.
*/ */
FormatManager* gFormatManager = NULL;
static status_t static status_t
update_media_formats() update_media_formats()
{ {
if (!sLock.IsLocked()) if (!sLock.IsLocked())
return B_NOT_ALLOWED; return B_NOT_ALLOWED;
BMessage request(MEDIA_SERVER_GET_FORMATS);
request.AddInt64("last_timestamp", sLastFormatsUpdate);
BMessage reply; BMessage reply;
status_t status = QueryServer(request, reply); if (gFormatManager == NULL)
if (status < B_OK) { gFormatManager = new FormatManager;
ERROR("BMediaFormats: Could not update formats: %s\n", gFormatManager->GetFormats(sLastFormatsUpdate, reply);
strerror(status));
return status;
}
// do we need an update at all? // do we need an update at all?
bool needUpdate; bool needUpdate;
@@ -616,40 +622,13 @@ BMediaFormats::MakeFormatFor(const media_format_description* descriptions,
int32 descriptionCount, media_format* format, uint32 flags, int32 descriptionCount, media_format* format, uint32 flags,
void* _reserved) void* _reserved)
{ {
BMessage request(MEDIA_SERVER_MAKE_FORMAT_FOR); if (gFormatManager == NULL)
for (int32 i = 0 ; i < descriptionCount ; i++) { gFormatManager = new FormatManager;
request.AddData("description", B_RAW_TYPE, &descriptions[i],
sizeof(descriptions[i]));
}
request.AddData("format", B_RAW_TYPE, format, sizeof(*format));
request.AddData("flags", B_UINT32_TYPE, &flags, sizeof(flags));
request.AddPointer("_reserved", _reserved);
BMessage reply; status_t status = gFormatManager->MakeFormatFor(descriptions,
status_t status = QueryServer(request, reply); descriptionCount, *format, flags, _reserved);
if (status != B_OK) {
ERROR("BMediaFormats: Could not make a format: %s\n", strerror(status));
return status;
}
// check the status return status;
if (reply.FindInt32("result", &status) < B_OK)
return B_ERROR;
if (status != B_OK)
return status;
// get the format
const void* data;
ssize_t size;
if (reply.FindData("format", B_RAW_TYPE, 0, &data, &size) != B_OK)
return B_ERROR;
if (size != sizeof(*format))
return B_ERROR;
// copy the BMessage's data into our format
*format = *(media_format*)data;
return B_OK;
} }