update to the codec api, docoder assignment is now handled in the server
multiple reader add-ons are probed to recognize a media file FormatManager does the translation from media_format to media_description git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5667 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
6d59046016
commit
046f31f91f
@ -599,6 +599,7 @@ typedef enum {
|
||||
B_WAV_FORMAT_FAMILY = 6,
|
||||
B_AIFF_FORMAT_FAMILY = 7,
|
||||
B_AVR_FORMAT_FAMILY = 8,
|
||||
B_OGG_FORMAT_FAMILY = 9,
|
||||
B_MISC_FORMAT_FAMILY = 99999,
|
||||
B_META_FORMAT_FAMILY = 100000
|
||||
} media_format_family;
|
||||
|
@ -106,7 +106,9 @@ enum {
|
||||
SERVER_REMOVEREFFOR,
|
||||
SERVER_REMOVEITEM,
|
||||
SERVER_GET_FORMAT_FOR_DESCRIPTION,
|
||||
SERVER_GET_META_DESCRIPTION_FOR_FORMAT,
|
||||
SERVER_GET_DESCRIPTION_FOR_FORMAT,
|
||||
SERVER_GET_READERS,
|
||||
SERVER_GET_DECODER_FOR_FORMAT,
|
||||
SERVER_MESSAGE_END,
|
||||
NODE_MESSAGE_START = 0x200,
|
||||
|
||||
@ -206,7 +208,7 @@ public:
|
||||
private:
|
||||
dev_t device;
|
||||
ino_t directory;
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
char name[B_FILE_NAME_LENGTH]; // == 256 bytes
|
||||
};
|
||||
|
||||
|
||||
@ -243,6 +245,12 @@ enum
|
||||
MAX_NODE_ID = 4000,
|
||||
};
|
||||
|
||||
// used by SERVER_GET_READERS
|
||||
enum
|
||||
{
|
||||
MAX_READERS = 40,
|
||||
};
|
||||
|
||||
struct addonserver_instantiate_dormant_node_request : public request_data
|
||||
{
|
||||
media_addon_id addonid;
|
||||
@ -889,14 +897,35 @@ struct server_get_format_for_description_reply : public reply_data
|
||||
media_format format;
|
||||
};
|
||||
|
||||
struct server_get_meta_description_for_format_request : public request_data
|
||||
struct server_get_description_for_format_request : public request_data
|
||||
{
|
||||
media_format format;
|
||||
media_format_family family;
|
||||
};
|
||||
|
||||
struct server_get_description_for_format_reply : public reply_data
|
||||
{
|
||||
media_format_description description;
|
||||
};
|
||||
|
||||
struct server_get_decoder_for_format_request : public request_data
|
||||
{
|
||||
media_format format;
|
||||
};
|
||||
|
||||
struct server_get_meta_description_for_format_reply : public reply_data
|
||||
struct server_get_decoder_for_format_reply : public reply_data
|
||||
{
|
||||
media_format_description description;
|
||||
xfer_entry_ref ref; // a ref to the decoder
|
||||
};
|
||||
|
||||
struct server_get_readers_request : public request_data
|
||||
{
|
||||
};
|
||||
|
||||
struct server_get_readers_reply : public reply_data
|
||||
{
|
||||
xfer_entry_ref ref[MAX_READERS]; // a list of refs to the reader
|
||||
int32 count;
|
||||
};
|
||||
|
||||
struct node_request_completed_command : public command_data
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "MediaPlugin.h"
|
||||
#include "MediaExtractor.h"
|
||||
|
||||
class AddOnManager;
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
|
||||
class Decoder
|
||||
@ -43,9 +45,17 @@ class DecoderPlugin : public MediaPlugin
|
||||
public:
|
||||
DecoderPlugin();
|
||||
|
||||
virtual Decoder *NewDecoder() = 0;
|
||||
virtual Decoder * NewDecoder() = 0;
|
||||
|
||||
status_t PublishDecoder(const char *meta_description, const char *short_name, const char *pretty_name, const char *default_mapping = 0);
|
||||
status_t PublishDecoder(const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping = 0);
|
||||
|
||||
private:
|
||||
friend class AddOnManager;
|
||||
void Setup(void *publish_hook);
|
||||
void * fPublishHook;
|
||||
};
|
||||
|
||||
} } // namespace BPrivate::media
|
||||
|
@ -24,11 +24,11 @@ public:
|
||||
PluginManager();
|
||||
~PluginManager();
|
||||
|
||||
MediaPlugin * GetPlugin(const char *name);
|
||||
MediaPlugin * GetPlugin(const entry_ref &ref);
|
||||
void PutPlugin(MediaPlugin *plugin);
|
||||
|
||||
private:
|
||||
bool LoadPlugin(const char *name, MediaPlugin **plugin, image_id *image);
|
||||
bool LoadPlugin(const entry_ref &ref, MediaPlugin **plugin, image_id *image);
|
||||
|
||||
struct plugin_info
|
||||
{
|
||||
|
@ -154,7 +154,7 @@ mp3Reader::Sniff(int32 *streamCount)
|
||||
TRACE("mp3Reader::Sniff: file size is %Ld bytes\n", fFileSize);
|
||||
|
||||
if (!IsMp3File()) {
|
||||
TRACE("mp3Reader::Sniff: non recognized as mp3 file\n");
|
||||
TRACE("mp3Reader::Sniff: not recognized as mp3 file\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@ -903,7 +903,7 @@ mp3Reader::GetFrameLength(void *header)
|
||||
int bitrate_index = (h[2] >> 4) & 0x0f;
|
||||
int sampling_rate_index = (h[2] >> 2) & 0x03;
|
||||
int padding = (h[2] >> 1) & 0x01;
|
||||
/* no interested in the other bits */
|
||||
/* not interested in the other bits */
|
||||
|
||||
int bitrate = bit_rate_table[mpeg_version_index][layer_index][bitrate_index];
|
||||
int framerate = frame_rate_table[mpeg_version_index][sampling_rate_index];
|
||||
|
@ -27,14 +27,25 @@ Decoder::Setup(MediaExtractor *extractor, int32 stream)
|
||||
}
|
||||
|
||||
DecoderPlugin::DecoderPlugin()
|
||||
: fPublishHook(0)
|
||||
{
|
||||
}
|
||||
|
||||
typedef status_t (*publish_func)(DecoderPlugin *, const char *, const char *, const char *, const char *);
|
||||
|
||||
status_t
|
||||
DecoderPlugin::PublishDecoder(const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */)
|
||||
{
|
||||
return _PublishDecoder(this, meta_description, short_name, pretty_name, default_mapping);
|
||||
if (fPublishHook)
|
||||
return ((publish_func)fPublishHook)(this, meta_description, short_name, pretty_name, default_mapping);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
DecoderPlugin::Setup(void *publish_hook)
|
||||
{
|
||||
fPublishHook = publish_hook;
|
||||
}
|
||||
|
@ -172,8 +172,14 @@ BMediaFormats::GetCodeFor(const media_format & format,
|
||||
media_format_family family,
|
||||
media_format_description * out_description)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
server_get_description_for_format_request request;
|
||||
server_get_description_for_format_reply reply;
|
||||
request.format = format;
|
||||
request.family = family;
|
||||
if (B_OK != QueryServer(SERVER_GET_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply)))
|
||||
return B_ERROR;
|
||||
*out_description = reply.description;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -246,6 +252,8 @@ bool operator==(const media_format_description & a, const media_format_descripti
|
||||
return a.u.aiff.codec == b.u.aiff.codec;
|
||||
case B_AVR_FORMAT_FAMILY:
|
||||
return a.u.avr.id == b.u.avr.id;
|
||||
case B_OGG_FORMAT_FAMILY:
|
||||
return false; // XXX fix this
|
||||
case B_MISC_FORMAT_FAMILY:
|
||||
return a.u.misc.file_format == b.u.misc.file_format && a.u.misc.codec == b.u.misc.codec;
|
||||
case B_META_FORMAT_FAMILY:
|
||||
@ -276,6 +284,8 @@ bool operator<(const media_format_description & a, const media_format_descriptio
|
||||
return a.u.aiff.codec < b.u.aiff.codec;
|
||||
case B_AVR_FORMAT_FAMILY:
|
||||
return a.u.avr.id < b.u.avr.id;
|
||||
case B_OGG_FORMAT_FAMILY:
|
||||
return false; // XXX fix this
|
||||
case B_MISC_FORMAT_FAMILY:
|
||||
return a.u.misc.file_format < b.u.misc.file_format || a.u.misc.codec < b.u.misc.codec;
|
||||
case B_META_FORMAT_FAMILY:
|
||||
@ -303,14 +313,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 (in_desc.family == B_BEOS_FORMAT_FAMILY && in_desc.u.beos.format == B_BEOS_FORMAT_RAW_AUDIO)
|
||||
reply.format.type = B_MEDIA_RAW_AUDIO;
|
||||
else
|
||||
reply.format.type = B_MEDIA_ENCODED_AUDIO;
|
||||
reply.format.u.encoded_audio.encoding = (enum media_encoded_audio_format::audio_encoding) 1;
|
||||
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;
|
||||
@ -319,13 +323,14 @@ _get_format_for_description(media_format *out_format, const media_format_descrip
|
||||
status_t
|
||||
_get_meta_description_for_format(media_format_description *out_desc, const media_format &in_format)
|
||||
{
|
||||
server_get_meta_description_for_format_request request;
|
||||
server_get_meta_description_for_format_reply reply;
|
||||
server_get_description_for_format_request request;
|
||||
server_get_description_for_format_reply reply;
|
||||
|
||||
request.format = in_format;
|
||||
request.family = B_META_FORMAT_FAMILY;
|
||||
|
||||
// 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_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply)))
|
||||
return B_ERROR;
|
||||
|
||||
*out_desc = reply.description;
|
||||
return B_OK;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "PluginManager.h"
|
||||
#include "DataExchange.h"
|
||||
#include "debug.h"
|
||||
|
||||
PluginManager _plugin_manager;
|
||||
@ -12,16 +13,24 @@ _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BData
|
||||
{
|
||||
printf("_CreateReader enter\n");
|
||||
|
||||
MediaPlugin *plugin;
|
||||
ReaderPlugin *readerplugin;
|
||||
// get list of available readers from, the server
|
||||
server_get_readers_request request;
|
||||
server_get_readers_reply reply;
|
||||
if (B_OK != QueryServer(SERVER_GET_READERS, &request, sizeof(request), &reply, sizeof(reply))) {
|
||||
printf("_CreateReader: can't get list of readers\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
plugin = _plugin_manager.GetPlugin("mp3_reader");
|
||||
// try each reader by calling it's Sniff function...
|
||||
for (int32 i = 0; i < reply.count; i++) {
|
||||
entry_ref ref = reply.ref[i];
|
||||
MediaPlugin *plugin = _plugin_manager.GetPlugin(ref);
|
||||
if (!plugin) {
|
||||
printf("_CreateReader: GetPlugin failed\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
readerplugin = dynamic_cast<ReaderPlugin *>(plugin);
|
||||
ReaderPlugin *readerplugin = dynamic_cast<ReaderPlugin *>(plugin);
|
||||
if (!readerplugin) {
|
||||
printf("_CreateReader: dynamic_cast failed\n");
|
||||
return B_ERROR;
|
||||
@ -35,18 +44,19 @@ _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BData
|
||||
|
||||
(*reader)->Setup(source);
|
||||
|
||||
if (B_OK != (*reader)->Sniff(streamCount)) {
|
||||
printf("_CreateReader: Sniff failed\n");
|
||||
_DestroyReader(*reader);
|
||||
return B_MEDIA_NO_HANDLER;
|
||||
// return B_ERROR;
|
||||
if (B_OK == (*reader)->Sniff(streamCount)) {
|
||||
printf("_CreateReader: Sniff success\n");
|
||||
(*reader)->GetFileFormatInfo(mff);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
(*reader)->GetFileFormatInfo(mff);
|
||||
// _DestroyReader(*reader);
|
||||
delete *reader;
|
||||
_plugin_manager.PutPlugin(plugin);
|
||||
}
|
||||
|
||||
printf("_CreateReader leave\n");
|
||||
|
||||
return B_OK;
|
||||
return B_MEDIA_NO_HANDLER;
|
||||
}
|
||||
|
||||
status_t
|
||||
@ -54,10 +64,19 @@ _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *for
|
||||
{
|
||||
printf("_CreateDecoder enter\n");
|
||||
|
||||
// get decoder for this format from the server
|
||||
server_get_decoder_for_format_request request;
|
||||
server_get_decoder_for_format_reply reply;
|
||||
request.format = *format;
|
||||
if (B_OK != QueryServer(SERVER_GET_DECODER_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply))) {
|
||||
printf("_CreateReader: can't get decoder for format\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
MediaPlugin *plugin;
|
||||
DecoderPlugin *decoderplugin;
|
||||
|
||||
plugin = _plugin_manager.GetPlugin("mp3_decoder");
|
||||
plugin = _plugin_manager.GetPlugin(reply.ref);
|
||||
if (!plugin) {
|
||||
printf("_CreateDecoder: GetPlugin failed\n");
|
||||
return B_ERROR;
|
||||
@ -96,20 +115,6 @@ _DestroyDecoder(Decoder *decoder)
|
||||
delete 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()
|
||||
{
|
||||
@ -135,7 +140,7 @@ PluginManager::~PluginManager()
|
||||
|
||||
|
||||
MediaPlugin *
|
||||
PluginManager::GetPlugin(const char *name)
|
||||
PluginManager::GetPlugin(const entry_ref &ref)
|
||||
{
|
||||
fLocker->Lock();
|
||||
|
||||
@ -144,7 +149,7 @@ PluginManager::GetPlugin(const char *name)
|
||||
plugin_info info;
|
||||
|
||||
for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) {
|
||||
if (0 == strcmp(name, pinfo->name)) {
|
||||
if (0 == strcmp(ref.name, pinfo->name)) {
|
||||
plugin = pinfo->plugin;
|
||||
pinfo->usecount++;
|
||||
fLocker->Unlock();
|
||||
@ -152,17 +157,17 @@ PluginManager::GetPlugin(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
if (!LoadPlugin(name, &info.plugin, &info.image)) {
|
||||
printf("PluginManager: Error, loading PlugIn %s failed\n", name);
|
||||
if (!LoadPlugin(ref, &info.plugin, &info.image)) {
|
||||
printf("PluginManager: Error, loading PlugIn %s failed\n", ref.name);
|
||||
fLocker->Unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(info.name, name);
|
||||
strcpy(info.name, ref.name);
|
||||
info.usecount = 1;
|
||||
fPluginList->Insert(info);
|
||||
|
||||
printf("PluginManager: PlugIn %s loaded\n", name);
|
||||
printf("PluginManager: PlugIn %s loaded\n", ref.name);
|
||||
|
||||
plugin = info.plugin;
|
||||
|
||||
@ -198,31 +203,23 @@ PluginManager::PutPlugin(MediaPlugin *plugin)
|
||||
|
||||
|
||||
bool
|
||||
PluginManager::LoadPlugin(const char *name, MediaPlugin **plugin, image_id *image)
|
||||
PluginManager::LoadPlugin(const entry_ref &ref, 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);
|
||||
BPath p(&ref);
|
||||
|
||||
printf("PluginManager: LoadPlugin trying to load %s\n", p.Path());
|
||||
|
||||
image_id id;
|
||||
id = load_add_on(p.Path());
|
||||
if (id < 0)
|
||||
continue;
|
||||
return false;
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
MediaPlugin *pl;
|
||||
@ -231,13 +228,10 @@ PluginManager::LoadPlugin(const char *name, MediaPlugin **plugin, image_id *imag
|
||||
if (pl == 0) {
|
||||
printf("PluginManager: Error, LoadPlugin instantiate_plugin in %s returned 0\n", p.Path());
|
||||
unload_add_on(id);
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
*plugin = pl;
|
||||
*image = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ _SoundPlayNode::_SoundPlayNode(const char *name, const media_multi_audio_format
|
||||
mFormat.u.raw_audio = *format;
|
||||
|
||||
DPRINTF("Format Info:\n");
|
||||
DPRINTF(" frame_rate: %f\n",mFormat.u.raw_audio.frame_rate);
|
||||
DPRINTF(" frame_rate: %.1f (%ld)\n", mFormat.u.raw_audio.frame_rate, (int32)mFormat.u.raw_audio.frame_rate);
|
||||
DPRINTF(" channel_count: %ld\n",mFormat.u.raw_audio.channel_count);
|
||||
DPRINTF(" byte_order: %ld (",mFormat.u.raw_audio.byte_order);
|
||||
switch (mFormat.u.raw_audio.byte_order) {
|
||||
@ -366,12 +366,11 @@ _SoundPlayNode::Connect(status_t error, const media_source& source, const media_
|
||||
TRACE("_SoundPlayNode::Connect: downstream latency = %Ld\n", mLatency);
|
||||
|
||||
// reset our buffer duration, etc. to avoid later calculations
|
||||
bigtime_t duration = mOutput.format.u.raw_audio.buffer_size * 10000
|
||||
/ ( (mOutput.format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK)
|
||||
* mOutput.format.u.raw_audio.channel_count)
|
||||
/ ((int32)(mOutput.format.u.raw_audio.frame_rate / 100));
|
||||
bigtime_t duration = ((mOutput.format.u.raw_audio.buffer_size * 1000000LL)
|
||||
/ ((mOutput.format.u.raw_audio.format & media_raw_audio_format::B_AUDIO_SIZE_MASK) * mOutput.format.u.raw_audio.channel_count))
|
||||
/ (int32)mOutput.format.u.raw_audio.frame_rate;
|
||||
SetBufferDuration(duration);
|
||||
TRACE("_SoundPlayNode::Connect: buffer duaration is %Ld\n", duration);
|
||||
TRACE("_SoundPlayNode::Connect: buffer duration is %Ld\n", duration);
|
||||
|
||||
mInternalLatency = (3 * BufferDuration()) / 4;
|
||||
TRACE("_SoundPlayNode::Connect: using %Ld as internal latency\n", mInternalLatency);
|
||||
@ -614,7 +613,7 @@ _SoundPlayNode::SendNewBuffer(const media_timed_event *event, bigtime_t lateness
|
||||
|
||||
// The buffer is on its way; now schedule the next one to go
|
||||
// nextEvent is the time at which the buffer should arrive at it's destination
|
||||
bigtime_t nextEvent = mStartTime + bigtime_t((1000000LL * mFramesSent) / mOutput.format.u.raw_audio.frame_rate);
|
||||
bigtime_t nextEvent = mStartTime + bigtime_t((1000000LL * mFramesSent) / (int32)mOutput.format.u.raw_audio.frame_rate);
|
||||
media_timed_event nextBufferEvent(nextEvent, SEND_NEW_BUFFER_EVENT);
|
||||
EventQueue()->AddEvent(nextBufferEvent);
|
||||
|
||||
|
258
src/servers/media/AddOnManager.cpp
Normal file
258
src/servers/media/AddOnManager.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
#include <MediaFormats.h>
|
||||
#include <Locker.h>
|
||||
#include <Path.h>
|
||||
#include <Entry.h>
|
||||
#include <Directory.h>
|
||||
#include <image.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "AddOnManager.h"
|
||||
#include "FormatManager.h"
|
||||
#include "debug.h"
|
||||
|
||||
extern FormatManager *gFormatManager;
|
||||
extern AddOnManager *gAddOnManager;
|
||||
|
||||
status_t
|
||||
_PublishDecoder(DecoderPlugin *decoderplugin,
|
||||
const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */);
|
||||
|
||||
bool operator==(const media_meta_description & a, const media_meta_description & b);
|
||||
|
||||
AddOnManager::AddOnManager()
|
||||
: fLocker(new BLocker),
|
||||
fReaderList(new List<reader_info>),
|
||||
fWriterList(new List<writer_info>),
|
||||
fDecoderList(new List<decoder_info>),
|
||||
fEncoderList(new List<encoder_info>),
|
||||
fReaderInfo(0),
|
||||
fWriterInfo(0),
|
||||
fDecoderInfo(0),
|
||||
fEncoderInfo(0)
|
||||
{
|
||||
}
|
||||
|
||||
AddOnManager::~AddOnManager()
|
||||
{
|
||||
delete fLocker;
|
||||
delete fReaderList;
|
||||
delete fWriterList;
|
||||
delete fDecoderList;
|
||||
delete fEncoderList;
|
||||
}
|
||||
|
||||
void
|
||||
AddOnManager::LoadState()
|
||||
{
|
||||
RegisterAddOns();
|
||||
}
|
||||
|
||||
void
|
||||
AddOnManager::SaveState()
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
AddOnManager::GetDecoderForFormat(xfer_entry_ref *out_ref,
|
||||
const media_format &in_format)
|
||||
{
|
||||
media_format_description desc;
|
||||
|
||||
if (B_OK != gFormatManager->GetDescriptionForFormat(&desc, in_format, B_META_FORMAT_FAMILY)) {
|
||||
printf("AddOnManager::GetDecoderForFormat: Error, meta format description unknown\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fLocker->Lock();
|
||||
decoder_info *info;
|
||||
for (fDecoderList->Rewind(); fDecoderList->GetNext(&info); ) {
|
||||
media_meta_description *meta_desc;
|
||||
for (info->meta_desc.Rewind(); info->meta_desc.GetNext(&meta_desc); ) {
|
||||
if (desc.u.meta == *meta_desc) {
|
||||
printf("AddOnManager::GetDecoderForFormat: found decoder %s for format %s\n", info->ref.name, meta_desc->description);
|
||||
*out_ref = info->ref;
|
||||
fLocker->Unlock();
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
fLocker->Unlock();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
status_t
|
||||
AddOnManager::GetReaders(xfer_entry_ref *out_res, int32 *out_count, int32 max_count)
|
||||
{
|
||||
fLocker->Lock();
|
||||
|
||||
*out_count = 0;
|
||||
|
||||
reader_info *info;
|
||||
for (*out_count = 0, fReaderList->Rewind(); fReaderList->GetNext(&info) && *out_count <= max_count; *out_count += 1)
|
||||
out_res[*out_count] = info->ref;
|
||||
|
||||
fLocker->Unlock();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
AddOnManager::RegisterAddOns()
|
||||
{
|
||||
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++) {
|
||||
BDirectory dir(searchdir[i]);
|
||||
BEntry e;
|
||||
while (B_OK == dir.GetNextEntry(&e)) {
|
||||
BPath p(&e);
|
||||
entry_ref ref;
|
||||
e.GetRef(&ref);
|
||||
|
||||
printf("AddOnManager: RegisterAddOns 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("AddOnManager: Error, RegisterAddOns 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("AddOnManager: Error, RegisterAddOns instantiate_plugin in %s returned 0\n", p.Path());
|
||||
unload_add_on(id);
|
||||
continue;
|
||||
}
|
||||
|
||||
ReaderPlugin *rp = dynamic_cast<ReaderPlugin *>(pl);
|
||||
if (rp)
|
||||
RegisterReader(rp, ref);
|
||||
|
||||
DecoderPlugin *dp = dynamic_cast<DecoderPlugin *>(pl);
|
||||
if (dp)
|
||||
RegisterDecoder(dp, ref);
|
||||
|
||||
delete pl;
|
||||
unload_add_on(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AddOnManager::RegisterReader(ReaderPlugin *reader, const entry_ref &ref)
|
||||
{
|
||||
bool already_found;
|
||||
reader_info *pinfo;
|
||||
|
||||
fLocker->Lock();
|
||||
for (already_found = false, fReaderList->Rewind(); fReaderList->GetNext(&pinfo); )
|
||||
if (0 == strcmp(pinfo->ref.name, ref.name)) {
|
||||
already_found = true;
|
||||
break;
|
||||
}
|
||||
fLocker->Unlock();
|
||||
if (already_found)
|
||||
return;
|
||||
|
||||
printf("AddOnManager::RegisterReader, name %s\n", ref.name);
|
||||
|
||||
reader_info info;
|
||||
info.ref = ref;
|
||||
|
||||
if (B_OK != reader->RegisterPlugin())
|
||||
return;
|
||||
|
||||
fLocker->Lock();
|
||||
fReaderList->Insert(info);
|
||||
fLocker->Unlock();
|
||||
}
|
||||
|
||||
void
|
||||
AddOnManager::RegisterDecoder(DecoderPlugin *decoder, const entry_ref &ref)
|
||||
{
|
||||
bool already_found;
|
||||
decoder_info *pinfo;
|
||||
|
||||
fLocker->Lock();
|
||||
for (already_found = false, fDecoderList->Rewind(); fDecoderList->GetNext(&pinfo); )
|
||||
if (0 == strcmp(pinfo->ref.name, ref.name)) {
|
||||
already_found = true;
|
||||
break;
|
||||
}
|
||||
fLocker->Unlock();
|
||||
if (already_found)
|
||||
return;
|
||||
|
||||
printf("AddOnManager::RegisterDecoder, name %s\n", ref.name);
|
||||
|
||||
decoder->Setup((void*)&_PublishDecoder);
|
||||
|
||||
decoder_info info;
|
||||
info.ref = ref;
|
||||
fDecoderInfo = &info;
|
||||
|
||||
if (B_OK != decoder->RegisterPlugin())
|
||||
return;
|
||||
|
||||
fLocker->Lock();
|
||||
fDecoderList->Insert(info);
|
||||
fLocker->Unlock();
|
||||
fDecoderInfo = 0;
|
||||
}
|
||||
|
||||
status_t
|
||||
AddOnManager::PublishDecoderCallback(DecoderPlugin *decoderplugin,
|
||||
const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */)
|
||||
{
|
||||
|
||||
printf("AddOnManager::PublishDecoderCallback: meta_description \"%s\", short_name \"%s\", pretty_name \"%s\", default_mapping \"%s\"\n",
|
||||
meta_description, short_name, pretty_name, default_mapping);
|
||||
|
||||
media_meta_description meta_desc;
|
||||
snprintf(meta_desc.description, sizeof(meta_desc), "%s", meta_description);
|
||||
|
||||
fDecoderInfo->meta_desc.Insert(meta_desc);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
//typedef status_t *(*publish_func)(DecoderPlugin *, const char *, const char *, const char *, const char *);
|
||||
status_t
|
||||
_PublishDecoder(DecoderPlugin *decoderplugin,
|
||||
const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */)
|
||||
{
|
||||
return gAddOnManager->PublishDecoderCallback(decoderplugin,
|
||||
meta_description,
|
||||
short_name,
|
||||
pretty_name,
|
||||
default_mapping);
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const media_meta_description & a, const media_meta_description & b)
|
||||
{
|
||||
return 0 == strcmp(a.description, b.description);
|
||||
}
|
72
src/servers/media/AddOnManager.h
Normal file
72
src/servers/media/AddOnManager.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef _ADD_ON_MANAGER_H
|
||||
#define _ADD_ON_MANAGER_H
|
||||
|
||||
// Manager for codec add-ons (reader, writer, encoder, decoder)
|
||||
// BMediaAddOn are handled in the NodeManager
|
||||
|
||||
#include "TList.h"
|
||||
#include "ReaderPlugin.h"
|
||||
#include "DecoderPlugin.h"
|
||||
#include "DataExchange.h"
|
||||
|
||||
class AddOnManager
|
||||
{
|
||||
public:
|
||||
AddOnManager();
|
||||
~AddOnManager();
|
||||
|
||||
void LoadState();
|
||||
void SaveState();
|
||||
|
||||
status_t GetDecoderForFormat(xfer_entry_ref *out_ref,
|
||||
const media_format &in_format);
|
||||
|
||||
status_t GetReaders(xfer_entry_ref *out_res, int32 *out_count, int32 max_count);
|
||||
|
||||
status_t PublishDecoderCallback(DecoderPlugin *decoderplugin,
|
||||
const char *meta_description,
|
||||
const char *short_name,
|
||||
const char *pretty_name,
|
||||
const char *default_mapping /* = 0 */);
|
||||
|
||||
private:
|
||||
void RegisterAddOns();
|
||||
void RegisterReader(ReaderPlugin *reader, const entry_ref &ref);
|
||||
void RegisterDecoder(DecoderPlugin *decoder, const entry_ref &ref);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
struct reader_info
|
||||
{
|
||||
entry_ref ref;
|
||||
};
|
||||
struct writer_info
|
||||
{
|
||||
entry_ref ref;
|
||||
};
|
||||
struct decoder_info
|
||||
{
|
||||
entry_ref ref;
|
||||
List<media_meta_description> meta_desc;
|
||||
};
|
||||
struct encoder_info
|
||||
{
|
||||
entry_ref ref;
|
||||
};
|
||||
|
||||
BLocker *fLocker;
|
||||
List<reader_info> *fReaderList;
|
||||
List<writer_info> *fWriterList;
|
||||
List<decoder_info> *fDecoderList;
|
||||
List<encoder_info> *fEncoderList;
|
||||
|
||||
reader_info *fReaderInfo;
|
||||
writer_info *fWriterInfo;
|
||||
decoder_info *fDecoderInfo;
|
||||
encoder_info *fEncoderInfo;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _ADD_ON_MANAGER_H
|
180
src/servers/media/FormatManager.cpp
Normal file
180
src/servers/media/FormatManager.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
#include <stdio.h>
|
||||
#include <MediaFormats.h>
|
||||
#include <string.h>
|
||||
#include "FormatManager.h"
|
||||
#include "debug.h"
|
||||
|
||||
const char *family_to_string(media_format_family in_family);
|
||||
const char *string_for_description(const media_format_description &in_description, char *string, size_t length);
|
||||
|
||||
FormatManager::FormatManager()
|
||||
{
|
||||
}
|
||||
|
||||
FormatManager::~FormatManager()
|
||||
{
|
||||
}
|
||||
|
||||
status_t
|
||||
FormatManager::GetFormatForDescription(media_format *out_format,
|
||||
const media_format_description &in_desc)
|
||||
{
|
||||
char s[128];
|
||||
printf("GetFormatForDescription, description: %s\n",
|
||||
string_for_description(in_desc, s, sizeof(s)));
|
||||
|
||||
memset(out_format, 0, sizeof(*out_format));
|
||||
|
||||
if (in_desc.family == B_BEOS_FORMAT_FAMILY && in_desc.u.beos.format == B_BEOS_FORMAT_RAW_AUDIO)
|
||||
out_format->type = B_MEDIA_RAW_AUDIO;
|
||||
else {
|
||||
out_format->type = B_MEDIA_ENCODED_AUDIO;
|
||||
out_format->u.encoded_audio.encoding = (enum media_encoded_audio_format::audio_encoding) in_desc.family;
|
||||
}
|
||||
|
||||
string_for_format(*out_format, s, sizeof(s));
|
||||
printf(" encoding %d, format %s\n", (int)out_format->u.encoded_audio.encoding, s);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
FormatManager::GetDescriptionForFormat(media_format_description *out_description,
|
||||
const media_format &in_format,
|
||||
media_format_family in_family)
|
||||
{
|
||||
printf("GetDescriptionForFormat, requested %s family\n",
|
||||
family_to_string(in_family));
|
||||
char s[128];
|
||||
string_for_format(in_format, s, sizeof(s));
|
||||
printf(" encoding %d, format %s\n", (int)in_format.u.encoded_audio.encoding, s);
|
||||
|
||||
|
||||
if (in_family != B_META_FORMAT_FAMILY)
|
||||
return B_ERROR;
|
||||
|
||||
if (in_format.type == B_MEDIA_RAW_AUDIO) {
|
||||
out_description->family = B_META_FORMAT_FAMILY;
|
||||
strcpy(out_description->u.meta.description, "audiocodec/raw");
|
||||
goto finished;
|
||||
}
|
||||
if (in_format.type == B_MEDIA_RAW_VIDEO) {
|
||||
out_description->family = B_META_FORMAT_FAMILY;
|
||||
strcpy(out_description->u.meta.description, "videocodec/raw");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
out_description->family = B_META_FORMAT_FAMILY;
|
||||
switch (in_format.u.encoded_audio.encoding) {
|
||||
|
||||
case B_MPEG_FORMAT_FAMILY:
|
||||
strcpy(out_description->u.meta.description, "audiocodec/mpeg1layer3");
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
finished:
|
||||
printf(" description: %s\n",
|
||||
string_for_description(*out_description, s, sizeof(s)));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
FormatManager::LoadState()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
FormatManager::SaveState()
|
||||
{
|
||||
}
|
||||
|
||||
const char *
|
||||
family_to_string(media_format_family family)
|
||||
{
|
||||
switch (family) {
|
||||
case B_ANY_FORMAT_FAMILY:
|
||||
return "any";
|
||||
case B_BEOS_FORMAT_FAMILY:
|
||||
return "BeOS";
|
||||
case B_QUICKTIME_FORMAT_FAMILY:
|
||||
return "Quicktime";
|
||||
case B_AVI_FORMAT_FAMILY:
|
||||
return "AVI";
|
||||
case B_ASF_FORMAT_FAMILY:
|
||||
return "ASF";
|
||||
case B_MPEG_FORMAT_FAMILY:
|
||||
return "MPEG";
|
||||
case B_WAV_FORMAT_FAMILY:
|
||||
return "WAV";
|
||||
case B_AIFF_FORMAT_FAMILY:
|
||||
return "AIFF";
|
||||
case B_AVR_FORMAT_FAMILY:
|
||||
return "AVR";
|
||||
case B_OGG_FORMAT_FAMILY:
|
||||
return "OGG";
|
||||
case B_MISC_FORMAT_FAMILY:
|
||||
return "misc";
|
||||
case B_META_FORMAT_FAMILY:
|
||||
return "meta";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
string_for_description(const media_format_description &desc, char *string, size_t length)
|
||||
{
|
||||
switch (desc.family) {
|
||||
case B_ANY_FORMAT_FAMILY:
|
||||
snprintf(string, length, "any format");
|
||||
break;
|
||||
case B_BEOS_FORMAT_FAMILY:
|
||||
snprintf(string, length, "BeOS format, format id 0x%lx", desc.u.beos.format);
|
||||
break;
|
||||
case B_QUICKTIME_FORMAT_FAMILY:
|
||||
snprintf(string, length, "Quicktime format, vendor id 0x%lx, codec id 0x%lx", desc.u.quicktime.vendor, desc.u.quicktime.codec);
|
||||
break;
|
||||
case B_AVI_FORMAT_FAMILY:
|
||||
snprintf(string, length, "AVI format, codec id 0x%lx", desc.u.avi.codec);
|
||||
break;
|
||||
case B_ASF_FORMAT_FAMILY:
|
||||
snprintf(string, length, "ASF format, GUID %02x %02x %02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
desc.u.asf.guid.data[0], desc.u.asf.guid.data[1],
|
||||
desc.u.asf.guid.data[2], desc.u.asf.guid.data[3],
|
||||
desc.u.asf.guid.data[4], desc.u.asf.guid.data[5],
|
||||
desc.u.asf.guid.data[6], desc.u.asf.guid.data[7],
|
||||
desc.u.asf.guid.data[8], desc.u.asf.guid.data[9],
|
||||
desc.u.asf.guid.data[10], desc.u.asf.guid.data[11],
|
||||
desc.u.asf.guid.data[12], desc.u.asf.guid.data[13],
|
||||
desc.u.asf.guid.data[14], desc.u.asf.guid.data[15]);
|
||||
break;
|
||||
case B_MPEG_FORMAT_FAMILY:
|
||||
snprintf(string, length, "MPEG format, id 0x%lx", desc.u.mpeg.id);
|
||||
break;
|
||||
case B_WAV_FORMAT_FAMILY:
|
||||
snprintf(string, length, "WAV format, codec id 0x%lx", desc.u.wav.codec);
|
||||
break;
|
||||
case B_AIFF_FORMAT_FAMILY:
|
||||
snprintf(string, length, "AIFF format, codec id 0x%lx", desc.u.aiff.codec);
|
||||
break;
|
||||
case B_AVR_FORMAT_FAMILY:
|
||||
snprintf(string, length, "AVR format, id 0x%lx", desc.u.avr.id);
|
||||
break;
|
||||
case B_OGG_FORMAT_FAMILY:
|
||||
snprintf(string, length, "OGG format");
|
||||
break;
|
||||
case B_MISC_FORMAT_FAMILY:
|
||||
snprintf(string, length, "misc format, file-format id 0x%lx, codec id 0x%lx", desc.u.misc.file_format, desc.u.misc.codec);
|
||||
break;
|
||||
case B_META_FORMAT_FAMILY:
|
||||
snprintf(string, length, "meta format, description %s", desc.u.meta.description);
|
||||
break;
|
||||
default:
|
||||
snprintf(string, length, "unknown format");
|
||||
break;
|
||||
}
|
||||
return string;
|
||||
}
|
21
src/servers/media/FormatManager.h
Normal file
21
src/servers/media/FormatManager.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _FORMAT_MANAGER_H
|
||||
#define _FORMAT_MANAGER_H
|
||||
|
||||
class FormatManager
|
||||
{
|
||||
public:
|
||||
FormatManager();
|
||||
~FormatManager();
|
||||
|
||||
void LoadState();
|
||||
void SaveState();
|
||||
|
||||
status_t GetFormatForDescription(media_format *out_format,
|
||||
const media_format_description &in_description);
|
||||
|
||||
status_t GetDescriptionForFormat(media_format_description *out_description,
|
||||
const media_format &in_format,
|
||||
media_format_family in_family);
|
||||
};
|
||||
|
||||
#endif // _FORMAT_MANAGER_H
|
@ -6,9 +6,11 @@ AddResources media_server : media_server.rdef ;
|
||||
|
||||
Server media_server :
|
||||
media_server.cpp
|
||||
AddOnManager.cpp
|
||||
AppManager.cpp
|
||||
BufferManager.cpp
|
||||
DefaultManager.cpp
|
||||
FormatManager.cpp
|
||||
MMediaFilesManager.cpp
|
||||
NodeManager.cpp
|
||||
NotificationManager.cpp
|
||||
|
@ -118,7 +118,7 @@ MMediaFilesManager::LoadState()
|
||||
}
|
||||
/*if (file.Read(&vol, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||
return B_ERROR;*/
|
||||
TRACE(" %s: %s, volume: %f\n", key, val, *(float *)&vol);
|
||||
//TRACE(" %s: %s, volume: %f\n", key, val, *(float *)&vol);
|
||||
|
||||
entry_ref ref;
|
||||
if(len>1) {
|
||||
|
@ -43,7 +43,9 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Ov
|
||||
#include "DataExchange.h"
|
||||
#include "BufferManager.h"
|
||||
#include "NodeManager.h"
|
||||
#include "AddOnManager.h"
|
||||
#include "AppManager.h"
|
||||
#include "FormatManager.h"
|
||||
#include "MediaMisc.h"
|
||||
#include "media_server.h"
|
||||
#include "debug.h"
|
||||
@ -55,11 +57,13 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Ov
|
||||
*
|
||||
*/
|
||||
|
||||
NotificationManager *gNotificationManager;
|
||||
BufferManager *gBufferManager;
|
||||
AppManager *gAppManager;
|
||||
NodeManager *gNodeManager;
|
||||
MMediaFilesManager *gMMediaFilesManager;
|
||||
AddOnManager * gAddOnManager;
|
||||
AppManager * gAppManager;
|
||||
BufferManager * gBufferManager;
|
||||
FormatManager * gFormatManager;
|
||||
MMediaFilesManager * gMMediaFilesManager;
|
||||
NodeManager * gNodeManager;
|
||||
NotificationManager * gNotificationManager;
|
||||
|
||||
namespace BPrivate { namespace media {
|
||||
extern team_id team;
|
||||
@ -121,6 +125,8 @@ ServerApp::ServerApp()
|
||||
gAppManager = new AppManager;
|
||||
gNodeManager = new NodeManager;
|
||||
gMMediaFilesManager = new MMediaFilesManager;
|
||||
gFormatManager = new FormatManager;
|
||||
gAddOnManager = new AddOnManager;
|
||||
|
||||
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
||||
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
||||
@ -128,17 +134,21 @@ ServerApp::ServerApp()
|
||||
|
||||
// StartSystemTimeSource();
|
||||
gNodeManager->LoadState();
|
||||
gFormatManager->LoadState();
|
||||
gAddOnManager->LoadState();
|
||||
gAppManager->StartAddonServer();
|
||||
}
|
||||
|
||||
ServerApp::~ServerApp()
|
||||
{
|
||||
TRACE("ServerApp::~ServerApp()\n");
|
||||
delete gAddOnManager;
|
||||
delete gNotificationManager;
|
||||
delete gBufferManager;
|
||||
delete gAppManager;
|
||||
delete gNodeManager;
|
||||
delete gMMediaFilesManager;
|
||||
delete gFormatManager;
|
||||
delete fLocker;
|
||||
delete_port(control_port);
|
||||
status_t err;
|
||||
@ -173,6 +183,8 @@ ServerApp::QuitRequested()
|
||||
TRACE("ServerApp::QuitRequested()\n");
|
||||
gMMediaFilesManager->SaveState();
|
||||
gNodeManager->SaveState();
|
||||
gFormatManager->SaveState();
|
||||
gAddOnManager->SaveState();
|
||||
gAppManager->TerminateAddonServer();
|
||||
return true;
|
||||
}
|
||||
@ -671,6 +683,42 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_FORMAT_FOR_DESCRIPTION:
|
||||
{
|
||||
const server_get_format_for_description_request *request = reinterpret_cast<const server_get_format_for_description_request *>(data);
|
||||
server_get_format_for_description_reply reply;
|
||||
rv = gFormatManager->GetFormatForDescription(&reply.format, request->description);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_DESCRIPTION_FOR_FORMAT:
|
||||
{
|
||||
const server_get_description_for_format_request *request = reinterpret_cast<const server_get_description_for_format_request *>(data);
|
||||
server_get_description_for_format_reply reply;
|
||||
rv = gFormatManager->GetDescriptionForFormat(&reply.description, request->format, request->family);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_READERS:
|
||||
{
|
||||
const server_get_readers_request *request = reinterpret_cast<const server_get_readers_request *>(data);
|
||||
server_get_readers_reply reply;
|
||||
rv = gAddOnManager->GetReaders(reply.ref, &reply.count, MAX_READERS);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVER_GET_DECODER_FOR_FORMAT:
|
||||
{
|
||||
const server_get_decoder_for_format_request *request = reinterpret_cast<const server_get_decoder_for_format_request *>(data);
|
||||
server_get_decoder_for_format_reply reply;
|
||||
rv = gAddOnManager->GetDecoderForFormat(&reply.ref, request->format);
|
||||
request->SendReply(rv, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("media_server: received unknown message code %#08lx\n",code);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user