--- a/doc/asmack-beem/beem_patches/50-remove-jingle_mediaimpl.patch Tue Jan 18 00:26:02 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4039 +0,0 @@
-Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaSession.java (working copy)
-@@ -1,92 +0,0 @@
--/**
-- * $RCSfile: TestMediaSession.java,v $
-- * $Revision: 1.1 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--package org.jivesoftware.smackx.jingle.mediaimpl.test;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--/**
-- * This Class implements a complete JingleMediaSession for unit testing.
-- *
-- * @author Thiago Camargo
-- */
--public class TestMediaSession extends JingleMediaSession {
--
-- /**
-- * Creates a TestMediaSession with defined payload type, remote and local candidates
-- *
-- * @param payloadType Payload of the jmf
-- * @param remote the remote information. The candidate that the jmf will be sent to.
-- * @param local the local information. The candidate that will receive the jmf
-- * @param locator media locator
-- */
-- public TestMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
-- final String locator, JingleSession jingleSession) {
-- super(payloadType, remote, local, "Test", jingleSession);
-- initialize();
-- }
--
-- /**
-- * Initialize the screen share channels.
-- */
-- public void initialize() {
--
-- }
--
-- /**
-- * Starts transmission and for NAT Traversal reasons start receiving also.
-- */
-- public void startTrasmit() {
--
-- }
--
-- /**
-- * Set transmit activity. If the active is true, the instance should trasmit.
-- * If it is set to false, the instance should pause transmit.
-- *
-- * @param active active state
-- */
-- public void setTrasmit(boolean active) {
--
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void startReceive() {
-- // Do nothing
-- }
--
-- /**
-- * Stops transmission and for NAT Traversal reasons stop receiving also.
-- */
-- public void stopTrasmit() {
--
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void stopReceive() {
--
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/test/TestMediaManager.java (working copy)
-@@ -1,93 +0,0 @@
--/**
-- * $RCSfile: TestMediaManager.java,v $
-- * $Revision: 1.3 $
-- * $Date: 25/12/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.test;
--
--import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--import org.jivesoftware.smackx.jingle.JingleSession;
--
--import java.util.*;
--
--/**
-- * Implements a MediaManager for test purposes.
-- *
-- * @author Thiago Camargo
-- */
--
--public class TestMediaManager extends JingleMediaManager {
--
-- public static final String MEDIA_NAME = "TestMedia";
--
-- private List<PayloadType> payloads = new ArrayList<PayloadType>();
--
-- private PayloadType preferredPayloadType = null;
--
-- public TestMediaManager(JingleTransportManager transportManager) {
-- super(transportManager);
-- }
--
-- /**
-- * Return all supported Payloads for this Manager.
-- *
-- * @return The Payload List
-- */
-- public List<PayloadType> getPayloads() {
-- return payloads;
-- }
--
-- public void setPayloads(List<PayloadType> payloads) {
-- this.payloads.addAll(payloads);
-- }
--
-- /**
-- * Returns a new JingleMediaSession
-- *
-- * @param payloadType payloadType
-- * @param remote remote Candidate
-- * @param local local Candidate
-- * @return JingleMediaSession JingleMediaSession
-- */
-- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote,
-- final TransportCandidate local, final JingleSession jingleSession) {
-- TestMediaSession session = null;
--
-- session = new TestMediaSession(payloadType, remote, local, "", jingleSession);
--
-- return session;
-- }
--
-- public PayloadType getPreferredPayloadType() {
-- if (preferredPayloadType != null)
-- return preferredPayloadType;
-- return super.getPreferredPayloadType();
-- }
--
-- public void setPreferredPayloadType(PayloadType preferredPayloadType) {
-- this.preferredPayloadType = preferredPayloadType;
-- }
--
-- public String getName() {
-- return MEDIA_NAME;
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/JMFInit.java (working copy)
-@@ -1,282 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl;
--
--import java.awt.Frame;
--import java.awt.TextArea;
--import java.awt.Toolkit;
--import java.util.Vector;
--
--import javax.media.Format;
--import javax.media.PlugInManager;
--import javax.media.Renderer;
--import javax.media.format.AudioFormat;
--
--import org.jivesoftware.smackx.jingle.SmackLogger;
--
--import com.sun.media.ExclusiveUse;
--import com.sun.media.util.Registry;
--
--public class JMFInit extends Frame implements Runnable {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(JMFInit.class);
--
-- private String tempDir = "/tmp";
--
-- private boolean done = false;
--
-- private String userHome;
--
-- private boolean visible = false;
--
-- public JMFInit(String[] args, boolean visible) {
-- super("Initializing JMF...");
--
-- this.visible = visible;
--
-- Registry.set("secure.allowCaptureFromApplets", true);
-- Registry.set("secure.allowSaveFileFromApplets", true);
--
-- updateTemp(args);
--
-- try {
-- Registry.commit();
-- }
-- catch (Exception e) {
--
-- message("Failed to commit to JMFRegistry!");
-- }
--
-- Thread detectThread = new Thread(this);
-- detectThread.run();
--
-- /*
-- * int slept = 0; while (!done && slept < 60 * 1000 * 2) { try {
-- * Thread.currentThread().sleep(500); } catch (InterruptedException ie) { }
-- * slept += 500; }
-- *
-- * if (!done) { console.error("Detection is taking too long!
-- * Aborting!"); message("Detection is taking too long! Aborting!"); }
-- *
-- * try { Thread.currentThread().sleep(2000); } catch
-- * (InterruptedException ie) { }
-- */
-- }
--
-- public void run() {
-- detectDirectAudio();
-- detectS8DirectAudio();
-- detectCaptureDevices();
-- done = true;
-- }
--
-- private void updateTemp(String[] args) {
-- if (args != null && args.length > 0) {
-- tempDir = args[0];
--
-- message("Setting cache directory to " + tempDir);
-- Registry r = new Registry();
-- try {
-- r.set("secure.cacheDir", tempDir);
-- r.commit();
--
-- message("Updated registry");
-- }
-- catch (Exception e) {
-- message("Couldn't update registry!");
-- }
-- }
-- }
--
-- private void detectCaptureDevices() {
-- // check if JavaSound capture is available
-- message("Looking for Audio capturer");
-- Class dsauto;
-- try {
-- dsauto = Class.forName("DirectSoundAuto");
-- dsauto.newInstance();
-- message("Finished detecting DirectSound capturer");
-- }
-- catch (ThreadDeath td) {
-- throw td;
-- }
-- catch (Throwable t) {
-- //Do nothing
-- }
--
-- Class jsauto;
-- try {
-- jsauto = Class.forName("JavaSoundAuto");
-- jsauto.newInstance();
-- message("Finished detecting javasound capturer");
-- }
-- catch (ThreadDeath td) {
-- throw td;
-- }
-- catch (Throwable t) {
-- message("JavaSound capturer detection failed!");
-- }
--
-- /*
-- // Check if VFWAuto or SunVideoAuto is available
-- message("Looking for video capture devices");
-- Class auto = null;
-- Class autoPlus = null;
-- try {
-- auto = Class.forName("VFWAuto");
-- }
-- catch (Exception e) {
-- }
-- if (auto == null) {
-- try {
-- auto = Class.forName("SunVideoAuto");
-- }
-- catch (Exception ee) {
--
-- }
-- try {
-- autoPlus = Class.forName("SunVideoPlusAuto");
-- }
-- catch (Exception ee) {
--
-- }
-- }
-- if (auto == null) {
-- try {
-- auto = Class.forName("V4LAuto");
-- }
-- catch (Exception ee) {
--
-- }
-- }
-- try {
-- Object instance = auto.newInstance();
-- if (autoPlus != null) {
-- Object instancePlus = autoPlus.newInstance();
-- }
--
-- message("Finished detecting video capture devices");
-- }
-- catch (ThreadDeath td) {
-- throw td;
-- }
-- catch (Throwable t) {
--
-- message("Capture device detection failed!");
-- }
-- */
-- }
--
-- private void detectDirectAudio() {
-- Class cls;
-- int plType = PlugInManager.RENDERER;
-- String dar = "com.sun.media.renderer.audio.DirectAudioRenderer";
-- try {
-- // Check if this is the Windows Performance Pack - hack
-- cls = Class.forName("VFWAuto");
-- // Check if DS capture is supported, otherwise fail DS renderer
-- // since NT doesn't have capture
-- cls = Class.forName("com.sun.media.protocol.dsound.DSound");
-- // Find the renderer class and instantiate it.
-- cls = Class.forName(dar);
--
-- Renderer rend = (Renderer) cls.newInstance();
-- try {
-- // Set the format and open the device
-- AudioFormat af = new AudioFormat(AudioFormat.LINEAR, 44100, 16,
-- 2);
-- rend.setInputFormat(af);
-- rend.open();
-- Format[] inputFormats = rend.getSupportedInputFormats();
-- // Register the device
-- PlugInManager.addPlugIn(dar, inputFormats, new Format[0],
-- plType);
-- // Move it to the top of the list
-- Vector rendList = PlugInManager.getPlugInList(null, null,
-- plType);
-- int listSize = rendList.size();
-- if (rendList.elementAt(listSize - 1).equals(dar)) {
-- rendList.removeElementAt(listSize - 1);
-- rendList.insertElementAt(dar, 0);
-- PlugInManager.setPlugInList(rendList, plType);
-- PlugInManager.commit();
-- // Log.debug("registered");
-- }
-- rend.close();
-- }
-- catch (Throwable t) {
-- // Log.debug("Error " + t);
-- }
-- }
-- catch (Throwable tt) {
-- //Do nothing
-- }
-- }
--
-- private void detectS8DirectAudio() {
-- Class cls;
-- int plType = PlugInManager.RENDERER;
-- String dar = "com.sun.media.renderer.audio.DirectAudioRenderer";
-- try {
-- // Check if this is the solaris Performance Pack - hack
-- cls = Class.forName("SunVideoAuto");
--
-- // Find the renderer class and instantiate it.
-- cls = Class.forName(dar);
--
-- Renderer rend = (Renderer) cls.newInstance();
--
-- if (rend instanceof ExclusiveUse
-- && !((ExclusiveUse) rend).isExclusive()) {
-- // sol8+, DAR supports mixing
-- Vector rendList = PlugInManager.getPlugInList(null, null,
-- plType);
-- int listSize = rendList.size();
-- boolean found = false;
-- String rname = null;
--
-- for (int i = 0; i < listSize; i++) {
-- rname = (String) (rendList.elementAt(i));
-- if (rname.equals(dar)) { // DAR is in the registry
-- found = true;
-- rendList.removeElementAt(i);
-- break;
-- }
-- }
--
-- if (found) {
-- rendList.insertElementAt(dar, 0);
-- PlugInManager.setPlugInList(rendList, plType);
-- PlugInManager.commit();
-- }
-- }
-- }
-- catch (Throwable tt) {
-- //Do nothing
-- }
-- }
--
-- private void message(String mesg) {
-- LOGGER.debug(mesg);
-- }
--
-- private void createGUI() {
-- TextArea textBox = new TextArea(5, 50);
-- add("Center", textBox);
-- textBox.setEditable(false);
-- addNotify();
-- pack();
--
-- int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize()
-- .getWidth();
-- int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize()
-- .getHeight();
--
-- setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2);
--
-- setVisible(visible);
--
-- }
--
-- public static void start(boolean visible) {
-- new JMFInit(null, visible);
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java (working copy)
-@@ -1,174 +0,0 @@
--/**
-- * $RCSfile: Demo.java,v $
-- * $Revision: 1.3 $
-- * $Date: 28/12/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--package org.jivesoftware.smackx.jingle.mediaimpl.demo;
--
--import org.jivesoftware.smack.Connection;
--import org.jivesoftware.smack.XMPPConnection;
--import org.jivesoftware.smack.XMPPException;
--import org.jivesoftware.smackx.jingle.JingleManager;
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.JingleSessionRequest;
--import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
--import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
--import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager;
--import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
--import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
--
--import javax.swing.*;
--import java.awt.event.ActionEvent;
--import java.util.ArrayList;
--import java.util.List;
--
--/**
-- * Jingle Demo Application. It register in a XMPP Server and let users place calls using a full JID and auto-receive calls.
-- * Parameters: Server User Pass.
-- */
--public class Demo extends JFrame {
--
-- private JingleTransportManager transportManager = null;
-- private Connection xmppConnection = null;
--
-- private String server = null;
-- private String user = null;
-- private String pass = null;
--
-- private JingleManager jm = null;
-- private JingleSession incoming = null;
-- private JingleSession outgoing = null;
--
-- private JTextField jid;
--
-- public Demo(String server, String user, String pass) {
--
-- this.server = server;
-- this.user = user;
-- this.pass = pass;
--
-- if (user.equals("jeffw")) {
-- jid = new JTextField("eowyn" + "@" + server + "/Smack");
-- } else {
-- jid = new JTextField("jeffw" + "@" + server + "/Smack");
-- }
--
-- xmppConnection = new XMPPConnection(server);
-- try {
-- xmppConnection.connect();
-- xmppConnection.login(user, pass);
-- initialize();
-- }
-- catch (XMPPException e) {
-- e.printStackTrace();
-- }
-- }
--
-- public void initialize() {
-- ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "10.47.47.53", 3478);
-- List<JingleMediaManager> mediaManagers = new ArrayList<JingleMediaManager>();
-- //mediaManagers.add(new JmfMediaManager(icetm0));
-- mediaManagers.add(new SpeexMediaManager(icetm0));
-- mediaManagers.add(new ScreenShareMediaManager(icetm0));
-- jm = new JingleManager(xmppConnection, mediaManagers);
-- jm.addCreationListener(icetm0);
--
-- jm.addJingleSessionRequestListener(new JingleSessionRequestListener() {
-- public void sessionRequested(JingleSessionRequest request) {
--
--// if (incoming != null)
--// return;
--
-- try {
-- // Accept the call
-- incoming = request.accept();
--
-- // Start the call
-- incoming.startIncoming();
-- }
-- catch (XMPPException e) {
-- e.printStackTrace();
-- }
--
-- }
-- });
-- createGUI();
-- }
--
-- public void createGUI() {
--
-- JPanel jPanel = new JPanel();
--
-- jPanel.add(jid);
--
-- jPanel.add(new JButton(new AbstractAction("Call") {
-- public void actionPerformed(ActionEvent e) {
-- if (outgoing != null) return;
-- try {
-- outgoing = jm.createOutgoingJingleSession(jid.getText());
-- outgoing.startOutgoing();
-- }
-- catch (XMPPException e1) {
-- e1.printStackTrace();
-- }
-- }
-- }));
--
-- jPanel.add(new JButton(new AbstractAction("Hangup") {
-- public void actionPerformed(ActionEvent e) {
-- if (outgoing != null)
-- try {
-- outgoing.terminate();
-- }
-- catch (XMPPException e1) {
-- e1.printStackTrace();
-- }
-- finally {
-- outgoing = null;
-- }
-- if (incoming != null)
-- try {
-- incoming.terminate();
-- }
-- catch (XMPPException e1) {
-- e1.printStackTrace();
-- }
-- finally {
-- incoming = null;
-- }
-- }
-- }));
--
-- this.add(jPanel);
--
-- }
--
-- public static void main(String args[]) {
--
-- Demo demo = null;
--
-- if (args.length > 2) {
-- demo = new Demo(args[0], args[1], args[2]);
-- demo.pack();
-- demo.setVisible(true);
-- demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-- }
--
-- }
--
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java (working copy)
-@@ -1,206 +0,0 @@
--/**
-- * $RCSfile: ScreenShareSession.java,v $
-- * $Revision: 1.2 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
--
--import java.awt.Rectangle;
--import java.awt.event.WindowAdapter;
--import java.awt.event.WindowEvent;
--import java.io.IOException;
--import java.net.DatagramSocket;
--import java.net.InetAddress;
--import java.net.ServerSocket;
--import java.net.UnknownHostException;
--
--import javax.swing.JFrame;
--import javax.swing.JPanel;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageReceiver;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--/**
-- * This Class implements a complete JingleMediaSession.
-- * It sould be used to transmit and receive captured images from the Display.
-- * This Class should be automaticly controlled by JingleSession.
-- * For better NAT Traversal support this implementation don't support only receive or only transmit.
-- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
-- *
-- * @author Thiago Camargo
-- */
--public class ScreenShareSession extends JingleMediaSession {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(ScreenShareSession.class);
--
-- private ImageTransmitter transmitter = null;
-- private ImageReceiver receiver = null;
-- private int width = 600;
-- private int height = 600;
--
-- /**
-- * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
-- *
-- * @param payloadType Payload of the jmf
-- * @param remote the remote information. The candidate that the jmf will be sent to.
-- * @param local the local information. The candidate that will receive the jmf
-- * @param locator media locator
-- */
-- public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
-- final String locator, JingleSession jingleSession) {
-- super(payloadType, remote, local, "Screen", jingleSession);
-- initialize();
-- }
--
-- /**
-- * Initialize the screen share channels.
-- */
-- public void initialize() {
--
-- JingleSession session = getJingleSession();
-- if ((session != null) && (session.getInitiator().equals(session.getConnection().getUser()))) {
-- // If the initiator of the jingle session is us then we transmit a screen share.
-- try {
-- InetAddress remote = InetAddress.getByName(getRemote().getIp());
-- transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(),
-- new Rectangle(0, 0, width, height));
-- } catch (Exception e) {
-- e.printStackTrace();
-- }
--
-- } else {
-- // Otherwise we receive a screen share.
-- JFrame window = new JFrame();
-- JPanel jp = new JPanel();
-- window.add(jp);
--
-- window.setLocation(0, 0);
-- window.setSize(600, 600);
--
-- window.addWindowListener(new WindowAdapter() {
-- public void windowClosed(WindowEvent e) {
-- receiver.stop();
-- }
-- });
--
-- try {
-- receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width,
-- height);
-- LOGGER.debug("Receiving on:" + receiver.getLocalPort());
-- } catch (UnknownHostException e) {
-- e.printStackTrace();
-- }
--
-- jp.add(receiver);
-- receiver.setVisible(true);
-- window.setAlwaysOnTop(true);
-- window.setVisible(true);
-- }
-- }
--
-- /**
-- * Starts transmission and for NAT Traversal reasons start receiving also.
-- */
-- public void startTrasmit() {
-- new Thread(transmitter).start();
-- }
--
-- /**
-- * Set transmit activity. If the active is true, the instance should trasmit.
-- * If it is set to false, the instance should pause transmit.
-- *
-- * @param active active state
-- */
-- public void setTrasmit(boolean active) {
-- transmitter.setTransmit(true);
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void startReceive() {
-- // Do nothing
-- }
--
-- /**
-- * Stops transmission and for NAT Traversal reasons stop receiving also.
-- */
-- public void stopTrasmit() {
-- if (transmitter != null) {
-- transmitter.stop();
-- }
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void stopReceive() {
-- if (receiver != null) {
-- receiver.stop();
-- }
-- }
--
-- /**
-- * Obtain a free port we can use.
-- *
-- * @return A free port number.
-- */
-- protected int getFreePort() {
-- ServerSocket ss;
-- int freePort = 0;
--
-- for (int i = 0; i < 10; i++) {
-- freePort = (int) (10000 + Math.round(Math.random() * 10000));
-- freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-- try {
-- ss = new ServerSocket(freePort);
-- freePort = ss.getLocalPort();
-- ss.close();
-- return freePort;
-- } catch (IOException e) {
-- e.printStackTrace();
-- }
-- }
-- try {
-- ss = new ServerSocket(0);
-- freePort = ss.getLocalPort();
-- ss.close();
-- } catch (IOException e) {
-- e.printStackTrace();
-- }
-- return freePort;
-- }
--
-- public void setEncoder(ImageEncoder encoder) {
-- if (encoder != null) {
-- this.transmitter.setEncoder(encoder);
-- }
-- }
--
-- public void setDecoder(ImageDecoder decoder) {
-- if (decoder != null) {
-- this.receiver.setDecoder(decoder);
-- }
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageTransmitter.java (working copy)
-@@ -1,204 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.AWTException;
--import java.awt.Rectangle;
--import java.awt.Robot;
--import java.awt.image.BufferedImage;
--import java.awt.image.PixelGrabber;
--import java.io.ByteArrayOutputStream;
--import java.io.IOException;
--import java.net.DatagramPacket;
--import java.net.DatagramSocket;
--import java.net.InetAddress;
--import java.util.Arrays;
--
--import org.jivesoftware.smackx.jingle.SmackLogger;
--
--/**
-- * UDP Image Receiver.
-- * It uses PNG Tiles into UDP packets.
-- *
-- * @author Thiago Rocha Camargo
-- */
--public class ImageTransmitter implements Runnable {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(ImageTransmitter.class);
--
-- private Robot robot;
-- private InetAddress localHost;
-- private InetAddress remoteHost;
-- private int localPort;
-- private int remotePort;
-- public static final int tileWidth = 25;
-- private boolean on = true;
-- private boolean transmit = false;
-- private DatagramSocket socket;
-- private Rectangle area;
-- private int tiles[][][];
-- private int maxI;
-- private int maxJ;
-- private ImageEncoder encoder;
-- public final static int KEYFRAME = 10;
--
-- public ImageTransmitter(DatagramSocket socket, InetAddress remoteHost, int remotePort, Rectangle area) {
--
-- try {
-- robot = new Robot();
--
-- maxI = (int) Math.ceil(area.getWidth() / tileWidth);
-- maxJ = (int) Math.ceil(area.getHeight() / tileWidth);
--
-- tiles = new int[maxI][maxJ][tileWidth * tileWidth];
--
-- this.area = area;
-- this.socket = socket;
-- localHost = socket.getLocalAddress();
-- localPort = socket.getLocalPort();
-- this.remoteHost = remoteHost;
-- this.remotePort = remotePort;
-- this.encoder = new DefaultEncoder();
--
-- transmit = true;
--
-- }
-- catch (AWTException e) {
-- e.printStackTrace();
-- }
--
-- }
--
-- public void start() {
-- byte buf[] = new byte[1024];
-- final DatagramPacket p = new DatagramPacket(buf, 1024);
--
-- int keyframe = 0;
--
-- while (on) {
-- if (transmit) {
--
-- BufferedImage capture = robot.createScreenCapture(area);
--
-- QuantizeFilter filter = new QuantizeFilter();
-- capture = filter.filter(capture, null);
--
-- long trace = System.currentTimeMillis();
--
-- if (++keyframe > KEYFRAME) {
-- keyframe = 0;
-- }
-- LOGGER.debug("KEYFRAME:" + keyframe);
--
-- for (int i = 0; i < maxI; i++) {
-- for (int j = 0; j < maxJ; j++) {
--
-- final BufferedImage bufferedImage = capture.getSubimage(i * tileWidth, j * tileWidth, tileWidth, tileWidth);
--
-- int pixels[] = new int[tileWidth * tileWidth];
--
-- PixelGrabber pg = new PixelGrabber(bufferedImage, 0, 0, tileWidth, tileWidth, pixels, 0, tileWidth);
--
-- try {
-- if (pg.grabPixels()) {
--
-- if (keyframe == KEYFRAME || !Arrays.equals(tiles[i][j], pixels)) {
--
-- ByteArrayOutputStream baos = encoder.encode(bufferedImage);
--
-- if (baos != null) {
--
-- try {
--
-- Thread.sleep(1);
--
-- baos.write(i);
-- baos.write(j);
--
-- byte[] bytesOut = baos.toByteArray();
--
-- if (bytesOut.length > 1000)
-- LOGGER.error("Bytes out > 1000. Equals " + bytesOut.length);
--
-- p.setData(bytesOut);
-- p.setAddress(remoteHost);
-- p.setPort(remotePort);
--
-- try {
-- socket.send(p);
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
--
-- tiles[i][j] = pixels;
--
-- }
-- catch (Exception e) {
-- }
--
-- }
--
-- }
--
-- }
-- }
-- catch (InterruptedException e) {
-- e.printStackTrace();
-- }
-- }
-- }
--
-- trace = (System.currentTimeMillis() - trace);
-- LOGGER.debug("Loop Time:" + trace);
--
-- if (trace < 500) {
-- try {
-- Thread.sleep(500 - trace);
-- }
-- catch (InterruptedException e) {
-- e.printStackTrace();
-- }
-- }
-- }
-- }
-- }
--
-- public void run() {
-- start();
-- }
--
-- /**
-- * Set Transmit Enabled/Disabled
-- *
-- * @param transmit boolean Enabled/Disabled
-- */
-- public void setTransmit(boolean transmit) {
-- this.transmit = transmit;
-- }
--
-- /**
-- * Get the encoder used to encode Images Tiles
-- *
-- * @return encoder
-- */
-- public ImageEncoder getEncoder() {
-- return encoder;
-- }
--
-- /**
-- * Set the encoder used to encode Image Tiles
-- *
-- * @param encoder encoder
-- */
-- public void setEncoder(ImageEncoder encoder) {
-- this.encoder = encoder;
-- }
--
-- /**
-- * Stops Transmitter
-- */
-- public void stop() {
-- this.transmit = false;
-- this.on = false;
-- socket.close();
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageEncoder.java (working copy)
-@@ -1,13 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.image.BufferedImage;
--import java.io.ByteArrayOutputStream;
--
--/**
-- * Image Encoder Interface use this interface if you want to change the default encoder
-- *
-- * @author Thiago Rocha Camargo
-- */
--public interface ImageEncoder {
-- public ByteArrayOutputStream encode(BufferedImage bufferedImage);
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/PixelUtils.java (working copy)
-@@ -1,223 +0,0 @@
--/*
--Copyright 2006 Jerry Huxtable
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
--*/
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.*;
--import java.util.Random;
--
--/**
-- * Some more useful math functions for image processing.
-- * These are becoming obsolete as we move to Java2D. Use MiscComposite instead.
-- */
--public class PixelUtils {
--
-- public final static int REPLACE = 0;
-- public final static int NORMAL = 1;
-- public final static int MIN = 2;
-- public final static int MAX = 3;
-- public final static int ADD = 4;
-- public final static int SUBTRACT = 5;
-- public final static int DIFFERENCE = 6;
-- public final static int MULTIPLY = 7;
-- public final static int HUE = 8;
-- public final static int SATURATION = 9;
-- public final static int VALUE = 10;
-- public final static int COLOR = 11;
-- public final static int SCREEN = 12;
-- public final static int AVERAGE = 13;
-- public final static int OVERLAY = 14;
-- public final static int CLEAR = 15;
-- public final static int EXCHANGE = 16;
-- public final static int DISSOLVE = 17;
-- public final static int DST_IN = 18;
-- public final static int ALPHA = 19;
-- public final static int ALPHA_TO_GRAY = 20;
--
-- private static Random randomGenerator = new Random();
--
-- /**
-- * Clamp a value to the range 0..255
-- */
-- public static int clamp(int c) {
-- if (c < 0)
-- return 0;
-- if (c > 255)
-- return 255;
-- return c;
-- }
--
-- public static int interpolate(int v1, int v2, float f) {
-- return clamp((int)(v1+f*(v2-v1)));
-- }
--
-- public static int brightness(int rgb) {
-- int r = (rgb >> 16) & 0xff;
-- int g = (rgb >> 8) & 0xff;
-- int b = rgb & 0xff;
-- return (r+g+b)/3;
-- }
--
-- public static boolean nearColors(int rgb1, int rgb2, int tolerance) {
-- int r1 = (rgb1 >> 16) & 0xff;
-- int g1 = (rgb1 >> 8) & 0xff;
-- int b1 = rgb1 & 0xff;
-- int r2 = (rgb2 >> 16) & 0xff;
-- int g2 = (rgb2 >> 8) & 0xff;
-- int b2 = rgb2 & 0xff;
-- return Math.abs(r1-r2) <= tolerance && Math.abs(g1-g2) <= tolerance && Math.abs(b1-b2) <= tolerance;
-- }
--
-- private final static float hsb1[] = new float[3];//FIXME-not thread safe
-- private final static float hsb2[] = new float[3];//FIXME-not thread safe
--
-- // Return rgb1 painted onto rgb2
-- public static int combinePixels(int rgb1, int rgb2, int op) {
-- return combinePixels(rgb1, rgb2, op, 0xff);
-- }
--
-- public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha, int channelMask) {
-- return (rgb2 & ~channelMask) | combinePixels(rgb1 & channelMask, rgb2, op, extraAlpha);
-- }
--
-- public static int combinePixels(int rgb1, int rgb2, int op, int extraAlpha) {
-- if (op == REPLACE)
-- return rgb1;
-- int a1 = (rgb1 >> 24) & 0xff;
-- int r1 = (rgb1 >> 16) & 0xff;
-- int g1 = (rgb1 >> 8) & 0xff;
-- int b1 = rgb1 & 0xff;
-- int a2 = (rgb2 >> 24) & 0xff;
-- int r2 = (rgb2 >> 16) & 0xff;
-- int g2 = (rgb2 >> 8) & 0xff;
-- int b2 = rgb2 & 0xff;
--
-- switch (op) {
-- case NORMAL:
-- break;
-- case MIN:
-- r1 = Math.min(r1, r2);
-- g1 = Math.min(g1, g2);
-- b1 = Math.min(b1, b2);
-- break;
-- case MAX:
-- r1 = Math.max(r1, r2);
-- g1 = Math.max(g1, g2);
-- b1 = Math.max(b1, b2);
-- break;
-- case ADD:
-- r1 = clamp(r1+r2);
-- g1 = clamp(g1+g2);
-- b1 = clamp(b1+b2);
-- break;
-- case SUBTRACT:
-- r1 = clamp(r2-r1);
-- g1 = clamp(g2-g1);
-- b1 = clamp(b2-b1);
-- break;
-- case DIFFERENCE:
-- r1 = clamp(Math.abs(r1-r2));
-- g1 = clamp(Math.abs(g1-g2));
-- b1 = clamp(Math.abs(b1-b2));
-- break;
-- case MULTIPLY:
-- r1 = clamp(r1*r2/255);
-- g1 = clamp(g1*g2/255);
-- b1 = clamp(b1*b2/255);
-- break;
-- case DISSOLVE:
-- if ((randomGenerator.nextInt() & 0xff) <= a1) {
-- r1 = r2;
-- g1 = g2;
-- b1 = b2;
-- }
-- break;
-- case AVERAGE:
-- r1 = (r1+r2)/2;
-- g1 = (g1+g2)/2;
-- b1 = (b1+b2)/2;
-- break;
-- case HUE:
-- case SATURATION:
-- case VALUE:
-- case COLOR:
-- Color.RGBtoHSB(r1, g1, b1, hsb1);
-- Color.RGBtoHSB(r2, g2, b2, hsb2);
-- switch (op) {
-- case HUE:
-- hsb2[0] = hsb1[0];
-- break;
-- case SATURATION:
-- hsb2[1] = hsb1[1];
-- break;
-- case VALUE:
-- hsb2[2] = hsb1[2];
-- break;
-- case COLOR:
-- hsb2[0] = hsb1[0];
-- hsb2[1] = hsb1[1];
-- break;
-- }
-- rgb1 = Color.HSBtoRGB(hsb2[0], hsb2[1], hsb2[2]);
-- r1 = (rgb1 >> 16) & 0xff;
-- g1 = (rgb1 >> 8) & 0xff;
-- b1 = rgb1 & 0xff;
-- break;
-- case SCREEN:
-- r1 = 255 - ((255 - r1) * (255 - r2)) / 255;
-- g1 = 255 - ((255 - g1) * (255 - g2)) / 255;
-- b1 = 255 - ((255 - b1) * (255 - b2)) / 255;
-- break;
-- case OVERLAY:
-- int m, s;
-- s = 255 - ((255 - r1) * (255 - r2)) / 255;
-- m = r1 * r2 / 255;
-- r1 = (s * r1 + m * (255 - r1)) / 255;
-- s = 255 - ((255 - g1) * (255 - g2)) / 255;
-- m = g1 * g2 / 255;
-- g1 = (s * g1 + m * (255 - g1)) / 255;
-- s = 255 - ((255 - b1) * (255 - b2)) / 255;
-- m = b1 * b2 / 255;
-- b1 = (s * b1 + m * (255 - b1)) / 255;
-- break;
-- case CLEAR:
-- r1 = g1 = b1 = 0xff;
-- break;
-- case DST_IN:
-- r1 = clamp((r2*a1)/255);
-- g1 = clamp((g2*a1)/255);
-- b1 = clamp((b2*a1)/255);
-- a1 = clamp((a2*a1)/255);
-- return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
-- case ALPHA:
-- a1 = a1*a2/255;
-- return (a1 << 24) | (r2 << 16) | (g2 << 8) | b2;
-- case ALPHA_TO_GRAY:
-- int na = 255-a1;
-- return (a1 << 24) | (na << 16) | (na << 8) | na;
-- }
-- if (extraAlpha != 0xff || a1 != 0xff) {
-- a1 = a1*extraAlpha/255;
-- int a3 = (255-a1)*a2/255;
-- r1 = clamp((r1*a1+r2*a3)/255);
-- g1 = clamp((g1*a1+g2*a3)/255);
-- b1 = clamp((b1*a1+b2*a3)/255);
-- a1 = clamp(a1+a3);
-- }
-- return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
-- }
--
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/Quantizer.java (working copy)
-@@ -1,53 +0,0 @@
--/*
--Copyright 2006 Jerry Huxtable
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
--*/
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--/**
-- * The interface for an image quantizer. The addColor method is called (repeatedly
-- * if necessary) with all the image pixels. A color table can then be returned by
-- * calling the buildColorTable method.
-- */
--public interface Quantizer {
-- /**
-- * Initialize the quantizer. This should be called before adding any pixels.
-- * @param numColors the number of colors we're quantizing to.
-- */
-- public void setup(int numColors);
--
-- /**
-- * Add pixels to the quantizer.
-- * @param pixels the array of ARGB pixels
-- * @param offset the offset into the array
-- * @param count the count of pixels
-- */
-- public void addPixels(int[] pixels, int offset, int count);
--
-- /**
-- * Build a color table from the added pixels.
-- * @return an array of ARGB pixels representing a color table
-- */
-- public int[] buildColorTable();
--
-- /**
-- * Using the previously-built color table, return the index into that table for a pixel.
-- * This is guaranteed to return a valid index - returning the index of a color closer
-- * to that requested if necessary.
-- * @param rgb the pixel to find
-- * @return the pixel's index in the color table
-- */
-- public int getIndexForColor(int rgb);
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultEncoder.java (working copy)
-@@ -1,24 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import javax.imageio.ImageIO;
--import java.awt.image.BufferedImage;
--import java.io.ByteArrayOutputStream;
--import java.io.IOException;
--
--/**
-- * Implements a default PNG Encoder
-- */
--public class DefaultEncoder implements ImageEncoder{
--
-- public ByteArrayOutputStream encode(BufferedImage bufferedImage) {
-- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-- try {
-- ImageIO.write(bufferedImage, "png", baos);
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- baos = null;
-- }
-- return baos;
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/QuantizeFilter.java (working copy)
-@@ -1,178 +0,0 @@
--/*
--Copyright 2006 Jerry Huxtable
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
--*/
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.*;
--
--/**
-- * A filter which quantizes an image to a set number of colors - useful for producing
-- * images which are to be encoded using an index color model. The filter can perform
-- * Floyd-Steinberg error-diffusion dithering if required. At present, the quantization
-- * is done using an octtree algorithm but I eventually hope to add more quantization
-- * methods such as median cut. Note: at present, the filter produces an image which
-- * uses the RGB color model (because the application it was written for required it).
-- * I hope to extend it to produce an IndexColorModel by request.
-- */
--public class QuantizeFilter extends WholeImageFilter {
--
-- /**
-- * Floyd-Steinberg dithering matrix.
-- */
-- protected final static int[] matrix = {
-- 0, 0, 0,
-- 0, 0, 7,
-- 3, 5, 1,
-- };
-- private int sum = 3+5+7+1;
--
-- private boolean dither;
-- private int numColors = 256;
-- private boolean serpentine = true;
--
-- /**
-- * Set the number of colors to quantize to.
-- * @param numColors the number of colors. The default is 256.
-- */
-- public void setNumColors(int numColors) {
-- this.numColors = Math.min(Math.max(numColors, 8), 256);
-- }
--
-- /**
-- * Get the number of colors to quantize to.
-- * @return the number of colors.
-- */
-- public int getNumColors() {
-- return numColors;
-- }
--
-- /**
-- * Set whether to use dithering or not. If not, the image is posterized.
-- * @param dither true to use dithering
-- */
-- public void setDither(boolean dither) {
-- this.dither = dither;
-- }
--
-- /**
-- * Return the dithering setting
-- * @return the current setting
-- */
-- public boolean getDither() {
-- return dither;
-- }
--
-- /**
-- * Set whether to use a serpentine pattern for return or not. This can reduce 'avalanche' artifacts in the output.
-- * @param serpentine true to use serpentine pattern
-- */
-- public void setSerpentine(boolean serpentine) {
-- this.serpentine = serpentine;
-- }
--
-- /**
-- * Return the serpentine setting
-- * @return the current setting
-- */
-- public boolean getSerpentine() {
-- return serpentine;
-- }
--
-- public void quantize(int[] inPixels, int[] outPixels, int width, int height, int numColors, boolean dither, boolean serpentine) {
-- int count = width*height;
-- Quantizer quantizer = new OctTreeQuantizer();
-- quantizer.setup(numColors);
-- quantizer.addPixels(inPixels, 0, count);
-- int[] table = quantizer.buildColorTable();
--
-- if (!dither) {
-- for (int i = 0; i < count; i++)
-- outPixels[i] = table[quantizer.getIndexForColor(inPixels[i])];
-- } else {
-- int index = 0;
-- for (int y = 0; y < height; y++) {
-- boolean reverse = serpentine && (y & 1) == 1;
-- int direction;
-- if (reverse) {
-- index = y*width+width-1;
-- direction = -1;
-- } else {
-- index = y*width;
-- direction = 1;
-- }
-- for (int x = 0; x < width; x++) {
-- int rgb1 = inPixels[index];
-- int rgb2 = table[quantizer.getIndexForColor(rgb1)];
--
-- outPixels[index] = rgb2;
--
-- int r1 = (rgb1 >> 16) & 0xff;
-- int g1 = (rgb1 >> 8) & 0xff;
-- int b1 = rgb1 & 0xff;
--
-- int r2 = (rgb2 >> 16) & 0xff;
-- int g2 = (rgb2 >> 8) & 0xff;
-- int b2 = rgb2 & 0xff;
--
-- int er = r1-r2;
-- int eg = g1-g2;
-- int eb = b1-b2;
--
-- for (int i = -1; i <= 1; i++) {
-- int iy = i+y;
-- if (0 <= iy && iy < height) {
-- for (int j = -1; j <= 1; j++) {
-- int jx = j+x;
-- if (0 <= jx && jx < width) {
-- int w;
-- if (reverse)
-- w = matrix[(i+1)*3-j+1];
-- else
-- w = matrix[(i+1)*3+j+1];
-- if (w != 0) {
-- int k = reverse ? index - j : index + j;
-- rgb1 = inPixels[k];
-- r1 = (rgb1 >> 16) & 0xff;
-- g1 = (rgb1 >> 8) & 0xff;
-- b1 = rgb1 & 0xff;
-- r1 += er * w/sum;
-- g1 += eg * w/sum;
-- b1 += eb * w/sum;
-- inPixels[k] = (PixelUtils.clamp(r1) << 16) | (PixelUtils.clamp(g1) << 8) | PixelUtils.clamp(b1);
-- }
-- }
-- }
-- }
-- }
-- index += direction;
-- }
-- }
-- }
-- }
--
-- protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) {
-- int[] outPixels = new int[width*height];
--
-- quantize(inPixels, outPixels, width, height, numColors, dither, serpentine);
--
-- return outPixels;
-- }
--
-- public String toString() {
-- return "Colors/Quantize...";
-- }
--
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageReceiver.java (working copy)
-@@ -1,150 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.*;
--import java.awt.image.BufferedImage;
--import java.io.ByteArrayInputStream;
--import java.io.IOException;
--import java.net.DatagramPacket;
--import java.net.DatagramSocket;
--import java.net.InetAddress;
--import java.net.SocketException;
--
--/**
-- * UDP Image Receiver.
-- * It uses PNG Tiles into UDP packets.
-- *
-- * @author Thiago Rocha Camargo
-- */
--public class ImageReceiver extends Canvas {
--
-- private boolean on = true;
-- private DatagramSocket socket;
-- private BufferedImage tiles[][];
-- private static final int tileWidth = ImageTransmitter.tileWidth;
-- private InetAddress localHost;
-- private InetAddress remoteHost;
-- private int localPort;
-- private int remotePort;
-- private ImageDecoder decoder;
--
-- public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) {
-- tiles = new BufferedImage[width][height];
--
-- try {
--
-- socket = new DatagramSocket(localPort);
-- localHost = socket.getLocalAddress();
-- this.remoteHost = remoteHost;
-- this.remotePort = remotePort;
-- this.localPort = localPort;
-- this.decoder = new DefaultDecoder();
--
-- new Thread(new Runnable() {
-- public void run() {
-- byte buf[] = new byte[1024];
-- DatagramPacket p = new DatagramPacket(buf, 1024);
-- try {
-- while (on) {
-- socket.receive(p);
--
-- int length = p.getLength();
--
-- BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2));
--
-- if (bufferedImage != null) {
--
-- int x = p.getData()[length - 2];
-- int y = p.getData()[length - 1];
--
-- drawTile(x, y, bufferedImage);
--
-- }
--
-- }
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- }
-- }).start();
--
-- new Thread(new Runnable() {
-- public void run() {
-- byte buf[] = new byte[1024];
-- DatagramPacket p = new DatagramPacket(buf, 1024);
-- try {
-- while (on) {
--
-- p.setAddress(remoteHost);
-- p.setPort(remotePort);
-- socket.send(p);
--
-- try {
-- Thread.sleep(1000);
-- }
-- catch (InterruptedException e) {
-- e.printStackTrace();
-- }
--
-- }
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- }
-- }).start();
--
-- }
-- catch (SocketException e) {
-- e.printStackTrace();
-- }
-- this.setSize(width, height);
-- }
--
-- public InetAddress getLocalHost() {
-- return localHost;
-- }
--
-- public InetAddress getRemoteHost() {
-- return remoteHost;
-- }
--
-- public int getLocalPort() {
-- return localPort;
-- }
--
-- public int getRemotePort() {
-- return remotePort;
-- }
--
-- public DatagramSocket getDatagramSocket() {
-- return socket;
-- }
--
-- public void drawTile(int x, int y, BufferedImage bufferedImage) {
-- tiles[x][y] = bufferedImage;
-- //repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth);
-- this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this);
-- }
--
-- public void paint(Graphics g) {
-- for (int i = 0; i < tiles.length; i++) {
-- for (int j = 0; j < tiles[0].length; j++) {
-- g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this);
-- }
-- }
-- }
--
-- public ImageDecoder getDecoder() {
-- return decoder;
-- }
--
-- public void setDecoder(ImageDecoder decoder) {
-- this.decoder = decoder;
-- }
--
-- public void stop(){
-- this.on=false;
-- socket.close();
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/WholeImageFilter.java (working copy)
-@@ -1,86 +0,0 @@
--/*
--Copyright 2006 Jerry Huxtable
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
--*/
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.*;
--import java.awt.image.BufferedImage;
--import java.awt.image.ColorModel;
--import java.awt.image.WritableRaster;
--
--/**
-- * A filter which acts as a superclass for filters which need to have the whole image in memory
-- * to do their stuff.
-- */
--public abstract class WholeImageFilter extends AbstractBufferedImageOp {
--
-- /**
-- * The output image bounds.
-- */
-- protected Rectangle transformedSpace;
--
-- /**
-- * The input image bounds.
-- */
-- protected Rectangle originalSpace;
--
-- /**
-- * Construct a WholeImageFilter.
-- */
-- public WholeImageFilter() {
-- }
--
-- public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
-- int width = src.getWidth();
-- int height = src.getHeight();
-- int type = src.getType();
-- WritableRaster srcRaster = src.getRaster();
--
-- originalSpace = new Rectangle(0, 0, width, height);
-- transformedSpace = new Rectangle(0, 0, width, height);
-- transformSpace(transformedSpace);
--
-- if ( dst == null ) {
-- ColorModel dstCM = src.getColorModel();
-- dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(transformedSpace.width, transformedSpace.height), dstCM.isAlphaPremultiplied(), null);
-- }
-- WritableRaster dstRaster = dst.getRaster();
--
-- int[] inPixels = getRGB( src, 0, 0, width, height, null );
-- inPixels = filterPixels( width, height, inPixels, transformedSpace );
-- setRGB( dst, 0, 0, transformedSpace.width, transformedSpace.height, inPixels );
--
-- return dst;
-- }
--
-- /**
-- * Calculate output bounds for given input bounds.
-- * @param rect input and output rectangle
-- */
-- protected void transformSpace(Rectangle rect) {
-- }
--
-- /**
-- * Actually filter the pixels.
-- * @param width the image width
-- * @param height the image height
-- * @param inPixels the image pixels
-- * @param transformedSpace the output bounds
-- * @return the output pixels
-- */
-- protected abstract int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace );
--}
--
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/AbstractBufferedImageOp.java (working copy)
-@@ -1,98 +0,0 @@
--/*
--Copyright 2006 Jerry Huxtable
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
--*/
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.*;
--import java.awt.geom.Point2D;
--import java.awt.geom.Rectangle2D;
--import java.awt.image.BufferedImage;
--import java.awt.image.BufferedImageOp;
--import java.awt.image.ColorModel;
--
--/**
-- * A convenience class which implements those methods of BufferedImageOp which are rarely changed.
-- */
--public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {
--
-- public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
-- if ( dstCM == null )
-- dstCM = src.getColorModel();
-- return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
-- }
--
-- public Rectangle2D getBounds2D( BufferedImage src ) {
-- return new Rectangle(0, 0, src.getWidth(), src.getHeight());
-- }
--
-- public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
-- if ( dstPt == null )
-- dstPt = new Point2D.Double();
-- dstPt.setLocation( srcPt.getX(), srcPt.getY() );
-- return dstPt;
-- }
--
-- public RenderingHints getRenderingHints() {
-- return null;
-- }
--
-- /**
-- * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
-- * penalty of BufferedImage.getRGB unmanaging the image.
-- * @param image a BufferedImage object
-- * @param x the left edge of the pixel block
-- * @param y the right edge of the pixel block
-- * @param width the width of the pixel arry
-- * @param height the height of the pixel arry
-- * @param pixels the array to hold the returned pixels. May be null.
-- * @return the pixels
-- * @see #setRGB
-- */
-- public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
-- int type = image.getType();
-- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
-- return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
-- return image.getRGB( x, y, width, height, pixels, 0, width );
-- }
--
-- /**
-- * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
-- * penalty of BufferedImage.setRGB unmanaging the image.
-- * @param image a BufferedImage object
-- * @param x the left edge of the pixel block
-- * @param y the right edge of the pixel block
-- * @param width the width of the pixel arry
-- * @param height the height of the pixel arry
-- * @param pixels the array of pixels to set
-- * @see #getRGB
-- */
-- public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
-- int type = image.getType();
-- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
-- image.getRaster().setDataElements( x, y, width, height, pixels );
-- else
-- image.setRGB( x, y, width, height, pixels, 0, width );
-- }
--
-- public Object clone() {
-- try {
-- return super.clone();
-- }
-- catch ( CloneNotSupportedException e ) {
-- return null;
-- }
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/ImageDecoder.java (working copy)
-@@ -1,15 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.awt.image.BufferedImage;
--import java.io.ByteArrayInputStream;
--import java.io.IOException;
--
--/**
-- * Image Decoder Interface use this interface if you want to change the default decoder
-- *
-- * @author Thiago Rocha Camargo
-- */
--public interface ImageDecoder {
--
-- public BufferedImage decode(ByteArrayInputStream stream) throws IOException;
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/OctTreeQuantizer.java (working copy)
-@@ -1,287 +0,0 @@
--/*
--Copyright 2006 Jerry Huxtable
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
--*/
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import java.io.PrintStream;
--import java.util.Vector;
--
--import org.jivesoftware.smackx.jingle.SmackLogger;
--
--/**
-- * An image Quantizer based on the Octree algorithm. This is a very basic implementation
-- * at present and could be much improved by picking the nodes to reduce more carefully
-- * (i.e. not completely at random) when I get the time.
-- */
--public class OctTreeQuantizer implements Quantizer {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(OctTreeQuantizer.class);
--
-- /**
-- * The greatest depth the tree is allowed to reach
-- */
-- final static int MAX_LEVEL = 5;
--
-- /**
-- * An Octtree node.
-- */
-- class OctTreeNode {
-- int children;
-- int level;
-- OctTreeNode parent;
-- OctTreeNode leaf[] = new OctTreeNode[8];
-- boolean isLeaf;
-- int count;
-- int totalRed;
-- int totalGreen;
-- int totalBlue;
-- int index;
--
-- /**
-- * A debugging method which prints the tree out.
-- */
-- public void list(PrintStream s, int level) {
-- String indentStr = "";
-- for (int i = 0; i < level; i++)
-- indentStr += " ";
-- if (count == 0)
-- LOGGER.debug(indentStr + index + ": count=" + count);
-- else
-- LOGGER.debug(indentStr + index + ": count=" + count + " red=" + (totalRed/count) + " green=" + (totalGreen / count) + " blue=" + (totalBlue / count));
-- for (int i = 0; i < 8; i++)
-- if (leaf[i] != null)
-- leaf[i].list(s, level+2);
-- }
-- }
--
-- private int nodes = 0;
-- private OctTreeNode root;
-- private int reduceColors;
-- private int maximumColors;
-- private int colors = 0;
-- private Vector[] colorList;
--
-- public OctTreeQuantizer() {
-- setup(256);
-- colorList = new Vector[MAX_LEVEL+1];
-- for (int i = 0; i < MAX_LEVEL+1; i++)
-- colorList[i] = new Vector();
-- root = new OctTreeNode();
-- }
--
-- /**
-- * Initialize the quantizer. This should be called before adding any pixels.
-- * @param numColors the number of colors we're quantizing to.
-- */
-- public void setup(int numColors) {
-- maximumColors = numColors;
-- reduceColors = Math.max(512, numColors * 2);
-- }
--
-- /**
-- * Add pixels to the quantizer.
-- * @param pixels the array of ARGB pixels
-- * @param offset the offset into the array
-- * @param count the count of pixels
-- */
-- public void addPixels(int[] pixels, int offset, int count) {
-- for (int i = 0; i < count; i++) {
-- insertColor(pixels[i+offset]);
-- if (colors > reduceColors)
-- reduceTree(reduceColors);
-- }
-- }
--
-- /**
-- * Get the color table index for a color.
-- * @param rgb the color
-- * @return the index
-- */
-- public int getIndexForColor(int rgb) {
-- int red = (rgb >> 16) & 0xff;
-- int green = (rgb >> 8) & 0xff;
-- int blue = rgb & 0xff;
--
-- OctTreeNode node = root;
--
-- for (int level = 0; level <= MAX_LEVEL; level++) {
-- OctTreeNode child;
-- int bit = 0x80 >> level;
--
-- int index = 0;
-- if ((red & bit) != 0)
-- index += 4;
-- if ((green & bit) != 0)
-- index += 2;
-- if ((blue & bit) != 0)
-- index += 1;
--
-- child = node.leaf[index];
--
-- if (child == null)
-- return node.index;
-- else if (child.isLeaf)
-- return child.index;
-- else
-- node = child;
-- }
-- LOGGER.debug("getIndexForColor failed");
-- return 0;
-- }
--
-- private void insertColor(int rgb) {
-- int red = (rgb >> 16) & 0xff;
-- int green = (rgb >> 8) & 0xff;
-- int blue = rgb & 0xff;
--
-- OctTreeNode node = root;
--
--// LOGGER.debug("insertColor="+Integer.toHexString(rgb));
-- for (int level = 0; level <= MAX_LEVEL; level++) {
-- OctTreeNode child;
-- int bit = 0x80 >> level;
--
-- int index = 0;
-- if ((red & bit) != 0)
-- index += 4;
-- if ((green & bit) != 0)
-- index += 2;
-- if ((blue & bit) != 0)
-- index += 1;
--
-- child = node.leaf[index];
--
-- if (child == null) {
-- node.children++;
--
-- child = new OctTreeNode();
-- child.parent = node;
-- node.leaf[index] = child;
-- node.isLeaf = false;
-- nodes++;
-- colorList[level].addElement(child);
--
-- if (level == MAX_LEVEL) {
-- child.isLeaf = true;
-- child.count = 1;
-- child.totalRed = red;
-- child.totalGreen = green;
-- child.totalBlue = blue;
-- child.level = level;
-- colors++;
-- return;
-- }
--
-- node = child;
-- } else if (child.isLeaf) {
-- child.count++;
-- child.totalRed += red;
-- child.totalGreen += green;
-- child.totalBlue += blue;
-- return;
-- } else
-- node = child;
-- }
-- LOGGER.debug("insertColor failed");
-- }
--
-- private void reduceTree(int numColors) {
-- for (int level = MAX_LEVEL-1; level >= 0; level--) {
-- Vector v = colorList[level];
-- if (v != null && v.size() > 0) {
-- for (int j = 0; j < v.size(); j++) {
-- OctTreeNode node = (OctTreeNode)v.elementAt(j);
-- if (node.children > 0) {
-- for (int i = 0; i < 8; i++) {
-- OctTreeNode child = node.leaf[i];
-- if (child != null) {
-- if (!child.isLeaf)
-- LOGGER.debug("not a leaf!");
-- node.count += child.count;
-- node.totalRed += child.totalRed;
-- node.totalGreen += child.totalGreen;
-- node.totalBlue += child.totalBlue;
-- node.leaf[i] = null;
-- node.children--;
-- colors--;
-- nodes--;
-- colorList[level+1].removeElement(child);
-- }
-- }
-- node.isLeaf = true;
-- colors++;
-- if (colors <= numColors)
-- return;
-- }
-- }
-- }
-- }
--
-- LOGGER.debug("Unable to reduce the OctTree");
-- }
--
-- /**
-- * Build the color table.
-- * @return the color table
-- */
-- public int[] buildColorTable() {
-- int[] table = new int[colors];
-- buildColorTable(root, table, 0);
-- return table;
-- }
--
-- /**
-- * A quick way to use the quantizer. Just create a table the right size and pass in the pixels.
-- * @param inPixels the input colors
-- * @param table the output color table
-- */
-- public void buildColorTable(int[] inPixels, int[] table) {
-- int count = inPixels.length;
-- maximumColors = table.length;
-- for (int i = 0; i < count; i++) {
-- insertColor(inPixels[i]);
-- if (colors > reduceColors)
-- reduceTree(reduceColors);
-- }
-- if (colors > maximumColors)
-- reduceTree(maximumColors);
-- buildColorTable(root, table, 0);
-- }
--
-- private int buildColorTable(OctTreeNode node, int[] table, int index) {
-- if (colors > maximumColors)
-- reduceTree(maximumColors);
--
-- if (node.isLeaf) {
-- int count = node.count;
-- table[index] = 0xff000000 |
-- ((node.totalRed/count) << 16) |
-- ((node.totalGreen/count) << 8) |
-- node.totalBlue/count;
-- node.index = index++;
-- } else {
-- for (int i = 0; i < 8; i++) {
-- if (node.leaf[i] != null) {
-- node.index = index;
-- index = buildColorTable(node.leaf[i], table, index);
-- }
-- }
-- }
-- return index;
-- }
--
--}
--
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/api/DefaultDecoder.java (working copy)
-@@ -1,16 +0,0 @@
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare.api;
--
--import javax.imageio.ImageIO;
--import java.awt.image.BufferedImage;
--import java.io.ByteArrayInputStream;
--import java.io.IOException;
--
--/**
-- * Implements a default PNG decoder.
-- */
--public class DefaultDecoder implements ImageDecoder {
--
-- public BufferedImage decode(ByteArrayInputStream stream) throws IOException {
-- return ImageIO.read(stream);
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java (working copy)
-@@ -1,115 +0,0 @@
--/**
-- * $RCSfile: ScreenShareMediaManager.java,v $
-- * $Revision: 1.3 $
-- * $Date: 25/12/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
--import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
--import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--import java.util.ArrayList;
--import java.util.List;
--
--/**
-- * Implements a JingleMediaManager for ScreenSharing.
-- * It currently uses an Audio payload Type. Which needs to be fixed in the next version.
-- *
-- * @author Thiago Camargo
-- */
--
--public class ScreenShareMediaManager extends JingleMediaManager {
--
-- public static final String MEDIA_NAME = "ScreenShare";
--
-- private List<PayloadType> payloads = new ArrayList<PayloadType>();
--
-- private ImageDecoder decoder = null;
-- private ImageEncoder encoder = null;
--
-- public ScreenShareMediaManager(JingleTransportManager transportManager) {
-- super(transportManager);
-- setupPayloads();
-- }
--
-- /**
-- * Setup API supported Payloads
-- */
-- private void setupPayloads() {
-- payloads.add(new PayloadType.Audio(30, "sshare"));
-- }
--
-- /**
-- * Return all supported Payloads for this Manager.
-- *
-- * @return The Payload List
-- */
-- public List<PayloadType> getPayloads() {
-- return payloads;
-- }
--
-- /**
-- * Returns a new JingleMediaSession
-- *
-- * @param payloadType payloadType
-- * @param remote remote Candidate
-- * @param local local Candidate
-- * @return JingleMediaSession JingleMediaSession
-- */
-- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-- ScreenShareSession session = null;
-- session = new ScreenShareSession(payloadType, remote, local, "Screen", jingleSession);
-- if (encoder != null) {
-- session.setEncoder(encoder);
-- }
-- if (decoder != null) {
-- session.setDecoder(decoder);
-- }
-- return session;
-- }
--
-- public PayloadType getPreferredPayloadType() {
-- return super.getPreferredPayloadType();
-- }
--
-- public ImageDecoder getDecoder() {
-- return decoder;
-- }
--
-- public void setDecoder(ImageDecoder decoder) {
-- this.decoder = decoder;
-- }
--
-- public ImageEncoder getEncoder() {
-- return encoder;
-- }
--
-- public void setEncoder(ImageEncoder encoder) {
-- this.encoder = encoder;
-- }
--
-- public String getName() {
-- return MEDIA_NAME;
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java (working copy)
-@@ -1,106 +0,0 @@
--/**
-- * $RCSfile: MultiMediaManager.java,v $
-- * $Revision: 1.3 $
-- * $Date: 25/12/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.multi;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--import java.util.ArrayList;
--import java.util.List;
--
--/**
-- * Implements a MultiMediaManager using other JingleMediaManager implementations.
-- * It supports every Codecs that JingleMediaManagers added has.
-- *
-- * @author Thiago Camargo
-- */
--
--public class MultiMediaManager extends JingleMediaManager {
--
-- public static final String MEDIA_NAME = "Multi";
--
-- private List<JingleMediaManager> managers = new ArrayList<JingleMediaManager>();
--
-- private PayloadType preferredPayloadType = null;
--
-- public MultiMediaManager(JingleTransportManager transportManager) {
-- super(transportManager);
-- }
--
-- public void addMediaManager(JingleMediaManager manager) {
-- managers.add(manager);
-- }
--
-- public void removeMediaManager(JingleMediaManager manager) {
-- managers.remove(manager);
-- }
--
-- /**
-- * Return all supported Payloads for this Manager.
-- *
-- * @return The Payload List
-- */
-- public List<PayloadType> getPayloads() {
-- List<PayloadType> list = new ArrayList<PayloadType>();
-- if (preferredPayloadType != null) list.add(preferredPayloadType);
-- for (JingleMediaManager manager : managers) {
-- for (PayloadType payloadType : manager.getPayloads()) {
-- if (!list.contains(payloadType) && !payloadType.equals(preferredPayloadType))
-- list.add(payloadType);
-- }
-- }
-- return list;
-- }
--
-- /**
-- * Returns a new JingleMediaSession
-- *
-- * @param payloadType payloadType
-- * @param remote remote Candidate
-- * @param local local Candidate
-- * @return JingleMediaSession JingleMediaSession
-- */
-- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-- for (JingleMediaManager manager : managers) {
-- if (manager.getPayloads().contains(payloadType)) {
-- return manager.createMediaSession(payloadType, remote, local, jingleSession);
-- }
-- }
-- return null;
-- }
--
-- public PayloadType getPreferredPayloadType() {
-- if (preferredPayloadType != null) return preferredPayloadType;
-- return super.getPreferredPayloadType();
-- }
--
-- public void setPreferredPayloadType(PayloadType preferredPayloadType) {
-- this.preferredPayloadType = preferredPayloadType;
-- }
--
-- public String getName() {
-- return MEDIA_NAME;
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java (working copy)
-@@ -1,165 +0,0 @@
--/**
-- * $RCSfile: AudioMediaSession.java,v $
-- * $Revision: 1.1 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
--
--import java.io.IOException;
--import java.net.ServerSocket;
--
--import javax.media.MediaLocator;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--/**
-- * This Class implements a complete JingleMediaSession.
-- * It sould be used to transmit and receive audio captured from the Mic.
-- * This Class should be automaticly controlled by JingleSession.
-- * But you could also use in any VOIP application.
-- * For better NAT Traversal support this implementation don't support only receive or only transmit.
-- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
-- *
-- * @author Thiago Camargo
-- */
--public class AudioMediaSession extends JingleMediaSession {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class);
--
-- private AudioChannel audioChannel;
--
-- /**
-- * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
-- *
-- * @param payloadType Payload of the jmf
-- * @param remote the remote information. The candidate that the jmf will be sent to.
-- * @param local the local information. The candidate that will receive the jmf
-- * @param locator media locator
-- */
-- public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
-- final TransportCandidate local, String locator, JingleSession jingleSession) {
-- super(payloadType, remote, local, locator==null?"dsound://":locator,jingleSession);
-- initialize();
-- }
--
-- /**
-- * Initialize the Audio Channel to make it able to send and receive audio
-- */
-- public void initialize() {
--
-- String ip;
-- String localIp;
-- int localPort;
-- int remotePort;
--
-- if (this.getLocal().getSymmetric() != null) {
-- ip = this.getLocal().getIp();
-- localIp = this.getLocal().getLocalIp();
-- localPort = getFreePort();
-- remotePort = this.getLocal().getSymmetric().getPort();
--
-- LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort);
--
-- }
-- else {
-- ip = this.getRemote().getIp();
-- localIp = this.getLocal().getLocalIp();
-- localPort = this.getLocal().getPort();
-- remotePort = this.getRemote().getPort();
-- }
--
-- audioChannel = new AudioChannel(new MediaLocator(this.getMediaLocator()), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType()),this);
-- }
--
-- /**
-- * Starts transmission and for NAT Traversal reasons start receiving also.
-- */
-- public void startTrasmit() {
-- audioChannel.start();
-- }
--
-- /**
-- * Set transmit activity. If the active is true, the instance should trasmit.
-- * If it is set to false, the instance should pause transmit.
-- *
-- * @param active active state
-- */
-- public void setTrasmit(boolean active) {
-- audioChannel.setTrasmit(active);
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void startReceive() {
-- // Do nothing
-- }
--
-- /**
-- * Stops transmission and for NAT Traversal reasons stop receiving also.
-- */
-- public void stopTrasmit() {
-- if (audioChannel != null)
-- audioChannel.stop();
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void stopReceive() {
-- // Do nothing
-- }
--
-- /**
-- * Obtain a free port we can use.
-- *
-- * @return A free port number.
-- */
-- protected int getFreePort() {
-- ServerSocket ss;
-- int freePort = 0;
--
-- for (int i = 0; i < 10; i++) {
-- freePort = (int) (10000 + Math.round(Math.random() * 10000));
-- freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-- try {
-- ss = new ServerSocket(freePort);
-- freePort = ss.getLocalPort();
-- ss.close();
-- return freePort;
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- }
-- try {
-- ss = new ServerSocket(0);
-- freePort = ss.getLocalPort();
-- ss.close();
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- return freePort;
-- }
--
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java (working copy)
-@@ -1,171 +0,0 @@
--/**
-- * $RCSfile: AudioReceiver.java,v $
-- * $Revision: 1.1 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
--
--import javax.media.ControllerErrorEvent;
--import javax.media.ControllerEvent;
--import javax.media.ControllerListener;
--import javax.media.Player;
--import javax.media.RealizeCompleteEvent;
--import javax.media.protocol.DataSource;
--import javax.media.rtp.Participant;
--import javax.media.rtp.RTPControl;
--import javax.media.rtp.ReceiveStream;
--import javax.media.rtp.ReceiveStreamListener;
--import javax.media.rtp.SessionListener;
--import javax.media.rtp.event.ByeEvent;
--import javax.media.rtp.event.NewParticipantEvent;
--import javax.media.rtp.event.NewReceiveStreamEvent;
--import javax.media.rtp.event.ReceiveStreamEvent;
--import javax.media.rtp.event.RemotePayloadChangeEvent;
--import javax.media.rtp.event.SessionEvent;
--import javax.media.rtp.event.StreamMappedEvent;
--
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--
--/**
-- * This class implements receive methods and listeners to be used in AudioChannel
-- *
-- * @author Thiago Camargo
-- */
--public class AudioReceiver implements ReceiveStreamListener, SessionListener,
-- ControllerListener {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioReceiver.class);
--
-- boolean dataReceived = false;
--
-- Object dataSync;
-- JingleMediaSession jingleMediaSession;
--
-- public AudioReceiver(final Object dataSync, final JingleMediaSession jingleMediaSession) {
-- this.dataSync = dataSync;
-- this.jingleMediaSession = jingleMediaSession;
-- }
--
-- /**
-- * JingleSessionListener.
-- */
-- public synchronized void update(SessionEvent evt) {
-- if (evt instanceof NewParticipantEvent) {
-- Participant p = ((NewParticipantEvent) evt).getParticipant();
-- LOGGER.error(" - A new participant had just joined: " + p.getCNAME());
-- }
-- }
--
-- /**
-- * ReceiveStreamListener
-- */
-- public synchronized void update(ReceiveStreamEvent evt) {
--
-- Participant participant = evt.getParticipant(); // could be null.
-- ReceiveStream stream = evt.getReceiveStream(); // could be null.
--
-- if (evt instanceof RemotePayloadChangeEvent) {
-- LOGGER.error(" - Received an RTP PayloadChangeEvent.");
-- LOGGER.error("Sorry, cannot handle payload change.");
--
-- }
-- else if (evt instanceof NewReceiveStreamEvent) {
--
-- try {
-- stream = evt.getReceiveStream();
-- DataSource ds = stream.getDataSource();
--
-- // Find out the formats.
-- RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl");
-- if (ctl != null) {
-- LOGGER.error(" - Recevied new RTP stream: " + ctl.getFormat());
-- }
-- else
-- LOGGER.error(" - Recevied new RTP stream");
--
-- if (participant == null)
-- LOGGER.error(" The sender of this stream had yet to be identified.");
-- else {
-- LOGGER.error(" The stream comes from: " + participant.getCNAME());
-- }
--
-- // create a player by passing datasource to the Media Manager
-- Player p = javax.media.Manager.createPlayer(ds);
-- if (p == null)
-- return;
--
-- p.addControllerListener(this);
-- p.realize();
-- jingleMediaSession.mediaReceived(participant != null ? participant.getCNAME() : "");
--
-- // Notify intialize() that a new stream had arrived.
-- synchronized (dataSync) {
-- dataReceived = true;
-- dataSync.notifyAll();
-- }
--
-- }
-- catch (Exception e) {
-- LOGGER.error("NewReceiveStreamEvent exception " + e.getMessage());
-- return;
-- }
--
-- }
-- else if (evt instanceof StreamMappedEvent) {
--
-- if (stream != null && stream.getDataSource() != null) {
-- DataSource ds = stream.getDataSource();
-- // Find out the formats.
-- RTPControl ctl = (RTPControl) ds.getControl("javax.jmf.rtp.RTPControl");
-- LOGGER.error(" - The previously unidentified stream ");
-- if (ctl != null)
-- LOGGER.error(" " + ctl.getFormat());
-- LOGGER.error(" had now been identified as sent by: " + participant.getCNAME());
-- }
-- }
-- else if (evt instanceof ByeEvent) {
--
-- LOGGER.error(" - Got \"bye\" from: " + participant.getCNAME());
--
-- }
--
-- }
--
-- /**
-- * ControllerListener for the Players.
-- */
-- public synchronized void controllerUpdate(ControllerEvent ce) {
--
-- Player p = (Player) ce.getSourceController();
--
-- if (p == null)
-- return;
--
-- // Get this when the internal players are realized.
-- if (ce instanceof RealizeCompleteEvent) {
-- p.start();
-- }
--
-- if (ce instanceof ControllerErrorEvent) {
-- p.removeControllerListener(this);
-- LOGGER.error("Receiver internal error: " + ce);
-- }
--
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java (working copy)
-@@ -1,170 +0,0 @@
--/**
-- * $RCSfile: JmfMediaManager.java,v $
-- * $Revision: 1.3 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
--
--import java.io.File;
--import java.io.IOException;
--import java.util.ArrayList;
--import java.util.List;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.mediaimpl.JMFInit;
--import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--/**
-- * Implements a jingleMediaManager using JMF based API.
-- * It supports GSM and G723 codecs.
-- * <i>This API only currently works on windows and Mac.</i>
-- *
-- * @author Thiago Camargo
-- */
--public class JmfMediaManager extends JingleMediaManager {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(JmfMediaManager.class);
--
-- public static final String MEDIA_NAME = "JMF";
--
--
-- private List<PayloadType> payloads = new ArrayList<PayloadType>();
-- private String mediaLocator = null;
--
-- /**
-- * Creates a Media Manager instance
-- */
-- public JmfMediaManager(JingleTransportManager transportManager) {
-- super(transportManager);
-- setupPayloads();
-- }
--
-- /**
-- * Creates a Media Manager instance
-- *
-- * @param mediaLocator Media Locator
-- */
-- public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) {
-- super(transportManager);
-- this.mediaLocator = mediaLocator;
-- setupPayloads();
-- }
--
-- /**
-- * Returns a new jingleMediaSession
-- *
-- * @param payloadType payloadType
-- * @param remote remote Candidate
-- * @param local local Candidate
-- * @return JingleMediaSession
-- */
-- public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-- return new AudioMediaSession(payloadType, remote, local, mediaLocator, jingleSession);
-- }
--
-- /**
-- * Setup API supported Payloads
-- */
-- private void setupPayloads() {
-- payloads.add(new PayloadType.Audio(3, "gsm"));
-- payloads.add(new PayloadType.Audio(4, "g723"));
-- payloads.add(new PayloadType.Audio(0, "PCMU", 16000));
-- }
--
-- /**
-- * Return all supported Payloads for this Manager
-- *
-- * @return The Payload List
-- */
-- public List<PayloadType> getPayloads() {
-- return payloads;
-- }
--
-- /**
-- * Return the media locator or null if not defined
-- *
-- * @return media locator
-- */
-- public String getMediaLocator() {
-- return mediaLocator;
-- }
--
-- /**
-- * Set the media locator
-- *
-- * @param mediaLocator media locator or null to use default
-- */
-- public void setMediaLocator(String mediaLocator) {
-- this.mediaLocator = mediaLocator;
-- }
--
-- /**
-- * Runs JMFInit the first time the application is started so that capture
-- * devices are properly detected and initialized by JMF.
-- */
-- public static void setupJMF() {
-- // .jmf is the place where we store the jmf.properties file used
-- // by JMF. if the directory does not exist or it does not contain
-- // a jmf.properties file. or if the jmf.properties file has 0 length
-- // then this is the first time we're running and should continue to
-- // with JMFInit
-- String homeDir = System.getProperty("user.home");
-- File jmfDir = new File(homeDir, ".jmf");
-- String classpath = System.getProperty("java.class.path");
-- classpath += System.getProperty("path.separator")
-- + jmfDir.getAbsolutePath();
-- System.setProperty("java.class.path", classpath);
--
-- if (!jmfDir.exists())
-- jmfDir.mkdir();
--
-- File jmfProperties = new File(jmfDir, "jmf.properties");
--
-- if (!jmfProperties.exists()) {
-- try {
-- jmfProperties.createNewFile();
-- }
-- catch (IOException ex) {
-- LOGGER.debug("Failed to create jmf.properties");
-- ex.printStackTrace();
-- }
-- }
--
-- // if we're running on linux checkout that libjmutil.so is where it
-- // should be and put it there.
-- runLinuxPreInstall();
--
-- //if (jmfProperties.length() == 0) {
-- new JMFInit(null, false);
-- //}
--
-- }
--
-- private static void runLinuxPreInstall() {
-- // @TODO Implement Linux Pre-Install
-- }
--
-- public String getName() {
-- return MEDIA_NAME;
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java (working copy)
-@@ -1,553 +0,0 @@
--/**
-- * $RCSfile: AudioChannel.java,v $
-- * $Revision: 1.1 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
--
--import java.io.IOException;
--import java.net.InetAddress;
--import java.net.UnknownHostException;
--import java.util.ArrayList;
--import java.util.List;
--
--import javax.media.Codec;
--import javax.media.Controller;
--import javax.media.ControllerClosedEvent;
--import javax.media.ControllerEvent;
--import javax.media.ControllerListener;
--import javax.media.Format;
--import javax.media.MediaLocator;
--import javax.media.NoProcessorException;
--import javax.media.Processor;
--import javax.media.UnsupportedPlugInException;
--import javax.media.control.BufferControl;
--import javax.media.control.PacketSizeControl;
--import javax.media.control.TrackControl;
--import javax.media.format.AudioFormat;
--import javax.media.protocol.ContentDescriptor;
--import javax.media.protocol.DataSource;
--import javax.media.protocol.PushBufferDataSource;
--import javax.media.protocol.PushBufferStream;
--import javax.media.rtp.InvalidSessionAddressException;
--import javax.media.rtp.RTPManager;
--import javax.media.rtp.SendStream;
--import javax.media.rtp.SessionAddress;
--
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--
--/**
-- * An Easy to use Audio Channel implemented using JMF.
-- * It sends and receives jmf for and from desired IPs and ports.
-- * Also has a rport Symetric behavior for better NAT Traversal.
-- * It send data from a defined port and receive data in the same port, making NAT binds easier.
-- * <p/>
-- * Send from portA to portB and receive from portB in portA.
-- * <p/>
-- * Sending
-- * portA ---> portB
-- * <p/>
-- * Receiving
-- * portB ---> portA
-- * <p/>
-- * <i>Transmit and Receive are interdependents. To receive you MUST trasmit. </i>
-- *
-- * @author Thiago Camargo
-- */
--public class AudioChannel {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioChannel.class);
--
-- private MediaLocator locator;
-- private String localIpAddress;
-- private String remoteIpAddress;
-- private int localPort;
-- private int portBase;
-- private Format format;
--
-- private Processor processor = null;
-- private RTPManager rtpMgrs[];
-- private DataSource dataOutput = null;
-- private AudioReceiver audioReceiver;
--
-- private List<SendStream> sendStreams = new ArrayList<SendStream>();
--
-- private JingleMediaSession jingleMediaSession;
--
-- private boolean started = false;
--
-- /**
-- * Creates an Audio Channel for a desired jmf locator. For instance: new MediaLocator("dsound://")
-- *
-- * @param locator media locator
-- * @param localIpAddress local IP address
-- * @param remoteIpAddress remote IP address
-- * @param localPort local port number
-- * @param remotePort remote port number
-- * @param format audio format
-- */
-- public AudioChannel(MediaLocator locator,
-- String localIpAddress,
-- String remoteIpAddress,
-- int localPort,
-- int remotePort,
-- Format format, JingleMediaSession jingleMediaSession) {
--
-- this.locator = locator;
-- this.localIpAddress = localIpAddress;
-- this.remoteIpAddress = remoteIpAddress;
-- this.localPort = localPort;
-- this.portBase = remotePort;
-- this.format = format;
-- this.jingleMediaSession = jingleMediaSession;
-- }
--
-- /**
-- * Starts the transmission. Returns null if transmission started ok.
-- * Otherwise it returns a string with the reason why the setup failed.
-- * Starts receive also.
-- *
-- * @return result description
-- */
-- public synchronized String start() {
-- if (started) return null;
--
-- // Create a processor for the specified jmf locator
-- String result = createProcessor();
-- if (result != null) {
-- started = false;
-- }
--
-- // Create an RTP session to transmit the output of the
-- // processor to the specified IP address and port no.
-- result = createTransmitter();
-- if (result != null) {
-- processor.close();
-- processor = null;
-- started = false;
-- }
-- else {
-- started = true;
-- }
--
-- // Start the transmission
-- processor.start();
--
-- return null;
-- }
--
-- /**
-- * Stops the transmission if already started.
-- * Stops the receiver also.
-- */
-- public void stop() {
-- if (!started) return;
-- synchronized (this) {
-- try {
-- started = false;
-- if (processor != null) {
-- processor.stop();
-- processor = null;
--
-- for (RTPManager rtpMgr : rtpMgrs) {
-- rtpMgr.removeReceiveStreamListener(audioReceiver);
-- rtpMgr.removeSessionListener(audioReceiver);
-- rtpMgr.removeTargets("Session ended.");
-- rtpMgr.dispose();
-- }
--
-- sendStreams.clear();
--
-- }
-- }
-- catch (Exception e) {
-- e.printStackTrace();
-- }
-- }
-- }
--
-- private String createProcessor() {
-- if (locator == null)
-- return "Locator is null";
--
-- DataSource ds;
--
-- try {
-- ds = javax.media.Manager.createDataSource(locator);
-- }
-- catch (Exception e) {
-- // Try JavaSound Locator as a last resort
-- try {
-- ds = javax.media.Manager.createDataSource(new MediaLocator("javasound://"));
-- }
-- catch (Exception ee) {
-- return "Couldn't create DataSource";
-- }
-- }
--
-- // Try to create a processor to handle the input jmf locator
-- try {
-- processor = javax.media.Manager.createProcessor(ds);
-- }
-- catch (NoProcessorException npe) {
-- npe.printStackTrace();
-- return "Couldn't create processor";
-- }
-- catch (IOException ioe) {
-- ioe.printStackTrace();
-- return "IOException creating processor";
-- }
--
-- // Wait for it to configure
-- boolean result = waitForState(processor, Processor.Configured);
-- if (!result){
-- return "Couldn't configure processor";
-- }
--
-- // Get the tracks from the processor
-- TrackControl[] tracks = processor.getTrackControls();
--
-- // Do we have atleast one track?
-- if (tracks == null || tracks.length < 1){
-- return "Couldn't find tracks in processor";
-- }
--
-- // Set the output content descriptor to RAW_RTP
-- // This will limit the supported formats reported from
-- // Track.getSupportedFormats to only valid RTP formats.
-- ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
-- processor.setContentDescriptor(cd);
--
-- Format supported[];
-- Format chosen = null;
-- boolean atLeastOneTrack = false;
--
-- // Program the tracks.
-- for (int i = 0; i < tracks.length; i++) {
-- if (tracks[i].isEnabled()) {
--
-- supported = tracks[i].getSupportedFormats();
--
-- if (supported.length > 0) {
-- for (Format format : supported) {
-- if (format instanceof AudioFormat) {
-- if (this.format.matches(format))
-- chosen = format;
-- }
-- }
-- if (chosen != null) {
-- tracks[i].setFormat(chosen);
-- LOGGER.error("Track " + i + " is set to transmit as:");
-- LOGGER.error(" " + chosen);
--
-- if (tracks[i].getFormat() instanceof AudioFormat) {
-- int packetRate = 20;
-- PacketSizeControl pktCtrl = (PacketSizeControl) processor.getControl(PacketSizeControl.class.getName());
-- if (pktCtrl != null) {
-- try {
-- pktCtrl.setPacketSize(getPacketSize(tracks[i].getFormat(), packetRate));
-- }
-- catch (IllegalArgumentException e) {
-- pktCtrl.setPacketSize(80);
-- // Do nothing
-- }
-- }
--
-- if (tracks[i].getFormat().getEncoding().equals(AudioFormat.ULAW_RTP)) {
-- Codec codec[] = new Codec[3];
--
-- codec[0] = new com.ibm.media.codec.audio.rc.RCModule();
-- codec[1] = new com.ibm.media.codec.audio.ulaw.JavaEncoder();
-- codec[2] = new com.sun.media.codec.audio.ulaw.Packetizer();
-- ((com.sun.media.codec.audio.ulaw.Packetizer) codec
-- [2]).setPacketSize(160);
--
-- try {
-- tracks[i].setCodecChain(codec);
-- }
-- catch (UnsupportedPlugInException e) {
-- e.printStackTrace();
-- }
-- }
--
-- }
--
-- atLeastOneTrack = true;
-- }
-- else
-- tracks[i].setEnabled(false);
-- }
-- else
-- tracks[i].setEnabled(false);
-- }
-- }
--
-- if (!atLeastOneTrack)
-- return "Couldn't set any of the tracks to a valid RTP format";
--
-- result = waitForState(processor, Controller.Realized);
-- if (!result)
-- return "Couldn't realize processor";
--
-- // Get the output data source of the processor
-- dataOutput = processor.getDataOutput();
--
-- return null;
-- }
--
-- /**
-- * Get the best packet size for a given codec and a codec rate
-- *
-- * @param codecFormat
-- * @param milliseconds
-- * @return
-- * @throws IllegalArgumentException
-- */
-- private int getPacketSize(Format codecFormat, int milliseconds) throws IllegalArgumentException {
-- String encoding = codecFormat.getEncoding();
-- if (encoding.equalsIgnoreCase(AudioFormat.GSM) ||
-- encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) {
-- return milliseconds * 4; // 1 byte per millisec
-- }
-- else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) ||
-- encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) {
-- return milliseconds * 8;
-- }
-- else {
-- throw new IllegalArgumentException("Unknown codec type");
-- }
-- }
--
-- /**
-- * Use the RTPManager API to create sessions for each jmf
-- * track of the processor.
-- *
-- * @return description
-- */
-- private String createTransmitter() {
--
-- // Cheated. Should have checked the type.
-- PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;
-- PushBufferStream pbss[] = pbds.getStreams();
--
-- rtpMgrs = new RTPManager[pbss.length];
-- SessionAddress localAddr, destAddr;
-- InetAddress ipAddr;
-- SendStream sendStream;
-- audioReceiver = new AudioReceiver(this, jingleMediaSession);
-- int port;
--
-- for (int i = 0; i < pbss.length; i++) {
-- try {
-- rtpMgrs[i] = RTPManager.newInstance();
--
-- port = portBase + 2 * i;
-- ipAddr = InetAddress.getByName(remoteIpAddress);
--
-- localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress),
-- localPort);
--
-- destAddr = new SessionAddress(ipAddr, port);
--
-- rtpMgrs[i].addReceiveStreamListener(audioReceiver);
-- rtpMgrs[i].addSessionListener(audioReceiver);
--
-- BufferControl bc = (BufferControl) rtpMgrs[i].getControl("javax.media.control.BufferControl");
-- if (bc != null) {
-- int bl = 160;
-- bc.setBufferLength(bl);
-- }
--
-- try {
--
-- rtpMgrs[i].initialize(localAddr);
--
-- }
-- catch (InvalidSessionAddressException e) {
-- // In case the local address is not allowed to read, we user another local address
-- SessionAddress sessAddr = new SessionAddress();
-- localAddr = new SessionAddress(sessAddr.getDataAddress(),
-- localPort);
-- rtpMgrs[i].initialize(localAddr);
-- }
--
-- rtpMgrs[i].addTarget(destAddr);
--
-- LOGGER.error("Created RTP session at " + localPort + " to: " + remoteIpAddress + " " + port);
--
-- sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
--
-- sendStreams.add(sendStream);
--
-- sendStream.start();
--
-- }
-- catch (Exception e) {
-- e.printStackTrace();
-- return e.getMessage();
-- }
-- }
--
-- return null;
-- }
--
-- /**
-- * Set transmit activity. If the active is true, the instance should trasmit.
-- * If it is set to false, the instance should pause transmit.
-- *
-- * @param active active state
-- */
-- public void setTrasmit(boolean active) {
-- for (SendStream sendStream : sendStreams) {
-- try {
-- if (active) {
-- sendStream.start();
-- LOGGER.debug("START");
-- }
-- else {
-- sendStream.stop();
-- LOGGER.debug("STOP");
-- }
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
--
-- }
-- }
--
-- /**
-- * *************************************************************
-- * Convenience methods to handle processor's state changes.
-- * **************************************************************
-- */
--
-- private Integer stateLock = 0;
-- private boolean failed = false;
--
-- Integer getStateLock() {
-- return stateLock;
-- }
--
-- void setFailed() {
-- failed = true;
-- }
--
-- private synchronized boolean waitForState(Processor p, int state) {
-- p.addControllerListener(new StateListener());
-- failed = false;
--
-- // Call the required method on the processor
-- if (state == Processor.Configured) {
-- p.configure();
-- }
-- else if (state == Processor.Realized) {
-- p.realize();
-- }
--
-- // Wait until we get an event that confirms the
-- // success of the method, or a failure event.
-- // See StateListener inner class
-- while (p.getState() < state && !failed) {
-- synchronized (getStateLock()) {
-- try {
-- getStateLock().wait();
-- }
-- catch (InterruptedException ie) {
-- return false;
-- }
-- }
-- }
--
-- return !failed;
-- }
--
-- /**
-- * *************************************************************
-- * Inner Classes
-- * **************************************************************
-- */
--
-- class StateListener implements ControllerListener {
--
-- public void controllerUpdate(ControllerEvent ce) {
--
-- // If there was an error during configure or
-- // realize, the processor will be closed
-- if (ce instanceof ControllerClosedEvent)
-- setFailed();
--
-- // All controller events, send a notification
-- // to the waiting thread in waitForState method.
-- if (ce != null) {
-- synchronized (getStateLock()) {
-- getStateLock().notifyAll();
-- }
-- }
-- }
-- }
--
-- public static void main(String args[]) {
--
-- InetAddress localhost;
-- try {
-- localhost = InetAddress.getLocalHost();
--
-- AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP), null);
-- AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://8000"), localhost.getHostAddress(), localhost.getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP), null);
--
-- audioChannel0.start();
-- audioChannel1.start();
--
-- try {
-- Thread.sleep(5000);
-- }
-- catch (InterruptedException e) {
-- e.printStackTrace();
-- }
--
-- audioChannel0.setTrasmit(false);
-- audioChannel1.setTrasmit(false);
--
-- try {
-- Thread.sleep(5000);
-- }
-- catch (InterruptedException e) {
-- e.printStackTrace();
-- }
--
-- audioChannel0.setTrasmit(true);
-- audioChannel1.setTrasmit(true);
--
-- try {
-- Thread.sleep(5000);
-- }
-- catch (InterruptedException e) {
-- e.printStackTrace();
-- }
--
-- audioChannel0.stop();
-- audioChannel1.stop();
--
-- }
-- catch (UnknownHostException e) {
-- e.printStackTrace();
-- }
--
-- }
--}
-\ No newline at end of file
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java (working copy)
-@@ -1,55 +0,0 @@
--/**
-- * $RCSfile: AudioFormatUtils.java,v $
-- * $Revision: 1.1 $
-- * $Date: 08/11/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
--
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--
--import javax.media.format.AudioFormat;
--
--/**
-- * Audio Format Utils.
-- *
-- * @author Thiago Camargo
-- */
--public class AudioFormatUtils {
--
-- /**
-- * Return a JMF AudioFormat for a given Jingle Payload type.
-- * Return null if the payload is not supported by this jmf API.
-- *
-- * @param payloadtype payloadtype
-- * @return correspondent audioType
-- */
-- public static AudioFormat getAudioFormat(PayloadType payloadtype) {
--
-- switch (payloadtype.getId()) {
-- case 0:
-- return new AudioFormat(AudioFormat.ULAW_RTP);
-- case 3:
-- return new AudioFormat(AudioFormat.GSM_RTP);
-- case 4:
-- return new AudioFormat(AudioFormat.G723_RTP);
-- default:
-- return null;
-- }
--
-- }
--
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java (working copy)
-@@ -1,134 +0,0 @@
--/**
-- * $RCSfile: SpeexMediaManager.java,v $
-- * $Revision: 1.3 $
-- * $Date: 25/12/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--package org.jivesoftware.smackx.jingle.mediaimpl.jspeex;
--
--import java.io.File;
--import java.io.IOException;
--import java.util.ArrayList;
--import java.util.List;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.mediaimpl.JMFInit;
--import org.jivesoftware.smackx.jingle.nat.JingleTransportManager;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--/**
-- * Implements a jingleMediaManager using JMF based API and JSpeex.
-- * It supports Speex codec.
-- * <i>This API only currently works on windows.</i>
-- *
-- * @author Thiago Camargo
-- */
--public class SpeexMediaManager extends JingleMediaManager {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(SpeexMediaManager.class);
--
-- public static final String MEDIA_NAME = "Speex";
--
-- private List<PayloadType> payloads = new ArrayList<PayloadType>();
--
-- public SpeexMediaManager(JingleTransportManager transportManager) {
-- super(transportManager);
-- setupPayloads();
-- setupJMF();
-- }
--
-- /**
-- * Returns a new jingleMediaSession
-- *
-- * @param payloadType payloadType
-- * @param remote remote Candidate
-- * @param local local Candidate
-- * @return JingleMediaSession
-- */
-- public JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
-- return new AudioMediaSession(payloadType, remote, local, null,null);
-- }
--
-- /**
-- * Setup API supported Payloads
-- */
-- private void setupPayloads() {
-- payloads.add(new PayloadType.Audio(15, "speex"));
-- }
--
-- /**
-- * Return all supported Payloads for this Manager
-- *
-- * @return The Payload List
-- */
-- public List<PayloadType> getPayloads() {
-- return payloads;
-- }
--
-- /**
-- * Runs JMFInit the first time the application is started so that capture
-- * devices are properly detected and initialized by JMF.
-- */
-- public static void setupJMF() {
-- // .jmf is the place where we store the jmf.properties file used
-- // by JMF. if the directory does not exist or it does not contain
-- // a jmf.properties file. or if the jmf.properties file has 0 length
-- // then this is the first time we're running and should continue to
-- // with JMFInit
-- String homeDir = System.getProperty("user.home");
-- File jmfDir = new File(homeDir, ".jmf");
-- String classpath = System.getProperty("java.class.path");
-- classpath += System.getProperty("path.separator")
-- + jmfDir.getAbsolutePath();
-- System.setProperty("java.class.path", classpath);
--
-- if (!jmfDir.exists())
-- jmfDir.mkdir();
--
-- File jmfProperties = new File(jmfDir, "jmf.properties");
--
-- if (!jmfProperties.exists()) {
-- try {
-- jmfProperties.createNewFile();
-- }
-- catch (IOException ex) {
-- LOGGER.debug("Failed to create jmf.properties");
-- ex.printStackTrace();
-- }
-- }
--
-- // if we're running on linux checkout that libjmutil.so is where it
-- // should be and put it there.
-- runLinuxPreInstall();
--
-- if (jmfProperties.length() == 0) {
-- new JMFInit(null, false);
-- }
--
-- }
--
-- private static void runLinuxPreInstall() {
-- // @TODO Implement Linux Pre-Install
-- }
--
-- public String getName() {
-- return MEDIA_NAME;
-- }
--}
-Index: org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java
-===================================================================
---- org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java (revision 11644)
-+++ org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java (working copy)
-@@ -1,245 +0,0 @@
--/**
-- * $RCSfile: AudioMediaSession.java,v $
-- * $Revision: 1.1 $
-- * $Date: 25/12/2006
-- * <p/>
-- * Copyright 2003-2006 Jive Software.
-- * <p/>
-- * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
-- * you may not use this file except in compliance with the License.
-- * You may obtain a copy of the License at
-- * <p/>
-- * http://www.apache.org/licenses/LICENSE-2.0
-- * <p/>
-- * Unless required by applicable law or agreed to in writing, software
-- * distributed under the License is distributed on an "AS IS" BASIS,
-- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- * See the License for the specific language governing permissions and
-- * limitations under the License.
-- */
--
--package org.jivesoftware.smackx.jingle.mediaimpl.jspeex;
--
--import java.io.IOException;
--import java.net.DatagramSocket;
--import java.net.InetAddress;
--import java.net.ServerSocket;
--import java.security.GeneralSecurityException;
--
--import javax.media.NoProcessorException;
--import javax.media.format.UnsupportedFormatException;
--import javax.media.rtp.rtcp.SenderReport;
--import javax.media.rtp.rtcp.SourceDescription;
--
--import mil.jfcom.cie.media.session.MediaSession;
--import mil.jfcom.cie.media.session.MediaSessionListener;
--import mil.jfcom.cie.media.session.StreamPlayer;
--import mil.jfcom.cie.media.srtp.packetizer.SpeexFormat;
--
--import org.jivesoftware.smackx.jingle.JingleSession;
--import org.jivesoftware.smackx.jingle.SmackLogger;
--import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
--import org.jivesoftware.smackx.jingle.media.PayloadType;
--import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
--
--/**
-- * This Class implements a complete JingleMediaSession.
-- * It sould be used to transmit and receive audio captured from the Mic.
-- * This Class should be automaticly controlled by JingleSession.
-- * But you could also use in any VOIP application.
-- * For better NAT Traversal support this implementation don't support only receive or only transmit.
-- * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
-- *
-- * @author Thiago Camargo
-- */
--
--public class AudioMediaSession extends JingleMediaSession implements MediaSessionListener {
--
-- private static final SmackLogger LOGGER = SmackLogger.getLogger(AudioMediaSession.class);
--
-- private MediaSession mediaSession;
--
-- /**
-- * Create a Session using Speex Codec
-- *
-- * @param localhost localHost
-- * @param localPort localPort
-- * @param remoteHost remoteHost
-- * @param remotePort remotePort
-- * @param eventHandler eventHandler
-- * @param quality quality
-- * @param secure secure
-- * @param micOn micOn
-- * @return MediaSession
-- * @throws NoProcessorException
-- * @throws UnsupportedFormatException
-- * @throws IOException
-- * @throws GeneralSecurityException
-- */
-- public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException {
--
-- SpeexFormat.setFramesPerPacket(1);
-- /**
-- * The master key. Hardcoded for now.
-- */
-- byte[] masterKey = new byte[]{(byte) 0xE1, (byte) 0xF9, 0x7A, 0x0D, 0x3E, 0x01, (byte) 0x8B, (byte) 0xE0, (byte) 0xD6, 0x4F, (byte) 0xA3, 0x2C, 0x06, (byte) 0xDE, 0x41, 0x39};
--
-- /**
-- * The master salt. Hardcoded for now.
-- */
-- byte[] masterSalt = new byte[]{0x0E, (byte) 0xC6, 0x75, (byte) 0xAD, 0x49, (byte) 0x8A, (byte) 0xFE, (byte) 0xEB, (byte) 0xB6, (byte) 0x96, 0x0B, 0x3A, (byte) 0xAB, (byte) 0xE6};
--
-- DatagramSocket[] localPorts = MediaSession.getLocalPorts(InetAddress.getByName(localhost), localPort);
-- MediaSession session = MediaSession.createInstance(remoteHost, remotePort, localPorts, quality, secure, masterKey, masterSalt);
-- session.setListener(eventHandler);
--
-- session.setSourceDescription(new SourceDescription[]{new SourceDescription(SourceDescription.SOURCE_DESC_NAME, "Superman", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_EMAIL, "cdcie.tester@je.jfcom.mil", 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_LOC, InetAddress.getByName(localhost) + " Port " + session.getLocalDataPort(), 1, false), new SourceDescription(SourceDescription.SOURCE_DESC_TOOL, "JFCOM CDCIE Audio Chat", 1, false)});
-- return session;
-- }
--
--
-- /**
-- * Creates a org.jivesoftware.jingleaudio.jspeex.AudioMediaSession with defined payload type, remote and local candidates
-- *
-- * @param payloadType Payload of the jmf
-- * @param remote the remote information. The candidate that the jmf will be sent to.
-- * @param local the local information. The candidate that will receive the jmf
-- * @param locator media locator
-- */
-- public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
-- final TransportCandidate local, String locator, JingleSession jingleSession) {
-- super(payloadType, remote, local, locator == null ? "dsound://" : locator, jingleSession);
-- initialize();
-- }
--
-- /**
-- * Initialize the Audio Channel to make it able to send and receive audio
-- */
-- public void initialize() {
--
-- String ip;
-- String localIp;
-- int localPort;
-- int remotePort;
--
-- if (this.getLocal().getSymmetric() != null) {
-- ip = this.getLocal().getIp();
-- localIp = this.getLocal().getLocalIp();
-- localPort = getFreePort();
-- remotePort = this.getLocal().getSymmetric().getPort();
--
-- LOGGER.debug(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort);
--
-- }
-- else {
-- ip = this.getRemote().getIp();
-- localIp = this.getLocal().getLocalIp();
-- localPort = this.getLocal().getPort();
-- remotePort = this.getRemote().getPort();
-- }
--
-- try {
-- mediaSession = createSession(localIp, localPort, ip, remotePort, this, 2, false, true);
-- }
-- catch (NoProcessorException e) {
-- e.printStackTrace();
-- }
-- catch (UnsupportedFormatException e) {
-- e.printStackTrace();
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- catch (GeneralSecurityException e) {
-- e.printStackTrace();
-- }
-- }
--
-- /**
-- * Starts transmission and for NAT Traversal reasons start receiving also.
-- */
-- public void startTrasmit() {
-- try {
-- LOGGER.debug("start");
-- mediaSession.start(true);
-- this.mediaReceived("");
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- }
--
-- /**
-- * Set transmit activity. If the active is true, the instance should trasmit.
-- * If it is set to false, the instance should pause transmit.
-- *
-- * @param active active state
-- */
-- public void setTrasmit(boolean active) {
-- // Do nothing
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void startReceive() {
-- // Do nothing
-- }
--
-- /**
-- * Stops transmission and for NAT Traversal reasons stop receiving also.
-- */
-- public void stopTrasmit() {
-- if (mediaSession != null)
-- mediaSession.close();
-- }
--
-- /**
-- * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
-- */
-- public void stopReceive() {
-- // Do nothing
-- }
--
-- public void newStreamIdentified(StreamPlayer streamPlayer) {
-- }
--
-- public void senderReportReceived(SenderReport report) {
-- }
--
-- public void streamClosed(StreamPlayer stream, boolean timeout) {
-- }
--
-- /**
-- * Obtain a free port we can use.
-- *
-- * @return A free port number.
-- */
-- protected int getFreePort() {
-- ServerSocket ss;
-- int freePort = 0;
--
-- for (int i = 0; i < 10; i++) {
-- freePort = (int) (10000 + Math.round(Math.random() * 10000));
-- freePort = freePort % 2 == 0 ? freePort : freePort + 1;
-- try {
-- ss = new ServerSocket(freePort);
-- freePort = ss.getLocalPort();
-- ss.close();
-- return freePort;
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- }
-- try {
-- ss = new ServerSocket(0);
-- freePort = ss.getLocalPort();
-- ss.close();
-- }
-- catch (IOException e) {
-- e.printStackTrace();
-- }
-- return freePort;
-- }
--}