Use default profile-level-id if absent in Describe SDP for MPEG4-LATM

PiperOrigin-RevId: 524003092
This commit is contained in:
michaelkatz 2023-04-13 16:06:09 +01:00 committed by Rohit Singh
parent 1c557e2fd1
commit 165f4f2fd4
3 changed files with 49 additions and 4 deletions

View File

@ -98,6 +98,9 @@
* Retry with TCP if RTSP Setup with UDP fails with RTSP Error 461
UnsupportedTransport
([#11069](https://github.com/google/ExoPlayer/issues/11069)).
* For MPEG4-LATM, use default profile-level-id value if absent in Describe
Response SDP message
([#302](https://github.com/androidx/media/issues/302)).
* IMA DAI extension:
* Fix a bug where a new ad group is inserted in live streams because the
calculated content position in consecutive timelines varies slightly.

View File

@ -229,7 +229,8 @@ import com.google.common.collect.ImmutableMap;
.setChannelCount(aacConfig.channelCount)
.setCodecs(aacConfig.codecs);
}
processAacFmtpAttribute(formatBuilder, fmtpParameters, channelCount, clockRate);
processAacFmtpAttribute(
formatBuilder, fmtpParameters, mediaEncoding, channelCount, clockRate);
break;
case MimeTypes.AUDIO_AMR_NB:
case MimeTypes.AUDIO_AMR_WB:
@ -311,11 +312,17 @@ import com.google.common.collect.ImmutableMap;
private static void processAacFmtpAttribute(
Format.Builder formatBuilder,
ImmutableMap<String, String> fmtpAttributes,
String mediaEncoding,
int channelCount,
int sampleRate) {
@Nullable String profileLevel = fmtpAttributes.get(PARAMETER_PROFILE_LEVEL_ID);
if (profileLevel == null && mediaEncoding.equals(RtpPayloadFormat.RTP_MEDIA_MPEG4_LATM_AUDIO)) {
// As defined in RFC3016 Section 5.3 for MPEG4-LATM, if profile-level-id is not specified,
// then a default value of 30 should be used.
profileLevel = "30";
}
checkArgument(
fmtpAttributes.containsKey(PARAMETER_PROFILE_LEVEL_ID), "missing profile-level-id param");
String profileLevel = checkNotNull(fmtpAttributes.get(PARAMETER_PROFILE_LEVEL_ID));
profileLevel != null && !profileLevel.isEmpty(), "missing profile-level-id param");
formatBuilder.setCodecs(AAC_CODECS_PREFIX + profileLevel);
formatBuilder.setInitializationData(
ImmutableList.of(

View File

@ -402,6 +402,22 @@ public class RtspMediaTrackTest {
assertThat(rtpPayloadFormat.format.codecs).isEqualTo("avc1.64001F");
}
@Test
public void
generatePayloadFormat_withMpeg4LatmMediaDescriptionMissingProfileLevel_generatesCorrectProfileLevel() {
MediaDescription mediaDescription =
new MediaDescription.Builder(
MEDIA_TYPE_AUDIO, /* port= */ 0, RTP_AVP_PROFILE, /* payloadType= */ 96)
.setConnection("IN IP4 0.0.0.0")
.setBitrate(96_000)
.addAttribute(ATTR_RTPMAP, "96 MP4A-LATM/44100")
.addAttribute(ATTR_FMTP, "96 config=40002410adca00; cpresent=0")
.addAttribute(ATTR_CONTROL, "track1")
.build();
RtpPayloadFormat rtpPayloadFormat = RtspMediaTrack.generatePayloadFormat(mediaDescription);
assertThat(rtpPayloadFormat.format.codecs).isEqualTo("mp4a.40.30");
}
@Test
public void
generatePayloadFormat_withAacMediaDescriptionMissingFmtpAttribute_throwsIllegalArgumentException() {
@ -420,7 +436,7 @@ public class RtspMediaTrackTest {
@Test
public void
generatePayloadFormat_withMediaDescriptionMissingProfileLevel_throwsIllegalArgumentException() {
generatePayloadFormat_withMpeg4GenericMediaDescriptionMissingProfileLevel_throwsIllegalArgumentException() {
MediaDescription mediaDescription =
new MediaDescription.Builder(
MEDIA_TYPE_AUDIO, /* port= */ 0, RTP_AVP_PROFILE, /* payloadType= */ 97)
@ -437,6 +453,25 @@ public class RtspMediaTrackTest {
() -> RtspMediaTrack.generatePayloadFormat(mediaDescription));
}
@Test
public void
generatePayloadFormat_withMpeg4GenericMediaDescriptionEmptyProfileLevel_throwsIllegalArgumentException() {
MediaDescription mediaDescription =
new MediaDescription.Builder(
MEDIA_TYPE_AUDIO, /* port= */ 0, RTP_AVP_PROFILE, /* payloadType= */ 97)
.setConnection("IN IP4 0.0.0.0")
.setBitrate(96_000)
.addAttribute(ATTR_RTPMAP, "97 MPEG4-GENERIC/44100")
.addAttribute(
ATTR_FMTP,
"97 streamtype=5;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1208;profile-level-id=;")
.addAttribute(ATTR_CONTROL, "track1")
.build();
assertThrows(
IllegalArgumentException.class,
() -> RtspMediaTrack.generatePayloadFormat(mediaDescription));
}
@Test
public void
generatePayloadFormat_withH264MediaDescriptionMissingFmtpAttribute_throwsIllegalArgumentException() {