From 7cd2513b824db570e3db1ac0aad919859989e4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 30 Jul 2009 20:05:11 +0000 Subject: [PATCH] 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 --- headers/private/media/DataExchange.h | 8 ++-- headers/private/media/EncoderPlugin.h | 26 ++++++++++--- headers/private/media/PluginManager.h | 2 - src/kits/media/PluginManager.cpp | 37 ++++-------------- src/servers/media/AddOnManager.cpp | 56 ++++++++++++--------------- src/servers/media/AddOnManager.h | 9 +++-- src/servers/media/media_server.cpp | 11 +++--- 7 files changed, 68 insertions(+), 81 deletions(-) diff --git a/headers/private/media/DataExchange.h b/headers/private/media/DataExchange.h index e3d7cff4e9..736e984466 100644 --- a/headers/private/media/DataExchange.h +++ b/headers/private/media/DataExchange.h @@ -133,7 +133,7 @@ enum { SERVER_GET_DECODER_FOR_FORMAT, SERVER_GET_WRITER_FOR_FORMAT_FAMILY, SERVER_GET_FILE_FORMAT_FOR_COOKIE, - SERVER_GET_ENCODER_FOR_FORMAT, + SERVER_GET_ENCODER_FOR_CODEC_INFO, SERVER_MESSAGE_END, NODE_MESSAGE_START = 0x200, @@ -808,11 +808,11 @@ struct server_get_decoder_for_format_reply : reply_data { // a ref to the decoder }; -struct server_get_encoder_for_format_request : request_data { - media_format format; +struct server_get_encoder_for_codec_info_request : request_data { + 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; // a ref to the encoder }; diff --git a/headers/private/media/EncoderPlugin.h b/headers/private/media/EncoderPlugin.h index 1620a5d02f..cb19f238c9 100644 --- a/headers/private/media/EncoderPlugin.h +++ b/headers/private/media/EncoderPlugin.h @@ -1,10 +1,16 @@ +/* + * Copyright 2009, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT license. + */ #ifndef _ENCODER_PLUGIN_H #define _ENCODER_PLUGIN_H + #include #include #include "MediaPlugin.h" + class AddOnManager; namespace BPrivate { namespace media { @@ -18,15 +24,14 @@ public: size_t chunkSize, uint32 flags) = 0; }; + class Encoder { public: Encoder(); virtual ~Encoder(); - virtual void GetCodecInfo(media_codec_info* codecInfo) = 0; - 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, size_t size, uint32 flags = 0) = 0; @@ -67,8 +72,19 @@ class EncoderPlugin : public virtual MediaPlugin { public: EncoderPlugin(); - virtual Encoder* NewEncoder(uint index) = 0; - virtual status_t GetSupportedFormats(media_format** formats, + virtual Encoder* NewEncoder( + 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; }; diff --git a/headers/private/media/PluginManager.h b/headers/private/media/PluginManager.h index f4e91e00eb..28c5761efb 100644 --- a/headers/private/media/PluginManager.h +++ b/headers/private/media/PluginManager.h @@ -51,8 +51,6 @@ public: status_t CreateEncoder(Encoder** encoder, const media_codec_info* codecInfo, uint32 flags); - status_t GetEncoderInfo(Encoder* encoder, - media_codec_info* _info) const; void DestroyEncoder(Encoder* encoder); private: diff --git a/src/kits/media/PluginManager.cpp b/src/kits/media/PluginManager.cpp index cc0af09f43..6b22b3e5c1 100644 --- a/src/kits/media/PluginManager.cpp +++ b/src/kits/media/PluginManager.cpp @@ -257,16 +257,15 @@ PluginManager::CreateEncoder(Encoder** _encoder, { TRACE("PluginManager::CreateEncoder enter\n"); -#if 0 - // get decoder for this format from the server - server_get_encoder_for_format_request request; - server_get_encoder_for_format_reply reply; - request.format = format; - status_t ret = QueryServer(SERVER_GET_ENCODER_FOR_FORMAT, &request, + // Get encoder for this codec info from the server + server_get_encoder_for_codec_info_request request; + server_get_encoder_for_codec_info_reply reply; + request.id = codecInfo->id; + status_t ret = QueryServer(SERVER_GET_ENCODER_FOR_CODEC_INFO, &request, sizeof(request), &reply, sizeof(reply)); if (ret != B_OK) { - printf("PluginManager::CreateEncoder: can't get encoder for format: " - "%s\n", strerror(ret)); + printf("PluginManager::CreateEncoder: can't get encoder for codec %s: " + "%s\n", codecInfo->pretty_name, strerror(ret)); return ret; } @@ -283,9 +282,7 @@ PluginManager::CreateEncoder(Encoder** _encoder, return B_ERROR; } - // TODO: In theory, one EncoderPlugin could support multiple Encoders, - // but this is not yet handled (passing "0" as index/ID). - *_encoder = encoderPlugin->NewEncoder(0); + *_encoder = encoderPlugin->NewEncoder(*codecInfo); if (*_encoder == NULL) { printf("PluginManager::CreateEncoder: NewEncoder() failed\n"); PutPlugin(plugin); @@ -296,24 +293,6 @@ PluginManager::CreateEncoder(Encoder** _encoder, 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; } diff --git a/src/servers/media/AddOnManager.cpp b/src/servers/media/AddOnManager.cpp index 463b4c17d3..e9dfe4288f 100644 --- a/src/servers/media/AddOnManager.cpp +++ b/src/servers/media/AddOnManager.cpp @@ -63,7 +63,8 @@ private: AddOnManager::AddOnManager() : fLock("add-on manager"), - fNextWriterFormatFamilyID(0) + fNextWriterFormatFamilyID(0), + fNextEncoderCodecInfoID(0) { } @@ -141,38 +142,25 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount, status_t -AddOnManager::GetEncoderForFormat(xfer_entry_ref* _encoderRef, - const media_format& format) +AddOnManager::GetEncoder(xfer_entry_ref* _encoderRef, int32 id) { - 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); - printf("AddOnManager::GetEncoderForFormat: searching encoder for encoding " - "%ld\n", format.Encoding()); - encoder_info* info; for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) { - media_format* encoderFormat; - for (info->formats.Rewind(); info->formats.GetNext(&encoderFormat);) { - // check if the encoder matches the supplied format - if (!encoderFormat->Matches(&format)) - continue; - + // check if the encoder matches the supplied format + if (info->internalID == id) { 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; return B_OK; } } + + printf("AddOnManager::GetEncoderForFormat: failed to find encoder for id " + "%ld\n", id); + return B_ENTRY_NOT_FOUND; } @@ -203,7 +191,7 @@ AddOnManager::GetFileFormat(media_file_format* _fileFormat, int32 cookie) BAutolock locker(fLock); media_file_format* fileFormat; - if (fFileFormats.Get(cookie, &fileFormat)) { + if (fWriterFileFormats.Get(cookie, &fileFormat)) { *_fileFormat = *fileFormat; return B_OK; } @@ -436,7 +424,7 @@ AddOnManager::_RegisterWriter(WriterPlugin* writer, const entry_ref& ref) fileFormat.id.device = ref.device; fileFormat.id.internal_id = info.internalID; - fFileFormats.Insert(fileFormat); + fWriterFileFormats.Insert(fileFormat); } fWriterList.Insert(info); @@ -460,17 +448,23 @@ AddOnManager::_RegisterEncoder(EncoderPlugin* plugin, const entry_ref& ref) encoder_info info; info.ref = ref; + info.internalID = fNextEncoderCodecInfoID++; - // Get list of support media_formats... - media_format* formats = NULL; + // Get list of supported codecs... + const media_codec_info* codecInfos = NULL; size_t count = 0; - if (plugin->GetSupportedFormats(&formats, &count) != B_OK) { - printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedFormats" + if (plugin->GetSupportedCodecs(&codecInfos, &count) != B_OK) { + printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedCodecs" "(...) failed!\n"); 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); } diff --git a/src/servers/media/AddOnManager.h b/src/servers/media/AddOnManager.h index 6c2ef71cfc..b7704b953e 100644 --- a/src/servers/media/AddOnManager.h +++ b/src/servers/media/AddOnManager.h @@ -41,8 +41,7 @@ public: status_t GetReaders(xfer_entry_ref* _ref, int32* _count, int32 maxCount); - status_t GetEncoderForFormat(xfer_entry_ref* _ref, - const media_format& format); + status_t GetEncoder(xfer_entry_ref* _ref, int32 id); status_t GetWriter(xfer_entry_ref* _ref, uint32 internalID); @@ -78,7 +77,8 @@ private: }; struct encoder_info { entry_ref ref; - List formats; + uint32 internalID; + List codecInfos; }; BLocker fLock; @@ -87,9 +87,10 @@ private: List fDecoderList; List fEncoderList; - List fFileFormats; + List fWriterFileFormats; uint32 fNextWriterFormatFamilyID; + uint32 fNextEncoderCodecInfoID; AddOnMonitorHandler* fHandler; AddOnMonitor* fAddOnMonitor; diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index 6d405dbef1..fdc436dec4 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -908,14 +908,13 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size) 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< - const server_get_encoder_for_format_request *>(data); - server_get_encoder_for_format_reply reply; - rv = gAddOnManager->GetEncoderForFormat(&reply.ref, - request->format); + const server_get_encoder_for_codec_info_request *>(data); + server_get_encoder_for_codec_info_reply reply; + rv = gAddOnManager->GetEncoder(&reply.ref, request->id); request->SendReply(rv, &reply, sizeof(reply)); break; }