diff --git a/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java b/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java index 6ef69d9ec0..47256c06a1 100644 --- a/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java +++ b/libraries/muxer/src/androidTest/java/androidx/media3/muxer/Mp4MuxerEndToEndParameterizedAndroidTest.java @@ -51,6 +51,7 @@ public class Mp4MuxerEndToEndParameterizedAndroidTest { private static final String H265_HDR10_MP4 = "hdr10-720p.mp4"; private static final String H265_WITH_METADATA_TRACK_MP4 = "h265_with_metadata_track.mp4"; private static final String AV1_MP4 = "sample_av1.mp4"; + private static final String AMR_NB = "bbb_mono_8kHz_12.2kbps_amrnb.3gp"; private static final String AMR_WB = "bbb_mono_16kHz_23.05kbps_amrwb.3gp"; private static final String MPEG4_MP4 = "bbb_176x144_192kbps_15fps_mpeg4.mp4"; @@ -63,6 +64,7 @@ public class Mp4MuxerEndToEndParameterizedAndroidTest { H265_HDR10_MP4, H265_WITH_METADATA_TRACK_MP4, AV1_MP4, + AMR_NB, AMR_WB, MPEG4_MP4); } diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java index fe570c41a2..43420ed066 100644 --- a/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java +++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Boxes.java @@ -544,8 +544,10 @@ import java.util.List; case MimeTypes.AUDIO_AAC: case MimeTypes.VIDEO_MP4V: return esdsBox(format); + case MimeTypes.AUDIO_AMR_NB: + return damrBox(/* mode= */ (short) 0x81FF); // mode set: all enabled for AMR-NB case MimeTypes.AUDIO_AMR_WB: - return damrBox(/* mode= */ (short) 0x83FF); // mode set: all enabled + return damrBox(/* mode= */ (short) 0x83FF); // mode set: all enabled for AMR-WB case MimeTypes.VIDEO_H264: return avcCBox(format); case MimeTypes.VIDEO_H265: @@ -1322,6 +1324,8 @@ import java.util.List; switch (mimeType) { case MimeTypes.AUDIO_AAC: return "mp4a"; + case MimeTypes.AUDIO_AMR_NB: + return "samr"; case MimeTypes.AUDIO_AMR_WB: return "sawb"; case MimeTypes.VIDEO_H264: diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java index 7c8ce48960..a5902031bc 100644 --- a/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java +++ b/libraries/muxer/src/test/java/androidx/media3/muxer/BoxesTest.java @@ -254,6 +254,27 @@ public class BoxesTest { context, dumpableBox, getExpectedDumpFilePath("audio_sample_entry_box_mp4a")); } + @Test + public void createAudioSampleEntryBox_forSamr_matchesExpected() throws Exception { + Format format = + new Format.Builder() + .setPeakBitrate(128000) + .setSampleRate(48000) + .setId(3) + .setSampleMimeType(MimeTypes.AUDIO_AMR_NB) + .setChannelCount(2) + .setAverageBitrate(128000) + .setLanguage("```") + .setMaxInputSize(502) + .build(); + + ByteBuffer audioSampleEntryBox = Boxes.audioSampleEntry(format); + + DumpableMp4Box dumpableBox = new DumpableMp4Box(audioSampleEntryBox); + DumpFileAsserts.assertOutput( + context, dumpableBox, getExpectedDumpFilePath("audio_sample_entry_box_samr")); + } + @Test public void createAudioSampleEntryBox_forSawb_matchesExpected() throws Exception { Format format = diff --git a/libraries/test_data/src/test/assets/media/mp4/bbb_mono_8kHz_12.2kbps_amrnb.3gp b/libraries/test_data/src/test/assets/media/mp4/bbb_mono_8kHz_12.2kbps_amrnb.3gp new file mode 100644 index 0000000000..a450b919af Binary files /dev/null and b/libraries/test_data/src/test/assets/media/mp4/bbb_mono_8kHz_12.2kbps_amrnb.3gp differ diff --git a/libraries/test_data/src/test/assets/muxerdumps/audio_sample_entry_box_samr.dump b/libraries/test_data/src/test/assets/muxerdumps/audio_sample_entry_box_samr.dump new file mode 100644 index 0000000000..2d271a947b --- /dev/null +++ b/libraries/test_data/src/test/assets/muxerdumps/audio_sample_entry_box_samr.dump @@ -0,0 +1,2 @@ +samr (53 bytes): + Data = length 45, hash 7F055BB3 diff --git a/libraries/test_data/src/test/assets/muxerdumps/bbb_mono_8kHz_12.2kbps_amrnb.3gp.dump b/libraries/test_data/src/test/assets/muxerdumps/bbb_mono_8kHz_12.2kbps_amrnb.3gp.dump new file mode 100644 index 0000000000..c73ebb42f7 --- /dev/null +++ b/libraries/test_data/src/test/assets/muxerdumps/bbb_mono_8kHz_12.2kbps_amrnb.3gp.dump @@ -0,0 +1,624 @@ +seekMap: + isSeekable = true + duration = 3000000 + getPosition(0) = [[timeUs=0, position=400052]] + getPosition(1) = [[timeUs=1, position=400052]] + getPosition(1500000) = [[timeUs=1500000, position=402452]] + getPosition(3000000) = [[timeUs=3000000, position=404852]] +numberOfTracks = 1 +track 0: + total output bytes = 4832 + sample count = 151 + format 0: + id = 1 + sampleMimeType = audio/3gpp + maxInputSize = 62 + channelCount = 1 + sampleRate = 8000 + language = und + metadata = entries=[Mp4Timestamp: creation time=100000000, modification time=500000000, timescale=10000] + sample 0: + time = 0 + flags = 1 + data = length 32, hash 53582FC7 + sample 1: + time = 20000 + flags = 1 + data = length 32, hash 5685F9D6 + sample 2: + time = 40000 + flags = 1 + data = length 32, hash 979442D3 + sample 3: + time = 60000 + flags = 1 + data = length 32, hash D6C2D2B3 + sample 4: + time = 80000 + flags = 1 + data = length 32, hash 4D7A467C + sample 5: + time = 100000 + flags = 1 + data = length 32, hash D24FBF21 + sample 6: + time = 120000 + flags = 1 + data = length 32, hash 39A010D0 + sample 7: + time = 140000 + flags = 1 + data = length 32, hash 238FB065 + sample 8: + time = 160000 + flags = 1 + data = length 32, hash 7F460D8F + sample 9: + time = 180000 + flags = 1 + data = length 32, hash 4144D57A + sample 10: + time = 200000 + flags = 1 + data = length 32, hash 17FAFC32 + sample 11: + time = 220000 + flags = 1 + data = length 32, hash BBB92AF1 + sample 12: + time = 240000 + flags = 1 + data = length 32, hash 8662DF11 + sample 13: + time = 260000 + flags = 1 + data = length 32, hash ADE12517 + sample 14: + time = 280000 + flags = 1 + data = length 32, hash 42A2F90 + sample 15: + time = 300000 + flags = 1 + data = length 32, hash BA4736EE + sample 16: + time = 320000 + flags = 1 + data = length 32, hash DC3899EE + sample 17: + time = 340000 + flags = 1 + data = length 32, hash 9680E057 + sample 18: + time = 360000 + flags = 1 + data = length 32, hash 9DD4439A + sample 19: + time = 380000 + flags = 1 + data = length 32, hash A187A2E8 + sample 20: + time = 400000 + flags = 1 + data = length 32, hash 2181AFA7 + sample 21: + time = 420000 + flags = 1 + data = length 32, hash 2C46A44 + sample 22: + time = 440000 + flags = 1 + data = length 32, hash 45492E08 + sample 23: + time = 460000 + flags = 1 + data = length 32, hash 7E8B40BC + sample 24: + time = 480000 + flags = 1 + data = length 32, hash 8A572FB6 + sample 25: + time = 500000 + flags = 1 + data = length 32, hash 271382F7 + sample 26: + time = 520000 + flags = 1 + data = length 32, hash 31B52A2C + sample 27: + time = 540000 + flags = 1 + data = length 32, hash 1C0C6ACD + sample 28: + time = 560000 + flags = 1 + data = length 32, hash 12AF988B + sample 29: + time = 580000 + flags = 1 + data = length 32, hash 1EC318A2 + sample 30: + time = 600000 + flags = 1 + data = length 32, hash F0082E10 + sample 31: + time = 620000 + flags = 1 + data = length 32, hash 6F21FBC4 + sample 32: + time = 640000 + flags = 1 + data = length 32, hash A52D353D + sample 33: + time = 660000 + flags = 1 + data = length 32, hash C1B9C8E2 + sample 34: + time = 680000 + flags = 1 + data = length 32, hash 3BC2F23F + sample 35: + time = 700000 + flags = 1 + data = length 32, hash 7ACFCF02 + sample 36: + time = 720000 + flags = 1 + data = length 32, hash 296A9084 + sample 37: + time = 740000 + flags = 1 + data = length 32, hash 87B5C8E2 + sample 38: + time = 760000 + flags = 1 + data = length 32, hash C1C5851 + sample 39: + time = 780000 + flags = 1 + data = length 32, hash AD17B487 + sample 40: + time = 800000 + flags = 1 + data = length 32, hash E6806069 + sample 41: + time = 820000 + flags = 1 + data = length 32, hash AB5007B5 + sample 42: + time = 840000 + flags = 1 + data = length 32, hash 29DA3044 + sample 43: + time = 860000 + flags = 1 + data = length 32, hash 680DE283 + sample 44: + time = 880000 + flags = 1 + data = length 32, hash E5BB6CEF + sample 45: + time = 900000 + flags = 1 + data = length 32, hash 654EFBD4 + sample 46: + time = 920000 + flags = 1 + data = length 32, hash 3BFBC4E5 + sample 47: + time = 940000 + flags = 1 + data = length 32, hash 10F1217A + sample 48: + time = 960000 + flags = 1 + data = length 32, hash E37EF991 + sample 49: + time = 980000 + flags = 1 + data = length 32, hash 42723B2D + sample 50: + time = 1000000 + flags = 1 + data = length 32, hash 2D52F18B + sample 51: + time = 1020000 + flags = 1 + data = length 32, hash 6F62245B + sample 52: + time = 1040000 + flags = 1 + data = length 32, hash BA89ADED + sample 53: + time = 1060000 + flags = 1 + data = length 32, hash FCF8C5E2 + sample 54: + time = 1080000 + flags = 1 + data = length 32, hash F9AEEE3D + sample 55: + time = 1100000 + flags = 1 + data = length 32, hash 2E465113 + sample 56: + time = 1120000 + flags = 1 + data = length 32, hash 59CF2666 + sample 57: + time = 1140000 + flags = 1 + data = length 32, hash 3AB7A8D9 + sample 58: + time = 1160000 + flags = 1 + data = length 32, hash EB9D3A8E + sample 59: + time = 1180000 + flags = 1 + data = length 32, hash 6539E15F + sample 60: + time = 1200000 + flags = 1 + data = length 32, hash 2CAB1170 + sample 61: + time = 1220000 + flags = 1 + data = length 32, hash D0CA4456 + sample 62: + time = 1240000 + flags = 1 + data = length 32, hash DB3DBEE6 + sample 63: + time = 1260000 + flags = 1 + data = length 32, hash 6D094AC4 + sample 64: + time = 1280000 + flags = 1 + data = length 32, hash 2D6471B + sample 65: + time = 1300000 + flags = 1 + data = length 32, hash 86D257FB + sample 66: + time = 1320000 + flags = 1 + data = length 32, hash D8733063 + sample 67: + time = 1340000 + flags = 1 + data = length 32, hash C975C837 + sample 68: + time = 1360000 + flags = 1 + data = length 32, hash 2D548A68 + sample 69: + time = 1380000 + flags = 1 + data = length 32, hash 7A4907BA + sample 70: + time = 1400000 + flags = 1 + data = length 32, hash 6BDFDEB5 + sample 71: + time = 1420000 + flags = 1 + data = length 32, hash 272D422E + sample 72: + time = 1440000 + flags = 1 + data = length 32, hash BBFDCD7B + sample 73: + time = 1460000 + flags = 1 + data = length 32, hash 81F7CBF2 + sample 74: + time = 1480000 + flags = 1 + data = length 32, hash C18523A + sample 75: + time = 1500000 + flags = 1 + data = length 32, hash E062FDDB + sample 76: + time = 1520000 + flags = 1 + data = length 32, hash A756C4C8 + sample 77: + time = 1540000 + flags = 1 + data = length 32, hash A4FA6865 + sample 78: + time = 1560000 + flags = 1 + data = length 32, hash 6BC22B + sample 79: + time = 1580000 + flags = 1 + data = length 32, hash 37041F06 + sample 80: + time = 1600000 + flags = 1 + data = length 32, hash A9049020 + sample 81: + time = 1620000 + flags = 1 + data = length 32, hash E3C9552A + sample 82: + time = 1640000 + flags = 1 + data = length 32, hash 6EB2559 + sample 83: + time = 1660000 + flags = 1 + data = length 32, hash 988FD295 + sample 84: + time = 1680000 + flags = 1 + data = length 32, hash 6E0FFFA8 + sample 85: + time = 1700000 + flags = 1 + data = length 32, hash 4A16A2E5 + sample 86: + time = 1720000 + flags = 1 + data = length 32, hash 8526E110 + sample 87: + time = 1740000 + flags = 1 + data = length 32, hash 9C0F881C + sample 88: + time = 1760000 + flags = 1 + data = length 32, hash 68DF67F7 + sample 89: + time = 1780000 + flags = 1 + data = length 32, hash A789F088 + sample 90: + time = 1800000 + flags = 1 + data = length 32, hash B9CF3A20 + sample 91: + time = 1820000 + flags = 1 + data = length 32, hash 2AFD3C01 + sample 92: + time = 1840000 + flags = 1 + data = length 32, hash 3F61D3F4 + sample 93: + time = 1860000 + flags = 1 + data = length 32, hash 2D210ECA + sample 94: + time = 1880000 + flags = 1 + data = length 32, hash B8143A84 + sample 95: + time = 1900000 + flags = 1 + data = length 32, hash FE8EBC16 + sample 96: + time = 1920000 + flags = 1 + data = length 32, hash 85A9EE5D + sample 97: + time = 1940000 + flags = 1 + data = length 32, hash 3BDF48D1 + sample 98: + time = 1960000 + flags = 1 + data = length 32, hash 8EBCE992 + sample 99: + time = 1980000 + flags = 1 + data = length 32, hash B22AFFF + sample 100: + time = 2000000 + flags = 1 + data = length 32, hash 5F01BAC9 + sample 101: + time = 2020000 + flags = 1 + data = length 32, hash C6B7BD37 + sample 102: + time = 2040000 + flags = 1 + data = length 32, hash 5102216 + sample 103: + time = 2060000 + flags = 1 + data = length 32, hash 8FE06144 + sample 104: + time = 2080000 + flags = 1 + data = length 32, hash ED90D421 + sample 105: + time = 2100000 + flags = 1 + data = length 32, hash 15971BF0 + sample 106: + time = 2120000 + flags = 1 + data = length 32, hash 1B2D1ADE + sample 107: + time = 2140000 + flags = 1 + data = length 32, hash A8A54AD2 + sample 108: + time = 2160000 + flags = 1 + data = length 32, hash 270646A2 + sample 109: + time = 2180000 + flags = 1 + data = length 32, hash 27DB772F + sample 110: + time = 2200000 + flags = 1 + data = length 32, hash FBD3938 + sample 111: + time = 2220000 + flags = 1 + data = length 32, hash FA27CAFB + sample 112: + time = 2240000 + flags = 1 + data = length 32, hash 828AB2A4 + sample 113: + time = 2260000 + flags = 1 + data = length 32, hash 5788D8F1 + sample 114: + time = 2280000 + flags = 1 + data = length 32, hash B7A5AEB0 + sample 115: + time = 2300000 + flags = 1 + data = length 32, hash 272DC4BC + sample 116: + time = 2320000 + flags = 1 + data = length 32, hash 56C2540E + sample 117: + time = 2340000 + flags = 1 + data = length 32, hash 3236D8C + sample 118: + time = 2360000 + flags = 1 + data = length 32, hash 6C0650B + sample 119: + time = 2380000 + flags = 1 + data = length 32, hash 1EA3E6C3 + sample 120: + time = 2400000 + flags = 1 + data = length 32, hash 6512496C + sample 121: + time = 2420000 + flags = 1 + data = length 32, hash 82CD3C74 + sample 122: + time = 2440000 + flags = 1 + data = length 32, hash 7EDFB3A4 + sample 123: + time = 2460000 + flags = 1 + data = length 32, hash AAFD22AB + sample 124: + time = 2480000 + flags = 1 + data = length 32, hash 8577D9D1 + sample 125: + time = 2500000 + flags = 1 + data = length 32, hash B8A22921 + sample 126: + time = 2520000 + flags = 1 + data = length 32, hash 5E4EFC87 + sample 127: + time = 2540000 + flags = 1 + data = length 32, hash 35A5463F + sample 128: + time = 2560000 + flags = 1 + data = length 32, hash 3EBC0376 + sample 129: + time = 2580000 + flags = 1 + data = length 32, hash F515CB86 + sample 130: + time = 2600000 + flags = 1 + data = length 32, hash B113F72C + sample 131: + time = 2620000 + flags = 1 + data = length 32, hash 420AE0 + sample 132: + time = 2640000 + flags = 1 + data = length 32, hash 86D53F0F + sample 133: + time = 2660000 + flags = 1 + data = length 32, hash 5600867C + sample 134: + time = 2680000 + flags = 1 + data = length 32, hash EB4D89B6 + sample 135: + time = 2700000 + flags = 1 + data = length 32, hash 9BCD0B44 + sample 136: + time = 2720000 + flags = 1 + data = length 32, hash 4629F424 + sample 137: + time = 2740000 + flags = 1 + data = length 32, hash DFAA65F7 + sample 138: + time = 2760000 + flags = 1 + data = length 32, hash 9CF2BD6A + sample 139: + time = 2780000 + flags = 1 + data = length 32, hash 7A36CAB4 + sample 140: + time = 2800000 + flags = 1 + data = length 32, hash 1B9BCD43 + sample 141: + time = 2820000 + flags = 1 + data = length 32, hash 409B739C + sample 142: + time = 2840000 + flags = 1 + data = length 32, hash 126CAB5A + sample 143: + time = 2860000 + flags = 1 + data = length 32, hash 58173930 + sample 144: + time = 2880000 + flags = 1 + data = length 32, hash 32F281F + sample 145: + time = 2900000 + flags = 1 + data = length 32, hash D3F26DE + sample 146: + time = 2920000 + flags = 1 + data = length 32, hash C13BE9A7 + sample 147: + time = 2940000 + flags = 1 + data = length 32, hash 854B6181 + sample 148: + time = 2960000 + flags = 1 + data = length 32, hash 1E217D84 + sample 149: + time = 2980000 + flags = 1 + data = length 32, hash B121F36A + sample 150: + time = 3000000 + flags = 536870913 + data = length 32, hash 67FBC502 +tracksEnded = true