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

📄 datasource.java

📁 FMJ(freedom media for java)是java视频开发的新选择
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package net.sf.fmj.media.protocol.civil;import java.awt.Component;import java.awt.Dimension;import java.io.IOException;import java.io.InterruptedIOException;import java.util.List;import java.util.logging.Level;import java.util.logging.Logger;import javax.media.Buffer;import javax.media.CaptureDeviceInfo;import javax.media.Format;import javax.media.Time;import javax.media.control.FormatControl;import javax.media.format.RGBFormat;import javax.media.format.VideoFormat;import javax.media.protocol.BufferTransferHandler;import javax.media.protocol.CaptureDevice;import javax.media.protocol.ContentDescriptor;import javax.media.protocol.PushBufferDataSource;import javax.media.protocol.PushBufferStream;import net.sf.fmj.utility.FPSCounter;import net.sf.fmj.utility.LoggerSingleton;import com.lti.civil.CaptureException;import com.lti.civil.CaptureObserver;import com.lti.civil.CaptureStream;import com.lti.civil.CaptureSystem;import com.lti.civil.CaptureSystemFactory;import com.lti.civil.DefaultCaptureSystemFactorySingleton;import com.lti.civil.Image;import com.lti.utils.synchronization.CloseableThread;import com.lti.utils.synchronization.ProducerConsumerQueue;import com.lti.utils.synchronization.SynchronizedBoolean;import com.lti.utils.synchronization.SynchronizedObjectHolder;import com.lti.utils.synchronization.ThreadGroupMgr;/** * DataSource for CIVIL video. * @author Ken Larson * */public class DataSource extends PushBufferDataSource implements CaptureDevice{	private static final boolean TRACE = true;	private static final Logger logger = LoggerSingleton.logger;	private CaptureSystem system;	private String deviceId;	private CaptureStream captureStream;	private MyPushBufferStream pushBufferStream;	/**	 * The JMF video output format we are delivering.	 */	private VideoFormat outputVideoFormat = null;			private boolean connected;	private static final int BUFFER_QUEUE_SIZE = 2; // after this many items in queue, we will drop frames.												  	// the frame dropping allows us to stay going in real-time.													// TODO: this might not be good for some applications.													// TODO: we are still dropping some frames even after													// optimization.	private final ProducerConsumerQueue bufferQueue = new ProducerConsumerQueue(BUFFER_QUEUE_SIZE);//    private boolean bufferQueueEnabled = false;	// synch on bufferQueue to use.  if false, only 1 item is kept in buffer queue.//    											// this allows us to not buffer frames before we are reading them, to minimize the//    											// latency between the images coming in, and the images going out.    	private static final boolean TRACE_FPS = false;		//@Override	public void connect() throws IOException	{		if (TRACE) logger.fine("connect");		// Normally, we allow a re-connection even if we are connected, due to an oddity in the way Manager works. See comments there 		// in createPlayer(MediaLocator sourceLocator).		// however, because capture devices won't go back to previous data even if we reconnect, there is no point in reconnecting.		if (connected)			return;		try		{		    CaptureSystemFactory factory = DefaultCaptureSystemFactorySingleton.instance();			system = factory.createCaptureSystem();			system.init();	// TODO: dispose of properly		    			if (TRACE) logger.fine("Opening " + getLocator().getRemainder());						// see if it is an ordinal URL like civil:0 or civil:/0			final int ordinal = ordinal(getLocator().getRemainder());			if (ordinal >= 0)			{	deviceId = deviceIdFromOrdinal(ordinal);				if (deviceId == null)					throw new IOException("Unable to convert ordinal " + ordinal + " to a capture device");			}			else			{				deviceId = getLocator().getRemainder();			}						captureStream = system.openCaptureDeviceStream(deviceId);			captureStream.getVideoFormat();			outputVideoFormat = convertCivilFormat(captureStream.getVideoFormat());						captureStream.setObserver(new MyCaptureObserver());						pushBufferStream = new MyPushBufferStream();					}		catch (CaptureException e)		{	logger.log(Level.WARNING, "" + e, e);			throw new IOException("" + e);		}				connected = true;			}		// handle ordinal locators, like civil:0 or civil:/0	private static int ordinal(String remainder)	{		try		{			// allow either with slash or without			if (remainder.startsWith("/"))				remainder = remainder.substring(1);			return Integer.parseInt(remainder);		}		catch (Exception e)		{	return -1;		}	}		private String deviceIdFromOrdinal(int index) throws CaptureException	{		final List list = system.getCaptureDeviceInfoList();		if (index < 0 || index >= list.size())			return null;						com.lti.civil.CaptureDeviceInfo info = (com.lti.civil.CaptureDeviceInfo) list.get(index);		return info.getDeviceID();			}		//@Override	public void disconnect()	{		if (TRACE) logger.fine("disconnect");		if (!connected)			return;				if (pushBufferStream != null)			pushBufferStream.dispose();				try		{			stop();		} catch (IOException e)		{			logger.log(Level.WARNING, "" + e, e);		}				if (captureStream != null)		{			try			{				captureStream.dispose();			} catch (CaptureException e)			{				logger.log(Level.WARNING, "" + e, e);			}			finally			{	captureStream = null;			}		}				connected = false;	}	private static final String CONTENT_TYPE = ContentDescriptor.RAW;	//@Override	public String getContentType()	{		return CONTENT_TYPE;	// TODO: what should this be?	}	//@Override	public Object getControl(String controlType)	{		return null;	}	//@Override	public Object[] getControls()	{		return new Object[0];	}	private final SynchronizedBoolean started = new SynchronizedBoolean(false);	//@Override	public void start() throws IOException	{		if (TRACE) logger.fine("start");				if (started.getValue())		{	logger.warning("Civil DataSource.start called while already started, ignoring");			return;		}				try 		{			captureStream.start();		} catch (CaptureException e) 		{			logger.log(Level.WARNING, "" + e, e);			throw new IOException("" + e);		}			started.setValue(true);	}	//@Override	public void stop() throws IOException	{		if (TRACE) logger.fine("stop");		if (!started.getValue())			return;				try		{			if (captureStream != null)			{	captureStream.stop();				}						synchronized (bufferQueue)			{				while (!bufferQueue.isEmpty())					bufferQueue.get();//				if (!bufferQueueEnabled)//				{	//					// now that we not reading, stop queuing.//					bufferQueueEnabled = false;//				}			}		} catch (CaptureException e)		{			logger.log(Level.WARNING, "" + e, e);			throw new IOException("" + e);		}		catch (InterruptedException e)		{	throw new InterruptedIOException("" + e);		}		finally		{			started.setValue(false);		}	}	//@Override	public Time getDuration()	{		return DURATION_UNBOUNDED;	}	public PushBufferStream[] getStreams()	{		if (TRACE) logger.fine("getStreams");		if (pushBufferStream == null)			return new PushBufferStream[0];		return new PushBufferStream[] {pushBufferStream};	}		private class MyCaptureObserver implements CaptureObserver	{		public void onError(CaptureStream sender, CaptureException e)		{			logger.log(Level.WARNING, "" + e, e); // TODO: how to handle?		}		private long firstImageTimestamp = -1L;	// used to make timestamps start with zero		// This is needed for proper playback when using JMF.				private final FPSCounter fpsCounter = new FPSCounter();		public void onNewImage(CaptureStream sender, Image image)		{			

⌨️ 快捷键说明

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