You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openmeetings.apache.org by co...@google.com on 2013/02/19 20:33:33 UTC
[red5phone] r94 committed - Video support: initial code is commited
Revision: 94
Author: solomax666@gmail.com
Date: Tue Feb 19 11:33:08 2013
Log: Video support: initial code is commited
http://code.google.com/p/red5phone/source/detail?r=94
Added:
/branches/red5sip/src/java/org/red5/codecs/SIPCodecH264.java
/branches/red5sip/src/java/org/red5/sip/app/RTPStreamVideoReceiver.java
/branches/red5sip/src/java/org/red5/sip/app/SIPVideoLauncher.java
Modified:
/branches/red5sip/src/java/org/red5/codecs/SIPCodec.java
/branches/red5sip/src/java/org/red5/codecs/SIPCodecFactory.java
/branches/red5sip/src/java/org/red5/sip/app/Application.java
/branches/red5sip/src/java/org/red5/sip/app/IMediaReceiver.java
/branches/red5sip/src/java/org/red5/sip/app/PlayNetStream.java
/branches/red5sip/src/java/org/red5/sip/app/RTMPRoomClient.java
/branches/red5sip/src/java/org/red5/sip/app/SIPTransport.java
/branches/red5sip/src/java/org/red5/sip/app/SIPUserAgent.java
/branches/red5sip/src/java/org/red5/sip/app/SIPUserAgentProfile.java
/branches/red5sip/src/java/org/red5/sip/app/SdpUtils.java
/branches/red5sip/src/java/org/zoolu/sdp/SessionDescriptor.java
=======================================
--- /dev/null
+++ /branches/red5sip/src/java/org/red5/codecs/SIPCodecH264.java Tue Feb 19
11:33:08 2013
@@ -0,0 +1,114 @@
+package org.red5.codecs;
+
+public class SIPCodecH264 implements SIPCodec {
+
+ private static final String codecName = "H264";
+ private static final int codecId = 35;
+ private static int defaultEncodedFrameSize = 160;
+ private static int defaultDecodedFrameSize = 160;
+ private int outgoingPacketization = 90000;
+ private int incomingPacketization = 90000;
+
+ @Override
+ public void encodeInit(int defaultEncodePacketization) {
+ if (this.outgoingPacketization == 0) {
+ this.outgoingPacketization = defaultEncodePacketization;
+ }
+ }
+
+ @Override
+ public void decodeInit(int defaultDecodePacketization) {
+ if (this.incomingPacketization == 0) {
+ this.incomingPacketization = defaultDecodePacketization;
+ }
+ }
+
+ @Override
+ public String codecNegotiateAttribute(String attributeName,
+ String localAttributeValue, String remoteAttributeValue) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int getCodecBlankPacket(byte[] buffer, int offset) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int pcmToCodec(float[] bufferIn, byte[] bufferOut) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int codecToPcm(byte[] bufferIn, float[] bufferOut) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int getIncomingEncodedFrameSize() {
+ return (defaultEncodedFrameSize / SIPCodec.DEFAULT_PACKETIZATION) *
incomingPacketization;
+ }
+
+ @Override
+ public int getIncomingDecodedFrameSize() {
+ return (defaultDecodedFrameSize / SIPCodec.DEFAULT_PACKETIZATION) *
incomingPacketization;
+ }
+
+ @Override
+ public int getOutgoingEncodedFrameSize() {
+ return (defaultEncodedFrameSize / SIPCodec.DEFAULT_PACKETIZATION) *
outgoingPacketization;
+ }
+
+ @Override
+ public int getOutgoingDecodedFrameSize() {
+ return (defaultDecodedFrameSize / SIPCodec.DEFAULT_PACKETIZATION) *
outgoingPacketization;
+ }
+
+ @Override
+ public int getSampleRate() {
+ return 90000;
+ }
+
+ @Override
+ public String getCodecName() {
+ return codecName;
+ }
+
+ @Override
+ public int getCodecId() {
+ return codecId;
+ }
+
+ @Override
+ public int getIncomingPacketization() {
+ return (defaultEncodedFrameSize / SIPCodec.DEFAULT_PACKETIZATION) *
incomingPacketization;
+ }
+
+ @Override
+ public int getOutgoingPacketization() {
+ return 2048;//( defaultDecodedFrameSize / SIPCodec.DEFAULT_PACKETIZATION
) * outgoingPacketization;
+ }
+
+ @Override
+ public void setLocalPtime(int localPtime) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setRemotePtime(int remotePtime) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String[] getCodecMediaAttributes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
=======================================
--- /dev/null
+++ /branches/red5sip/src/java/org/red5/sip/app/RTPStreamVideoReceiver.java
Tue Feb 19 11:33:08 2013
@@ -0,0 +1,50 @@
+package org.red5.sip.app;
+
+import java.net.DatagramSocket;
+import org.red5.codecs.SIPCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import local.net.RtpPacket;
+import local.net.RtpSocket;
+
+public class RTPStreamVideoReceiver extends Thread {
+
+ protected static Logger log =
LoggerFactory.getLogger(RTPStreamVideoReceiver.class);
+ public static int RTP_HEADER_SIZE = 12;
+ protected RtpSocket rtpSocket;
+ protected IMediaReceiver mediaReceiver;
+ protected SIPCodec codec;
+ private boolean running;
+
+ public RTPStreamVideoReceiver(IMediaReceiver mediaReceiver,
DatagramSocket socket, SIPCodec codec) {
+ this.mediaReceiver = mediaReceiver;
+ rtpSocket = new RtpSocket(socket);
+ this.codec = codec;
+ }
+
+ @Override
+ public void interrupt() {
+ running = false;
+ }
+
+ @Override
+ public void run() {
+ running = true;
+
+ try {
+ while(running) {
+ byte[] sourceBuffer = new byte[codec.getIncomingDecodedFrameSize()];
+ RtpPacket rtpPacket = new RtpPacket(sourceBuffer, 0);
+ rtpSocket.receive(rtpPacket);
+ byte[] destBuffer = new byte[rtpPacket.getLength() -
rtpPacket.getHeaderLength()];
+ System.arraycopy(sourceBuffer, rtpPacket.getHeaderLength(),
destBuffer, 0, destBuffer.length);
+ mediaReceiver.pushVideo(destBuffer, rtpPacket.getTimestamp(),
codec.getCodecId());
+ }
+ } catch (Exception e) {
+ log.error("", e);
+ }
+ rtpSocket.close();
+ }
+
+}
=======================================
--- /dev/null
+++ /branches/red5sip/src/java/org/red5/sip/app/SIPVideoLauncher.java Tue
Feb 19 11:33:08 2013
@@ -0,0 +1,39 @@
+package org.red5.sip.app;
+
+import java.net.DatagramSocket;
+
+import org.red5.codecs.SIPCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import local.ua.MediaLauncher;
+
+public class SIPVideoLauncher implements MediaLauncher {
+
+ protected static Logger log =
LoggerFactory.getLogger(SIPVideoLauncher.class);
+ protected DatagramSocket socket;
+ protected RTPStreamVideoReceiver receiver;
+
+ public SIPVideoLauncher(int localPort, String remoteAddr, int remotePort,
IMediaReceiver mediaReceiver, SIPCodec codec) {
+ try {
+ socket = new DatagramSocket(localPort);
+ receiver = new RTPStreamVideoReceiver(mediaReceiver, socket, codec);
+ } catch (Exception e) {
+ log.error("", e);
+ }
+ }
+
+ @Override
+ public boolean startMedia() {
+ log.debug("startMedia()");
+ receiver.start();
+ return true;
+ }
+
+ @Override
+ public boolean stopMedia() {
+ log.debug("stopMedia()");
+ return false;
+ }
+
+}
=======================================
--- /branches/red5sip/src/java/org/red5/codecs/SIPCodec.java Fri Feb 10
07:37:46 2012
+++ /branches/red5sip/src/java/org/red5/codecs/SIPCodec.java Tue Feb 19
11:33:08 2013
@@ -2,7 +2,7 @@
/**
- * Interface for audio codecs
+ * Interface for media codecs
* */
public interface SIPCodec {
=======================================
--- /branches/red5sip/src/java/org/red5/codecs/SIPCodecFactory.java Sun Feb
17 19:49:41 2013
+++ /branches/red5sip/src/java/org/red5/codecs/SIPCodecFactory.java Tue Feb
19 11:33:08 2013
@@ -26,8 +26,10 @@
// ----------------
// Available video codecs
- private int[] availableVideoCodecsId = {};
+ private static final int videoCodecH264 = 35;
+ private int[] availableVideoCodecsId = {videoCodecH264};
+
private static SIPCodecFactory singletonSIPCodecFactory = new
SIPCodecFactory();
@@ -43,7 +45,7 @@
* Create a new instance of SIPCodec by codec id.
* @return The codec associated with "codecId".
* */
- public SIPCodec getSIPAudioCodec( int codecId ) {
+ public SIPCodec getSIPMediaCodec( int codecId ) {
SIPCodec sipCodec;
@@ -64,6 +66,9 @@
case audioCodeciLBC:
sipCodec = new SIPCodeciLBC();
break;
+ case videoCodecH264:
+ sipCodec = new SIPCodecH264();
+ break;
default:
sipCodec = null;
}
@@ -90,7 +95,7 @@
for ( int i = 0; i < availableAudioCodecsId.length; i++ ) {
int codecId = availableAudioCodecsId[ i ];
- SIPCodec codec = getSIPAudioCodec( codecId );
+ SIPCodec codec = getSIPMediaCodec( codecId );
availableCodecs[i] = codec;
}
@@ -110,7 +115,7 @@
for ( int i = 0; i < availableVideoCodecsId.length; i++ ) {
int codecId = availableVideoCodecsId[ i ];
- SIPCodec codec = getSIPAudioCodec( codecId );
+ SIPCodec codec = getSIPMediaCodec( codecId );
availableCodecs[i] = codec;
}
@@ -143,7 +148,7 @@
printLog( "getAvailableAudioCodecsWithPrecedence",
"codecId = [" + codecId + "]." );
- SIPCodec sipCodec = getSIPAudioCodec(
+ SIPCodec sipCodec = getSIPMediaCodec(
Integer.valueOf( codecId ).intValue() );
if ( sipCodec != null ) {
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/Application.java Mon Feb 18
02:34:27 2013
+++ /branches/red5sip/src/java/org/red5/sip/app/Application.java Tue Feb 19
11:33:08 2013
@@ -16,21 +16,23 @@
private static final Logger log =
LoggerFactory.getLogger(Application.class);
private static final int SIP_START_PORT = 5070;
private static final int SOUND_START_PORT = 3010;
+ private static final int VIDEO_START_PORT = 7010;
private static int sipPort = SIP_START_PORT;
private static int soundPort = SOUND_START_PORT;
+ private static int videoPort = VIDEO_START_PORT;
private Properties props = null;
private Map<Integer, SIPTransport> transportMap = new HashMap<Integer,
SIPTransport>();
private RTMPControlClient rtmpControlClient;
- private SIPTransport createSIPTransport(Properties prop, int room_id) {
+ public SIPTransport createSIPTransport(Properties prop, int room_id) {
log.info("Creating SIP trasport for room: " + room_id);
RTPStreamSender.useASAO =
prop.getProperty("red5.codec", "asao").equals("asao");
RTMPRoomClient roomClient = new RTMPRoomClient(
prop.getProperty("red5.host")
, prop.getProperty("om.context", "openmeetings")
, room_id);
-
- SIPTransport sipTransport = new SIPTransport(roomClient,
sipPort++, soundPort++) {
+
+ SIPTransport sipTransport = new SIPTransport(roomClient,
sipPort++, soundPort++, videoPort++) {
public void onUaRegistrationSuccess(SIPRegisterAgent ra,
NameAddress target, NameAddress contact, String result) {
log.info("Registered successfully");
this.roomClient.setSipNumberListener(this);
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/IMediaReceiver.java Fri Feb
10 07:37:46 2012
+++ /branches/red5sip/src/java/org/red5/sip/app/IMediaReceiver.java Tue Feb
19 11:33:08 2013
@@ -6,6 +6,8 @@
void pushAudio( byte[] audio, long ts, int codec ) throws IOException;
+ void pushVideo( byte[] video, long ts, int codec ) throws IOException;
+
void setSender( IMediaSender sender );
}
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/PlayNetStream.java Sun Feb
17 19:49:41 2013
+++ /branches/red5sip/src/java/org/red5/sip/app/PlayNetStream.java Tue Feb
19 11:33:08 2013
@@ -17,6 +17,8 @@
private int audioTs = 0;
+ private int videoTs = 0;
+
private IMediaSender mediaSender;
private IMediaStream mediaStream;
@@ -63,8 +65,8 @@
}
if (rtmpEvent instanceof VideoData) {
- // videoTs += rtmpEvent.getTimestamp();
- // tag.setTimestamp(videoTs);
+ videoTs += rtmpEvent.getTimestamp();
+ //tag.setTimestamp(videoTs);
} else if (rtmpEvent instanceof AudioData) {
audioTs = rtmpEvent.getTimestamp();
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/RTMPRoomClient.java Mon Feb
18 21:27:45 2013
+++ /branches/red5sip/src/java/org/red5/sip/app/RTMPRoomClient.java Tue Feb
19 11:33:08 2013
@@ -2,6 +2,7 @@
import java.io.IOException;
import java.lang.reflect.Field;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -27,6 +28,7 @@
import org.red5.server.net.rtmp.codec.RTMP;
import org.red5.server.net.rtmp.event.AudioData;
import org.red5.server.net.rtmp.event.Notify;
+import org.red5.server.net.rtmp.event.VideoData;
import org.red5.server.net.rtmp.message.Header;
import org.red5.server.net.rtmp.status.StatusCodes;
import org.red5.server.service.Call;
@@ -45,7 +47,8 @@
private long broadCastId = -1;
private RTMPConnection conn;
private IMediaSender sender;
- private IoBuffer buffer;
+ private IoBuffer audioBuffer;
+ private IoBuffer videoBuffer;
private int kt = 0;
private Integer publishStreamId = null;
private boolean reconnect = true;
@@ -469,21 +472,21 @@
if( publishStreamId == null) {
return;
}
- if ( buffer == null ) {
- buffer = IoBuffer.allocate( 1024 );
- buffer.setAutoExpand( true );
+ if ( audioBuffer == null ) {
+ audioBuffer = IoBuffer.allocate( 1024 );
+ audioBuffer.setAutoExpand( true );
}
- buffer.clear();
+ audioBuffer.clear();
- buffer.put( (byte) codec ); // first byte 2 mono 5500; 6 mono
11025; 22
+ audioBuffer.put( (byte) codec ); // first byte 2 mono 5500; 6 mono
11025; 22
// mono 11025 adpcm 82 nellymoser 8000 178
// speex 8000
- buffer.put( audio );
+ audioBuffer.put( audio );
- buffer.flip();
+ audioBuffer.flip();
- AudioData audioData = new AudioData( buffer );
+ AudioData audioData = new AudioData( audioBuffer );
audioData.setTimestamp( (int) ts );
kt++;
@@ -495,4 +498,28 @@
rtmpMsg.setBody( audioData );
publishStreamData( publishStreamId, rtmpMsg );
}
+
+ @Override
+ public void pushVideo(byte[] video, long ts, int codec) throws
IOException {
+ if( publishStreamId == null) {
+ return;
+ }
+ if (videoBuffer == null || (videoBuffer.capacity() < video.length
&& !videoBuffer.isAutoExpand())) {
+ videoBuffer = IoBuffer.allocate(video.length);
+ videoBuffer.setAutoExpand(true);
+ }
+
+ videoBuffer.clear();
+ //videoBuffer.put((byte) codec);
+ videoBuffer.put(video);
+ videoBuffer.flip();
+
+ VideoData videoData = new VideoData(videoBuffer);
+ videoData.setTimestamp((int) ts);
+
+ RTMPMessage message = new RTMPMessage();
+ message.setBody(videoData);
+
+ publishStreamData(publishStreamId, message);
+ }
}
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/SIPTransport.java Mon Feb
18 21:27:45 2013
+++ /branches/red5sip/src/java/org/red5/sip/app/SIPTransport.java Tue Feb
19 11:33:08 2013
@@ -21,7 +21,8 @@
private String username;
private String password;
private int sipPort;
- private int rtpPort;
+ private int rtpAudioPort;
+ private int rtpVideoPort;
private String proxy;
private String number;
@@ -29,10 +30,11 @@
log.debug(s);
}
- public SIPTransport(RTMPRoomClient roomClient, int sipPort, int rtpPort) {
+ public SIPTransport(RTMPRoomClient roomClient, int sipPort, int
rtpAudioPort, int rtpVideoPort) {
this.roomClient = roomClient;
this.sipPort = sipPort;
- this.rtpPort = rtpPort;
+ this.rtpAudioPort = rtpAudioPort;
+ this.rtpVideoPort = rtpVideoPort;
}
public void login(String obproxy, String phone, String username,
@@ -56,7 +58,8 @@
.setOutboundProxy(new SocketAddress(opt_outbound_proxy));
user_profile = new SIPUserAgentProfile();
- user_profile.audioPort = rtpPort;
+ user_profile.audioPort = rtpAudioPort;
+ user_profile.videoPort = rtpVideoPort;
user_profile.username = username;
user_profile.passwd = password;
user_profile.realm = realm;
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/SIPUserAgent.java Sun Feb
17 19:49:41 2013
+++ /branches/red5sip/src/java/org/red5/sip/app/SIPUserAgent.java Tue Feb
19 11:33:08 2013
@@ -79,8 +79,11 @@
private IMediaReceiver mediaReceiver;
/** Sip codec to be used on audio session */
- private SIPCodec sipCodec = null;
+ private SIPCodec sipAudioCodec = null;
+ /** Sip codec to be used on video session */
+ private SIPCodec sipVideoCodec = null;
+
// *********************** Startup Configuration
***********************
@@ -469,13 +472,13 @@
if ( audioApp == null ) {
- if ( sipCodec != null ) {
+ if ( sipAudioCodec != null ) {
- audioApp = new SIPAudioLauncher( sipCodec,
localAudioPort,
+ audioApp = new SIPAudioLauncher( sipAudioCodec,
localAudioPort,
remoteMediaAddress, remoteAudioPort,
mediaReceiver);
}
else {
- printLog( "launchMediaApplication", "SipCodec not
initialized." );
+ printLog( "launchMediaApplication", "Audio SipCodec
not initialized." );
}
}
@@ -485,15 +488,17 @@
}
}
if ( userProfile.video && localVideoPort != 0 &&
remoteVideoPort != 0 ) {
-
- if ( videoApp == null ) {
-
- printLog( "launchMediaApplication",
- "No external video application nor JMF has been
provided: Video not started." );
- return;
+ if (videoApp == null) {
+ if (sipVideoCodec != null) {
+ videoApp = new SIPVideoLauncher(localVideoPort,
remoteMediaAddress, remoteAudioPort, mediaReceiver, sipVideoCodec);
+ } else {
+ printLog( "launchMediaApplication", "Video SipCodec not
initialized." );
+ }
+ }
+
+ if (videoApp != null) {
+ videoApp.startMedia();
}
-
- videoApp.startMedia();
}
}
@@ -550,9 +555,10 @@
// attributes can be then matched.
SessionDescriptor newSdp =
SdpUtils.makeMediaPayloadsNegotiation(localSdp, remoteSdp);
- // After we can create the correct audio codec considering
- // audio negotiation made above.
- sipCodec = SdpUtils.getNegotiatedAudioCodec( newSdp );
+ // After we can create the correct audio and video codecs
considering
+ // audio and video negotiations made above.
+ sipAudioCodec = SdpUtils.getNegotiatedAudioCodec( newSdp );
+ sipVideoCodec = SdpUtils.getNegotiatedVideoCodec( newSdp );
// Now we complete the SDP negotiation informing the selected
// codec, so it can be internally updated during the process.
@@ -565,7 +571,7 @@
// Finally, we use the "newSdp" and "remoteSdp" to initialize
// the lasting codec informations.
SIPCodecUtils.initSipAudioCodec(
- sipCodec,
+ sipAudioCodec,
userProfile.audioDefaultPacketization,
userProfile.audioDefaultPacketization, newSdp,
remoteSdp );
}
@@ -647,7 +653,8 @@
// After we can create the correct audio codec considering
// audio negotiation made above.
- sipCodec = SdpUtils.getNegotiatedAudioCodec( newSdp );
+ sipAudioCodec = SdpUtils.getNegotiatedAudioCodec( newSdp );
+ sipVideoCodec = SdpUtils.getNegotiatedVideoCodec( newSdp );
// Now we complete the SDP negotiation informing the selected
// codec, so it can be internally updated during the process.
@@ -660,7 +667,7 @@
// Finally, we use the "newSdp" and "remoteSdp" to initialize
// the lasting codec informations.
SIPCodecUtils.initSipAudioCodec(
- sipCodec,
+ sipAudioCodec,
userProfile.audioDefaultPacketization,
userProfile.audioDefaultPacketization, newSdp, remoteSdp );
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/SIPUserAgentProfile.java
Fri Feb 10 07:37:46 2012
+++ /branches/red5sip/src/java/org/red5/sip/app/SIPUserAgentProfile.java
Tue Feb 19 11:33:08 2013
@@ -128,7 +128,7 @@
public boolean audio = true;
/** Whether using video */
- public boolean video = false;
+ public boolean video = true;
/** Whether playing in receive only mode */
public boolean recvOnly = false;
=======================================
--- /branches/red5sip/src/java/org/red5/sip/app/SdpUtils.java Sun Feb 17
20:38:26 2013
+++ /branches/red5sip/src/java/org/red5/sip/app/SdpUtils.java Tue Feb 19
11:33:08 2013
@@ -17,6 +17,26 @@
protected static Logger log = LoggerFactory.getLogger( SdpUtils.class
);
+ public static SIPCodec getNegotiatedVideoCodec(SessionDescriptor
negotiatedSDP) {
+ String rtpmap =
negotiatedSDP.getMediaDescriptor(SIPCodec.MEDIA_TYPE_VIDEO).
+ getAttribute(SIPCodec.ATTRIBUTE_RTPMAP).getAttributeValue();
+ printLog( "getNegotiatedVideoCodec", "rtpmap = [" + rtpmap + "]." );
+ if (rtpmap.isEmpty()) return null;
+ int payloadId = Integer.parseInt(rtpmap.substring(0,
rtpmap.indexOf(" ")));
+ SIPCodec sipCodec =
SIPCodecFactory.getInstance().getSIPMediaCodec(payloadId);
+ if ( sipCodec == null ) {
+
+ printLog( "getNegotiatedAudioCodec", "Error... codec not
found." );
+ }
+ else {
+
+ printLog( "getNegotiatedAudioCodec",
+ "payloadType = " + sipCodec.getCodecId() +
+ ", payloadName = " + sipCodec.getCodecName() + "." );
+ }
+ return sipCodec;
+ }
+
/**
* @return Returns the audio codec to be used on current session.
*/
@@ -40,7 +60,7 @@
printLog( "getNegotiatedAudioCodec", "payloadId = [" +
payloadId + "]." );
- sipCodec = SIPCodecFactory.getInstance().getSIPAudioCodec(
payloadId );
+ sipCodec = SIPCodecFactory.getInstance().getSIPMediaCodec(
payloadId );
if ( sipCodec == null ) {
@@ -217,7 +237,7 @@
SIPCodec[] videoCodecs =
SIPCodecFactory.getInstance().getAvailableVideoCodecs();
Vector<AttributeField> videoAttributes = new
Vector<AttributeField>();
- for ( int videoIndex = 0; videoIndex < audioCodecsNumber;
videoIndex++ ) {
+ for ( int videoIndex = 0; videoIndex < videoCodecsNumber;
videoIndex++ ) {
String payloadId = String.valueOf(
videoCodecs[videoIndex].getCodecId() );
String rtpmapParamValue = payloadId;
@@ -271,7 +291,7 @@
if ( initialDescriptor.getMediaDescriptor(
SIPCodec.MEDIA_TYPE_VIDEO ) == null ) {
initialDescriptor.addMedia(
- new MediaField( SIPCodec.MEDIA_TYPE_VIDEO,
audioPort, 0, "RTP/AVP", formatList ),
+ new MediaField( SIPCodec.MEDIA_TYPE_VIDEO,
videoPort, 0, "RTP/AVP", formatList ),
videoAttribute );
}
else {
@@ -282,7 +302,7 @@
}
String[] commonVideoMediaAttributes =
-
SIPCodecFactory.getInstance().getCommonAudioMediaAttributes();
+
SIPCodecFactory.getInstance().getCommonVideoMediaAttributes();
if ( commonVideoMediaAttributes != null ) {
@@ -444,18 +464,15 @@
for ( Enumeration<AttributeField> attributesEnum =
newSdpAttributes.elements(); attributesEnum.hasMoreElements(); ) {
AttributeField mediaAttribute =
attributesEnum.nextElement();
-
- if ( newSdp.getMediaDescriptors().size() == 0 ) {
- newSdp.addMediaDescriptor( new MediaDescriptor(
- new MediaField(
localDescriptor.getMedia().getMedia(),
-
localDescriptor.getMedia().getPort(),
- 0,
-
localDescriptor.getMedia().getTransport(),
- formatList ),
- localDescriptor.getConnection() ) );
- }
-
+ newSdp.addMediaDescriptor( new MediaDescriptor(
+ new MediaField(
localDescriptor.getMedia().getMedia(),
+
localDescriptor.getMedia().getPort(),
+ 0,
+ localDescriptor.getMedia().getTransport(),
+ formatList ),
+ localDescriptor.getConnection() ) );
+
newSdp.getMediaDescriptor(
localDescriptor.getMedia().getMedia() ).
addAttribute( mediaAttribute );
}
@@ -623,7 +640,7 @@
AttributeField localAttribute =
findAttributeByPayloadId(
remoteAttribute.getAttributeName(), payloadId,
localMedia );
- SIPCodec sipCodec =
SIPCodecFactory.getInstance().getSIPAudioCodec(
+ SIPCodec sipCodec =
SIPCodecFactory.getInstance().getSIPMediaCodec(
Integer.valueOf( payloadId ) );
if ( sipCodec != null ) {
=======================================
--- /branches/red5sip/src/java/org/zoolu/sdp/SessionDescriptor.java Sun Feb
17 19:49:41 2013
+++ /branches/red5sip/src/java/org/zoolu/sdp/SessionDescriptor.java Tue Feb
19 11:33:08 2013
@@ -157,15 +157,20 @@
}
// parse session attributes
av=new Vector<AttributeField>();
- while (par.hasMore() && par.startsWith("a="))
- { AttributeField attribute=par.parseAttributeField();
- av.addElement(attribute);
- }
+ while (par.hasMore()) {
+ if (par.startsWith("a=")) {
+ AttributeField attribute=par.parseAttributeField();
+ av.addElement(attribute);
+ } else par.goToNextLine();
+ }
+ par.setPos(0);
// parse media descriptors
media=new Vector<MediaDescriptor>();
- MediaDescriptor md;
- while ((md=par.parseMediaDescriptor())!=null)
- { addMediaDescriptor(md);
+ while (par.hasMore()) {
+ if (par.startsWith("m=")) {
+ MediaDescriptor md = par.parseMediaDescriptor();
+ if (md != null) addMediaDescriptor(md);
+ } else par.goToNextLine();
}
}