Home      |      Products      |      Services      |      About      |      Portfolio
Download source code
Name: isdsjmf-v1.02.zip
Size: 20.1 KB

To register your copy of this software, click the PayPal "Buy Now" button ($24.99 USD):

Updated release: April 26, 2005
Fixed seek issue where pointer would not seek to correct address from within the buffer window to a read-ahead point. This would cause H263 videos and other codecs to constantly crash.

Updated release: November 21, 2003
Fixed "freeze" issue with MPEG-1 movies

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:

  • Seek location is within ringbuffer
    Simply update the internal ringbuffer pointer
  • Seek location is ahead and outside ringbuffer
    Continue reading data into the ringbuffer until the current location in the data stream matches the seek location requested. In otherwords, skip data.
  • Seek location is behind and before ringbuffer
    Restart the input stream from the beginning and then go to step #2.

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  |