Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Derived Media Handler not called in between Open and Close



Hello,

I need to write a component that should be called any time an application wants to play video through QuickTime so it can check some data in the movie file (in media "Initialize") and either modify it before playing or let QT do its things as usual.
I thought of creating a derived media handler to override the Apple Video Media Handler ('mhlr'/'vide') which seems to be used for every kind of video files I must check. I decided to capture this media handler so that each time an application opens a video movie, my component is called first. It can then check if it must act on the media or not. If not, it just calls the original media handler. Otherwise it edits the data (in the idle function) before drawing it with the regular codec.
So far my component appears to register properly, with the intended flags, type, subtype and manufacturer. I can verify that the captured media handler is removed from the list of available media handlers. Also, I can verify that the Open and Close functions are called properly and the memory allocated, set and disposed as I want. But that's all. At the moment I would like to use the "Idle" and "Initialize" functions in my component and delegating all the others but they are never called. For testing, I added SetDimensions and SetMatrix too but they are not called either when I changed the size of the window playing the movie.
I looked carefully at the Apple sample codes, but they are all for codecs or importers/exporters. I found 3 older examples of media handlers but they are not directly applicable because many things seemed to have changed (in particular the use of ComponentDispatchHelper.c.


So I guess my question is twofold:
1. Is my approach correct or is it too dangerous or forbidden to override this kind of "low level" component?
2. Why only "Open" and "Close" are called and not "Initialize" and "Idle"?
(by the way, I could not get the "Register" function to be called even after setting the corresponding flag in the component resource; I no longer use this flag now anyway, since I read it is not recommended on Mac OS X: <http://developer.apple.com/qa/qa2001/ qa1192.html>)


Sorry for the long post...
I've spent the last few days trying to make this work but to no avail. I've read everything I could find on the subject in the archives, the sample codes and elsewhere thanks to Google, but it has only got me started. The most interesting articles on media handlers and component capture I could find are more than 10 years old so things have changed in some areas.


Thanks a lot in advance for your help.

Olivier


Here are the relevant parts of my code:

------------------- MyMediaHandler.c -------------------

// Setup required for ComponentDispatchHelper.c

#define MEDIA_BASENAME()			MYMH_
#define MEDIA_GLOBALS()				MYMH_GlobalsHdl storage

#define CALLCOMPONENT_BASENAME()	MEDIA_BASENAME()
#define CALLCOMPONENT_GLOBALS()		MEDIA_GLOBALS()

#define COMPONENT_UPP_PREFIX()		uppMedia
#define COMPONENT_SELECT_PREFIX()  	kMedia
#define COMPONENT_DISPATCH_FILE		"MyMediaHandler_Dispatch.h"

#define GET_DELEGATE_COMPONENT()	((**storage).fDelegate)

(...)

// Type definitions
// Instance storage (passed by the Component Manager)
typedef struct MYMH_Globals {
// component stuff
ComponentInstance fDelegate; // the base component we are delegating to
ComponentInstance fSelf; // ourself
ComponentInstance fParent; // our parent, if we are targeted by another media handler

...


} MYMH_Globals, *MYMH_GlobalsPtr, **MYMH_GlobalsHdl;

// Component storage (accessed through GetComponentRefcon)
typedef struct MYMH_SharedGlobals {
	Component	delegateComponent;
	long		instanceCount;
} MYMH_SharedGlobals, *MYMH_SharedGlobalsPtr, **MYMH_SharedGlobalsHdl;



PASCAL_RTN ComponentResult MYMH_Open (MYMH_GlobalsHdl storage, ComponentInstance theSelf)
{
MYMH_GlobalsHdl myStorage = NULL;
MYMH_SharedGlobalsPtr mySharedStorage = NULL;
Component myComponent = NULL;


	... (allocate the instance memory (myStorage) then tell the Comp. Mgr)
	(*myStorage)->fSelf = theSelf;	
	SetComponentInstanceStorage(theSelf, (Handle)myStorage);

	... (allocate the component memory (mySharedStorage) if needed)
	... (get our component rather than the instance: myComponent)
	... (get the component to be captured: delegateComponent)

// Capture the base video media handler
mySharedStorage->delegateComponent = CaptureComponent (delegateComponent, myComponent);
if (!mySharedStorage->delegateComponent) return (componentNotCaptured);


// open the base video media handler component and target it
result = OpenAComponent( mySharedStorage->delegateComponent, & ((*myStorage)->fDelegate) );
if (result == noErr) {
result = ComponentSetTarget((*myStorage)->fDelegate, (*myStorage)- >fSelf);
//if (result == badComponentSelector) SysBeep(60); // testing...
}
(mySharedStorage->instanceCount)++;
(*myStorage)->fParent = theSelf;

return result;
}


PASCAL_RTN ComponentResult MYMH_Close (MYMH_GlobalsHdl storage, ComponentInstance theSelf)
{
...
}


PASCAL_RTN ComponentResult MYMH_Version (MYMH_GlobalsHdl storage)
{
	...
}

PASCAL_RTN ComponentResult MYMH_Register (MYMH_GlobalsHdl storage)
{
	...
}

PASCAL_RTN ComponentResult MYMH_Target (MYMH_GlobalsHdl storage, ComponentInstance theTarget)
{
// remember who is at the top of our calling chain
(**storage).fParent = theTarget;

if ((**storage).fDelegate)
// inform the base media handler of the change
ComponentSetTarget((**storage).fDelegate, theTarget);

return(noErr);
}



PASCAL_RTN ComponentResult MYMH_Initialize (MYMH_GlobalsHdl storage, GetMovieCompleteParams *theGMC)
{
...
}


PASCAL_RTN ComponentResult MYMH_Idle (MYMH_GlobalsHdl storage, TimeValue theMediaTime, long theFlagsIn, long *theFlagsOut, const TimeRecord *theMovieTime)
{
...
}


PASCAL_RTN ComponentResult MYMH_SetDimensions (MYMH_GlobalsHdl storage, Fixed theWidth, Fixed theHeight)
{
...
}


PASCAL_RTN ComponentResult MYMH_SetMatrix (MYMH_GlobalsHdl storage, MatrixRecord *theTrackMovieMatrix)
{
...
}



------------------- MyMediaHandler_Dispatch.h -------------------

ComponentComment ("Count of selectors in range 0")
ComponentSelectorOffset (6)
//ComponentSelectorOffset (7) // if we add Unregister call, the count is 7


	ComponentComment ("Last selector range of this component")
	ComponentRangeCount (6)

	ComponentComment ("Size of each selector range in bits")
	ComponentRangeShift (8)
	ComponentRangeMask (FF)

	ComponentComment ("Core Selector Range")
	ComponentRangeBegin (0)
		//StdComponentCall 	(Unregister)
		StdComponentCall 	(Target)
		StdComponentCall 	(Register)	// No change if I use ComponentError
		StdComponentCall 	(Version)	// instead of StdComponentCall for
		StdComponentCall 	(CanDo)	// CanDo or Register
		StdComponentCall 	(Close)
		StdComponentCall 	(Open)
	ComponentRangeEnd (0)

	ComponentRangeUnused (1)		// selectors 0x00xx
	ComponentRangeUnused (2)		// selectors 0x01xx
	ComponentRangeUnused (3)		// selectors 0x02xx
	ComponentRangeUnused (4)		// selectors 0x03xx
	ComponentRangeUnused (5)		// selectors 0x04xx

	ComponentComment ("My Media Handler Range")
	ComponentRangeBegin (6)			// selectors 0x05xx (see MediaHandlers.h)
		ComponentError		(0)
		ComponentCall		(Initialize)
		ComponentDelegate	(SetHandlerCapabilities)
		ComponentCall		(Idle)
		ComponentDelegate	(GetMediaInfo)
		ComponentDelegate	(PutMediaInfo)
		ComponentDelegate	(SetActive)
		ComponentDelegate	(SetRate)
		ComponentDelegate	(GGetStatus)
		ComponentDelegate	(TrackEdited)
		ComponentDelegate	(SetMediaTimeScale)
		ComponentDelegate	(SetMovieTimeScale)
		ComponentDelegate	(SetGWorld)
		ComponentCall		(SetDimensions)
		ComponentDelegate	(SetClip)
		ComponentCall		(SetMatrix)
		ComponentDelegate	(GetTrackOpaque)
 		...
		ComponentDelegate	(0x0570)
		ComponentDelegate	(GGetLatency)
ComponentRangeEnd (6)


------------------- MyMediaHandler.r -------------------

resource 'thng' (kMYMH_ComponentResID, kMYMH_Name, purgeable) {
	kMYMH_ComponentType,							// component type
	kMYMH_MediaType,								// component subtype
	kMYMH_ComponentManufacturer,					// component manufacturer
	0,												// component flags
	kAnyComponentFlagsMask,							// component flags mask
	0,												// no 68K code use componentHasMultiplePlatforms
	0,												// no 68K code
	'STR ',											// component name resource type
	kMYMH_NameStringResID,							// component name resource ID
	'STR ',											// component info resource type
	kMYMH_InfoStringResID,							// component info resource ID
	0,												// component icon resource type
	0,												// component icon resource ID
	kMYMH_Version,
	componentDoAutoVersion | componentHasMultiplePlatforms,
	0,												// Resource ID of Icon Family
	{
#if TARGET_OS_MAC
	#if TARGET_REZ_CARBON_MACHO
		#if !(TARGET_REZ_MAC_PPC || TARGET_REZ_MAC_X86)
			#error "Platform architecture not defined!"
		#endif
		#if TARGET_REZ_MAC_PPC
			0x10000000,								// Flags
			'dlle',									// Code Resource type - Entry point
			kMYMH_ComponentResID,					// ID of 'mhlr' resource
			platformPowerPCNativeEntryPoint			// PowerPC-based Macintosh
		#endif
		#if TARGET_REZ_MAC_X86
			0,										// Flags
			'dlle',									// Code Resource type - Entry point
			kMYMH_ComponentResID,					// ID of 'dlle' resource
			platformIA32NativeEntryPoint			// Intel-based Macintosh
		#endif
	#else
		#error "TARGET_REZ_CARBON_MACHO should be defined."
	#endif
#elif TARGET_OS_WIN32
	#if TARGET_REZ_WIN32
		0,
		'dlle',
		kMYMH_ComponentResID,
		platformWin32
	#else
		#error "TARGET_REZ_WIN32 should be defined."
	#endif
#else
	#error "I have no idea what you're trying to do!"
#endif
	}
};

...

#if	TARGET_REZ_CARBON_MACHO || TARGET_REZ_WIN32
// Code Entry Point for Mach-O and Windows
	resource 'dlle' (kMYMH_ComponentResID, kMYMH_Name) {
		 "MYMH_ComponentDispatch"
	};
#endif





_______________________________________________
Do not post admin requests to the list. They will be ignored.
QuickTime-API mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quicktime-api/email@hidden

This email sent to email@hidden


Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.