Implements packetization-mode=0 from "RTP Payload Format for H.264 Video".

cusax-fix
Lyubomir Marinov 15 years ago
parent 5630819098
commit 9142c3dbcd

@ -0,0 +1,11 @@
--- a/libavcodec/libx264.c 2011-04-30 17:06:44.304599700 +0300
+++ b/libavcodec/libx264.c 2011-04-16 05:01:34.391924200 +0300
@@ -312,6 +312,8 @@
x4->params.b_sliced_threads = 1;
x4->params.b_vfr_input = 0;
+ x4->params.i_slice_max_size = avctx->rtp_payload_size;
+
x4->enc = x264_encoder_open(&x4->params);
if (!x4->enc)
return -1;

@ -193,6 +193,25 @@ public class MediaUtils
h264AdvancedAttributes.put("imageattr", createImageAttr(null, res));
// packetization-mode=1
addMediaFormats(
MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN,
"H264",
MediaType.VIDEO,
Constants.H264_RTP,
h264FormatParams,
h264AdvancedAttributes);
// packetization-mode=0
/*
* XXX At the time of this writing,
* EncodingConfiguration#compareEncodingPreferences(MediaFormat,
* MediaFormat) is incomplete and considers two MediaFormats to be equal
* if they have an equal number of format parameters (given that the
* encodings and clock rates are equal, of course). Either fix the
* method in question or don't add a format parameter for packetization
* mode 0 (which is equivalent to having packetization-mode explicitly
* defined as 0 anyway, according to the respective RFC).
*/
h264FormatParams.remove(packetizationMode);
addMediaFormats(
MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN,
"H264",

@ -106,6 +106,16 @@ public class JNIEncoder
*/
private long lastKeyframeRequestTime = System.currentTimeMillis();
/**
* The packetization mode to be used for the H.264 RTP payload output by
* this <tt>JNIEncoder</tt> and the associated packetizer. RFC 3984 "RTP
* Payload Format for H.264 Video" says that "[w]hen the value of
* packetization-mode is equal to 0 or packetization-mode is not present,
* the single NAL mode, as defined in section 6.2 of RFC 3984, MUST be
* used."
*/
private byte packetizationMode = 0;
/**
* The raw frame buffer.
*/
@ -220,7 +230,7 @@ private Format[] getMatchingOutputFormats(Format in)
videoIn.getFrameRate(),
ParameterizedVideoFormat.toMap(
PACKETIZATION_MODE_FMTP,
"1"))
Integer.toString(packetizationMode)))
};
}
@ -337,6 +347,11 @@ public synchronized void open()
FFmpeg.avcodeccontext_set_keyint_min(avctx, 0);
if (packetizationMode == 0)
FFmpeg.avcodeccontext_set_rtp_payload_size(
avctx,
Packetizer.MAX_PAYLOAD_SIZE);
if (FFmpeg.avcodec_open(avctx, avcodec) < 0)
{
throw
@ -550,7 +565,7 @@ public Format setOutputFormat(Format out)
fmtps = ((ParameterizedVideoFormat) out).getFormatParameters();
if (fmtps == null)
fmtps = new HashMap<String, String>();
fmtps.put(PACKETIZATION_MODE_FMTP, "1");
fmtps.put(PACKETIZATION_MODE_FMTP, Integer.toString(packetizationMode));
outputFormat
= new ParameterizedVideoFormat(
@ -564,4 +579,28 @@ public Format setOutputFormat(Format out)
// Return the selected outputFormat
return outputFormat;
}
/**
* Sets the packetization mode to be used for the H.264 RTP payload output
* by this <tt>JNIEncoder</tt> and the associated packetizer.
*
* @param packetizationMode the packetization mode to be used for the H.264
* RTP payload output by this <tt>JNIEncoder</tt> and the associated
* packetizer
*/
public void setPacketizationMode(String packetizationMode)
{
/*
* RFC 3984 "RTP Payload Format for H.264 Video" says that "[w]hen the
* value of packetization-mode is equal to 0 or packetization-mode is
* not present, the single NAL mode, as defined in section 6.2 of RFC
* 3984, MUST be used."
*/
if ((packetizationMode == null) || "0".equals(packetizationMode))
this.packetizationMode = 0;
else if ("1".equals(packetizationMode))
this.packetizationMode = 1;
else
throw new IllegalArgumentException("packetizationMode");
}
}

@ -8,6 +8,7 @@
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.media.*;
import javax.media.control.*;
@ -1259,6 +1260,19 @@ protected Format setProcessorFormat(
{
encoder = new JNIEncoder();
// packetization-mode
{
Map<String, String> formatParameters
= mediaFormat.getFormatParameters();
String packetizationMode
= (formatParameters == null)
? null
: formatParameters.get(
JNIEncoder.PACKETIZATION_MODE_FMTP);
encoder.setPacketizationMode(packetizationMode);
}
// The H.264 encoder needs to be notified of RTCP feedback message.
try
{

@ -161,6 +161,12 @@ public boolean equals(Object mediaFormat)
/**
* {@inheritDoc}
* <p>
* Takes into account RFC 3984 "RTP Payload Format for H.264 Video" which
* says that &quot;[w]hen the value of packetization-mode [format parameter]
* is equal to 0 or packetization-mode is not present, the single NAL mode,
* as defined in section 6.2 of RFC 3984, MUST be used.&quot;
* </p>
*
* @see MediaFormatImpl#formatParametersAreEqual(Map, Map)
*/
@ -200,6 +206,32 @@ public static boolean formatParametersAreEqual(
String encoding,
Map<String, String> fmtps1, Map<String, String> fmtps2)
{
/*
* RFC 3984 "RTP Payload Format for H.264 Video" says that "[w]hen the
* value of packetization-mode is equal to 0 or packetization-mode is
* not present, the single NAL mode, as defined in section 6.2 of RFC
* 3984, MUST be used."
*/
if ("H264".equalsIgnoreCase(encoding)
|| "h264/rtp".equalsIgnoreCase(encoding))
{
String packetizationMode = "packetization-mode";
String pm1 = null;
String pm2 = null;
if (fmtps1 != null)
pm1 = fmtps1.remove(packetizationMode);
if (fmtps2 != null)
pm2 = fmtps2.remove(packetizationMode);
if (pm1 == null)
pm1 = "0";
if (pm2 == null)
pm2 = "0";
if (!pm1.equals(pm2))
return false;
}
return
MediaFormatImpl.formatParametersAreEqual(encoding, fmtps1, fmtps2);
}
@ -207,6 +239,11 @@ public static boolean formatParametersAreEqual(
/**
* Determines whether the format parameters of this <tt>MediaFormat</tt>
* match a specific set of format parameters.
* <p>
* <tt>VideoMediaFormat</tt> reflects the fact that the
* <tt>packetization-mode</tt> format parameter distinguishes H.264 payload
* types.
* </p>
*
* @param fmtps the set of format parameters to match to the format
* parameters of this <tt>MediaFormat</tt>
@ -238,6 +275,29 @@ public static boolean formatParametersMatch(
String encoding,
Map<String, String> fmtps1 , Map<String, String> fmtps2)
{
/*
* RFC 3984 "RTP Payload Format for H.264 Video" says that "[w]hen the
* value of packetization-mode is equal to 0 or packetization-mode is
* not present, the single NAL mode, as defined in section 6.2 of RFC
* 3984, MUST be used."
*/
if ("H264".equalsIgnoreCase(encoding)
|| "h264/rtp".equalsIgnoreCase(encoding))
{
String packetizationMode = "packetization-mode";
String pm1
= (fmtps1 == null) ? null : fmtps1.get(packetizationMode);
String pm2
= (fmtps2 == null) ? null : fmtps2.get(packetizationMode);
if (pm1 == null)
pm1 = "0";
if (pm2 == null)
pm2 = "0";
if (!pm1.equals(pm2))
return false;
}
return true;
}

Loading…
Cancel
Save