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:
parent
20e3dd9dbe
commit
7c02339d2c
@ -1,122 +1,165 @@
|
|||||||
#include <stdio.h>
|
/*
|
||||||
#include <MediaFormats.h>
|
** Copyright 2004, the OpenBeOS project. All rights reserved.
|
||||||
#include <string.h>
|
** Distributed under the terms of the OpenBeOS License.
|
||||||
|
**
|
||||||
|
** Authors: Axel Dörfler, Marcus Overhagen
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "FormatManager.h"
|
#include "FormatManager.h"
|
||||||
#include "debug.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 *family_to_string(media_format_family in_family);
|
||||||
const char *string_for_description(const media_format_description &in_description, char *string, size_t length);
|
const char *string_for_description(const media_format_description &in_description, char *string, size_t length);
|
||||||
|
|
||||||
|
|
||||||
FormatManager::FormatManager()
|
FormatManager::FormatManager()
|
||||||
|
:
|
||||||
|
fLock("format manager"),
|
||||||
|
fLastUpdate(0),
|
||||||
|
fNextCodecID(1000)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FormatManager::~FormatManager()
|
FormatManager::~FormatManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
|
||||||
FormatManager::GetFormatForDescription(media_format *out_format,
|
/** This method is called when BMediaFormats asks for any updates
|
||||||
const media_format_description &in_desc)
|
* 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];
|
BAutolock locker(fLock);
|
||||||
printf("GetFormatForDescription, description: %s\n",
|
|
||||||
string_for_description(in_desc, s, sizeof(s)));
|
|
||||||
|
|
||||||
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)
|
message.SendReply(&reply, (BHandler *)NULL, TIMEOUT);
|
||||||
out_format->type = B_MEDIA_RAW_AUDIO;
|
return;
|
||||||
else {
|
}
|
||||||
out_format->type = B_MEDIA_ENCODED_AUDIO;
|
|
||||||
out_format->u.encoded_audio.encoding = (enum media_encoded_audio_format::audio_encoding) in_desc.family;
|
// 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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
|
||||||
FormatManager::GetDescriptionForFormat(media_format_description *out_description,
|
void
|
||||||
const media_format &in_format,
|
FormatManager::UnregisterDecoder(media_format &format)
|
||||||
media_format_family in_family)
|
|
||||||
{
|
{
|
||||||
printf("GetDescriptionForFormat, requested %s family\n",
|
UNIMPLEMENTED();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FormatManager::UnregisterEncoder(media_format &format)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FormatManager::LoadState()
|
FormatManager::LoadState()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FormatManager::SaveState()
|
FormatManager::SaveState()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
family_to_string(media_format_family family)
|
family_to_string(media_format_family family)
|
||||||
{
|
{
|
||||||
@ -150,6 +193,7 @@ family_to_string(media_format_family family)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
string_for_description(const media_format_description &desc, char *string, size_t length)
|
string_for_description(const media_format_description &desc, char *string, size_t length)
|
||||||
{
|
{
|
||||||
|
@ -1,21 +1,45 @@
|
|||||||
#ifndef _FORMAT_MANAGER_H
|
#ifndef _FORMAT_MANAGER_H
|
||||||
#define _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,
|
#include <ObjectList.h>
|
||||||
const media_format &in_format,
|
#include <Locker.h>
|
||||||
media_format_family in_family);
|
|
||||||
|
#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
|
#endif // _FORMAT_MANAGER_H
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
SubDir OBOS_TOP src servers media ;
|
SubDir OBOS_TOP src servers media ;
|
||||||
|
|
||||||
UsePrivateHeaders media ;
|
UsePrivateHeaders media ;
|
||||||
|
UsePrivateHeaders shared ;
|
||||||
|
|
||||||
AddResources media_server : media_server.rdef ;
|
AddResources media_server : media_server.rdef ;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user