Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.



Published on

  • Be the first to comment

  • Be the first to like this


  1. 1. Lecture14 Java Media Framework III – Some JMF Applications
  2. 2. Transcoding <ul><li>In transcoding, all we need to do is to set the output content descriptor of the processor to the one we want and then send the output of a processor to a DataSink. </li></ul>
  3. 3. Transcoding Algorithm <ul><li>Things to do in this transcoding example program : </li></ul><ul><li>1. Create a Processor using input MediaLocator and add a ControlerListener to it. </li></ul><ul><li>2. Get the Processor to the Configured state. </li></ul><ul><li>3. Set the output ContentDescriptor of the processor to the one we want. </li></ul><ul><li>4. Get the Processor to the Realized state. </li></ul><ul><li>5. Get the Processor output as a DataSource object. </li></ul><ul><li>6. Create a DataSink object from this DataSource object and a output MediaLocator. </li></ul><ul><li>7. Open the DataSink object. </li></ul><ul><li>8. Add a DataSink listener. </li></ul><ul><li>9. Start the Processor, DataSource, and the DataSink. </li></ul>
  4. 4. Transcoding Algorithm – Step 1 <ul><li>MediaLocator sourceFile = new MediaLocator(&quot;file://c:omp311avakiing.avi&quot;); </li></ul><ul><li>Processor p = Manager.createProcessor(sourceFile); </li></ul><ul><li>p.addControllerListener(new ControllerListener() { </li></ul><ul><li>public void controllerUpdate(ControllerEvent e) { </li></ul><ul><li>if (e instanceof StopEvent) { </li></ul><ul><li>p.close(); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>} ); </li></ul>
  5. 5. Transcoding Algorithm – Step 2 <ul><li>We will write a class called ProcessorWait which can wait until a given Processor object reaches a given state. </li></ul><ul><li>ProcessorWait pw = new ProcessorWait(p); </li></ul><ul><li>pw.waitForState(Processor.Configured); </li></ul>
  6. 6. Transcoding Algorithm – Steps 3,4,5,6,7 <ul><li>FileTypeDescriptor ot = new FileTypeDescriptor(&quot;video.quicktime&quot;); </li></ul><ul><li>p.setContentDescriptor(ot); </li></ul><ul><li>pw.waitForState(Processor.Realized); </li></ul><ul><li>DataSource ds = p.getDataOutput(); </li></ul><ul><li>MediaLocator sinkFile = new MediaLocator(&quot;file://;); </li></ul><ul><li>DataSink dsink = Manager.createDataSink(ds, sinkFile); </li></ul><ul><li>; </li></ul>
  7. 7. ContentDescriptor <ul><li>The following code segment could be used to obtain the corresponding FileTypeDescriptor object for a particular file extention. </li></ul><ul><li>String ext = &quot;mov&quot;; </li></ul><ul><li>String type =; </li></ul><ul><li>type = ContentDescriptor.mimeTypeToPackageName(type); </li></ul><ul><li>Note that the FileTypeDescriptor class is a subclass of ContentDescriptor class. </li></ul>
  8. 8. Transcoding Algorithm – Step 8 <ul><li>DataSink also has a event model. </li></ul><ul><li>Objects which implement DataSinkListener interface can register with the DataSink object as listeners. </li></ul><ul><li>The DataSinkListener interface has the following method: </li></ul><ul><li>public void dataSinkUpdate(DataSinkEvent e) </li></ul>
  9. 9. Transcoding Algorithm – Step 8 <ul><li>dsink.addDataSinkListener(new DataSinkListener() { </li></ul><ul><li>public void dataSinkUpdate(DataSinkEvent e) { </li></ul><ul><li>if (e instanceof EndOfStreamEvent) { </li></ul><ul><li>dsink.close(); </li></ul><ul><li>ds.disconnect(); </li></ul><ul><li>System.out.println(&quot;Done&quot;); </li></ul><ul><li>System.exit(0); </li></ul><ul><li>} else if (e instanceof DataSinkErrorEvent) { </li></ul><ul><li>System.out.println(&quot;Error in datasink&quot;); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>}); </li></ul>
  10. 10. Transcoding Algorithm – Step 9 <ul><li>By now we have constructed the processing chain and it is time to start streaming from the source file to the final destination file. </li></ul><ul><li>p.start(); </li></ul><ul><li>ds.start(); </li></ul><ul><li>dsink.start(); </li></ul>
  11. 11. ProcessorWait class <ul><li>class ProcessorWait implements ControllerListener { </li></ul><ul><li>Processor p; </li></ul><ul><li>boolean error = false; </li></ul><ul><li>public ProcessorWait(Processor p) { </li></ul><ul><li>this.p = p; </li></ul><ul><li>p.addControllerListener(this); </li></ul><ul><li>} </li></ul><ul><li>// public boolean waitForState(int state) </li></ul><ul><li>// public void controllerUpdate(ControllerEvent ce) </li></ul><ul><li>} </li></ul>
  12. 12. ProcessorWait class <ul><li>public boolean waitForState(int state) { </li></ul><ul><li>switch (state) { </li></ul><ul><li>case Processor.Configured: p.configure(); break; </li></ul><ul><li>case Processor.Realized: p.realize(); break; </li></ul><ul><li>case Processor.Prefetched: p.prefetch(); break; </li></ul><ul><li>case Processor.Started: p.start(); break; </li></ul><ul><li>} </li></ul><ul><li>while (p.getState() < state && !error) { </li></ul><ul><li>try { </li></ul><ul><li>wait(1000); </li></ul><ul><li>} catch (Exception e) {} </li></ul><ul><li>} </li></ul><ul><li>return !(error); </li></ul><ul><li>} </li></ul>
  13. 13. ProcessorWait class <ul><li>public void controllerUpdate(ControllerEvent ce) { </li></ul><ul><li>if (ce instanceof ControllerErrorEvent) { </li></ul><ul><li>error = true; </li></ul><ul><li>} </li></ul><ul><li>synchronized (this) { </li></ul><ul><li>notifyAll(); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  14. 14. Extending the DataSource Class <ul><li>Extending the DataSource class is useful in processing tasks such as: </li></ul><ul><ul><li>Splitting the tracks of media into different files. </li></ul></ul><ul><ul><li>Cutting different time segments from the media. </li></ul></ul><ul><li>we will look at how Buffer objects can be used in these tasks. </li></ul><ul><li>There are two types of Buffer based data source classes: </li></ul><ul><ul><li>PushBufferDataSource - abstracts a data source that manages data in the form of push streams. The streams, i.e. PushBufferStreams, from this data source contain Buffer objects. </li></ul></ul><ul><ul><li>PullBufferDataSource - Abstracts a media data-source that contains one or more PullBufferStreams and delivers data as Buffer objects. We will not talk about this! </li></ul></ul>
  15. 15. PushBufferStream <ul><li>PushBufferStream abstracts a read interface that pushes data in the form of Buffer objects. This interface allows a source stream to transfer data in the form of an entire media chunk to the user of this source stream. The media object or chunk transferred is the Buffer object as defined in </li></ul><ul><li>The user of the stream will allocate an empty Buffer object and pass this over to the source stream by calling the read() method. </li></ul><ul><li>The interested user of a particular PushBufferStream registers with the PushBufferStream by it with a BufferTransferHandler object by calling the setTransferHandler() method. </li></ul><ul><ul><li>The object implementing this BufferTransferHandler interface will be notified when the PushBufferStream has any new media data available in the form of a Buffer. This is done by calling the transferData() method of the BufferTransferHandler interface. </li></ul></ul><ul><ul><li>It is upto the user to take any action when it is notified via transferData() method. Usually the user reads the media chunk by providing an empty Buffer object via the read() method of the source stream. </li></ul></ul>
  16. 16. BufferTransferHandler interface <ul><li>Usually BufferTransferHandler interface is implemented by the class which implement the PushBufferStream itself. </li></ul><ul><li>The object implementing the BufferTransferHandler interface must implement the transferData(PushBufferStream pbs) method which usually does the following: </li></ul><ul><ul><li>Wait for the Buffer object to be available for this thread. </li></ul></ul><ul><ul><li>Read into the Buffer from the PushBufferStream. </li></ul></ul><ul><ul><li>Process the Buffer. </li></ul></ul><ul><ul><li>Make the Buffer available for other threads. </li></ul></ul><ul><ul><li>Call transferData of the BufferTransferHandler registered with this stream. </li></ul></ul>
  17. 17. read(Buffer b) method of PushBufferStream <ul><li>The read(Buffer b) method of PushBufferStream usually does the following: </li></ul><ul><ul><li>Wait for the Buffer object of this stream to be available for the current thread. </li></ul></ul><ul><ul><li>Process the contents of the specified Buffer object parameter of the read() method using the Buffer object this stream. It is usually a copy. </li></ul></ul><ul><ul><li>Make the Buffer object of this stream available for other threads. </li></ul></ul>
  18. 18. Extending the PushBufferDataSource <ul><li>The PushBufferDataSource need to implement its constructor, connect(), disconnect(), getContentType(), getControl(), getControls, getDuration(), start(), stop(), and getStreams() methods. </li></ul><ul><li>Most of these methods are not used by our intended task and hence we don't need to properly implement them. </li></ul>
  19. 19. Extending the PushBufferDataSource <ul><li>The PushBufferStream need to implement its constructor, endOfStream(), getContentDescriptor(), getContentLength(), getControl, getControls, getFormat(), read(), and setTransferHandler() methods. </li></ul>
  20. 20. Example <ul><li>We will write a very basic program which process Buffer objects. </li></ul><ul><li>We extend the PushBufferDataSource for this purpose. This new objects reads Buffer objects from a source and simply pass it on to other objects which are interested of reading from this source. </li></ul><ul><li>Please read the given source code </li></ul>