diff --git a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrack.java b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrack.java index 4217244c2d..c30adfe2a3 100644 --- a/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrack.java +++ b/library/rtsp/src/main/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrack.java @@ -31,6 +31,7 @@ import androidx.annotation.VisibleForTesting; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; 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.NalUnitUtil; import com.google.android.exoplayer2.util.Util; @@ -171,10 +172,6 @@ import com.google.common.collect.ImmutableMap; private static void processH264FmtpAttribute( Format.Builder formatBuilder, ImmutableMap 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)); String spropParameterSets = checkNotNull(fmtpAttributes.get(PARAMETER_SPROP_PARAMS)); String[] parameterSets = Util.split(spropParameterSets, ","); @@ -193,6 +190,15 @@ import com.google.common.collect.ImmutableMap; formatBuilder.setPixelWidthHeightRatio(spsData.pixelWidthAspectRatio); formatBuilder.setHeight(spsData.height); 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) { diff --git a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrackTest.java b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrackTest.java index 2afde70997..1b176fd292 100644 --- a/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrackTest.java +++ b/library/rtsp/src/test/java/com/google/android/exoplayer2/source/rtsp/RtspMediaTrackTest.java @@ -176,6 +176,23 @@ public class RtspMediaTrackTest { 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 public void generatePayloadFormat_withAacMediaDescriptionMissingFmtpAttribute_throwsIllegalArgumentException() { @@ -224,24 +241,6 @@ public class RtspMediaTrackTest { () -> 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 public void generatePayloadFormat_withH264MediaDescriptionMissingSpropParameter_throwsIllegalArgumentException() {