private void CallPluginRenderLoop ()
	{
		// Rendering of scene objects can happen here
		// Add the movie to the render plugin queue so it gets rendered
		if (Movie.Bink != IntPtr.Zero) {
			if (Type == BinkPluginType.GPUTexture && !usingOpenGL()) {
				if (renderer) {
					renderer.enabled = BinkRenderIsTextureSetReady (Movie.TextureSet) && m_yRenderTexture.IsCreated ();
				}	
			}

			//TextureSet was invalidated by window resize, re-create it. 
			if (!usingOpenGL() && Movie.TextureSet == IntPtr.Zero) {
				CreateTextureSet ();

				//Do not attempt to render if we cannot create the texture set
				if (Movie.TextureSet == IntPtr.Zero) {
					return;
				}
			}

			xScale = 1.0f;
			yScale = 1.0f;
			
			//For multiple-movie testing, scale and offset the second one so you can see it. 
			UpdateBinkRenderParameters (Movie.BinkWidth, Movie.BinkHeight);

			if (Type == BinkPluginType.GPUTexture && !usingOpenGL()) {
				if (!m_yRenderTexture.IsCreated ()) {
					m_yRenderTexture.Create ();
					m_cBRenderTexture.Create ();
					m_cRRenderTexture.Create ();
					
					if (UseAlpha) {
						m_ARenderTexture.Create ();
					}
					CreateTextureSet ();
					CacheNativeRenderPointer ();
					BinkRenderMarkReset (Movie.TextureSet, true);
				}
			}
			
			bool tickAutomatically = true;
#if BINK_QUEUE_TICK_MANUALLY
			tickAutomatically = false;
			//
			Bink.BINKSUMMARY summary = new Bink.BINKSUMMARY ();
			Bink.BinkGetSummary (Movie.Bink, ref summary);
			uint targetFrame = this.getTargetFrame (summary);
			bool skip = false;
			
			if (targetFrame == Movie.lastRenderedFrame) {
				skip = true;				
			}

			if (!BinkRenderOkToRender ()) {
				skip = true;
			}

			
      		if (!this.Movie.visible && this.SmartRender && Movie.lastRenderedFrame >= 0) {
				//only render if visible, or if first frame of video.	
				skip = true;				
			}

			this.Movie.visible = false; //will be set to true if any camera can see it.
      
			if (!skip) {				
				BinkRenderRespondToReset (Movie.Bink, Movie.TextureSet, NativeYTexture, NativecBTexture, NativecRTexture, NativeATexture);

				BinkRenderPreUpdate (Movie.Bink, Movie.TextureSet, NativeYTexture, NativecBTexture, NativecRTexture, NativeATexture);
				//Bink.BinkSetWillLoop(Movie.Bink,1); //test me.
				// Notify plugin we're about to update Bink
				//
				Bink.BinkDoFrameAsync(Movie.Bink,(uint)this.threadA,(uint)this.threadB);
				Bink.BinkDoFrameAsyncWait(Movie.Bink,-1);
        
					
				int frameDiff = ((int)targetFrame - Movie.currentFrame);
				if (frameDiff < -1 || // We have already gone past the target frame. We must rewind 
				    frameDiff > this.getFrameRate (summary) * 0.5f) { // The target frame is after us, but by a significant amount so we should jump  								
					
					Bink.BinkGoto (Movie.Bink, targetFrame, 0); 
					Movie.currentFrame = (int)targetFrame;
				}
			
				//
				// Decompress a frame
				//
				
				Movie.lastRenderedFrame = Movie.currentFrame;
				Movie.currentFrame++;
				Movie.needsBlit = true;
				//
				// Keep playing the Movie.
				//
				Bink.BinkNextFrame (Movie.Bink);
				//Bink.BinkDoFrameAsync(Movie.Bink,(uint)this.threadA,(uint)this.threadB);
				
			

				//UnityEngine.Debug.Log ("woo?");
				//
				// Notify plugin we're done updating
				//
				BinkRenderPostUpdate (Movie.Bink);
			}
			
			
#endif //BINK_QUEUE_TICK_MANUALLY
			BinkRenderQueueAdd (Movie.Bink, Movie.TextureSet, tickAutomatically, Movie.BinkWidth, Movie.BinkHeight, (int)(Screen.width * xScale), (int)(Screen.height * yScale), XOffset, YOffset, xScale, yScale, 1.0f, 0, NativeYTexture, NativecBTexture, NativecRTexture, NativeATexture);
			
		}

	}
	private IEnumerator CallPluginAtEndOfFrames ()
	{
		while (true) {
			
			// Wait until all frame rendering is done
			yield return new WaitForEndOfFrame ();
			if (!this.movieLoaded)
				continue;
			BinkPlayOptions bpo = this.getBinkPluginOptions ();
			
			if (bpo == null)
				continue;
			
				
			if (bpo.playAfterSeconds > 0f) {
				if (bpo.movieSpeed > 0f) {
					// Simple delay before movie starts playing
					bpo.playAfterSeconds -= this.getDeltaTime();
				}
			} else {
				bpo.movieTime += bpo.movieSpeed * this.getDeltaTime();
	      	}
	      	
			// We want bink to render the first frame even if playAfterSeconds is still counting down,
			// so everything below gets run regardless
	      	
			if (Type == BinkPluginType.Overlay ||
				(Type == BinkPluginType.GPUTexture && !usingOpenGL())) {
				CallPluginRenderLoop ();

				// Issue a plugin event with arbitrary integer identifier.
				// The plugin can distinguish between different
				// things it needs to do based on this ID.
				// For our simple plugin, it does not matter which ID we pass here.
				GL.IssuePluginEvent (1);
			} else {
				if (Movie.Bink != IntPtr.Zero) {
					//
					// Notify plugin we're about to update Bink
					//
					Bink.BINKSUMMARY summary = new Bink.BINKSUMMARY ();
					Bink.BinkGetSummary (Movie.Bink, ref summary);
					if (Bink.BinkWait (Movie.Bink) == 0) {
						BinkRenderPreUpdate (Movie.Bink, Movie.TextureSet, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

						//
						// Decompress a frame
						//
						Bink.BinkDoFrame (Movie.Bink);
						
						//
						// if we are falling behind, decompress an extra frame to catch up
						//          
						while (Bink.BinkShouldSkip(Movie.Bink) != 0) {
							Bink.BinkNextFrame (Movie.Bink);
							Bink.BinkDoFrame (Movie.Bink);
						}
						
						BinkConvertToTexture (Movie);
						
						//
						// Keep playing the Movie.
						//
						Bink.BinkNextFrame (Movie.Bink);
						BinkRenderPostUpdate (Movie.Bink);
					}
				}
			}
			
		}
	}
	//Load a movie and add it to the playing movie list
	public bool _LoadMovie (String name)
	{		
		this.threadA = BinkPlugin.currThread % BinkPlugin.NUM_THREADS;
		currThread++;
		this.threadB = BinkPlugin.currThread % BinkPlugin.NUM_THREADS;
		currThread++;
		
		long flags = Bink.BINKALPHA;
		switch (Type) {
		case BinkPluginType.Overlay:
		#if UNITY_WIN 
			flags = Bink.BINKALPHA | Bink.BINKIOPROCESSOR;
			if (!usingOpenGL()) {
				flags |= Bink.BINKNOFRAMEBUFFERS;
			}
		#endif
			break;
		case BinkPluginType.CPUTexture:
		case BinkPluginType.GPUTexture:
		#if UNITY_WIN 
			flags = Bink.BINKALPHA | Bink.BINKIOPROCESSOR;
		#endif
			break;
		default:
			break;
		}
	
		Movie.Bink = Bink.BinkOpen (name, flags);
	
		if (Movie.Bink != IntPtr.Zero) {
			Bink.BINKSUMMARY summary = new Bink.BINKSUMMARY ();
			Bink.BinkGetSummary (Movie.Bink, ref summary);
			Movie.BinkWidth = (int)summary.Width;
			Movie.BinkHeight = (int)summary.Height;

			UseAlpha = Alpha && BinkRenderMovieHasAlpha (Movie.Bink);

			if (!usingOpenGL()) {
				CreateRenderTextures ();
			}

			CreateTextureSet ();

			if (!usingOpenGL() && Movie.TextureSet == IntPtr.Zero) {
				UnityEngine.Debug.LogError (String.Format ("Failed to create Bink texture set for {0}", name));
			}
		} else {
			UnityEngine.Debug.LogError (String.Format ("BinkOpen failed to open {0}", name));
			return false;
		}
		
		this.movieLoaded = true;
		return true;
	}