基于JMF RTP的音视频传输

<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->
importjava.io.
* ;
importjava.awt.
* ;
importjava.net.
* ;
importjava.awt.
event . * ;
importjava.util.Vector;

importjavax.media.
* ;
importjavax.media.rtp.
* ;
importjavax.media.rtp.
event . * ;
importjavax.media.rtp.rtcp.
* ;
importjavax.media.protocol.
* ;
importjavax.media.protocol.DataSource;
importjavax.media.format.AudioFormat;
importjavax.media.format.VideoFormat;
importjavax.media.Format;
importjavax.media.format.FormatChangeEvent;
importjavax.media.control.BufferControl;


/* *
*AVReceive3toreceiveRTPtransmissionusingtheRTPConnector.
*/
public class AVReceive3implementsReceiveStreamListener,SessionListener,
ControllerListener
{
Stringsessions[]
= null ;
RTPManagermgrs[]
= null ;
VectorplayerWindows
= null ;

booleandataReceived
= false ;
ObjectdataSync
= new Object();


public AVReceive3(Stringsessions[]){
this .sessions = sessions;
}

protected booleaninitialize(){

try {
mgrs
= new RTPManager[sessions.length];
playerWindows
= new Vector();

SessionLabelsession;

// OpentheRTPsessions.
for ( int i = 0 ;i < sessions.length;i ++ ){

// Parsethesessionaddresses.
try {
session
= new SessionLabel(sessions[i]);
}
catch (IllegalArgumentExceptione){
System.err.println(
" Failedtoparsethesessionaddressgiven: " + sessions[i]);
return false ;
}

System.err.println(
" -OpenRTPsessionfor:addr: " + session.addr + " port: " + session.port + " ttl: " + session.ttl);

mgrs[i]
= (RTPManager)RTPManager.newInstance();
mgrs[i].addSessionListener(
this );
mgrs[i].addReceiveStreamListener(
this );

// InitializetheRTPManagerwiththeRTPSocketAdapter
mgrs[i].initialize( new RTPSocketAdapter(
InetAddress.getByName(session.addr),
session.port,session.ttl));

// Youcantryoutsomeotherbuffersizetosee
// ifyoucangetbettersmoothness.
BufferControlbc = (BufferControl)mgrs[i].getControl( " javax.media.control.BufferControl " );
if (bc != null )
bc.setBufferLength(
350 );
}

}
catch (Exceptione){
System.err.println(
" CannotcreatetheRTPSession: " + e.getMessage());
return false ;
}

// Waitfordatatoarrivebeforemovingon.

long then = System.currentTimeMillis();
long waitingPeriod = 30000 ; // waitforamaximumof30secs.

try {
synchronized(dataSync){
while ( ! dataReceived &&
System.currentTimeMillis()
- then < waitingPeriod){
if ( ! dataReceived)
System.err.println(
" -WaitingforRTPdatatoarrivedot.gif " );
dataSync.wait(
1000 );
}
}
}
catch (Exceptione){}

if ( ! dataReceived){
System.err.println(
" NoRTPdatawasreceived. " );
close();
return false ;
}

return true ;
}


public booleanisDone(){
return playerWindows.size() == 0 ;
}


/* *
*Closetheplayersandthesessionmanagers.
*/
protected void close(){

for ( int i = 0 ;i < playerWindows.size();i ++ ){
try {
((PlayerWindow)playerWindows.elementAt(i)).close();
}
catch (Exceptione){}
}

playerWindows.removeAllElements();

// closetheRTPsession.
for ( int i = 0 ;i < mgrs.length;i ++ ){
if (mgrs[i] != null ){
mgrs[i].removeTargets(
" ClosingsessionfromAVReceive3 " );
mgrs[i].dispose();
mgrs[i]
= null ;
}
}
}


PlayerWindowfind(Playerp){
for ( int i = 0 ;i < playerWindows.size();i ++ ){
PlayerWindowpw
= (PlayerWindow)playerWindows.elementAt(i);
if (pw.player == p)
return pw;
}
return null ;
}


PlayerWindowfind(ReceiveStreamstrm){
for ( int i = 0 ;i < playerWindows.size();i ++ ){
PlayerWindowpw
= (PlayerWindow)playerWindows.elementAt(i);
if (pw.stream == strm)
return pw;
}
return null ;
}


/* *
*SessionListener.
*/
public synchronized void update(SessionEventevt){
if (evtinstanceofNewParticipantEvent){
Participantp
= ((NewParticipantEvent)evt).getParticipant();
System.err.println(
" -Anewparticipanthadjustjoined: " + p.getCNAME());
}
}


/* *
*ReceiveStreamListener
*/
public synchronized void update(ReceiveStreamEventevt){

RTPManagermgr
= (RTPManager)evt.getSource();
Participantparticipant
= evt.getParticipant(); // couldbenull.
ReceiveStreamstream = evt.getReceiveStream(); // couldbenull.

if (evtinstanceofRemotePayloadChangeEvent){

System.err.println(
" -ReceivedanRTPPayloadChangeEvent. " );
System.err.println(
" Sorry,cannothandlepayloadchange. " );
System.exit(
0 );

}

else if (evtinstanceofNewReceiveStreamEvent){

try {
stream
= ((NewReceiveStreamEvent)evt).getReceiveStream();
DataSourceds
= stream.getDataSource();

// Findouttheformats.
RTPControlctl = (RTPControl)ds.getControl( " javax.media.rtp.RTPControl " );
if (ctl != null ){
System.err.println(
" -ReceviednewRTPstream: " + ctl.getFormat());
}
else
System.err.println(
" -ReceviednewRTPstream " );

if (participant == null )
System.err.println(
" Thesenderofthisstreamhadyettobeidentified. " );
else {
System.err.println(
" Thestreamcomesfrom: " + participant.getCNAME());
}

// createaplayerbypassingdatasourcetotheMediaManager
Playerp = javax.media.Manager.createPlayer(ds);
if (p == null )
return ;

p.addControllerListener(
this );
p.realize();
PlayerWindowpw
= new PlayerWindow(p,stream);
playerWindows.addElement(pw);

// Notifyintialize()thatanewstreamhadarrived.
synchronized(dataSync){
dataReceived
= true ;
dataSync.notifyAll();
}

}
catch (Exceptione){
System.err.println(
" NewReceiveStreamEventexception " + e.getMessage());
return ;
}

}

else if (evtinstanceofStreamMappedEvent){

if (stream != null && stream.getDataSource() != null ){
DataSourceds
= stream.getDataSource();
// Findouttheformats.
RTPControlctl = (RTPControl)ds.getControl( " javax.media.rtp.RTPControl " );
System.err.println(
" -Thepreviouslyunidentifiedstream " );
if (ctl != null )
System.err.println(
" " + ctl.getFormat());
System.err.println(
" hadnowbeenidentifiedassentby: " + participant.getCNAME());
}
}

else if (evtinstanceofByeEvent){

System.err.println(
" -Got/ " bye/ " from: " + participant.getCNAME());
PlayerWindowpw
= find(stream);
if (pw != null ){
pw.close();
playerWindows.removeElement(pw);
}
}

}


/* *
*ControllerListenerforthePlayers.
*/
public synchronized void controllerUpdate(ControllerEventce){

Playerp
= (Player)ce.getSourceController();

if (p == null )
return ;

// Getthiswhentheinternalplayersarerealized.
if (ceinstanceofRealizeCompleteEvent){
PlayerWindowpw
= find(p);
if (pw == null ){
// Somestrangehappened.
System.err.println( " Internalerror! " );
System.exit(
- 1 );
}
pw.initialize();
pw.setVisible(
true );
p.start();
}

if (ceinstanceofControllerErrorEvent){
p.removeControllerListener(
this );
PlayerWindowpw
= find(p);
if (pw != null ){
pw.close();
playerWindows.removeElement(pw);
}
System.err.println(
" AVReceive3internalerror: " + ce);
}

}


/* *
*Autilityclasstoparsethesessionaddresses.
*/
class SessionLabel{

public Stringaddr = null ;
public int port;
public int ttl = 1 ;

SessionLabel(Stringsession)throwsIllegalArgumentException{

int off;
StringportStr
= null ,ttlStr = null ;

if (session != null && session.length() > 0 ){
while (session.length() > 1 && session.charAt( 0 ) == ' / ' )
session
= session.substring( 1 );

// Nowseeifthere'saaddrspecified.
off = session.indexOf( ' / ' );
if (off == - 1 ){
if ( ! session.equals( "" ))
addr
= session;
}
else {
addr
= session.substring( 0 ,off);
session
= session.substring(off + 1 );
// Nowseeifthere'saportspecified
off = session.indexOf( ' / ' );
if (off == - 1 ){
if ( ! session.equals( "" ))
portStr
= session;
}
else {
portStr
= session.substring( 0 ,off);
session
= session.substring(off + 1 );
// Nowseeifthere'sattlspecified
off = session.indexOf( ' / ' );
if (off == - 1 ){
if ( ! session.equals( "" ))
ttlStr
= session;
}
else {
ttlStr
= session.substring( 0 ,off);
}
}
}
}

if (addr == null )
throw new IllegalArgumentException();

if (portStr != null ){
try {
Integerinteger
= Integer.valueOf(portStr);
if (integer != null )
port
= integer.intValue();
}
catch (Throwablet){
throw new IllegalArgumentException();
}
}
else
throw new IllegalArgumentException();

if (ttlStr != null ){
try {
Integerinteger
= Integer.valueOf(ttlStr);
if (integer != null )
ttl
= integer.intValue();
}
catch (Throwablet){
throw new IllegalArgumentException();
}
}
}
}


/* *
*GUIclassesforthePlayer.
*/
class PlayerWindowextendsFrame{

Playerplayer;
ReceiveStreamstream;

PlayerWindow(Playerp,ReceiveStreamstrm){
player
= p;
stream
= strm;
}

public void initialize(){
add(
new PlayerPanel(player));
}

public void close(){
player.close();
setVisible(
false );
dispose();
}

public void addNotify(){
super.addNotify();
pack();
}
}


/* *
*GUIclassesforthePlayer.
*/
class PlayerPanelextendsPanel{

Componentvc,cc;

PlayerPanel(Playerp){
setLayout(
new BorderLayout());
if ((vc = p.getVisualComponent()) != null )
add(
" Center " ,vc);
if ((cc = p.getControlPanelComponent()) != null )
add(
" South " ,cc);
}

public DimensiongetPreferredSize(){
int w = 0 ,h = 0 ;
if (vc != null ){
Dimensionsize
= vc.getPreferredSize();
w
= size.width;
h
= size.height;
}
if (cc != null ){
Dimensionsize
= cc.getPreferredSize();
if (w == 0 )
w
= size.width;
h
+= size.height;
}
if (w < 160 )
w
= 160 ;
return new Dimension(w,h);
}
}


public static void main(Stringargv[]){
if (argv.length == 0 )
prUsage();

AVReceive3avReceive
= new AVReceive3(argv);
if ( ! avReceive.initialize()){
System.err.println(
" Failedtoinitializethesessions. " );
System.exit(
- 1 );
}

// ChecktoseeifAVReceive3isdone.
try {
while ( ! avReceive.isDone())
Thread.sleep(
1000 );
}
catch (Exceptione){}

System.err.println(
" ExitingAVReceive3 " );
}


static void prUsage(){
System.err.println(
" Usage:AVReceive3<session><session>dot.gif " );
System.err.println(
" <session>:<address>/<port>/<ttl> " );
System.exit(
0 );
}

}
// endofAVReceive3

发送端代码:

<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> importjava.awt. * ;
importjava.io.
* ;
importjava.net.InetAddress;
importjavax.media.
* ;
importjavax.media.protocol.
* ;
importjavax.media.protocol.DataSource;
importjavax.media.format.
* ;
importjavax.media.control.TrackControl;
importjavax.media.control.QualityControl;
importjavax.media.rtp.
* ;
importjavax.media.rtp.rtcp.
* ;
importcom.sun.media.rtp.
* ;

public class AVTransmit3{

// InputMediaLocator
// Canbeafileorhttporcapturesource
private MediaLocatorlocator;
private StringipAddress;
private int portBase;

private Processorprocessor = null ;
private RTPManagerrtpMgrs[];
private DataSourcedataOutput = null ;

public AVTransmit3(MediaLocatorlocator,
StringipAddress,
Stringpb,
Formatformat){

this .locator = locator;
this .ipAddress = ipAddress;
Integerinteger
= Integer.valueOf(pb);
if (integer != null )
this .portBase = integer.intValue();
}

/* *
*Startsthetransmission.Returnsnulliftransmissionstartedok.
*Otherwiseitreturnsastringwiththereasonwhythesetupfailed.
*/
public synchronizedStringstart(){
Stringresult;

// Createaprocessorforthespecifiedmedialocator
// andprogramittooutputJPEG/RTP
result = createProcessor();
if (result != null )
return result;

// CreateanRTPsessiontotransmittheoutputofthe
// processortothespecifiedIPaddressandportno.
result = createTransmitter();
if (result != null ){
processor.close();
processor
= null ;
return result;
}

// Startthetransmission
processor.start();

return null ;
}

/* *
*Stopsthetransmissionifalreadystarted
*/
public void stop(){
synchronized(
this ){
if (processor != null ){
processor.stop();
processor.close();
processor
= null ;
for ( int i = 0 ;i < rtpMgrs.length;i ++ ){
rtpMgrs[i].removeTargets(
" Sessionended. " );
rtpMgrs[i].dispose();
}
}
}
}

private StringcreateProcessor(){
if (locator == null )
return " Locatorisnull " ;

DataSourceds;
DataSourceclone;

try {
ds
= javax.media.Manager.createDataSource(locator);
}
catch (Exceptione){
return " Couldn'tcreateDataSource " ;
}

// Trytocreateaprocessortohandletheinputmedialocator
try {
processor
= javax.media.Manager.createProcessor(ds);
}
catch (NoProcessorExceptionnpe){
return " Couldn'tcreateprocessor " ;
}
catch (IOExceptionioe){
return " IOExceptioncreatingprocessor " ;
}

// Waitforittoconfigure
booleanresult = waitForState(processor,Processor.Configured);
if (result == false )
return " Couldn'tconfigureprocessor " ;

// Getthetracksfromtheprocessor
TrackControl[]tracks = processor.getTrackControls();

// Dowehaveatleastonetrack?
if (tracks == null || tracks.length < 1 )
return " Couldn'tfindtracksinprocessor " ;

// SettheoutputcontentdescriptortoRAW_RTP
// Thiswilllimitthesupportedformatsreportedfrom
// Track.getSupportedFormatstoonlyvalidRTPformats.
ContentDescriptorcd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
processor.setContentDescriptor(cd);

Formatsupported[];
Formatchosen;
booleanatLeastOneTrack
= false ;

// Programthetracks.
for ( int i = 0 ;i < tracks.length;i ++ ){
Formatformat
= tracks[i].getFormat();
if (tracks[i].isEnabled()){

supported
= tracks[i].getSupportedFormats();

// We'vesettheoutputcontenttotheRAW_RTP.
// SoallthesupportedformatsshouldworkwithRTP.
// We'lljustpickthefirstone.

if (supported.length > 0 ){
if (supported[ 0 ]instanceofVideoFormat){
// Forvideoformats,weshoulddoublecheckthe
// sizessincenotallformatsworkinallsizes.
chosen = checkForVideoSizes(tracks[i].getFormat(),
supported[
0 ]);
}
else
chosen
= supported[ 0 ];
tracks[i].setFormat(chosen);
System.err.println(
" Track " + i + " issettotransmitas: " );
System.err.println(
" " + chosen);
atLeastOneTrack
= true ;
}
else
tracks[i].setEnabled(
false );
}
else
tracks[i].setEnabled(
false );
}

if ( ! atLeastOneTrack)
return " Couldn'tsetanyofthetrackstoavalidRTPformat " ;

// Realizetheprocessor.Thiswillinternallycreateaflow
// graphandattempttocreateanoutputdatasourceforJPEG/RTP
// audioframes.
result = waitForState(processor,Controller.Realized);
if (result == false )
return " Couldn'trealizeprocessor " ;

// SettheJPEGqualityto.5.
setJPEGQuality(processor, 0.5f );

// Gettheoutputdatasourceoftheprocessor
dataOutput = processor.getDataOutput();

return null ;
}


/* *
*UsetheRTPManagerAPItocreatesessionsforeachmedia
*trackoftheprocessor.
*/
private StringcreateTransmitter(){

// Cheated.Shouldhavecheckedthetype.
PushBufferDataSourcepbds = (PushBufferDataSource)dataOutput;
PushBufferStreampbss[]
= pbds.getStreams();

rtpMgrs
= new RTPManager[pbss.length];
SendStreamsendStream;
int port;
SourceDescriptionsrcDesList[];

for ( int i = 0 ;i < pbss.length;i ++ ){
try {
rtpMgrs[i]
= RTPManager.newInstance();

port
= portBase + 2 * i;

// InitializetheRTPManagerwiththeRTPSocketAdapter
rtpMgrs[i].initialize( new RTPSocketAdapter(
InetAddress.getByName(ipAddress),
port));

System.err.println(
" CreatedRTPsession: " + ipAddress + " " + port);

sendStream
= rtpMgrs[i].createSendStream(dataOutput,i);
sendStream.start();
}
catch (Exceptione){
return e.getMessage();
}
}

return null ;
}


/* *
*ForJPEGandH263,weknowthattheyonlyworkforparticular
*sizes.Sowe'llperformextracheckingheretomakesurethey
*areoftherightsizes.
*/
FormatcheckForVideoSizes(Formatoriginal,Formatsupported){

int width,height;
Dimensionsize
= ((VideoFormat)original).getSize();
FormatjpegFmt
= new Format(VideoFormat.JPEG_RTP);
Formath263Fmt
= new Format(VideoFormat.H263_RTP);

if (supported.matches(jpegFmt)){
// ForJPEG,makesurewidthandheightaredivisibleby8.
width = (size.width % 8 == 0 ? size.width:
(
int )(size.width / 8 ) * 8 );
height
= (size.height % 8 == 0 ? size.height:
(
int )(size.height / 8 ) * 8 );
}
else if (supported.matches(h263Fmt)){
// ForH.263,weonlysupportsomespecificsizes.
if (size.width < 128 ){
width
= 128 ;
height
= 96 ;
}
else if (size.width < 176 ){
width
= 176 ;
height
= 144 ;
}
else {
width
= 352 ;
height
= 288 ;
}
}
else {
// Wedon'tknowthisparticularformat.We'lljust
// leaveitalonethen.
return supported;
}

return ( new VideoFormat( null ,
new Dimension(width,height),
Format.NOT_SPECIFIED,
null ,
Format.NOT_SPECIFIED)).intersects(supported);
}


/* *
*SettingtheencodingqualitytothespecifiedvalueontheJPEGencoder.
*0.5isagooddefault.
*/
void setJPEGQuality(Playerp, float val){

Controlcs[]
= p.getControls();
QualityControlqc
= null ;
VideoFormatjpegFmt
= new VideoFormat(VideoFormat.JPEG);

// LoopthroughthecontrolstofindtheQualitycontrolfor
// theJPEGencoder.
for ( int i = 0 ;i < cs.length;i ++ ){

if (cs[i]instanceofQualityControl &&
cs[i]instanceofOwned){
Objectowner
= ((Owned)cs[i]).getOwner();

// ChecktoseeiftheownerisaCodec.
// Thencheckfortheoutputformat.
if (ownerinstanceofCodec){
Formatfmts[]
= ((Codec)owner).getSupportedOutputFormats( null );
for ( int j = 0 ;j < fmts.length;j ++ ){
if (fmts[j].matches(jpegFmt)){
qc
= (QualityControl)cs[i];
qc.setQuality(val);
System.err.println(
" -Settingqualityto " +
val
+ " on " + qc);
break ;
}
}
}
if (qc != null )
break ;
}
}
}


/* ***************************************************************
*Conveniencemethodstohandleprocessor'sstatechanges.
***************************************************************
*/

private IntegerstateLock = new Integer( 0 );
private booleanfailed = false ;

IntegergetStateLock(){
return stateLock;
}

void setFailed(){
failed
= true ;
}

private synchronizedbooleanwaitForState(Processorp, int state){
p.addControllerListener(
new StateListener());
failed
= false ;

// Calltherequiredmethodontheprocessor
if (state == Processor.Configured){
p.configure();
}
else if (state == Processor.Realized){
p.realize();
}

// Waituntilwegetaneventthatconfirmsthe
// successofthemethod,orafailureevent.
// SeeStateListenerinnerclass
while (p.getState() < state && ! failed){
synchronized(getStateLock()){
try {
getStateLock().wait();
}
catch (InterruptedExceptionie){
return false ;
}
}
}

if (failed)
return false ;
else
return true ;
}

/* ***************************************************************
*InnerClasses
***************************************************************
*/

class StateListenerimplementsControllerListener{

public void controllerUpdate(ControllerEventce){

// Iftherewasanerrorduringconfigureor
// realize,theprocessorwillbeclosed
if (ceinstanceofControllerClosedEvent)
setFailed();

// Allcontrollerevents,sendanotification
// tothewaitingthreadinwaitForStatemethod.
if (ceinstanceofControllerEvent){
synchronized(getStateLock()){
getStateLock().notifyAll();
}
}
}
}


/* ***************************************************************
*SampleUsageforAVTransmit3class
***************************************************************
*/

public static void main(String[]args){
// Weneedthreeparameterstodothetransmission
// Forexample,
// javaAVTransmit3file:/C:/media/test.mov129.130.131.13242050

if (args.length < 3 ){
prUsage();
}

Formatfmt
= null ;
int i = 0 ;

// Createaaudiotransmitobjectwiththespecifiedparams.
AVTransmit3at = new AVTransmit3( new MediaLocator(args[i]),
args[i
+ 1 ],args[i + 2 ],fmt);
// Startthetransmission
Stringresult = at.start();

// resultwillbenon-nulliftherewasanerror.Thereturn
// valueisaStringdescribingthepossibleerror.Printit.
if (result != null ){
System.err.println(
" Error: " + result);
System.exit(
0 );
}

System.err.println(
" Starttransmissionfor60secondsdot.gif " );

// Transmitfor60secondsandthenclosetheprocessor
// Thisisasafeguardwhenusingacapturedatasource
// sothatthecapturedevicewillbeproperlyreleased
// beforequitting.
// TherightthingtodowouldbetohaveaGUIwitha
// "Stop"buttonthatwouldcallstoponAVTransmit3
try {
Thread.currentThread().sleep(
60000 );
}
catch (InterruptedExceptionie){
}

// Stopthetransmission
at.stop();

System.err.println(
" dot.giftransmissionended. " );

System.exit(
0 );
}


static void prUsage(){
System.err.println(
" Usage:AVTransmit3<sourceURL><destIP><destPortBase> " );
System.err.println(
" <sourceURL>:inputURLorfilename " );
System.err.println(
" <destIP>:multicast,broadcastorunicastIPaddressforthetransmission " );
System.err.println(
" <destPortBase>:networkportnumbersforthetransmission. " );
System.err.println(
" ThefirsttrackwillusethedestPortBase. " );
System.err.println(
" ThenexttrackwillusedestPortBase+2andsoon./n " );
System.exit(
0 );
}
}

底层传输部分代码:

<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> importjava.io.IOException;
importjava.net.InetAddress;
importjava.net.DatagramSocket;
importjava.net.MulticastSocket;
importjava.net.DatagramPacket;
importjava.net.SocketException;

importjavax.media.protocol.DataSource;
importjavax.media.protocol.PushSourceStream;
importjavax.media.protocol.ContentDescriptor;
importjavax.media.protocol.SourceTransferHandler;
importjavax.media.rtp.RTPConnector;
importjavax.media.rtp.OutputDataStream;


/* *
*AnimplementationofRTPConnectorbasedonUDPsockets.
*/
public class RTPSocketAdapterimplementsRTPConnector{

DatagramSocketdataSock;
DatagramSocketctrlSock;

InetAddressaddr;
int port;

SockInputStreamdataInStrm
= null ,ctrlInStrm = null ;
SockOutputStreamdataOutStrm
= null ,ctrlOutStrm = null ;


public RTPSocketAdapter(InetAddressaddr, int port)throwsIOException{
this (addr,port, 1 );
}

public RTPSocketAdapter(InetAddressaddr, int port, int ttl)throwsIOException{

try {

if (addr.isMulticastAddress()){
dataSock
= new MulticastSocket(port);
ctrlSock
= new MulticastSocket(port + 1 );
((MulticastSocket)dataSock).joinGroup(addr);
((MulticastSocket)dataSock).setTimeToLive(ttl);
((MulticastSocket)ctrlSock).joinGroup(addr);
((MulticastSocket)ctrlSock).setTimeToLive(ttl);
}
else {
dataSock
= new DatagramSocket(port,InetAddress.getLocalHost());
ctrlSock
= new DatagramSocket(port + 1 ,InetAddress.getLocalHost());
}


}
catch (SocketExceptione){
throw new IOException(e.getMessage());
}

this .addr = addr;
this .port = port;
}

/* *
*ReturnsaninputstreamtoreceivetheRTPdata.
*/
public PushSourceStreamgetDataInputStream()throwsIOException{
if (dataInStrm == null ){
dataInStrm
= new SockInputStream(dataSock,addr,port);
dataInStrm.start();
}
return dataInStrm;
}

/* *
*ReturnsanoutputstreamtosendtheRTPdata.
*/
public OutputDataStreamgetDataOutputStream()throwsIOException{
if (dataOutStrm == null )
dataOutStrm
= new SockOutputStream(dataSock,addr,port);
return dataOutStrm;
}

/* *
*ReturnsaninputstreamtoreceivetheRTCPdata.
*/
public PushSourceStreamgetControlInputStream()throwsIOException{
if (ctrlInStrm == null ){
ctrlInStrm
= new SockInputStream(ctrlSock,addr,port + 1 );
ctrlInStrm.start();
}
return ctrlInStrm;
}

/* *
*ReturnsanoutputstreamtosendtheRTCPdata.
*/
public OutputDataStreamgetControlOutputStream()throwsIOException{
if (ctrlOutStrm == null )
ctrlOutStrm
= new SockOutputStream(ctrlSock,addr,port + 1 );
return ctrlOutStrm;
}

/* *
*ClosealltheRTP,RTCPstreams.
*/
public void close(){
if (dataInStrm != null )
dataInStrm.kill();
if (ctrlInStrm != null )
ctrlInStrm.kill();
dataSock.close();
ctrlSock.close();
}

/* *
*SetthereceivebuffersizeoftheRTPdatachannel.
*Thisisonlyahinttotheimplementation.Theactualimplementation
*maynotbeabletodoanythingtothis.
*/
public void setReceiveBufferSize( int size)throwsIOException{
dataSock.setReceiveBufferSize(size);
}

/* *
*GetthereceivebuffersizesetontheRTPdatachannel.
*Return-1ifthereceivebuffersizeisnotapplicablefor
*theimplementation.
*/
public int getReceiveBufferSize(){
try {
return dataSock.getReceiveBufferSize();
}
catch (Exceptione){
return - 1 ;
}
}

/* *
*SetthesendbuffersizeoftheRTPdatachannel.
*Thisisonlyahinttotheimplementation.Theactualimplementation
*maynotbeabletodoanythingtothis.
*/
public void setSendBufferSize( int size)throwsIOException{
dataSock.setSendBufferSize(size);
}

/* *
*GetthesendbuffersizesetontheRTPdatachannel.
*Return-1ifthesendbuffersizeisnotapplicablefor
*theimplementation.
*/
public int getSendBufferSize(){
try {
return dataSock.getSendBufferSize();
}
catch (Exceptione){
return - 1 ;
}
}

/* *
*ReturntheRTCPbandwidthfraction.Thisvalueisusedto
*initializetheRTPManager.CheckRTPManagerformoredetauls.
*Return-1tousethedefaultvalues.
*/
public double getRTCPBandwidthFraction(){
return - 1 ;
}

/* *
*ReturntheRTCPsenderbandwidthfraction.Thisvalueisusedto
*initializetheRTPManager.CheckRTPManagerformoredetauls.
*Return-1tousethedefaultvalues.
*/
public double getRTCPSenderBandwidthFraction(){
return - 1 ;
}


/* *
*AninnerclasstoimplementanOutputDataStreambasedonUDPsockets.
*/
class SockOutputStreamimplementsOutputDataStream{

DatagramSocketsock;
InetAddressaddr;
int port;

public SockOutputStream(DatagramSocketsock,InetAddressaddr, int port){
this .sock = sock;
this .addr = addr;
this .port = port;
}

public int write( byte data[], int offset, int len){
try {
sock.send(
new DatagramPacket(data,offset,len,addr,port));
}
catch (Exceptione){
return - 1 ;
}
return len;
}
}


/* *
*AninnerclasstoimplementanPushSourceStreambasedonUDPsockets.
*/
class SockInputStreamextendsThreadimplementsPushSourceStream{

DatagramSocketsock;
InetAddressaddr;
int port;
booleandone
= false ;
booleandataRead
= false ;

SourceTransferHandlersth
= null ;

public SockInputStream(DatagramSocketsock,InetAddressaddr, int port){
this .sock = sock;
this .addr = addr;
this .port = port;
}

public int read( byte buffer[], int offset, int length){
DatagramPacketp
= new DatagramPacket(buffer,offset,length,addr,port);
try {
sock.receive(p);
}
catch (IOExceptione){
return - 1 ;
}
synchronized(
this ){
dataRead
= true ;
notify();
}
return p.getLength();
}

public synchronized void start(){
super.start();
if (sth != null ){
dataRead
= true ;
notify();
}
}

public synchronized void kill(){
done
= true ;
notify();
}

public int getMinimumTransferSize(){
return 2 * 1024 ; // twicetheMTUsize,justtobesafe.
}

public synchronized void setTransferHandler(SourceTransferHandlersth){
this .sth = sth;
dataRead
= true ;
notify();
}

// Notapplicable.
public ContentDescriptorgetContentDescriptor(){
return null ;
}

// Notapplicable.
public long getContentLength(){
return LENGTH_UNKNOWN;
}

// Notapplicable.
public booleanendOfStream(){
return false ;
}

// Notapplicable.
public Object[]getControls(){
return new Object[ 0 ];
}

// Notapplicable.
public ObjectgetControl(Stringtype){
return null ;
}

/* *
*Loopandnotifythetransferhandlerofnewdata.
*/
public void run(){
while ( ! done){

synchronized(
this ){
while ( ! dataRead && ! done){
try {
wait();
}
catch (InterruptedExceptione){}
}
dataRead
= false ;
}

if (sth != null && ! done){
sth.transferData(
this );
}
}
}
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值