⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handler.java

📁 FMJ(freedom media for java)是java视频开发的新选择
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
		{			FilterGraph.stop(root);		} catch (IOException e)		{			logger.log(Level.WARNING, "" + e, e);			postControllerErrorEvent("" + e);			return false;		}				return true;	}	private boolean firstStart = true;		//@Override	public boolean doPlayerSyncStart(Time time)	{		logger.info("Handler.doPlayerSyncStart " + time + " " + getState());				// the first time we start, the threads are usually in place.  we only need to 		// create them here if we've been stopped.		if (firstStart)		{	firstStart = false;		}		else		{			// TODO: this code is duplicated in doRealize.			if (TRACE) logger.fine("Starting filter graph(s)");						try			{				FilterGraph.start(root);			} catch (IOException e)			{				logger.log(Level.WARNING, "" + e, e);				postControllerErrorEvent("" + e);				return false;			}						// TODO: we need to go to the correct time!			trackThreads = new TrackThread[root.getNumDestLinks()];						for (int i = 0; i < root.getNumDestLinks(); ++i)			{				if (root.getDestLink(i) != null)				{	final DemuxNode rootCopy = (DemuxNode) root.duplicate();					trackThreads[i] = new TrackThread(rootCopy, i, FilterGraph.PROCESS_DEFAULT); // use a copy of the graph for each thread, so that they don't interfere with each other.				}			}		}				for (int i = 0; i < trackThreads.length; ++i)		{			final TrackThread t = trackThreads[i];			if (t != null)				t.start(); 		}		return true;	}	//@Override	public Time getPlayerDuration()	{		// tricky because this gets called by the parent class. during realize, so we won't be in the realized state		// although we already have the tracks.          if( getState() < Realizing || root == null ) {      		logger.fine("getPlayerDuration: returning demuxDuration");      	          	return demuxDuration;        } else        {   //      if( getState() < Prefetched ) {        	        	// code borrowed from AbstractPlayer.  TODO: once each track has its own controller, there will be no need for this to be calculated here.        	Time duration = null;        	//Time d = getSource().getDuration();	    		//if (duration != null && duration.getNanoseconds() != Duration.DURATION_UNKNOWN.getNanoseconds()    		final Track[] tracks = root.getTracks();    		for (int i = 0; i < tracks.length; ++i)    		{    			try    			{    			 Time d = tracks[i].getDuration();    			 logger.fine("Track " + i + " has duration of " + d.getNanoseconds());    			 if (duration == null)    			 {    				 duration = d;    				 continue;    			 }                 if (d == DURATION_UNKNOWN ) {                     duration = d;                     break;                 }                 if( duration != DURATION_UNBOUNDED &&                     ( d == DURATION_UNBOUNDED ||                       d.getNanoseconds() >                       duration.getNanoseconds() ) )                 {                     duration = d;                 }    			}    			catch (Exception e)    			{	logger.log(Level.WARNING, "" + e, e);    				continue;    				// TODO: we get an NPE in at com.sun.media.parser.RawBufferParser$FrameTrack.getDuration(RawBufferParser.java:227)    				// when using that class for RTP reception.  Not sure why this is occurring, if it is a bug in JMF or FMJ.    				// for now, this is just a workaround so that we can continue.    			}    					    		}    		    		if (duration == null)    		{	logger.fine("getPlayerDuration: returning DURATION_UNKNOWN (2)");    			return DURATION_UNKNOWN;    		}    		    		logger.fine("getPlayerDuration: returning " + duration.getNanoseconds());            return duration;        }                // TODO:             //        } else//        //        	return DURATION_UNKNOWN;	// TODO// TODO: 	}	//@Override	public Time getPlayerStartLatency()	{		return new Time(0);	}	//@Override	public Component getVisualComponent()	{		return visualComponent;	}	// Processor:		public boolean doConfigure()	{		if (mode == PLAYER)			throw new UnsupportedOperationException();				// TODO: what to do here?		return true;	}		public DataSource getDataOutput() throws NotRealizedError	{		if (mode == PLAYER)			throw new UnsupportedOperationException();				if (getState() < Realized)			throw new NotRealizedError("Cannot call getDataOutput on an unrealized Processor.");		final MuxNode muxNode = (MuxNode) FilterGraph.getTail(root.getDestLink(0).getDestNode()); // TODO: hard coded to track zero				return muxNode.getMultiplexer().getDataOutput();	}	private TrackControl[] trackControls;		public TrackControl[] getTrackControls() throws NotConfiguredError	{		if (mode == PLAYER)			throw new UnsupportedOperationException();				if (getState() < Configured)			throw new NotConfiguredError("Cannot call getTrackControls on an unconfigured Processor.");				if (trackControls == null)		{				try			{				if (!getDemuxTracks())					throw new RuntimeException("Unable to get demux tracks");												final Track[] tracks = demux.getTracks();								trackControls = new TrackControl[tracks.length];							for (int trackNum = 0; trackNum < tracks.length; ++trackNum)				{					trackControls[trackNum] = new MyTrackControl(trackNum);				}						}			catch (IOException e)			{				throw new RuntimeException(e);			} catch (BadHeaderException e)			{				throw new RuntimeException(e);			}		}		return trackControls;					}	public ContentDescriptor[] getSupportedContentDescriptors() throws NotConfiguredError	{		if (mode == PLAYER)			throw new UnsupportedOperationException();				if (getState() < Configured)			throw new NotConfiguredError("Cannot call getSupportedContentDescriptors on an unconfigured Processor.");				final List muxs = /*<Multiplexer>*/ FilterGraph.findMuxs();	// TODO: only find ones that are reachable given the input		final List/*<ContentDescriptor>*/ result = new ArrayList();		for (int i = 0; i < muxs.size(); ++i)		{			final Multiplexer mux = (Multiplexer) muxs.get(i);			final Format[] f = mux.getSupportedOutputContentDescriptors(null);			for (int j = 0; j < f.length; ++j)				result.add(f[j]);		}				final ContentDescriptor[] arrayResult = new ContentDescriptor[result.size()];		for (int i = 0; i < result.size(); ++i)			arrayResult[i] = (ContentDescriptor) result.get(i);		return arrayResult;			}		/** builds mux muxInputFormats, only if not already built */	private void buildMux()	{		if (mux != null)			return;				if (!getDemuxTracks())			throw new RuntimeException("Unable to get demux tracks");				mux = FilterGraph.findMux(outputContentDescriptor);	// TODO: this works for RAW, but not RAW_RTP		if (mux == null)			throw new RuntimeException("Unable to find mux for " + outputContentDescriptor);		mux.setNumTracks(numTracks);		mux.setContentDescriptor(outputContentDescriptor);		muxInputFormats = new Format[numTracks];		// by default, input formats to the mux will be the same as the output formats		// of the demux.  If the caller uses a TrackControl, they can change this.		for (int i = 0; i < numTracks; ++i)		{			muxInputFormats[i] = mux.setInputFormat(tracks[i].getFormat(), i);		}			}		// TODO: implement.	// this appears to be able to control how the filter graph is built.		private class MyTrackControl implements TrackControl	{		private final int trackNum;		public MyTrackControl(final int trackNum)		{			super();			this.trackNum = trackNum;		}		public void setCodecChain(Codec[] codecs) throws UnsupportedPlugInException, NotConfiguredError		{			// TODO		}		public void setRenderer(Renderer renderer) throws UnsupportedPlugInException, NotConfiguredError		{//			 TODO		}		public Object getControl(String controlType)		{			return null;		}		public Object[] getControls()		{			return new Object[0];		}		public Format getFormat()		{			if (!getDemuxTracks())				throw new RuntimeException("Unable to get demux tracks");						if (muxInputFormats == null)				return tracks[trackNum].getFormat();	// TODO: this appears to be what JMF returns, if the format is not set.			return muxInputFormats[trackNum];		}		public Format[] getSupportedFormats()		{			buildMux();	// Not sure when JMF builds the MUX.			// TODO: FMJ returns this, but JMF returns a bunch of specific formats.			// we need to build FilterGraph.buildGraphToMux for this track, for all			// possible codec chains from the demux to the mux.			// if the mux supports multiple input formats, we should probably build all			// possible codec chains to all possible muxs.			// in FMJ, this is a relatively slow operation, by the way.			return mux.getSupportedInputFormats();		}		private boolean enabled = true;				public boolean isEnabled()		{			return enabled;		}		public void setEnabled(boolean enabled)		{			this.enabled = enabled;//			 TODO: how to actually make this take effect, if it is false?		}		public Format setFormat(Format format)		{			buildMux();		// Not sure when JMF builds the MUX.						// supposed to set the format of the input to this track of the MUX.			// this means we must already have created the mux?			// or maybe what this means, is we have to build a chain of configured codecs to 			// get to the mux?			// I think what this means is that we build the mux, and set the input format for this			// track on the mux.  when it comes time to build the graph, the input format on the mux			// is already fixed, so we don't negotiate it.			muxInputFormats[trackNum] = mux.setInputFormat(format, trackNum);			return muxInputFormats[trackNum];		}		public Component getControlComponent()		{			return null;		}			}			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -