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
This commit is contained in:
Axel Dörfler 2004-01-23 07:43:33 +00:00
parent 20e3dd9dbe
commit 7c02339d2c
3 changed files with 168 additions and 99 deletions

View File

@ -1,122 +1,165 @@
#include <stdio.h>
#include <MediaFormats.h>
#include <string.h>
/*
** 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 <Autolock.h>
#include <stdio.h>
#include <string.h>
#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)
{

View File

@ -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 <ObjectList.h>
#include <Locker.h>
#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<meta_format> fDecoderFormats;
BObjectList<meta_format> fEncoderFormats;
BObjectList<meta_format> fList;
BLocker fLock;
bigtime_t fLastUpdate;
int32 fNextCodecID;
};
#endif // _FORMAT_MANAGER_H

View File

@ -1,6 +1,7 @@
SubDir OBOS_TOP src servers media ;
UsePrivateHeaders media ;
UsePrivateHeaders shared ;
AddResources media_server : media_server.rdef ;