From f3d79634e640648deeaeca07bb62d780cd75d91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 29 Jul 2009 16:25:30 +0000 Subject: [PATCH] Beginnings of Encoder[Plugin] and Writer[Plugin] base classes and add-on management. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31922 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/media/EncoderPlugin.h | 81 ++++++++++++ headers/private/media/PluginManager.h | 18 ++- headers/private/media/WriterPlugin.h | 67 ++++++++++ src/kits/media/EncoderPlugin.cpp | 64 ++++++++++ src/kits/media/Jamfile | 2 + src/kits/media/PluginManager.cpp | 169 +++++++++++++++++++++++++- src/kits/media/ReaderPlugin.cpp | 2 +- src/kits/media/WriterPlugin.cpp | 50 ++++++++ 8 files changed, 447 insertions(+), 6 deletions(-) create mode 100644 headers/private/media/EncoderPlugin.h create mode 100644 headers/private/media/WriterPlugin.h create mode 100644 src/kits/media/EncoderPlugin.cpp create mode 100644 src/kits/media/WriterPlugin.cpp diff --git a/headers/private/media/EncoderPlugin.h b/headers/private/media/EncoderPlugin.h new file mode 100644 index 0000000000..82b9262117 --- /dev/null +++ b/headers/private/media/EncoderPlugin.h @@ -0,0 +1,81 @@ +#ifndef _ENCODER_PLUGIN_H +#define _ENCODER_PLUGIN_H + +#include +#include +#include "MediaPlugin.h" + +class AddOnManager; + +namespace BPrivate { namespace media { + +class PluginManager; + +class ChunkWriter { +public: + virtual ~ChunkWriter() {}; + virtual status_t WriteChunk(const void* chunkBuffer, + size_t chunkSize, + const media_header* mediaHeader) = 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; + + virtual status_t AddTrackInfo(uint32 code, const void* data, + size_t size, uint32 flags = 0) = 0; + + virtual status_t GetEncodeParameters( + encode_parameters* parameters) const = 0; + virtual status_t SetEncodeParameters( + encode_parameters* parameters) const = 0; + + virtual status_t Encode(const void* buffer, int64 frameCount, + media_encode_info* info) = 0; + + status_t WriteChunk(const void* chunkBuffer, + size_t chunkSize, + const media_header* mediaHeader); + + void SetChunkWriter(ChunkWriter* writer); + + virtual status_t Perform(perform_code code, void* data); + +private: + virtual void _ReservedEncoder1(); + virtual void _ReservedEncoder2(); + virtual void _ReservedEncoder3(); + virtual void _ReservedEncoder4(); + virtual void _ReservedEncoder5(); + + ChunkWriter* fChunkWriter; + + // needed for plug-in reference count management + friend class PluginManager; + MediaPlugin* fMediaPlugin; + + uint32 fReserved[5]; +}; + + +class EncoderPlugin : public virtual MediaPlugin { +public: + EncoderPlugin(); + + virtual Encoder* NewEncoder(uint index) = 0; + virtual status_t GetSupportedFormats(media_format** formats, + size_t* count) = 0; +}; + +} } // namespace BPrivate::media + +using namespace BPrivate::media; + +#endif // _ENCODER_PLUGIN_H diff --git a/headers/private/media/PluginManager.h b/headers/private/media/PluginManager.h index 904ebf9945..6d88a70eee 100644 --- a/headers/private/media/PluginManager.h +++ b/headers/private/media/PluginManager.h @@ -10,7 +10,9 @@ #include "DecoderPlugin.h" +#include "EncoderPlugin.h" #include "ReaderPlugin.h" +#include "WriterPlugin.h" #include #include @@ -26,7 +28,7 @@ public: MediaPlugin* GetPlugin(const entry_ref& ref); void PutPlugin(MediaPlugin* plugin); - + // Readers and Decoders status_t CreateReader(Reader** reader, int32* streamCount, media_file_format* mff, BDataIO* source); @@ -39,6 +41,20 @@ public: status_t GetDecoderInfo(Decoder* decoder, media_codec_info* _info) const; void DestroyDecoder(Decoder* decoder); + + // Writers and Encoders + status_t CreateWriter(Writer** writer, + const media_file_format& mff, + BDataIO* target); + void DestroyWriter(Writer* writer); + + status_t CreateEncoder(Encoder** encoder, + const media_format& format); + status_t CreateEncoder(Encoder** encoder, + const media_codec_info& mci); + status_t GetEncoderInfo(Encoder* encoder, + media_codec_info* _info) const; + void DestroyEncoder(Encoder* encoder); private: status_t _LoadPlugin(const entry_ref& ref, diff --git a/headers/private/media/WriterPlugin.h b/headers/private/media/WriterPlugin.h new file mode 100644 index 0000000000..e0012f8e1d --- /dev/null +++ b/headers/private/media/WriterPlugin.h @@ -0,0 +1,67 @@ +#ifndef _WRITER_PLUGIN_H +#define _WRITER_PLUGIN_H + +#include +#include "MediaPlugin.h" + +namespace BPrivate { namespace media { + +class PluginManager; + +class Writer { +public: + Writer(); + virtual ~Writer(); + + virtual status_t SetCopyright(const char* copyright) = 0; + virtual status_t CommitHeader() = 0; + virtual status_t Flush() = 0; + virtual status_t Close() = 0; + + virtual void GetFileFormatInfo(media_file_format* mff) = 0; + + virtual status_t AllocateCookie(void** cookie) = 0; + virtual status_t FreeCookie(void* cookie) = 0; + + virtual status_t AddTrackInfo(void* cookie, uint32 code, + const void* data, size_t size, + uint32 flags = 0) = 0; + + virtual status_t WriteNextChunk(void* cookie, + const void* chunkBuffer, size_t chunkSize, + uint32 flags) = 0; + + BDataIO* Target() const; + + virtual status_t Perform(perform_code code, void* data); + +private: + virtual void _ReservedWriter1(); + virtual void _ReservedWriter2(); + virtual void _ReservedWriter3(); + virtual void _ReservedWriter4(); + virtual void _ReservedWriter5(); + +public: // XXX for test programs only + void Setup(BDataIO* target); + + BDataIO* fTarget; + + // needed for plug-in reference count management + friend class PluginManager; + MediaPlugin* fMediaPlugin; + + uint32 fReserved[5]; +}; + + +class WriterPlugin : public virtual MediaPlugin { +public: + virtual Writer* NewWriter() = 0; +}; + +} } // namespace BPrivate::media + +using namespace BPrivate::media; + +#endif // _WRITER_PLUGIN_H diff --git a/src/kits/media/EncoderPlugin.cpp b/src/kits/media/EncoderPlugin.cpp new file mode 100644 index 0000000000..98b058bb95 --- /dev/null +++ b/src/kits/media/EncoderPlugin.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2009, Stephan Aßmus . All rights reserved. + * Copyright 2004, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include "EncoderPlugin.h" + +#include +#include + +#include + + +Encoder::Encoder() + : + fChunkWriter(NULL), + fMediaPlugin(NULL) +{ +} + + +Encoder::~Encoder() +{ + delete fChunkWriter; +} + + +status_t +Encoder::WriteChunk(const void* chunkBuffer, size_t chunkSize, + const media_header* mediaHeader) +{ + return fChunkWriter->WriteChunk(chunkBuffer, chunkSize, mediaHeader); +} + + +void +Encoder::SetChunkWriter(ChunkWriter* writer) +{ + delete fChunkWriter; + fChunkWriter = writer; +} + + +status_t +Encoder::Perform(perform_code code, void* data) +{ + return B_OK; +} + + +void Encoder::_ReservedEncoder1() {} +void Encoder::_ReservedEncoder2() {} +void Encoder::_ReservedEncoder3() {} +void Encoder::_ReservedEncoder4() {} +void Encoder::_ReservedEncoder5() {} + + +// #pragma mark - + + +EncoderPlugin::EncoderPlugin() +{ +} diff --git a/src/kits/media/Jamfile b/src/kits/media/Jamfile index 5755db6ca0..25e5f5e2b2 100644 --- a/src/kits/media/Jamfile +++ b/src/kits/media/Jamfile @@ -77,10 +77,12 @@ SharedLibrary libmedia.so : # Codec Plugin API ChunkCache.cpp DecoderPlugin.cpp + EncoderPlugin.cpp MediaExtractor.cpp MediaPlugin.cpp PluginManager.cpp ReaderPlugin.cpp + WriterPlugin.cpp : be $(TARGET_LIBSUPC++) ; diff --git a/src/kits/media/PluginManager.cpp b/src/kits/media/PluginManager.cpp index fb1acf7f04..6fe8461904 100644 --- a/src/kits/media/PluginManager.cpp +++ b/src/kits/media/PluginManager.cpp @@ -15,6 +15,9 @@ PluginManager _plugin_manager; +// #pragma mark - Readers/Decoders + + status_t PluginManager::CreateReader(Reader** reader, int32* streamCount, media_file_format* mff, BDataIO* source) @@ -115,13 +118,13 @@ PluginManager::CreateDecoder(Decoder** _decoder, const media_format& format) } MediaPlugin* plugin = GetPlugin(reply.ref); - if (!plugin) { + if (plugin == NULL) { printf("PluginManager::CreateDecoder: GetPlugin failed\n"); return B_ERROR; } DecoderPlugin* decoderPlugin = dynamic_cast(plugin); - if (!decoderPlugin) { + if (decoderPlugin == NULL) { printf("PluginManager::CreateDecoder: dynamic_cast failed\n"); PutPlugin(plugin); return B_ERROR; @@ -154,7 +157,7 @@ PluginManager::CreateDecoder(Decoder** decoder, const media_codec_info& mci) status_t PluginManager::GetDecoderInfo(Decoder* decoder, media_codec_info* _info) const { - if (!decoder) + if (decoder == NULL) return B_BAD_VALUE; decoder->GetCodecInfo(_info); @@ -181,7 +184,165 @@ PluginManager::DestroyDecoder(Decoder* decoder) } -// #pragma mark - +// #pragma mark - Writers/Encoders + + +status_t +PluginManager::CreateWriter(Writer** reader, const media_file_format& mff, + BDataIO* target) +{ + TRACE("PluginManager::CreateWriter enter\n"); + +#if 0 + // get list of available readers from the server + server_get_writer_request request; + request.file_format = mff; + server_get_writer_reply reply; + status_t ret = QueryServer(SERVER_GET_WRITER_FOR_FORMAT_FAMILY, &request, + sizeof(request), &reply, sizeof(reply)); + if (ret != B_OK) { + printf("PluginManager::CreateWriter: can't get writer for file " + "family: %s\n", strerror(ret)); + return ret; + } + + MediaPlugin* plugin = GetPlugin(reply.ref); + if (plugin == NULL) { + printf("PluginManager::CreateWriter: GetPlugin failed\n"); + return B_ERROR; + } + + WriterPlugin* writerPlugin = dynamic_cast(plugin); + if (writerPlugin == NULL) { + printf("PluginManager::CreateWriter: dynamic_cast failed\n"); + PutPlugin(plugin); + return B_ERROR; + } + + *writer = writerPlugin->NewWriter(); + if (*writer == NULL) { + printf("PluginManager::CreateWriter: NewWriter failed\n"); + PutPlugin(plugin); + return B_ERROR; + } + + (*writer)->Setup(target); + (*writer)->fMediaPlugin = plugin; + + TRACE("PluginManager::CreateWriter leave\n"); + return B_OK; +#else + TRACE("PluginManager::CreateWriter leave\n"); + return B_MEDIA_NO_HANDLER; +#endif +} + + +void +PluginManager::DestroyWriter(Writer* writer) +{ + if (writer != NULL) { + TRACE("PluginManager::DestroyWriter(%p (plugin: %p))\n", writer, + reader->fMediaPlugin); + // NOTE: We have to put the plug-in after deleting the writer, + // since otherwise we may actually unload the code for the + // destructor... + MediaPlugin* plugin = writer->fMediaPlugin; + delete writer; + PutPlugin(plugin); + } +} + + +status_t +PluginManager::CreateEncoder(Encoder** _encoder, const media_format& format) +{ +#if 0 + TRACE("PluginManager::CreateEncoder enter\n"); + + // 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, + sizeof(request), &reply, sizeof(reply)); + if (ret != B_OK) { + printf("PluginManager::CreateEncoder: can't get encoder for format: " + "%s\n", strerror(ret)); + return ret; + } + + MediaPlugin* plugin = GetPlugin(reply.ref); + if (!plugin) { + printf("PluginManager::CreateEncoder: GetPlugin failed\n"); + return B_ERROR; + } + + EncoderPlugin* encoderPlugin = dynamic_cast(plugin); + if (encoderPlugin == NULL) { + printf("PluginManager::CreateEncoder: dynamic_cast failed\n"); + PutPlugin(plugin); + return B_ERROR; + } + + *_encoder = encoderPlugin->NewEncoder(0); + if (*_decoder == NULL) { + printf("PluginManager::CreateEncoder: NewEncoder() failed\n"); + PutPlugin(plugin); + return B_ERROR; + } + TRACE(" created encoder: %p\n", *_encoder); + (*_encoder)->fMediaPlugin = plugin; + + TRACE("PluginManager::CreateEncoder leave\n"); + + return B_OK; +#else + return B_NOT_SUPPORTED; +#endif +} + + +status_t +PluginManager::CreateEncoder(Encoder** encoder, const media_codec_info& mci) +{ + // TODO + debugger("not implemented"); + return B_ERROR; +} + + +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; +} + + +void +PluginManager::DestroyEncoder(Encoder* encoder) +{ + if (encoder != NULL) { + TRACE("PluginManager::DestroyEncoder(%p, plugin: %p)\n", encoder, + encoder->fMediaPlugin); + // NOTE: We have to put the plug-in after deleting the encoder, + // since otherwise we may actually unload the code for the + // destructor... + MediaPlugin* plugin = encoder->fMediaPlugin; + delete encoder; + PutPlugin(plugin); + } +} + + +// #pragma mark - PluginManager::PluginManager() diff --git a/src/kits/media/ReaderPlugin.cpp b/src/kits/media/ReaderPlugin.cpp index 40148d0cd2..634cec2ad8 100644 --- a/src/kits/media/ReaderPlugin.cpp +++ b/src/kits/media/ReaderPlugin.cpp @@ -10,7 +10,7 @@ Reader::Reader() : - fSource(0), + fSource(NULL), fMediaPlugin(NULL) { } diff --git a/src/kits/media/WriterPlugin.cpp b/src/kits/media/WriterPlugin.cpp new file mode 100644 index 0000000000..bf4777ecef --- /dev/null +++ b/src/kits/media/WriterPlugin.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2009, Stephan Aßmus . All rights reserved. + * Copyright 2004, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include "WriterPlugin.h" + +#include + + +Writer::Writer() + : + fTarget(NULL), + fMediaPlugin(NULL) +{ +} + + +Writer::~Writer() +{ +} + + +BDataIO* +Writer::Target() const +{ + return fTarget; +} + + +void +Writer::Setup(BDataIO* target) +{ + fTarget = target; +} + + +status_t +Writer::Perform(perform_code code, void* data) +{ + return B_OK; +} + +void Writer::_ReservedWriter1() {} +void Writer::_ReservedWriter2() {} +void Writer::_ReservedWriter3() {} +void Writer::_ReservedWriter4() {} +void Writer::_ReservedWriter5() {} +