From 7c02339d2ca29d3ac975c02d9f37a586fdb0d65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 23 Jan 2004 07:43:33 +0000 Subject: [PATCH] Rewritten the FormatManager class. It now implements the new format registration needed for the BMediaFormats class. Does not yet implement a settings file, and does not yet support removing of existing decoders/encoders. Also, it currently replies in FormatManager::GetFormats() in the tread of the media server with a timeout of 5 seconds... git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6246 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/media/FormatManager.cpp | 214 +++++++++++++++++----------- src/servers/media/FormatManager.h | 52 +++++-- src/servers/media/Jamfile | 1 + 3 files changed, 168 insertions(+), 99 deletions(-) diff --git a/src/servers/media/FormatManager.cpp b/src/servers/media/FormatManager.cpp index b880ef28dd..85b574c7ac 100644 --- a/src/servers/media/FormatManager.cpp +++ b/src/servers/media/FormatManager.cpp @@ -1,122 +1,165 @@ -#include -#include -#include +/* +** Copyright 2004, the OpenBeOS project. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +** +** Authors: Axel Dörfler, Marcus Overhagen +*/ + + #include "FormatManager.h" #include "debug.h" +#include + +#include +#include + + +#define TIMEOUT 5000000LL + // 5 seconds timeout for sending the reply + // ToDo: do we really want to pause the server looper for this? + // would be better to offload this action to a second thread + 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() + : + fLock("format manager"), + fLastUpdate(0), + fNextCodecID(1000) { } + FormatManager::~FormatManager() { } - -status_t -FormatManager::GetFormatForDescription(media_format *out_format, - const media_format_description &in_desc) + + +/** This method is called when BMediaFormats asks for any updates + * made to our format list. + * If there were any changes since the last time, the whole + * list will be sent back. + */ + +void +FormatManager::GetFormats(BMessage &message) { - char s[128]; - printf("GetFormatForDescription, description: %s\n", - string_for_description(in_desc, s, sizeof(s))); + BAutolock locker(fLock); - memset(out_format, 0, sizeof(*out_format)); + bigtime_t lastUpdate; + if (message.FindInt64("last_timestamp", &lastUpdate) == B_OK + && lastUpdate >= fLastUpdate) { + // there weren't any changes since last time + BMessage reply; + reply.AddBool("need_update", false); - 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; + message.SendReply(&reply, (BHandler *)NULL, TIMEOUT); + return; + } + + // add all meta formats to the list + + BMessage reply; + reply.AddBool("need_update", true); + reply.AddInt64("timestamp", system_time()); + + int32 count = fList.CountItems(); + printf("FormatManager::GetFormats(): put %ld formats into message\n", count); + for (int32 i = 0; i < count; i++) { + meta_format *format = fList.ItemAt(i); + reply.AddData("formats", MEDIA_META_FORMAT_TYPE, format, sizeof(meta_format)); + } + + message.SendReply(&reply, (BHandler *)NULL, TIMEOUT); +} + + +status_t +FormatManager::RegisterDecoder(const media_format_description *descriptions, + int32 descriptionCount, media_format *format, uint32 flags) +{ + return RegisterDescriptions(descriptions, descriptionCount, format, flags, false); +} + + +status_t +FormatManager::RegisterEncoder(const media_format_description *descriptions, + int32 descriptionCount, media_format *format, uint32 flags) +{ + return RegisterDescriptions(descriptions, descriptionCount, format, flags, true); +} + + +status_t +FormatManager::RegisterDescriptions(const media_format_description *descriptions, + int32 descriptionCount, media_format *format, uint32 flags, bool encoder) +{ + BAutolock locker(fLock); + + int32 codec = fNextCodecID++; + fLastUpdate = system_time(); + + switch (format->type) { + case B_MEDIA_ENCODED_AUDIO: + format->u.encoded_audio.encoding = (media_encoded_audio_format::audio_encoding)codec; + break; + case B_MEDIA_ENCODED_VIDEO: + format->u.encoded_video.encoding = (media_encoded_video_format::video_encoding)codec; + break; + case B_MEDIA_MULTISTREAM: + format->u.multistream.format = codec; + break; + default: + // ToDo: what can we do for the raw formats? + break; + } + + // ToDo: support "flags" (B_SET_DEFAULT, B_EXCLUSIVE, B_NO_MERGE)! + + for (int32 i = 0; i < descriptionCount; i++) { + meta_format *metaFormat = new meta_format(descriptions[i], *format, codec); + + if (encoder) + fEncoderFormats.BinaryInsert(metaFormat, meta_format::Compare); + else + fDecoderFormats.BinaryInsert(metaFormat, meta_format::Compare); + + fList.BinaryInsert(metaFormat, meta_format::Compare); } - 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) + +void +FormatManager::UnregisterDecoder(media_format &format) { - 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; - - out_description->family = B_META_FORMAT_FAMILY; - - switch (in_format.type) { - case B_MEDIA_RAW_AUDIO: - strcpy(out_description->u.meta.description, "audiocodec/raw"); - break; - case B_MEDIA_RAW_VIDEO: - strcpy(out_description->u.meta.description, "videocodec/raw"); - break; - case B_MEDIA_ENCODED_AUDIO: - switch (in_format.u.encoded_audio.encoding) { - - case B_WAV_FORMAT_FAMILY: - case B_MPEG_FORMAT_FAMILY: - strcpy(out_description->u.meta.description, "audiocodec/mpeg1layer3"); - break; - - case 'vorb': - strcpy(out_description->u.meta.description, "audiocodec/vorbis"); - break; - - case 'Spee': - strcpy(out_description->u.meta.description, "audiocodec/speex"); - break; - - default: - return B_ERROR; - } - break; - case B_MEDIA_ENCODED_VIDEO: - switch (in_format.u.encoded_video.encoding) { - - case B_MPEG_FORMAT_FAMILY: - strcpy(out_description->u.meta.description, "videocodec/mpeg"); - break; - - case 'DX50': - strcpy(out_description->u.meta.description, "videocodec/mpeg4"); - break; - - default: - return B_ERROR; - } - break; - case B_MEDIA_UNKNOWN_TYPE: - strcpy(out_description->u.meta.description, "unknown"); - break; - default: - debugger("FormatManager::GetDescriptionForFormat"); - } - printf(" description: %s\n", - string_for_description(*out_description, s, sizeof(s))); - return B_OK; + UNIMPLEMENTED(); } + +void +FormatManager::UnregisterEncoder(media_format &format) +{ + UNIMPLEMENTED(); +} + + void FormatManager::LoadState() { } + void FormatManager::SaveState() { } + const char * family_to_string(media_format_family family) { @@ -150,6 +193,7 @@ family_to_string(media_format_family family) } } + const char * string_for_description(const media_format_description &desc, char *string, size_t length) { diff --git a/src/servers/media/FormatManager.h b/src/servers/media/FormatManager.h index d0b5ae55bc..26ac1292c9 100644 --- a/src/servers/media/FormatManager.h +++ b/src/servers/media/FormatManager.h @@ -1,21 +1,45 @@ #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); +#include +#include + +#include "MetaFormat.h" + + +class FormatManager { + public: + FormatManager(); + ~FormatManager(); + + void LoadState(); + void SaveState(); + + void GetFormats(BMessage &message); + + status_t RegisterDecoder(const media_format_description *descriptions, + int32 descriptionCount, media_format *format, uint32 flags); + status_t RegisterEncoder(const media_format_description *descriptions, + int32 descriptionCount, media_format *format, uint32 flags); + + void UnregisterDecoder(media_format &format); + void UnregisterEncoder(media_format &format); + + private: + status_t RegisterDescriptions(const media_format_description *descriptions, + int32 descriptionCount, media_format *format, uint32 flags, + bool encoder); + + private: + typedef BPrivate::media::meta_format meta_format; + + BObjectList fDecoderFormats; + BObjectList fEncoderFormats; + BObjectList fList; + BLocker fLock; + bigtime_t fLastUpdate; + int32 fNextCodecID; }; #endif // _FORMAT_MANAGER_H diff --git a/src/servers/media/Jamfile b/src/servers/media/Jamfile index a01a33778d..52583c2121 100644 --- a/src/servers/media/Jamfile +++ b/src/servers/media/Jamfile @@ -1,6 +1,7 @@ SubDir OBOS_TOP src servers media ; UsePrivateHeaders media ; +UsePrivateHeaders shared ; AddResources media_server : media_server.rdef ;