Fallback to generate profile-level-id using H264 SPS if it's missing
Related to: Issue: #9010 Profile-level-id (Format.codecs) can be generated from SPS if SDP does not include it. #minor-release PiperOrigin-RevId: 377251211
This commit is contained in:
parent
0edb7873e0
commit
016983ca9a
@ -31,6 +31,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.audio.AacUtil;
|
import com.google.android.exoplayer2.audio.AacUtil;
|
||||||
|
import com.google.android.exoplayer2.util.CodecSpecificDataUtil;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.NalUnitUtil;
|
import com.google.android.exoplayer2.util.NalUnitUtil;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
@ -171,10 +172,6 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
|
|
||||||
private static void processH264FmtpAttribute(
|
private static void processH264FmtpAttribute(
|
||||||
Format.Builder formatBuilder, ImmutableMap<String, String> fmtpAttributes) {
|
Format.Builder formatBuilder, ImmutableMap<String, String> fmtpAttributes) {
|
||||||
checkArgument(fmtpAttributes.containsKey(PARAMETER_PROFILE_LEVEL_ID));
|
|
||||||
String profileLevel = checkNotNull(fmtpAttributes.get(PARAMETER_PROFILE_LEVEL_ID));
|
|
||||||
formatBuilder.setCodecs(H264_CODECS_PREFIX + profileLevel);
|
|
||||||
|
|
||||||
checkArgument(fmtpAttributes.containsKey(PARAMETER_SPROP_PARAMS));
|
checkArgument(fmtpAttributes.containsKey(PARAMETER_SPROP_PARAMS));
|
||||||
String spropParameterSets = checkNotNull(fmtpAttributes.get(PARAMETER_SPROP_PARAMS));
|
String spropParameterSets = checkNotNull(fmtpAttributes.get(PARAMETER_SPROP_PARAMS));
|
||||||
String[] parameterSets = Util.split(spropParameterSets, ",");
|
String[] parameterSets = Util.split(spropParameterSets, ",");
|
||||||
@ -193,6 +190,15 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
formatBuilder.setPixelWidthHeightRatio(spsData.pixelWidthAspectRatio);
|
formatBuilder.setPixelWidthHeightRatio(spsData.pixelWidthAspectRatio);
|
||||||
formatBuilder.setHeight(spsData.height);
|
formatBuilder.setHeight(spsData.height);
|
||||||
formatBuilder.setWidth(spsData.width);
|
formatBuilder.setWidth(spsData.width);
|
||||||
|
|
||||||
|
@Nullable String profileLevel = fmtpAttributes.get(PARAMETER_PROFILE_LEVEL_ID);
|
||||||
|
if (profileLevel != null) {
|
||||||
|
formatBuilder.setCodecs(H264_CODECS_PREFIX + profileLevel);
|
||||||
|
} else {
|
||||||
|
formatBuilder.setCodecs(
|
||||||
|
CodecSpecificDataUtil.buildAvcCodecString(
|
||||||
|
spsData.profileIdc, spsData.constraintsFlagsAndReservedZero2Bits, spsData.levelIdc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] getH264InitializationDataFromParameterSet(String parameterSet) {
|
private static byte[] getH264InitializationDataFromParameterSet(String parameterSet) {
|
||||||
|
@ -176,6 +176,23 @@ public class RtspMediaTrackTest {
|
|||||||
assertThat(format).isEqualTo(expectedFormat);
|
assertThat(format).isEqualTo(expectedFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void
|
||||||
|
generatePayloadFormat_withH264MediaDescriptionMissingProfileLevel_generatesCorrectProfileLevel() {
|
||||||
|
MediaDescription mediaDescription =
|
||||||
|
new MediaDescription.Builder(MEDIA_TYPE_VIDEO, 0, RTP_AVP_PROFILE, 96)
|
||||||
|
.setConnection("IN IP4 0.0.0.0")
|
||||||
|
.setBitrate(500_000)
|
||||||
|
.addAttribute(ATTR_RTPMAP, "96 H264/90000")
|
||||||
|
.addAttribute(
|
||||||
|
ATTR_FMTP,
|
||||||
|
"96 packetization-mode=1;sprop-parameter-sets=Z2QAH6zZQPARabIAAAMACAAAAwGcHjBjLA==,aOvjyyLA")
|
||||||
|
.addAttribute(ATTR_CONTROL, "track1")
|
||||||
|
.build();
|
||||||
|
RtpPayloadFormat rtpPayloadFormat = RtspMediaTrack.generatePayloadFormat(mediaDescription);
|
||||||
|
assertThat(rtpPayloadFormat.format.codecs).isEqualTo("avc1.64001F");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
generatePayloadFormat_withAacMediaDescriptionMissingFmtpAttribute_throwsIllegalArgumentException() {
|
generatePayloadFormat_withAacMediaDescriptionMissingFmtpAttribute_throwsIllegalArgumentException() {
|
||||||
@ -224,24 +241,6 @@ public class RtspMediaTrackTest {
|
|||||||
() -> RtspMediaTrack.generatePayloadFormat(mediaDescription));
|
() -> RtspMediaTrack.generatePayloadFormat(mediaDescription));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void
|
|
||||||
generatePayloadFormat_withH264MediaDescriptionMissingProfileLevel_throwsIllegalArgumentException() {
|
|
||||||
MediaDescription mediaDescription =
|
|
||||||
new MediaDescription.Builder(MEDIA_TYPE_VIDEO, 0, RTP_AVP_PROFILE, 96)
|
|
||||||
.setConnection("IN IP4 0.0.0.0")
|
|
||||||
.setBitrate(500_000)
|
|
||||||
.addAttribute(ATTR_RTPMAP, "96 H264/90000")
|
|
||||||
.addAttribute(
|
|
||||||
ATTR_FMTP,
|
|
||||||
"96 packetization-mode=1;sprop-parameter-sets=Z2QAH6zZQPARabIAAAMACAAAAwGcHjBjLA==,aOvjyyLA")
|
|
||||||
.addAttribute(ATTR_CONTROL, "track1")
|
|
||||||
.build();
|
|
||||||
assertThrows(
|
|
||||||
IllegalArgumentException.class,
|
|
||||||
() -> RtspMediaTrack.generatePayloadFormat(mediaDescription));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
generatePayloadFormat_withH264MediaDescriptionMissingSpropParameter_throwsIllegalArgumentException() {
|
generatePayloadFormat_withH264MediaDescriptionMissingSpropParameter_throwsIllegalArgumentException() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user