Changed the way Encoders are published by EncoderPlugins. Encoder retrieval

in PluginManager is reenabled. We use the media_codec_info.id to reference
a specific plugin, while the sub_id will be used to reference individual
Encoders that the plugin supports. No idea if that's how it was intented, but
some comments hint in this direction. I failed to mention this before, but
comments are of course very welcome on any of these commits, as always.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31993 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-07-30 20:05:11 +00:00
parent 0814569216
commit 7cd2513b82
7 changed files with 68 additions and 81 deletions
+4 -4
View File
@@ -133,7 +133,7 @@ enum {
SERVER_GET_DECODER_FOR_FORMAT, SERVER_GET_DECODER_FOR_FORMAT,
SERVER_GET_WRITER_FOR_FORMAT_FAMILY, SERVER_GET_WRITER_FOR_FORMAT_FAMILY,
SERVER_GET_FILE_FORMAT_FOR_COOKIE, SERVER_GET_FILE_FORMAT_FOR_COOKIE,
SERVER_GET_ENCODER_FOR_FORMAT, SERVER_GET_ENCODER_FOR_CODEC_INFO,
SERVER_MESSAGE_END, SERVER_MESSAGE_END,
NODE_MESSAGE_START = 0x200, NODE_MESSAGE_START = 0x200,
@@ -808,11 +808,11 @@ struct server_get_decoder_for_format_reply : reply_data {
// a ref to the decoder // a ref to the decoder
}; };
struct server_get_encoder_for_format_request : request_data { struct server_get_encoder_for_codec_info_request : request_data {
media_format format; int32 id;
}; };
struct server_get_encoder_for_format_reply : reply_data { struct server_get_encoder_for_codec_info_reply : reply_data {
xfer_entry_ref ref; xfer_entry_ref ref;
// a ref to the encoder // a ref to the encoder
}; };
+21 -5
View File
@@ -1,10 +1,16 @@
/*
* Copyright 2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef _ENCODER_PLUGIN_H #ifndef _ENCODER_PLUGIN_H
#define _ENCODER_PLUGIN_H #define _ENCODER_PLUGIN_H
#include <MediaTrack.h> #include <MediaTrack.h>
#include <MediaFormats.h> #include <MediaFormats.h>
#include "MediaPlugin.h" #include "MediaPlugin.h"
class AddOnManager; class AddOnManager;
namespace BPrivate { namespace media { namespace BPrivate { namespace media {
@@ -18,15 +24,14 @@ public:
size_t chunkSize, uint32 flags) = 0; size_t chunkSize, uint32 flags) = 0;
}; };
class Encoder { class Encoder {
public: public:
Encoder(); Encoder();
virtual ~Encoder(); virtual ~Encoder();
virtual void GetCodecInfo(media_codec_info* codecInfo) = 0;
virtual status_t SetFormat(const media_file_format& fileFormat, virtual status_t SetFormat(const media_file_format& fileFormat,
const media_format& encodedFormat) = 0; media_format* _inOutEncodedFormat) = 0;
virtual status_t AddTrackInfo(uint32 code, const void* data, virtual status_t AddTrackInfo(uint32 code, const void* data,
size_t size, uint32 flags = 0) = 0; size_t size, uint32 flags = 0) = 0;
@@ -67,8 +72,19 @@ class EncoderPlugin : public virtual MediaPlugin {
public: public:
EncoderPlugin(); EncoderPlugin();
virtual Encoder* NewEncoder(uint index) = 0; virtual Encoder* NewEncoder(
virtual status_t GetSupportedFormats(media_format** formats, const media_codec_info& codecInfo) = 0;
// TODO: Maybe this also needs to return a media_format with wild cards
// so that we can support the respective get_next_encoder() functions
// that take media_formats with wild cards and specialize them.
// Then this interface could be turned into an iterator like interface:
//
// status_t GetNextSupportedCodec(int32* cookie,
// const media_codec_info* codecInfo,
// const media_format* format) = 0;
virtual status_t GetSupportedCodecs(
const media_codec_info** codecInfos,
size_t* count) = 0; size_t* count) = 0;
}; };
-2
View File
@@ -51,8 +51,6 @@ public:
status_t CreateEncoder(Encoder** encoder, status_t CreateEncoder(Encoder** encoder,
const media_codec_info* codecInfo, const media_codec_info* codecInfo,
uint32 flags); uint32 flags);
status_t GetEncoderInfo(Encoder* encoder,
media_codec_info* _info) const;
void DestroyEncoder(Encoder* encoder); void DestroyEncoder(Encoder* encoder);
private: private:
+8 -29
View File
@@ -257,16 +257,15 @@ PluginManager::CreateEncoder(Encoder** _encoder,
{ {
TRACE("PluginManager::CreateEncoder enter\n"); TRACE("PluginManager::CreateEncoder enter\n");
#if 0 // Get encoder for this codec info from the server
// get decoder for this format from the server server_get_encoder_for_codec_info_request request;
server_get_encoder_for_format_request request; server_get_encoder_for_codec_info_reply reply;
server_get_encoder_for_format_reply reply; request.id = codecInfo->id;
request.format = format; status_t ret = QueryServer(SERVER_GET_ENCODER_FOR_CODEC_INFO, &request,
status_t ret = QueryServer(SERVER_GET_ENCODER_FOR_FORMAT, &request,
sizeof(request), &reply, sizeof(reply)); sizeof(request), &reply, sizeof(reply));
if (ret != B_OK) { if (ret != B_OK) {
printf("PluginManager::CreateEncoder: can't get encoder for format: " printf("PluginManager::CreateEncoder: can't get encoder for codec %s: "
"%s\n", strerror(ret)); "%s\n", codecInfo->pretty_name, strerror(ret));
return ret; return ret;
} }
@@ -283,9 +282,7 @@ PluginManager::CreateEncoder(Encoder** _encoder,
return B_ERROR; return B_ERROR;
} }
// TODO: In theory, one EncoderPlugin could support multiple Encoders, *_encoder = encoderPlugin->NewEncoder(*codecInfo);
// but this is not yet handled (passing "0" as index/ID).
*_encoder = encoderPlugin->NewEncoder(0);
if (*_encoder == NULL) { if (*_encoder == NULL) {
printf("PluginManager::CreateEncoder: NewEncoder() failed\n"); printf("PluginManager::CreateEncoder: NewEncoder() failed\n");
PutPlugin(plugin); PutPlugin(plugin);
@@ -296,24 +293,6 @@ PluginManager::CreateEncoder(Encoder** _encoder,
TRACE("PluginManager::CreateEncoder leave\n"); TRACE("PluginManager::CreateEncoder leave\n");
return B_OK;
#else
TRACE("PluginManager::CreateEncoder leave\n");
return B_NOT_SUPPORTED;
#endif
}
status_t
PluginManager::GetEncoderInfo(Encoder* encoder, media_codec_info* _info) const
{
if (encoder == NULL)
return B_BAD_VALUE;
encoder->GetCodecInfo(_info);
// TODO:
// out_info->id =
// out_info->sub_id =
return B_OK; return B_OK;
} }
+24 -30
View File
@@ -63,7 +63,8 @@ private:
AddOnManager::AddOnManager() AddOnManager::AddOnManager()
: :
fLock("add-on manager"), fLock("add-on manager"),
fNextWriterFormatFamilyID(0) fNextWriterFormatFamilyID(0),
fNextEncoderCodecInfoID(0)
{ {
} }
@@ -141,38 +142,25 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount,
status_t status_t
AddOnManager::GetEncoderForFormat(xfer_entry_ref* _encoderRef, AddOnManager::GetEncoder(xfer_entry_ref* _encoderRef, int32 id)
const media_format& format)
{ {
if ((format.type == B_MEDIA_ENCODED_VIDEO
|| format.type == B_MEDIA_ENCODED_AUDIO
|| format.type == B_MEDIA_MULTISTREAM)
&& format.Encoding() == 0) {
return B_MEDIA_BAD_FORMAT;
}
if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE)
return B_MEDIA_BAD_FORMAT;
BAutolock locker(fLock); BAutolock locker(fLock);
printf("AddOnManager::GetEncoderForFormat: searching encoder for encoding "
"%ld\n", format.Encoding());
encoder_info* info; encoder_info* info;
for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) { for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) {
media_format* encoderFormat; // check if the encoder matches the supplied format
for (info->formats.Rewind(); info->formats.GetNext(&encoderFormat);) { if (info->internalID == id) {
// check if the encoder matches the supplied format
if (!encoderFormat->Matches(&format))
continue;
printf("AddOnManager::GetEncoderForFormat: found encoder %s for " printf("AddOnManager::GetEncoderForFormat: found encoder %s for "
"encoding %ld\n", info->ref.name, encoderFormat->Encoding()); "id %ld\n", info->ref.name, id);
*_encoderRef = info->ref; *_encoderRef = info->ref;
return B_OK; return B_OK;
} }
} }
printf("AddOnManager::GetEncoderForFormat: failed to find encoder for id "
"%ld\n", id);
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} }
@@ -203,7 +191,7 @@ AddOnManager::GetFileFormat(media_file_format* _fileFormat, int32 cookie)
BAutolock locker(fLock); BAutolock locker(fLock);
media_file_format* fileFormat; media_file_format* fileFormat;
if (fFileFormats.Get(cookie, &fileFormat)) { if (fWriterFileFormats.Get(cookie, &fileFormat)) {
*_fileFormat = *fileFormat; *_fileFormat = *fileFormat;
return B_OK; return B_OK;
} }
@@ -436,7 +424,7 @@ AddOnManager::_RegisterWriter(WriterPlugin* writer, const entry_ref& ref)
fileFormat.id.device = ref.device; fileFormat.id.device = ref.device;
fileFormat.id.internal_id = info.internalID; fileFormat.id.internal_id = info.internalID;
fFileFormats.Insert(fileFormat); fWriterFileFormats.Insert(fileFormat);
} }
fWriterList.Insert(info); fWriterList.Insert(info);
@@ -460,17 +448,23 @@ AddOnManager::_RegisterEncoder(EncoderPlugin* plugin, const entry_ref& ref)
encoder_info info; encoder_info info;
info.ref = ref; info.ref = ref;
info.internalID = fNextEncoderCodecInfoID++;
// Get list of support media_formats... // Get list of supported codecs...
media_format* formats = NULL; const media_codec_info* codecInfos = NULL;
size_t count = 0; size_t count = 0;
if (plugin->GetSupportedFormats(&formats, &count) != B_OK) { if (plugin->GetSupportedCodecs(&codecInfos, &count) != B_OK) {
printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedFormats" printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedCodecs"
"(...) failed!\n"); "(...) failed!\n");
return; return;
} }
for (uint i = 0 ; i < count ; i++)
info.formats.Insert(formats[i]); for (uint32 i = 0 ; i < count ; i++) {
media_codec_info codecInfo = codecInfos[i];
codecInfo.id = info.internalID;
codecInfo.sub_id = i;
info.codecInfos.Insert(codecInfo);
}
fEncoderList.Insert(info); fEncoderList.Insert(info);
} }
+5 -4
View File
@@ -41,8 +41,7 @@ public:
status_t GetReaders(xfer_entry_ref* _ref, status_t GetReaders(xfer_entry_ref* _ref,
int32* _count, int32 maxCount); int32* _count, int32 maxCount);
status_t GetEncoderForFormat(xfer_entry_ref* _ref, status_t GetEncoder(xfer_entry_ref* _ref, int32 id);
const media_format& format);
status_t GetWriter(xfer_entry_ref* _ref, status_t GetWriter(xfer_entry_ref* _ref,
uint32 internalID); uint32 internalID);
@@ -78,7 +77,8 @@ private:
}; };
struct encoder_info { struct encoder_info {
entry_ref ref; entry_ref ref;
List<media_format> formats; uint32 internalID;
List<media_codec_info> codecInfos;
}; };
BLocker fLock; BLocker fLock;
@@ -87,9 +87,10 @@ private:
List<decoder_info> fDecoderList; List<decoder_info> fDecoderList;
List<encoder_info> fEncoderList; List<encoder_info> fEncoderList;
List<media_file_format> fFileFormats; List<media_file_format> fWriterFileFormats;
uint32 fNextWriterFormatFamilyID; uint32 fNextWriterFormatFamilyID;
uint32 fNextEncoderCodecInfoID;
AddOnMonitorHandler* fHandler; AddOnMonitorHandler* fHandler;
AddOnMonitor* fAddOnMonitor; AddOnMonitor* fAddOnMonitor;
+5 -6
View File
@@ -908,14 +908,13 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
break; break;
} }
case SERVER_GET_ENCODER_FOR_FORMAT: case SERVER_GET_ENCODER_FOR_CODEC_INFO:
{ {
const server_get_encoder_for_format_request *request const server_get_encoder_for_codec_info_request *request
= reinterpret_cast< = reinterpret_cast<
const server_get_encoder_for_format_request *>(data); const server_get_encoder_for_codec_info_request *>(data);
server_get_encoder_for_format_reply reply; server_get_encoder_for_codec_info_reply reply;
rv = gAddOnManager->GetEncoderForFormat(&reply.ref, rv = gAddOnManager->GetEncoder(&reply.ref, request->id);
request->format);
request->SendReply(rv, &reply, sizeof(reply)); request->SendReply(rv, &reply, sizeof(reply));
break; break;
} }