?? avtransmitter.java
字號:
package net.java.mais.media;
/**
* <p>Title: Netsite TudoMais</p>
* <p>Description:JAIN-SIP Audio/Video phone application</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Organisation: CTBC Telecom / Netsite </p>
* @author Thiago Rocha Camargo (barata7@yahoo.com)
*/
/**
* <p>Title: SIP COMMUNICATOR</p>
* <p>Description:JAIN-SIP Audio/Video phone application</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Organisation: LSIIT laboratory (http://lsiit.u-strasbg.fr) </p>
* <p>Network Research Team (http://www-r2.u-strasbg.fr))</p>
* <p>Louis Pasteur University - Strasbourg - France</p>
* @author Emil Ivov (http://www.emcho.com)
* @author Paulo Pizzarro ( added support for media level connection parameter)
* @version 1.1
*
*/
import java.awt.Dimension;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Vector;
import javax.media.Codec;
import javax.media.Control;
import javax.media.Controller;
import javax.media.ControllerClosedEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.EndOfMediaEvent;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Owned;
import javax.media.Player;
import javax.media.Processor;
import javax.media.Time;
import javax.media.control.QualityControl;
import javax.media.control.TrackControl;
import javax.media.format.VideoFormat;
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 javax.media.rtp.rtcp.SourceDescription;
import javax.swing.JFrame;
public class AVTransmitter
{
// Input MediaLocator
// Can be a file or http or capture source
protected MediaLocator locator;
protected ArrayList ipAddresses = null;
protected Processor processor = null;
protected RTPManager rtpMgrs[];
protected AVReceiverMais avReceiver[];
//Used by mobility - keeps rtpMgrs[] corresponding addresses
protected SessionAddress sessionAddresses[] = null;
public Vector sendStreams;
protected DataSource dataOutput = null;
protected ArrayList ports = null;
protected ArrayList formatSets = null;
protected ArrayList contents = null;
protected ArrayList localPorts = null;
protected MediaManager mediaManCallback = null;
public int thePort=10001;
public AVTransmitter(Processor processor,
ArrayList ipAddresses,
ArrayList ports,
ArrayList formatSets,
ArrayList contents,
ArrayList localPorts)
{
try {
sendStreams=new Vector();
this.processor = processor;
this.ipAddresses = ipAddresses;
this.ports = ports;
this.formatSets = formatSets;
this.contents = contents;
this.localPorts = localPorts;
}
finally {
}
}
void setMediaManagerCallback(MediaManager mediaManager)
{
this.mediaManCallback = mediaManager;
}
/**
* Starts the transmission. Returns null if transmission started ok.
* Otherwise it returns a string with the reason why the setup failed.
*/
synchronized String start() throws MediaException
{
try {
String result;
configureProcessor();
// Create an RTP session to transmit the output of the
// processor to the specified IP address and port no.
try {
createTransmitter();
}
catch (MediaException ex) {
processor.close();
processor = null;
throw ex;
}
// Start the transmission
processor.start();
return null;
}
finally {
}
}
/**
* Stops the transmission if already started
*/
void stop()
{
try {
synchronized (this) {
if (processor != null) {
processor.stop();
if (rtpMgrs != null) {
for (int i = 0; i < rtpMgrs.length; i++) {
if (rtpMgrs[i] == null) {
continue;
}
rtpMgrs[i].removeTargets("Session ended.");
rtpMgrs[i].dispose();
}
}
}
}
}
finally {
}
}
protected void configureProcessor() throws MediaException
{
try {
if (processor == null) {
throw new MediaException("Processor is null.");
}
// Wait for the processor to configure
boolean result = true;
if (processor.getState() < Processor.Configured) {
result = waitForState(processor, Processor.Configured);
}
if (result == false) {
throw new MediaException("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) {
throw new MediaException("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 chosenFormat;
boolean atLeastOneTrack = false;
// Program the tracks.
for (int i = 0; i < tracks.length; i++) {
Format format = tracks[i].getFormat();
if (tracks[i].isEnabled()) {
supported = tracks[i].getSupportedFormats();
// We've set the output content to the RAW_RTP.
// So all the supported formats should work with RTP.
// We'll pick one that matches those specified by the constructor.
if (supported.length > 0) {
if (supported[0] instanceof VideoFormat) {
// For video formats, we should double check the
// sizes since not all formats work in all sizes.
int index = findFirstMatchingFormat(supported,
formatSets);
if (index != -1) {
chosenFormat = checkForVideoSizes(tracks[i].
getFormat(),
supported[index]);
tracks[i].setFormat(chosenFormat);
atLeastOneTrack = true;
}
else {
tracks[i].setEnabled(false);
}
}
else {
int index = findFirstMatchingFormat(supported,
formatSets);
if (index != -1) {
tracks[i].setFormat(supported[index]);
atLeastOneTrack = true;
}
else {
tracks[i].setEnabled(false);
}
}
}
else {
tracks[i].setEnabled(false);
}
}
else {
tracks[i].setEnabled(false);
}
}
if (!atLeastOneTrack) {
throw new MediaException(
"Couldn't set any of the tracks to a valid RTP format");
}
// Realize the processor. This will internally create a flow
// graph and attempt to create an output datasource
result = waitForState(processor, Controller.Realized);
if (result == false) {
throw new MediaException("Couldn't realize processor");
}
// Set the JPEG quality to .5.
//TODO set the jpeg quality through a property
setJPEGQuality(processor, 1f);
// Get the output data source of the processor
dataOutput = processor.getDataOutput();
}
finally {
}
}
public void setTrack(boolean set){
TrackControl[] tracks = processor.getTrackControls();
if (tracks == null || tracks.length < 1) {
return;
}
Format supported[];
boolean atLeastOneTrack = false;
for (int i = 0; i < tracks.length; i++) {
Format format = tracks[i].getFormat();
if (tracks[i].isEnabled()) {
supported = tracks[i].getSupportedFormats();
if (supported.length > 0) {
if (supported[0] instanceof VideoFormat) {
tracks[i].setEnabled(set);
System.out.println("VIDEO: "+set);
}
}
}
}
}
/**
* Use the RTPManager API to create sessions for each media
* track of the processor.
*/
protected void createTransmitter() throws MediaException
{
try {
PushBufferDataSource pbds = (PushBufferDataSource) dataOutput;
PushBufferStream pbss[] = pbds.getStreams();
rtpMgrs = new RTPManager[pbss.length];
avReceiver = new AVReceiverMais[pbss.length];
//used by mobility
sessionAddresses = new SessionAddress[pbss.length];
SessionAddress localAddr, destAddr;
InetAddress remoteAddress;
SendStream sendStream;
SourceDescription srcDesList[];
int port = 0;
String format = null;
String ipAddress = null;
try {
for (int i = 0; i < pbss.length; i++) {
try {
format = pbss[i].getFormat().getEncoding();
ipAddress = findIPAddressForFormat(format);
if(ipAddress == null) {
throw new MediaException(
"Internal error! AVTransmitter failed to find a"
+ " format's corresponding ipAddress");
}
remoteAddress = InetAddress.getByName(ipAddress);
}
catch (UnknownHostException ex) {
throw new MediaException("Failed to resolve remote address",
ex);
}
port = findPortForFormat(format);
if (port == -1) {
throw new MediaException(
"Internal error! AVTransmitter failed to find a"
+ " format's corresponding port");
}
// first try to bind to same port we're talking to for firewall
// support if that fails go for a random one
// which will be randomly changed and retried retryCount times.
// (erroneous comment reported by Joe.Provino at Sun.COM)
boolean success = true;
boolean createdRtpManager = false;
int retries = 4; // 4 retries
do {
success = true;
int localPort = 0;
if(retries == 4)
localPort = port;
else
localPort = (int) (63976 * Math.random()) + 1024;
thePort=localPort;
//localPort = Integer.parseInt(mediaManCallback.audioPort);
//localPort = Integer.parseInt(mediaManCallback.audioPort);
localPort = findPortForFormat(format);
localAddr = new SessionAddress(mediaManCallback.
getLocalHost(), localPort);
destAddr = new SessionAddress(remoteAddress, port);
rtpMgrs[i] = mediaManCallback.getRtpManager(localAddr);
if(rtpMgrs[i] == null)
{
rtpMgrs[i] = RTPManager.newInstance();
createdRtpManager = true;
}
else
{
success = true;
break;
}
try {
/////////////////////////////////////////////////////////
ArrayList sessions = new ArrayList();
String mediaType = null;
AVTransmitter at = this;
int remoteAudio = at.findPortForLocal(Integer.parseInt(mediaManCallback.getAudioPort()));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -