Makes 99 the preferred dynamic payload type of H.264 video using packetization-mode=0 and enables the assignment of preferred dynamic payload types through the configuration.

cusax-fix
Lyubomir Marinov 15 years ago
parent c669db1679
commit dfb28d0e6b

@ -81,7 +81,8 @@ felix.auto.start.49= \
#so make sure load the procotol service first, the contact list next
# and the implementations only after
felix.auto.start.50= \
reference:file:sc-bundles/contactlist.jar
reference:file:sc-bundles/contactlist.jar \
reference:file:sc-bundles/json.jar
felix.auto.start.52= \
reference:file:sc-bundles/neomedia.jar \
@ -112,7 +113,6 @@ felix.auto.start.66= \
reference:file:sc-bundles/update.jar \
reference:file:sc-bundles/swingnotification.jar \
reference:file:sc-bundles/osdependent.jar \
reference:file:sc-bundles/json.jar \
reference:file:sc-bundles/ldap.jar \
reference:file:sc-bundles/replacement.jar

@ -17,11 +17,14 @@
import javax.media.protocol.*;
import javax.swing.*;
import org.json.*;
import net.java.sip.communicator.impl.neomedia.codec.*;
import net.java.sip.communicator.impl.neomedia.codec.video.*;
import net.java.sip.communicator.impl.neomedia.device.*;
import net.java.sip.communicator.impl.neomedia.format.*;
import net.java.sip.communicator.impl.neomedia.protocol.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.service.neomedia.format.*;
@ -49,6 +52,13 @@ public class MediaServiceImpl
public static final String DISABLE_VIDEO_SUPPORT_PROPERTY_NAME
= "net.java.sip.communicator.service.media.DISABLE_VIDEO_SUPPORT";
/**
* The prefix of the property names the values of which specify the dynamic
* payload type preferences.
*/
private static final String DYNAMIC_PAYLOAD_TYPE_PREFERENCES_PNAME_PREFIX
= "net.java.sip.communicator.service.media.dynamicPayloadTypePreferences";
/**
* The value of the <tt>devices</tt> property of <tt>MediaServiceImpl</tt>
* when no <tt>MediaDevice</tt>s are available. Explicitly defined in order
@ -661,7 +671,7 @@ public Recorder createRecorder(MediaDevice device)
* that get dynamically assigned to {@link MediaFormat}s with no static
* payload type. The method is useful for formats such as "telephone-event"
* for example that is statically assigned the 101 payload type by some
* legacy systems. Signalling protocol implementations such as SIP and XMPP
* legacy systems. Signaling protocol implementations such as SIP and XMPP
* should make sure that, whenever this is possible, they assign to formats
* the dynamic payload type returned in this {@link Map}.
*
@ -674,10 +684,117 @@ public Map<MediaFormat, Byte> getDynamicPayloadTypePreferences()
{
dynamicPayloadTypePreferences = new HashMap<MediaFormat, Byte>();
/*
* Set the dynamicPayloadTypePreferences to their default values. If
* the user chooses to override them through the
* ConfigurationService, they will be overwritten later on.
*/
MediaFormat telephoneEvent
= MediaUtils.getMediaFormat("telephone-event", 8000);
if (telephoneEvent != null)
dynamicPayloadTypePreferences.put(telephoneEvent, (byte) 101);
MediaFormat h264
= MediaUtils.getMediaFormat(
"H264",
VideoMediaFormatImpl.DEFAULT_CLOCK_RATE);
if (h264 != null)
dynamicPayloadTypePreferences.put(h264, (byte) 99);
/*
* Try to load dynamicPayloadTypePreferences from the
* ConfigurationService.
*/
ConfigurationService config
= NeomediaActivator.getConfigurationService();
String prefix = DYNAMIC_PAYLOAD_TYPE_PREFERENCES_PNAME_PREFIX;
List<String> propertyNames
= config.getPropertyNamesByPrefix(prefix, true);
for (String propertyName : propertyNames)
{
/*
* The dynamic payload type is the name of the property name and
* the format which prefers it is the property value.
*/
byte dynamicPayloadTypePreference = 0;
Throwable exception = null;
try
{
dynamicPayloadTypePreference
= Byte.parseByte(
propertyName.substring(prefix.length() + 1));
}
catch (IndexOutOfBoundsException ioobe)
{
exception = ioobe;
}
catch (NumberFormatException nfe)
{
exception = nfe;
}
if (exception != null)
{
logger.warn(
"Ignoring dynamic payload type preference"
+ " which could not be parsed: "
+ propertyName,
exception);
continue;
}
String source = config.getString(propertyName);
if ((source != null) && (source.length() != 0))
{
try
{
JSONObject json = new JSONObject(source);
String encoding
= json.getString(MediaFormatImpl.ENCODING_PNAME);
int clockRate
= json.getInt(MediaFormatImpl.CLOCK_RATE_PNAME);
Map<String, String> fmtps
= new HashMap<String, String>();
if (json.has(MediaFormatImpl.FORMAT_PARAMETERS_PNAME))
{
JSONObject jsonFmtps
= json.getJSONObject(
MediaFormatImpl
.FORMAT_PARAMETERS_PNAME);
Iterator<?> jsonFmtpsIter = jsonFmtps.keys();
dynamicPayloadTypePreferences.put(telephoneEvent, (byte)101);
while (jsonFmtpsIter.hasNext())
{
String key = jsonFmtpsIter.next().toString();
String value = jsonFmtps.getString(key);
fmtps.put(key, value);
}
}
MediaFormat mediaFormat
= MediaUtils.getMediaFormat(
encoding, clockRate,
fmtps);
if (mediaFormat != null)
dynamicPayloadTypePreferences.put(
mediaFormat,
dynamicPayloadTypePreference);
}
catch (JSONException jsone)
{
logger.warn(
"Ignoring dynamic payload type preference"
+ " which could not be parsed: "
+ source,
jsone);
}
}
}
}
return dynamicPayloadTypePreferences;
}
@ -754,7 +871,7 @@ public void controllerUpdate(ControllerEvent event)
}
catch(Exception e)
{
e.printStackTrace();
logger.error("Failed to create video preview component", e);
}
return null;
@ -898,9 +1015,7 @@ public void hierarchyChanged(HierarchyEvent event)
return;
}
else
{
player.start();
}
if (windowListener == null)
{
@ -964,13 +1079,9 @@ public MediaDevice getMediaDeviceForPartialDesktopStreaming(
int display = -1;
if(dev != null)
{
display = dev.getIndex();
}
else
{
return null;
}
/* on Mac OS X, width have to be a multiple of 16 */
if(OSUtils.IS_MAC)
@ -1021,7 +1132,6 @@ public MediaDevice getMediaDeviceForPartialDesktopStreaming(
formats);
device = new MediaDeviceImpl(devInfo, MediaType.VIDEO);
return device;
}
@ -1038,11 +1148,9 @@ public void movePartialDesktopStreaming(MediaDevice mediaDevice, int x,
{
MediaDeviceImpl dev = (MediaDeviceImpl)mediaDevice;
if(!dev.getCaptureDeviceInfo().getLocator().getProtocol().
equals(ImageStreamingAuto.LOCATOR_PROTOCOL))
{
if(!dev.getCaptureDeviceInfo().getLocator().getProtocol().equals(
ImageStreamingAuto.LOCATOR_PROTOCOL))
return;
}
/* To move origin of the desktop capture, we need to access the
* JMF DataSource of imgstreaming
@ -1061,16 +1169,15 @@ public void movePartialDesktopStreaming(MediaDevice mediaDevice, int x,
ScreenDevice currentScreen = screen;
if(screen == null)
{
return;
}
Rectangle bounds = ((ScreenDeviceImpl)screen).getBounds();
x -= bounds.x;
y -= bounds.y;
((net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.imgstreaming.DataSource)
ds).setOrigin(0, currentScreen.getIndex(), x, y);
ds)
.setOrigin(0, currentScreen.getIndex(), x, y);
}
/**
@ -1086,12 +1193,7 @@ public boolean isPartialStreaming(MediaDevice mediaDevice)
MediaDeviceImpl dev = (MediaDeviceImpl)mediaDevice;
CaptureDeviceInfo devInfo = dev.getCaptureDeviceInfo();
if(devInfo.getName().startsWith("Partial desktop streaming"))
{
return true;
}
return false;
return devInfo.getName().startsWith("Partial desktop streaming");
}
/**
@ -1102,16 +1204,9 @@ public boolean isPartialStreaming(MediaDevice mediaDevice)
*/
public ScreenDevice getScreenForPoint(Point p)
{
List<ScreenDevice> devs = this.getAvailableScreenDevices();
for(ScreenDevice dev : devs)
{
for(ScreenDevice dev : getAvailableScreenDevices())
if(dev.containsPoint(p))
{
return dev;
}
}
return null;
}

@ -445,9 +445,30 @@ else if (format instanceof VideoFormat)
* the specified <tt>encoding</tt> and <tt>clockRate</tt>
*/
public static MediaFormat getMediaFormat(String encoding, double clockRate)
{
return getMediaFormat(encoding, clockRate, null);
}
/**
* Gets the <tt>MediaFormat</tt> known to <tt>MediaUtils</tt> and having the
* specified well-known <tt>encoding</tt> (name), <tt>clockRate</tt> and
* matching format parameters.
*
* @param encoding the well-known encoding (name) of the
* <tt>MediaFormat</tt> to get
* @param clockRate the clock rate of the <tt>MediaFormat</tt> to get
* @param fmtps the format parameters of the <tt>MediaFormat</tt> to get
* @return the <tt>MediaFormat</tt> known to <tt>MediaUtils</tt> and having
* the specified <tt>encoding</tt> (name), <tt>clockRate</tt> and matching
* format parameters
*/
public static MediaFormat getMediaFormat(
String encoding, double clockRate,
Map<String, String> fmtps)
{
for (MediaFormat format : getMediaFormats(encoding))
if (format.getClockRate() == clockRate)
if ((format.getClockRate() == clockRate)
&& format.formatParametersMatch(fmtps))
return format;
return null;
}

@ -25,6 +25,10 @@
public abstract class MediaFormatImpl<T extends Format>
implements MediaFormat
{
/**
* The name of the <tt>clockRate</tt> property of <tt>MediaFormatImpl</tt>.
*/
public static final String CLOCK_RATE_PNAME = "clockRate";
/**
* The value of the <tt>formatParameters</tt> property of
@ -35,6 +39,19 @@ public abstract class MediaFormatImpl<T extends Format>
static final Map<String, String> EMPTY_FORMAT_PARAMETERS
= Collections.emptyMap();
/**
* The name of the <tt>encoding</tt> property of <tt>MediaFormatImpl</tt>.
*/
public static final String ENCODING_PNAME = "encoding";
/**
* The name of the <tt>formatParameters</tt> property of
* <tt>MediaFormatImpl</tt>.
*/
public static final String FORMAT_PARAMETERS_PNAME = "fmtps";
/**
* Creates a new <tt>MediaFormat</tt> instance for a specific JMF
* <tt>Format</tt>.

@ -4,14 +4,15 @@ Bundle-Description: A bundle that offers Media capture and presentation capabili
Bundle-Vendor: sip-communicator.org
Bundle-Version: 0.0.1
System-Bundle: yes
Import-Package: org.osgi.framework,
org.xml.sax,
org.bouncycastle.crypto,
Import-Package: org.bouncycastle.crypto,
org.bouncycastle.crypto.digests,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.macs,
org.bouncycastle.crypto.params,
org.bouncycastle.crypto.prng,
org.bouncycastle.crypto.engines,
org.json,
org.osgi.framework,
org.xml.sax,
javax.imageio,
javax.sound.sampled,
javax.swing,

Loading…
Cancel
Save