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_WAV_FORMAT_FAMILY = 6,
|
||||||
B_AIFF_FORMAT_FAMILY = 7,
|
B_AIFF_FORMAT_FAMILY = 7,
|
||||||
B_AVR_FORMAT_FAMILY = 8,
|
B_AVR_FORMAT_FAMILY = 8,
|
||||||
|
B_OGG_FORMAT_FAMILY = 9,
|
||||||
B_MISC_FORMAT_FAMILY = 99999,
|
B_MISC_FORMAT_FAMILY = 99999,
|
||||||
B_META_FORMAT_FAMILY = 100000
|
B_META_FORMAT_FAMILY = 100000
|
||||||
} media_format_family;
|
} media_format_family;
|
||||||
|
@ -106,7 +106,9 @@ enum {
|
|||||||
SERVER_REMOVEREFFOR,
|
SERVER_REMOVEREFFOR,
|
||||||
SERVER_REMOVEITEM,
|
SERVER_REMOVEITEM,
|
||||||
SERVER_GET_FORMAT_FOR_DESCRIPTION,
|
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,
|
SERVER_MESSAGE_END,
|
||||||
NODE_MESSAGE_START = 0x200,
|
NODE_MESSAGE_START = 0x200,
|
||||||
|
|
||||||
@ -206,7 +208,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
dev_t device;
|
dev_t device;
|
||||||
ino_t directory;
|
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,
|
MAX_NODE_ID = 4000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// used by SERVER_GET_READERS
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_READERS = 40,
|
||||||
|
};
|
||||||
|
|
||||||
struct addonserver_instantiate_dormant_node_request : public request_data
|
struct addonserver_instantiate_dormant_node_request : public request_data
|
||||||
{
|
{
|
||||||
media_addon_id addonid;
|
media_addon_id addonid;
|
||||||
@ -889,14 +897,35 @@ struct server_get_format_for_description_reply : public reply_data
|
|||||||
media_format format;
|
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;
|
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
|
struct node_request_completed_command : public command_data
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "MediaPlugin.h"
|
#include "MediaPlugin.h"
|
||||||
#include "MediaExtractor.h"
|
#include "MediaExtractor.h"
|
||||||
|
|
||||||
|
class AddOnManager;
|
||||||
|
|
||||||
namespace BPrivate { namespace media {
|
namespace BPrivate { namespace media {
|
||||||
|
|
||||||
class Decoder
|
class Decoder
|
||||||
@ -41,11 +43,19 @@ private:
|
|||||||
class DecoderPlugin : public MediaPlugin
|
class DecoderPlugin : public MediaPlugin
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DecoderPlugin();
|
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
|
} } // namespace BPrivate::media
|
||||||
|
@ -24,11 +24,11 @@ public:
|
|||||||
PluginManager();
|
PluginManager();
|
||||||
~PluginManager();
|
~PluginManager();
|
||||||
|
|
||||||
MediaPlugin * GetPlugin(const char *name);
|
MediaPlugin * GetPlugin(const entry_ref &ref);
|
||||||
void PutPlugin(MediaPlugin *plugin);
|
void PutPlugin(MediaPlugin *plugin);
|
||||||
|
|
||||||
private:
|
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
|
struct plugin_info
|
||||||
{
|
{
|
||||||
|
@ -154,7 +154,7 @@ mp3Reader::Sniff(int32 *streamCount)
|
|||||||
TRACE("mp3Reader::Sniff: file size is %Ld bytes\n", fFileSize);
|
TRACE("mp3Reader::Sniff: file size is %Ld bytes\n", fFileSize);
|
||||||
|
|
||||||
if (!IsMp3File()) {
|
if (!IsMp3File()) {
|
||||||
TRACE("mp3Reader::Sniff: non recognized as mp3 file\n");
|
TRACE("mp3Reader::Sniff: not recognized as mp3 file\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -903,7 +903,7 @@ mp3Reader::GetFrameLength(void *header)
|
|||||||
int bitrate_index = (h[2] >> 4) & 0x0f;
|
int bitrate_index = (h[2] >> 4) & 0x0f;
|
||||||
int sampling_rate_index = (h[2] >> 2) & 0x03;
|
int sampling_rate_index = (h[2] >> 2) & 0x03;
|
||||||
int padding = (h[2] >> 1) & 0x01;
|
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 bitrate = bit_rate_table[mpeg_version_index][layer_index][bitrate_index];
|
||||||
int framerate = frame_rate_table[mpeg_version_index][sampling_rate_index];
|
int framerate = frame_rate_table[mpeg_version_index][sampling_rate_index];
|
||||||
|
@ -27,14 +27,25 @@ Decoder::Setup(MediaExtractor *extractor, int32 stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DecoderPlugin::DecoderPlugin()
|
DecoderPlugin::DecoderPlugin()
|
||||||
|
: fPublishHook(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef status_t (*publish_func)(DecoderPlugin *, const char *, const char *, const char *, const char *);
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DecoderPlugin::PublishDecoder(const char *meta_description,
|
DecoderPlugin::PublishDecoder(const char *meta_description,
|
||||||
const char *short_name,
|
const char *short_name,
|
||||||
const char *pretty_name,
|
const char *pretty_name,
|
||||||
const char *default_mapping /* = 0 */)
|
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_family family,
|
||||||
media_format_description * out_description)
|
media_format_description * out_description)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
server_get_description_for_format_request request;
|
||||||
return B_ERROR;
|
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;
|
return a.u.aiff.codec == b.u.aiff.codec;
|
||||||
case B_AVR_FORMAT_FAMILY:
|
case B_AVR_FORMAT_FAMILY:
|
||||||
return a.u.avr.id == b.u.avr.id;
|
return a.u.avr.id == b.u.avr.id;
|
||||||
|
case B_OGG_FORMAT_FAMILY:
|
||||||
|
return false; // XXX fix this
|
||||||
case B_MISC_FORMAT_FAMILY:
|
case B_MISC_FORMAT_FAMILY:
|
||||||
return a.u.misc.file_format == b.u.misc.file_format && a.u.misc.codec == b.u.misc.codec;
|
return a.u.misc.file_format == b.u.misc.file_format && a.u.misc.codec == b.u.misc.codec;
|
||||||
case B_META_FORMAT_FAMILY:
|
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;
|
return a.u.aiff.codec < b.u.aiff.codec;
|
||||||
case B_AVR_FORMAT_FAMILY:
|
case B_AVR_FORMAT_FAMILY:
|
||||||
return a.u.avr.id < b.u.avr.id;
|
return a.u.avr.id < b.u.avr.id;
|
||||||
|
case B_OGG_FORMAT_FAMILY:
|
||||||
|
return false; // XXX fix this
|
||||||
case B_MISC_FORMAT_FAMILY:
|
case B_MISC_FORMAT_FAMILY:
|
||||||
return a.u.misc.file_format < b.u.misc.file_format || a.u.misc.codec < b.u.misc.codec;
|
return a.u.misc.file_format < b.u.misc.file_format || a.u.misc.codec < b.u.misc.codec;
|
||||||
case B_META_FORMAT_FAMILY:
|
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;
|
request.description = in_desc;
|
||||||
|
|
||||||
// if (B_OK != QueryServer(SERVER_GET_FORMAT_FOR_DESCRIPTION, &request, sizeof(request), &reply, sizeof(reply)))
|
if (B_OK != QueryServer(SERVER_GET_FORMAT_FOR_DESCRIPTION, &request, sizeof(request), &reply, sizeof(reply)))
|
||||||
// return B_ERROR;
|
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;
|
|
||||||
|
|
||||||
*out_format = reply.format;
|
*out_format = reply.format;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -319,13 +323,14 @@ _get_format_for_description(media_format *out_format, const media_format_descrip
|
|||||||
status_t
|
status_t
|
||||||
_get_meta_description_for_format(media_format_description *out_desc, const media_format &in_format)
|
_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_description_for_format_request request;
|
||||||
server_get_meta_description_for_format_reply reply;
|
server_get_description_for_format_reply reply;
|
||||||
|
|
||||||
request.format = in_format;
|
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)))
|
if (B_OK != QueryServer(SERVER_GET_DESCRIPTION_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply)))
|
||||||
// return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
*out_desc = reply.description;
|
*out_desc = reply.description;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "PluginManager.h"
|
#include "PluginManager.h"
|
||||||
|
#include "DataExchange.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
PluginManager _plugin_manager;
|
PluginManager _plugin_manager;
|
||||||
@ -12,41 +13,50 @@ _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BData
|
|||||||
{
|
{
|
||||||
printf("_CreateReader enter\n");
|
printf("_CreateReader enter\n");
|
||||||
|
|
||||||
MediaPlugin *plugin;
|
// get list of available readers from, the server
|
||||||
ReaderPlugin *readerplugin;
|
server_get_readers_request request;
|
||||||
|
server_get_readers_reply reply;
|
||||||
plugin = _plugin_manager.GetPlugin("mp3_reader");
|
if (B_OK != QueryServer(SERVER_GET_READERS, &request, sizeof(request), &reply, sizeof(reply))) {
|
||||||
if (!plugin) {
|
printf("_CreateReader: can't get list of readers\n");
|
||||||
printf("_CreateReader: GetPlugin failed\n");
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
readerplugin = dynamic_cast<ReaderPlugin *>(plugin);
|
// try each reader by calling it's Sniff function...
|
||||||
if (!readerplugin) {
|
for (int32 i = 0; i < reply.count; i++) {
|
||||||
printf("_CreateReader: dynamic_cast failed\n");
|
entry_ref ref = reply.ref[i];
|
||||||
return B_ERROR;
|
MediaPlugin *plugin = _plugin_manager.GetPlugin(ref);
|
||||||
}
|
if (!plugin) {
|
||||||
|
printf("_CreateReader: GetPlugin failed\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
*reader = readerplugin->NewReader();
|
ReaderPlugin *readerplugin = dynamic_cast<ReaderPlugin *>(plugin);
|
||||||
if (! *reader) {
|
if (!readerplugin) {
|
||||||
printf("_CreateReader: NewReader failed\n");
|
printf("_CreateReader: dynamic_cast failed\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*reader)->Setup(source);
|
*reader = readerplugin->NewReader();
|
||||||
|
if (! *reader) {
|
||||||
|
printf("_CreateReader: NewReader failed\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (B_OK != (*reader)->Sniff(streamCount)) {
|
(*reader)->Setup(source);
|
||||||
printf("_CreateReader: Sniff failed\n");
|
|
||||||
_DestroyReader(*reader);
|
|
||||||
return B_MEDIA_NO_HANDLER;
|
|
||||||
// return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*reader)->GetFileFormatInfo(mff);
|
if (B_OK == (*reader)->Sniff(streamCount)) {
|
||||||
|
printf("_CreateReader: Sniff success\n");
|
||||||
printf("_CreateReader leave\n");
|
(*reader)->GetFileFormatInfo(mff);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
// _DestroyReader(*reader);
|
||||||
|
delete *reader;
|
||||||
|
_plugin_manager.PutPlugin(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("_CreateReader leave\n");
|
||||||
|
return B_MEDIA_NO_HANDLER;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
@ -54,10 +64,19 @@ _CreateDecoder(Decoder **decoder, media_codec_info *mci, const media_format *for
|
|||||||
{
|
{
|
||||||
printf("_CreateDecoder enter\n");
|
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;
|
MediaPlugin *plugin;
|
||||||
DecoderPlugin *decoderplugin;
|
DecoderPlugin *decoderplugin;
|
||||||
|
|
||||||
plugin = _plugin_manager.GetPlugin("mp3_decoder");
|
plugin = _plugin_manager.GetPlugin(reply.ref);
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
printf("_CreateDecoder: GetPlugin failed\n");
|
printf("_CreateDecoder: GetPlugin failed\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@ -96,20 +115,6 @@ _DestroyDecoder(Decoder *decoder)
|
|||||||
delete 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()
|
PluginManager::PluginManager()
|
||||||
{
|
{
|
||||||
@ -135,7 +140,7 @@ PluginManager::~PluginManager()
|
|||||||
|
|
||||||
|
|
||||||
MediaPlugin *
|
MediaPlugin *
|
||||||
PluginManager::GetPlugin(const char *name)
|
PluginManager::GetPlugin(const entry_ref &ref)
|
||||||
{
|
{
|
||||||
fLocker->Lock();
|
fLocker->Lock();
|
||||||
|
|
||||||
@ -144,7 +149,7 @@ PluginManager::GetPlugin(const char *name)
|
|||||||
plugin_info info;
|
plugin_info info;
|
||||||
|
|
||||||
for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) {
|
for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) {
|
||||||
if (0 == strcmp(name, pinfo->name)) {
|
if (0 == strcmp(ref.name, pinfo->name)) {
|
||||||
plugin = pinfo->plugin;
|
plugin = pinfo->plugin;
|
||||||
pinfo->usecount++;
|
pinfo->usecount++;
|
||||||
fLocker->Unlock();
|
fLocker->Unlock();
|
||||||
@ -152,17 +157,17 @@ PluginManager::GetPlugin(const char *name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LoadPlugin(name, &info.plugin, &info.image)) {
|
if (!LoadPlugin(ref, &info.plugin, &info.image)) {
|
||||||
printf("PluginManager: Error, loading PlugIn %s failed\n", name);
|
printf("PluginManager: Error, loading PlugIn %s failed\n", ref.name);
|
||||||
fLocker->Unlock();
|
fLocker->Unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(info.name, name);
|
strcpy(info.name, ref.name);
|
||||||
info.usecount = 1;
|
info.usecount = 1;
|
||||||
fPluginList->Insert(info);
|
fPluginList->Insert(info);
|
||||||
|
|
||||||
printf("PluginManager: PlugIn %s loaded\n", name);
|
printf("PluginManager: PlugIn %s loaded\n", ref.name);
|
||||||
|
|
||||||
plugin = info.plugin;
|
plugin = info.plugin;
|
||||||
|
|
||||||
@ -198,46 +203,35 @@ PluginManager::PutPlugin(MediaPlugin *plugin)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
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[] = {
|
BPath p(&ref);
|
||||||
"/boot/home/config/add-ons/media/plugins",
|
|
||||||
"/boot/beos/system/add-ons/media/plugins",
|
printf("PluginManager: LoadPlugin trying to load %s\n", p.Path());
|
||||||
"/boot/home/develop/openbeos/current/distro/x86.R1/beos/system/add-ons/media/plugins",
|
|
||||||
NULL
|
image_id id;
|
||||||
};
|
id = load_add_on(p.Path());
|
||||||
|
if (id < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MediaPlugin *(*instantiate_plugin_func)();
|
||||||
|
|
||||||
for (int i = 0; searchdir[i]; i++) {
|
if (get_image_symbol(id, "instantiate_plugin", B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) {
|
||||||
BPath p(searchdir[i], name);
|
printf("PluginManager: Error, LoadPlugin can't find instantiate_plugin in %s\n", p.Path());
|
||||||
|
unload_add_on(id);
|
||||||
printf("PluginManager: LoadPlugin trying to load %s\n", p.Path());
|
return false;
|
||||||
|
|
||||||
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;
|
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);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*plugin = pl;
|
||||||
|
*image = id;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ _SoundPlayNode::_SoundPlayNode(const char *name, const media_multi_audio_format
|
|||||||
mFormat.u.raw_audio = *format;
|
mFormat.u.raw_audio = *format;
|
||||||
|
|
||||||
DPRINTF("Format Info:\n");
|
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(" channel_count: %ld\n",mFormat.u.raw_audio.channel_count);
|
||||||
DPRINTF(" byte_order: %ld (",mFormat.u.raw_audio.byte_order);
|
DPRINTF(" byte_order: %ld (",mFormat.u.raw_audio.byte_order);
|
||||||
switch (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);
|
TRACE("_SoundPlayNode::Connect: downstream latency = %Ld\n", mLatency);
|
||||||
|
|
||||||
// reset our buffer duration, etc. to avoid later calculations
|
// reset our buffer duration, etc. to avoid later calculations
|
||||||
bigtime_t duration = mOutput.format.u.raw_audio.buffer_size * 10000
|
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.format & media_raw_audio_format::B_AUDIO_SIZE_MASK) * mOutput.format.u.raw_audio.channel_count))
|
||||||
* mOutput.format.u.raw_audio.channel_count)
|
/ (int32)mOutput.format.u.raw_audio.frame_rate;
|
||||||
/ ((int32)(mOutput.format.u.raw_audio.frame_rate / 100));
|
|
||||||
SetBufferDuration(duration);
|
SetBufferDuration(duration);
|
||||||
TRACE("_SoundPlayNode::Connect: buffer duaration is %Ld\n", duration);
|
TRACE("_SoundPlayNode::Connect: buffer duration is %Ld\n", duration);
|
||||||
|
|
||||||
mInternalLatency = (3 * BufferDuration()) / 4;
|
mInternalLatency = (3 * BufferDuration()) / 4;
|
||||||
TRACE("_SoundPlayNode::Connect: using %Ld as internal latency\n", mInternalLatency);
|
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
|
// 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
|
// 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);
|
media_timed_event nextBufferEvent(nextEvent, SEND_NEW_BUFFER_EVENT);
|
||||||
EventQueue()->AddEvent(nextBufferEvent);
|
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 :
|
Server media_server :
|
||||||
media_server.cpp
|
media_server.cpp
|
||||||
|
AddOnManager.cpp
|
||||||
AppManager.cpp
|
AppManager.cpp
|
||||||
BufferManager.cpp
|
BufferManager.cpp
|
||||||
DefaultManager.cpp
|
DefaultManager.cpp
|
||||||
|
FormatManager.cpp
|
||||||
MMediaFilesManager.cpp
|
MMediaFilesManager.cpp
|
||||||
NodeManager.cpp
|
NodeManager.cpp
|
||||||
NotificationManager.cpp
|
NotificationManager.cpp
|
||||||
|
@ -118,7 +118,7 @@ MMediaFilesManager::LoadState()
|
|||||||
}
|
}
|
||||||
/*if (file.Read(&vol, sizeof(uint32)) < (int32)sizeof(uint32))
|
/*if (file.Read(&vol, sizeof(uint32)) < (int32)sizeof(uint32))
|
||||||
return B_ERROR;*/
|
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;
|
entry_ref ref;
|
||||||
if(len>1) {
|
if(len>1) {
|
||||||
|
@ -43,7 +43,9 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Ov
|
|||||||
#include "DataExchange.h"
|
#include "DataExchange.h"
|
||||||
#include "BufferManager.h"
|
#include "BufferManager.h"
|
||||||
#include "NodeManager.h"
|
#include "NodeManager.h"
|
||||||
|
#include "AddOnManager.h"
|
||||||
#include "AppManager.h"
|
#include "AppManager.h"
|
||||||
|
#include "FormatManager.h"
|
||||||
#include "MediaMisc.h"
|
#include "MediaMisc.h"
|
||||||
#include "media_server.h"
|
#include "media_server.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
@ -55,11 +57,13 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 Marcus Ov
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NotificationManager *gNotificationManager;
|
AddOnManager * gAddOnManager;
|
||||||
BufferManager *gBufferManager;
|
AppManager * gAppManager;
|
||||||
AppManager *gAppManager;
|
BufferManager * gBufferManager;
|
||||||
NodeManager *gNodeManager;
|
FormatManager * gFormatManager;
|
||||||
MMediaFilesManager *gMMediaFilesManager;
|
MMediaFilesManager * gMMediaFilesManager;
|
||||||
|
NodeManager * gNodeManager;
|
||||||
|
NotificationManager * gNotificationManager;
|
||||||
|
|
||||||
namespace BPrivate { namespace media {
|
namespace BPrivate { namespace media {
|
||||||
extern team_id team;
|
extern team_id team;
|
||||||
@ -121,6 +125,8 @@ ServerApp::ServerApp()
|
|||||||
gAppManager = new AppManager;
|
gAppManager = new AppManager;
|
||||||
gNodeManager = new NodeManager;
|
gNodeManager = new NodeManager;
|
||||||
gMMediaFilesManager = new MMediaFilesManager;
|
gMMediaFilesManager = new MMediaFilesManager;
|
||||||
|
gFormatManager = new FormatManager;
|
||||||
|
gAddOnManager = new AddOnManager;
|
||||||
|
|
||||||
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
control_port = create_port(64, MEDIA_SERVER_PORT_NAME);
|
||||||
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
control_thread = spawn_thread(controlthread, "media_server control", 105, this);
|
||||||
@ -128,17 +134,21 @@ ServerApp::ServerApp()
|
|||||||
|
|
||||||
// StartSystemTimeSource();
|
// StartSystemTimeSource();
|
||||||
gNodeManager->LoadState();
|
gNodeManager->LoadState();
|
||||||
|
gFormatManager->LoadState();
|
||||||
|
gAddOnManager->LoadState();
|
||||||
gAppManager->StartAddonServer();
|
gAppManager->StartAddonServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerApp::~ServerApp()
|
ServerApp::~ServerApp()
|
||||||
{
|
{
|
||||||
TRACE("ServerApp::~ServerApp()\n");
|
TRACE("ServerApp::~ServerApp()\n");
|
||||||
|
delete gAddOnManager;
|
||||||
delete gNotificationManager;
|
delete gNotificationManager;
|
||||||
delete gBufferManager;
|
delete gBufferManager;
|
||||||
delete gAppManager;
|
delete gAppManager;
|
||||||
delete gNodeManager;
|
delete gNodeManager;
|
||||||
delete gMMediaFilesManager;
|
delete gMMediaFilesManager;
|
||||||
|
delete gFormatManager;
|
||||||
delete fLocker;
|
delete fLocker;
|
||||||
delete_port(control_port);
|
delete_port(control_port);
|
||||||
status_t err;
|
status_t err;
|
||||||
@ -173,6 +183,8 @@ ServerApp::QuitRequested()
|
|||||||
TRACE("ServerApp::QuitRequested()\n");
|
TRACE("ServerApp::QuitRequested()\n");
|
||||||
gMMediaFilesManager->SaveState();
|
gMMediaFilesManager->SaveState();
|
||||||
gNodeManager->SaveState();
|
gNodeManager->SaveState();
|
||||||
|
gFormatManager->SaveState();
|
||||||
|
gAddOnManager->SaveState();
|
||||||
gAppManager->TerminateAddonServer();
|
gAppManager->TerminateAddonServer();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -671,6 +683,42 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
break;
|
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:
|
default:
|
||||||
printf("media_server: received unknown message code %#08lx\n",code);
|
printf("media_server: received unknown message code %#08lx\n",code);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user