diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java b/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java index 51cdc6c09..714e489bb 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java @@ -177,7 +177,7 @@ public class MediaUtils = new HashMap(); String packetizationMode = "packetization-mode"; Map h264AdvancedAttributes - = new HashMap(); + = new HashMap(); h264FormatParams.put(packetizationMode, "1"); /* @@ -192,7 +192,6 @@ public class MediaUtils h264AdvancedAttributes.put("imageattr", createImageAttr(null, res)); - /* XXX temporary disable packetization mode 1 due to some problems // packetization-mode=1 addMediaFormats( MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, @@ -201,7 +200,6 @@ public class MediaUtils Constants.H264_RTP, h264FormatParams, h264AdvancedAttributes); - */ // packetization-mode=0 /* * XXX At the time of this writing, diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java index 6ed4d1467..6de163aef 100644 --- a/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java +++ b/src/net/java/sip/communicator/impl/neomedia/codec/video/h264/JNIEncoder.java @@ -160,7 +160,7 @@ public class JNIEncoder * the single NAL mode, as defined in section 6.2 of RFC 3984, MUST be * used." */ - private byte packetizationMode = 0; + private String packetizationMode; /** * The raw frame buffer. @@ -266,19 +266,28 @@ private Format[] getMatchingOutputFormats(Format in) { VideoFormat videoIn = (VideoFormat) in; - return - new Format[] - { - new ParameterizedVideoFormat( + String[] packetizationModes + = (this.packetizationMode == null) + ? new String[] { "0", "1" } + : new String[] { this.packetizationMode }; + Format[] matchingOutputFormats = new Format[packetizationModes.length]; + Dimension size = videoIn.getSize(); + float frameRate = videoIn.getFrameRate(); + + for (int index = packetizationModes.length - 1; index >= 0; index--) + { + matchingOutputFormats[index] + = new ParameterizedVideoFormat( Constants.H264, - videoIn.getSize(), + size, Format.NOT_SPECIFIED, Format.byteArray, - videoIn.getFrameRate(), + frameRate, ParameterizedVideoFormat.toMap( PACKETIZATION_MODE_FMTP, - Integer.toString(packetizationMode))) - }; + packetizationModes[index])); + } + return matchingOutputFormats; } /** @@ -296,21 +305,23 @@ public String getName() * Returns the list of formats supported at the output. * * @param in input Format to determine corresponding output - * Format/tt>s + * Formats * @return array of formats supported at output */ public Format[] getSupportedOutputFormats(Format in) { + Format[] supportedOutputFormats; + // null input format if (in == null) - return SUPPORTED_OUTPUT_FORMATS; - + supportedOutputFormats = SUPPORTED_OUTPUT_FORMATS; // mismatch input format - if (!(in instanceof VideoFormat) + else if (!(in instanceof VideoFormat) || (null == AbstractCodecExt.matches(in, inputFormats))) - return new Format[0]; - - return getMatchingOutputFormats(in); + supportedOutputFormats = new Format[0]; + else + supportedOutputFormats = getMatchingOutputFormats(in); + return supportedOutputFormats; } /** @@ -412,7 +423,7 @@ public synchronized void open() FFmpeg.avcodeccontext_set_keyint_min(avctx, 0); - if (packetizationMode == 0) + if ((null == packetizationMode) || "0".equals(packetizationMode)) { FFmpeg.avcodeccontext_set_rtp_payload_size(avctx, Packetizer.MAX_PAYLOAD_SIZE); @@ -696,7 +707,8 @@ public Format setOutputFormat(Format out) fmtps = ((ParameterizedVideoFormat) out).getFormatParameters(); if (fmtps == null) fmtps = new HashMap(); - fmtps.put(PACKETIZATION_MODE_FMTP, Integer.toString(packetizationMode)); + if (packetizationMode != null) + fmtps.put(PACKETIZATION_MODE_FMTP, packetizationMode); outputFormat = new ParameterizedVideoFormat( @@ -728,9 +740,9 @@ public void setPacketizationMode(String packetizationMode) * 3984, MUST be used." */ if ((packetizationMode == null) || "0".equals(packetizationMode)) - this.packetizationMode = 0; + this.packetizationMode = "0"; else if ("1".equals(packetizationMode)) - this.packetizationMode = 1; + this.packetizationMode = "1"; else throw new IllegalArgumentException("packetizationMode"); } diff --git a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java index 0205ed9dd..986d21e9c 100644 --- a/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java +++ b/src/net/java/sip/communicator/impl/neomedia/device/MediaDeviceSession.java @@ -292,16 +292,18 @@ else if (sourceFormat.matches(new Format(VideoFormat.H263_RTP))) } else { - // We don't know this particular format. We'll just leave it alone - //then. + // We don't know this particular format. We'll just leave it alone + // then. return sourceFormat; } - VideoFormat result = new VideoFormat(null, - new Dimension(width, height), - Format.NOT_SPECIFIED, - null, - Format.NOT_SPECIFIED); + VideoFormat result + = new VideoFormat( + null, + new Dimension(width, height), + Format.NOT_SPECIFIED, + null, + Format.NOT_SPECIFIED); return (VideoFormat) result.intersects(sourceFormat); } @@ -637,14 +639,13 @@ private static Format findFirstMatchingFormat( = (format instanceof AudioFormat) ? ((AudioFormat) format).getSampleRate() : Format.NOT_SPECIFIED; + ParameterizedVideoFormat parameterizedVideoFormat + = (format instanceof ParameterizedVideoFormat) + ? (ParameterizedVideoFormat) format + : null; for (Format match : formats) { - /* - * TODO Is the encoding enough? We've been explicitly told what - * format to use so it may be that its non-encoding attributes which - * have been specified are also necessary. - */ if (match.isSameEncoding(format)) { /* @@ -652,14 +653,27 @@ private static Format findFirstMatchingFormat( * AudioFormats may have different sample rates (i.e. clock * rates as we call them in MediaFormat). */ - if ((formatSampleRate != Format.NOT_SPECIFIED) - && (match instanceof AudioFormat)) + if (match instanceof AudioFormat) { - double matchSampleRate - = ((AudioFormat) match).getSampleRate(); + if (formatSampleRate != Format.NOT_SPECIFIED) + { + double matchSampleRate + = ((AudioFormat) match).getSampleRate(); - if ((matchSampleRate != Format.NOT_SPECIFIED) - && (matchSampleRate != formatSampleRate)) + if ((matchSampleRate != Format.NOT_SPECIFIED) + && (matchSampleRate != formatSampleRate)) + continue; + } + } + else if (match instanceof ParameterizedVideoFormat) + { + if (!((ParameterizedVideoFormat) match) + .formatParametersMatch(format)) + continue; + } + else if (parameterizedVideoFormat != null) + { + if (!parameterizedVideoFormat.formatParametersMatch(match)) continue; } return match; @@ -1393,8 +1407,8 @@ protected void setProcessorFormat( if (supportedFormats[0] instanceof AudioFormat) { if (FMJConditionals.FORCE_AUDIO_FORMAT != null) - trackControl - .setFormat(FMJConditionals.FORCE_AUDIO_FORMAT); + trackControl.setFormat( + FMJConditionals.FORCE_AUDIO_FORMAT); else { supportedFormat @@ -1423,7 +1437,6 @@ protected void setProcessorFormat( */ if (supportedFormat == null) supportedFormat = format; - if (supportedFormat != null) supportedFormat = assertSize((VideoFormat) supportedFormat); @@ -1441,8 +1454,7 @@ else if (!supportedFormat.equals(trackControl.getFormat())) mediaFormat, supportedFormat); if (setFormat == null) - logger - .error( + logger.error( "Failed to set format of track " + trackIndex + " to " @@ -1450,8 +1462,7 @@ else if (!supportedFormat.equals(trackControl.getFormat())) + ". Processor is in state " + processor.getState()); else if (setFormat != supportedFormat) - logger - .warn( + logger.warn( "Failed to change format of track " + trackIndex + " from " @@ -1461,8 +1472,7 @@ else if (setFormat != supportedFormat) + ". Processor is in state " + processor.getState()); else if (logger.isTraceEnabled()) - logger - .trace( + logger.trace( "Set format of track " + trackIndex + " to " diff --git a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java index 1ad9ce903..9e169ebea 100644 --- a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java @@ -113,7 +113,7 @@ public static MediaFormatImpl createInstance( formatParameters, advancedAttrs); } - if (format instanceof VideoFormat) + else if (format instanceof VideoFormat) return new VideoMediaFormatImpl( (VideoFormat) format, @@ -121,7 +121,8 @@ public static MediaFormatImpl createInstance( -1, formatParameters, advancedAttrs); - return null; + else + return null; } /** diff --git a/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java b/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java index 5d1f4843f..395e90605 100644 --- a/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java +++ b/src/net/java/sip/communicator/impl/neomedia/format/ParameterizedVideoFormat.java @@ -151,6 +151,19 @@ public boolean equals(Object obj) getFormatParameters(), objFmtps); } + public boolean formatParametersMatch(Format format) + { + Map formatFmtps = null; + + if (format instanceof ParameterizedVideoFormat) + formatFmtps + = ((ParameterizedVideoFormat) format).getFormatParameters(); + return + VideoMediaFormatImpl.formatParametersMatch( + getEncoding(), + getFormatParameters(), formatFmtps); + } + public String getFormatParameter(String name) { return fmtps.get(name); @@ -200,15 +213,7 @@ public boolean matches(Format format) if (!super.matches(format)) return false; - Map formatFmtps = null; - - if (format instanceof ParameterizedVideoFormat) - formatFmtps - = ((ParameterizedVideoFormat) format).getFormatParameters(); - return - VideoMediaFormatImpl.formatParametersMatch( - getEncoding(), - getFormatParameters(), formatFmtps); + return formatParametersMatch(format); } /** @@ -237,4 +242,32 @@ public static Map toMap(T... entries) } return map; } + + @Override + public String toString() + { + StringBuilder s = new StringBuilder(); + + s.append(super.toString()); + + // fmtps + { + s.append(", fmtps={"); + for (Map.Entry fmtp : fmtps.entrySet()) + { + s.append(fmtp.getKey()); + s.append('='); + s.append(fmtp.getValue()); + s.append(','); + } + + int lastIndex = s.length() - 1; + + if (s.charAt(lastIndex) == ',') + s.setCharAt(lastIndex, '}'); + else + s.append('}'); + } + return s.toString(); + } } diff --git a/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java index 29d2408b1..74ded711c 100644 --- a/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java @@ -112,13 +112,16 @@ public class VideoMediaFormatImpl Map formatParameters, Map advancedParameters) { - super(new VideoFormat( - format.getEncoding(), - format.getSize(), - format.getMaxDataLength(), - format.getDataType(), - frameRate - ), formatParameters, advancedParameters); + super( + new ParameterizedVideoFormat( + format.getEncoding(), + format.getSize(), + format.getMaxDataLength(), + format.getDataType(), + frameRate, + formatParameters), + formatParameters, + advancedParameters); this.clockRate = clockRate; }