To register your copy of this software, click the PayPal "Buy Now" button ($24.99 USD):
Updated release: April 26, 2005
Updated release: November 21, 2003
InputStream-based DataSource for the JMF
Have you ever been frustrated with the behavior of JMF towards your custom InputStream-based DataSource or URLDataSource? The reality is that it doesn't work. Almost every video codec requires random access to media data and data streams are sequentially accessed; this would explain the "Cannot find suitable player for xxx" exception. But this alone won't solve the problems with JMF and your need for an InputStream-based data source. There are any number of and types of exceptions and errors that can be thrown between the step of creating a Player object and realizing the player object. All of these exceptions are vague and many are caused by proprietary codec engines.
Through countless hours of trial and error, I have come up with a workable solution for anyone who wants to implement a DataSource for a sequentially accessed InputStream object. In my application, I needed to stream a video (of unknown codec) through a CipherInputStream object chained with a ZipInputStream object. Since the codec(s) seems to jump around the file grabbing bytes at complete random I had to develop a clever way of facillitating random access on my sequential data stream.
Using a Scrolling Window
I developed a special buffer that acts similarily to BufferedInputStream, but with a few enhancements. Essentially, it is a ringbuffer (or circular buffer) that reads upward through the input stream like a scrolling window:
The ringbuffer defaults to 256KB in size providing a clever performance improvement for interleaved videos. I theorized that most video codecs interleave video data, which means that the codec would seek to locations relatively near to the current location in the data stream as the video is played. I tested this theory on the old Cinepak codec and noticed that these intervals were roughly 48KB in size, which is within my ringbuffer size. This means that, by request of the media player, I could seek within the ringbuffer.
What happens when the user manually seeks to an arbitrary location in the video? This could mean seeking to data not already in the ringbuffer or even data already read in the past. The answer to this question would solve the problem of random access with sequential data streams. The following three cases were implemented:
Step #3 is unavoidable. For my application this meant re-acquiring the ZipInputStream object to the appropriate file and re-initializing the Cipher object and CipherInputStream object.
Source Code and Classes
The following files are available as shareware. If you intend to use the source code and/or classes, in either modified or original form, for commercial purposes, then you must purchase the source code and/or classes before or upon the 30-day evaluation period, which begins from the time you download the package.
These classes represent hours of research and development. Unauthorized use of them is intellectual property theft. Please show your support of future products by honoring the shareware system.
|Home | Contact | About | Services | Products | Clientele | Portfolio ||