[Haiku-commits] r30984 - in haiku/trunk: headers/private/media src/kits/media

stippi at mail.berlios.de stippi at mail.berlios.de
Sun Jun 7 20:11:09 CEST 2009


Author: stippi
Date: 2009-06-07 20:11:05 +0200 (Sun, 07 Jun 2009)
New Revision: 30984
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=30984&view=rev

Modified:
   haiku/trunk/headers/private/media/DecoderPlugin.h
   haiku/trunk/headers/private/media/PluginManager.h
   haiku/trunk/headers/private/media/ReaderPlugin.h
   haiku/trunk/src/kits/media/DecoderPlugin.cpp
   haiku/trunk/src/kits/media/PluginManager.cpp
   haiku/trunk/src/kits/media/ReaderPlugin.cpp
Log:
Resolved TODOs in PluginManager about leaking plugins when they are no longer
needed. I've added MediaPlugin* fields to Reader and Decoder plugin classes
which are set when the PluginManager hands out new instances. This way the
manager knows what plugin created the Decoder or Reader instance in the
Destroy*() methods and can decrease the reference count accordingly. Also added
some FBC stuffing to Decoder and Reader. All media plugins need to be recompiled,
in case anyone has some outside the Haiku tree.


Modified: haiku/trunk/headers/private/media/DecoderPlugin.h
===================================================================
--- haiku/trunk/headers/private/media/DecoderPlugin.h	2009-06-07 18:04:32 UTC (rev 30983)
+++ haiku/trunk/headers/private/media/DecoderPlugin.h	2009-06-07 18:11:05 UTC (rev 30984)
@@ -9,53 +9,75 @@
 
 namespace BPrivate { namespace media {
 
+class PluginManager;
+
 class ChunkProvider {
 public:
-	virtual			~ChunkProvider() {};
-	virtual status_t	GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
-						             media_header *mediaHeader) = 0;
+	virtual						~ChunkProvider() {};
+	virtual	status_t			GetNextChunk(const void** chunkBuffer,
+									size_t* chunkSize,
+									media_header* mediaHeader) = 0;
 };
 
-class Decoder
-{
+class Decoder {
 public:
-						Decoder();
-	virtual				~Decoder();
+								Decoder();
+	virtual						~Decoder();
 
-	virtual void		GetCodecInfo(media_codec_info *codecInfo) = 0;
+	virtual	void				GetCodecInfo(media_codec_info* codecInfo) = 0;
 
-						// Setup get's called with the info data from Reader::GetStreamInfo
-	virtual status_t	Setup(media_format *ioEncodedFormat, const void *infoBuffer, size_t infoSize) = 0;
+	// Setup get's called with the info data from Reader::GetStreamInfo
+	virtual	status_t			Setup(media_format* ioEncodedFormat,
+									const void* infoBuffer,
+									size_t infoSize) = 0;
 
-	virtual status_t	NegotiateOutputFormat(media_format *ioDecodedFormat) = 0;
+	virtual	status_t			NegotiateOutputFormat(
+									media_format* ioDecodedFormat) = 0;
 	
-	virtual status_t	Seek(uint32 seekTo,
-							 int64 seekFrame, int64 *frame,
-							 bigtime_t seekTime, bigtime_t *time) = 0;
+	virtual	status_t			Seek(uint32 seekTo, int64 seekFrame,
+									int64* frame, bigtime_t seekTime,
+									bigtime_t* time) = 0;
 							 
-	virtual status_t	Decode(void *buffer, int64 *frameCount,
-							   media_header *mediaHeader, media_decode_info *info = 0) = 0;
+	virtual status_t			Decode(void* buffer, int64* frameCount,
+									media_header* mediaHeader,
+									media_decode_info* info = 0) = 0;
 							   
-	status_t			GetNextChunk(const void **chunkBuffer, size_t *chunkSize,
-									 media_header *mediaHeader);
+			status_t			GetNextChunk(const void** chunkBuffer,
+									size_t* chunkSize,
+									media_header* mediaHeader);
 
-	void				SetChunkProvider(ChunkProvider *provider);
+			void				SetChunkProvider(ChunkProvider* provider);
+
+	virtual status_t			Perform(perform_code code, void* data);
+
 private:
-	ChunkProvider *		fChunkProvider;
+	virtual void				_ReservedDecoder1();
+	virtual void				_ReservedDecoder2();
+	virtual void				_ReservedDecoder3();
+	virtual void				_ReservedDecoder4();
+	virtual void				_ReservedDecoder5();
+
+			ChunkProvider*		fChunkProvider;
+
+	// needed for plug-in reference count management
+	friend class PluginManager;
+			MediaPlugin*		fMediaPlugin;
+
+			uint32				fReserved[5];
 };
 
 
-class DecoderPlugin : public virtual MediaPlugin
-{
-	public:
-		DecoderPlugin();
+class DecoderPlugin : public virtual MediaPlugin {
+public:
+								DecoderPlugin();
 
-		virtual Decoder *NewDecoder(uint index) = 0;
-		virtual status_t GetSupportedFormats(media_format ** formats, size_t * count) = 0;
+	virtual	Decoder*			NewDecoder(uint index) = 0;
+	virtual	status_t			GetSupportedFormats(media_format** formats,
+									size_t * count) = 0;
 };
 
 } } // namespace BPrivate::media
 
 using namespace BPrivate::media;
 
-#endif
+#endif // _DECODER_PLUGIN_H

Modified: haiku/trunk/headers/private/media/PluginManager.h
===================================================================
--- haiku/trunk/headers/private/media/PluginManager.h	2009-06-07 18:04:32 UTC (rev 30983)
+++ haiku/trunk/headers/private/media/PluginManager.h	2009-06-07 18:11:05 UTC (rev 30984)
@@ -36,6 +36,15 @@
 		int			usecount;
 		MediaPlugin *plugin;
 		image_id	image;
+
+		plugin_info& operator=(const plugin_info& other)
+		{
+			strcpy(name, other.name);
+			usecount = other.usecount;
+			plugin = other.plugin;
+			image = other.image;
+			return *this;
+		}
 	};
 
 	List<plugin_info> *fPluginList;

Modified: haiku/trunk/headers/private/media/ReaderPlugin.h
===================================================================
--- haiku/trunk/headers/private/media/ReaderPlugin.h	2009-06-07 18:04:32 UTC (rev 30983)
+++ haiku/trunk/headers/private/media/ReaderPlugin.h	2009-06-07 18:11:05 UTC (rev 30984)
@@ -6,6 +6,8 @@
 
 namespace BPrivate { namespace media {
 
+class PluginManager;
+
 enum {
 	B_MEDIA_SEEK_TO_TIME	= 0x10000,
 	B_MEDIA_SEEK_TO_FRAME	= 0x20000
@@ -41,12 +43,26 @@
 									media_header* mediaHeader) = 0;
 	
 			BDataIO*			Source() const;
-	
+
+	virtual status_t			Perform(perform_code code, void* data);
+
 private:
+	virtual void				_ReservedReader1();
+	virtual void				_ReservedReader2();
+	virtual void				_ReservedReader3();
+	virtual void				_ReservedReader4();
+	virtual void				_ReservedReader5();
+
 public: // XXX for test programs only
 			void				Setup(BDataIO* source);
 
 			BDataIO*			fSource;
+
+	// needed for plug-in reference count management
+	friend class PluginManager;
+			MediaPlugin*		fMediaPlugin;
+
+			uint32				fReserved[5];
 };
 
 

Modified: haiku/trunk/src/kits/media/DecoderPlugin.cpp
===================================================================
--- haiku/trunk/src/kits/media/DecoderPlugin.cpp	2009-06-07 18:04:32 UTC (rev 30983)
+++ haiku/trunk/src/kits/media/DecoderPlugin.cpp	2009-06-07 18:11:05 UTC (rev 30984)
@@ -1,18 +1,20 @@
 /* 
-** Copyright 2004, Marcus Overhagen. All rights reserved.
-** Distributed under the terms of the OpenBeOS License.
-*/
+ * Copyright 2004, Marcus Overhagen. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
 
-
 #include "DecoderPlugin.h"
 
-#include <MediaFormats.h>
 #include <stdio.h>
 #include <string.h>
 
+#include <MediaFormats.h>
 
+
 Decoder::Decoder()
- :	fChunkProvider(NULL)
+	:
+	fChunkProvider(NULL),
+	fMediaPlugin(NULL)
 {
 }
 
@@ -39,6 +41,18 @@
 }
 
 
+status_t
+Decoder::Perform(perform_code code, void* _data)
+{
+	return B_OK;
+}
+
+void Decoder::_ReservedDecoder1() {}
+void Decoder::_ReservedDecoder2() {}
+void Decoder::_ReservedDecoder3() {}
+void Decoder::_ReservedDecoder4() {}
+void Decoder::_ReservedDecoder5() {}
+
 //	#pragma mark -
 
 

Modified: haiku/trunk/src/kits/media/PluginManager.cpp
===================================================================
--- haiku/trunk/src/kits/media/PluginManager.cpp	2009-06-07 18:04:32 UTC (rev 30983)
+++ haiku/trunk/src/kits/media/PluginManager.cpp	2009-06-07 18:11:05 UTC (rev 30984)
@@ -49,7 +49,7 @@
 			return B_ERROR;
 		}
 
-		ReaderPlugin *readerPlugin = dynamic_cast<ReaderPlugin *>(plugin);
+		ReaderPlugin *readerPlugin = dynamic_cast<ReaderPlugin*>(plugin);
 		if (!readerPlugin) {
 			printf("PluginManager::CreateReader: dynamic_cast failed\n");
 			PutPlugin(plugin);
@@ -57,7 +57,7 @@
 		}
 
 		*reader = readerPlugin->NewReader();
-		if (! *reader) {
+		if (*reader == NULL) {
 			printf("PluginManager::CreateReader: NewReader failed\n");
 			PutPlugin(plugin);
 			return B_ERROR;
@@ -65,6 +65,7 @@
 
 		seekable_source->Seek(0, SEEK_SET);
 		(*reader)->Setup(seekable_source);
+		(*reader)->fMediaPlugin = plugin;
 
 		if ((*reader)->Sniff(streamCount) == B_OK) {
 			TRACE("PluginManager::CreateReader: Sniff success "
@@ -73,9 +74,7 @@
 			return B_OK;
 		}
 
-		// _DestroyReader(*reader);
-		delete *reader;
-		PutPlugin(plugin);
+		DestroyReader(*reader);
 	}
 
 	TRACE("PluginManager::CreateReader leave\n");
@@ -84,10 +83,18 @@
 
 
 void
-PluginManager::DestroyReader(Reader *reader)
+PluginManager::DestroyReader(Reader* reader)
 {
-	// ToDo: must call put plugin
-	delete reader;
+	if (reader != NULL) {
+		TRACE("PluginManager::DestroyReader(%p (plugin: %p))\n", reader,
+			reader->fMediaPlugin);
+		// NOTE: We have to put the plug-in after deleting the reader,
+		// since otherwise we may actually unload the code for the
+		// destructor...
+		MediaPlugin* plugin = reader->fMediaPlugin;
+		delete reader;
+		PutPlugin(plugin);
+	}
 }
 
 
@@ -108,7 +115,7 @@
 		return ret;
 	}
 
-	MediaPlugin *plugin = GetPlugin(reply.ref);
+	MediaPlugin* plugin = GetPlugin(reply.ref);
 	if (!plugin) {
 		printf("PluginManager::CreateDecoder: GetPlugin failed\n");
 		return B_ERROR;
@@ -127,6 +134,8 @@
 		PutPlugin(plugin);
 		return B_ERROR;
 	}
+	TRACE("  created decoder: %p\n", *_decoder);
+	(*_decoder)->fMediaPlugin = plugin;
 
 	TRACE("PluginManager::CreateDecoder leave\n");
 
@@ -161,8 +170,16 @@
 void
 PluginManager::DestroyDecoder(Decoder *decoder)
 {
-	// ToDo: must call put plugin
-	delete decoder;
+	if (decoder != NULL) {
+		TRACE("PluginManager::DestroyDecoder(%p, plugin: %p)\n", decoder,
+			decoder->fMediaPlugin);
+		// NOTE: We have to put the plug-in after deleting the decoder,
+		// since otherwise we may actually unload the code for the
+		// destructor...
+		MediaPlugin* plugin = decoder->fMediaPlugin;
+		delete decoder;
+		PutPlugin(plugin);
+	}
 }
 
 
@@ -180,14 +197,13 @@
 PluginManager::~PluginManager()
 {
 	CALLED();
-	while (!fPluginList->IsEmpty()) {
+	for (int i = fPluginList->CountItems() - 1; i >= 0; i--) {
 		plugin_info *info = NULL;
-		fPluginList->Get(fPluginList->CountItems() - 1, &info);
+		fPluginList->Get(i, &info);
 		printf("PluginManager: Error, unloading PlugIn %s with usecount "
 			"%d\n", info->name, info->usecount);
 		delete info->plugin;
 		unload_add_on(info->image);
-		fPluginList->Remove(fPluginList->CountItems() - 1);
 	}
 	delete fLocker;
 }
@@ -196,6 +212,7 @@
 MediaPlugin *
 PluginManager::GetPlugin(const entry_ref &ref)
 {
+	TRACE("PluginManager::GetPlugin(%s)\n", ref.name);
 	fLocker->Lock();
 	
 	MediaPlugin *plugin;
@@ -206,6 +223,7 @@
 		if (0 == strcmp(ref.name, pinfo->name)) {
 			plugin = pinfo->plugin;
 			pinfo->usecount++;
+			TRACE("  found existing plugin: %p\n", pinfo->plugin);
 			fLocker->Unlock();
 			return plugin;
 		}
@@ -224,6 +242,7 @@
 	TRACE("PluginManager: PlugIn %s loaded\n", ref.name);
 
 	plugin = info.plugin;
+	TRACE("  loaded plugin: %p\n", plugin);
 	
 	fLocker->Unlock();
 	return plugin;
@@ -231,8 +250,9 @@
 
 
 void
-PluginManager::PutPlugin(MediaPlugin *plugin)
+PluginManager::PutPlugin(MediaPlugin* plugin)
 {
+	TRACE("PluginManager::PutPlugin()\n");
 	fLocker->Lock();
 	
 	plugin_info *pinfo;
@@ -241,7 +261,9 @@
 		if (plugin == pinfo->plugin) {
 			pinfo->usecount--;
 			if (pinfo->usecount == 0) {
+				TRACE("  deleting %p\n", pinfo->plugin);
 				delete pinfo->plugin;
+				TRACE("  unloading add-on: %ld\n\n", pinfo->image);
 				unload_add_on(pinfo->image);
 				fPluginList->RemoveCurrent();
 			}
@@ -266,6 +288,7 @@
 
 	image_id id;
 	id = load_add_on(p.Path());
+	TRACE("  loaded add-on: %ld\n", id);
 	if (id < 0)
 		return B_ERROR;
 		

Modified: haiku/trunk/src/kits/media/ReaderPlugin.cpp
===================================================================
--- haiku/trunk/src/kits/media/ReaderPlugin.cpp	2009-06-07 18:04:32 UTC (rev 30983)
+++ haiku/trunk/src/kits/media/ReaderPlugin.cpp	2009-06-07 18:11:05 UTC (rev 30984)
@@ -1,8 +1,17 @@
+/* 
+ * Copyright 2004, Marcus Overhagen. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
 #include "ReaderPlugin.h"
 
+#include <stdio.h>
 
+
 Reader::Reader()
- :	fSource(0)
+	:
+	fSource(0),
+	fMediaPlugin(NULL)
 {
 }
 
@@ -38,3 +47,17 @@
 {
 	fSource = source;
 }
+
+
+status_t
+Reader::Perform(perform_code code, void* _data)
+{
+	return B_OK;
+}
+
+void Reader::_ReservedReader1() {}
+void Reader::_ReservedReader2() {}
+void Reader::_ReservedReader3() {}
+void Reader::_ReservedReader4() {}
+void Reader::_ReservedReader5() {}
+




More information about the Haiku-commits mailing list