Fixes the problem reported on the dev mailing list in the thread 'Error message in video call' by Conrad Beckert, re-enables packetization-mode=1 for H.264.

cusax-fix
Lyubomir Marinov 15 years ago
parent 6dd6ed4155
commit 87520e84a8

@ -177,7 +177,7 @@ public class MediaUtils
= new HashMap<String, String>();
String packetizationMode = "packetization-mode";
Map<String, String> h264AdvancedAttributes
= new HashMap<String, String>();
= new HashMap<String, String>();
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,

@ -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 <tt>Format</tt> to determine corresponding output
* <tt>Format/tt>s
* <tt>Format</tt>s
* @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<String, String>();
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");
}

@ -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 "

@ -113,7 +113,7 @@ public static MediaFormatImpl<? extends Format> createInstance(
formatParameters,
advancedAttrs);
}
if (format instanceof VideoFormat)
else if (format instanceof VideoFormat)
return
new VideoMediaFormatImpl(
(VideoFormat) format,
@ -121,7 +121,8 @@ public static MediaFormatImpl<? extends Format> createInstance(
-1,
formatParameters,
advancedAttrs);
return null;
else
return null;
}
/**

@ -151,6 +151,19 @@ public boolean equals(Object obj)
getFormatParameters(), objFmtps);
}
public boolean formatParametersMatch(Format format)
{
Map<String, String> 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<String, String> 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 <T> Map<T, T> toMap(T... entries)
}
return map;
}
@Override
public String toString()
{
StringBuilder s = new StringBuilder();
s.append(super.toString());
// fmtps
{
s.append(", fmtps={");
for (Map.Entry<String, String> 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();
}
}

@ -112,13 +112,16 @@ public class VideoMediaFormatImpl
Map<String, String> formatParameters,
Map<String, String> 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;
}

Loading…
Cancel
Save