public void Parse_TestData_ReturnsValidFrame() { var testCodecInfo = new AACCodecInfo { ConfigBytes = new byte[] { 20, 8 }, IndexDeltaLength = 3, IndexLength = 3, SizeLength = 13 }; byte[] testBytes = Convert.FromBase64String( "ABAPyAE2Nay0eJ0OEMF4cOFyZeskqICVBWXLiAFDYHBG3GXFf0r/3nn+pRYcsdweO8Pzlxhjm0Q5QrEf7jx31b1PX8VuZOcZZ516jVY6sW/ISf8SQb6fONzpYJLiNRi7SO1o+" + "ByL8qHHiUeF9EoqyQ1VgamBApL8XaznlKoszkm9Td02961s0SznSmtSZcuhaEYCZaPe1k5qM+U3wHzs3CCnWMSNsK9UNCq1dzSm4YZWRkJPIY4oXJXsSCW67r8Xdb4slBDvxqu709z" + "ggyqrTuoOtkR3aHhFs6JHL8QwVgiusj39H8FrZ8Nu3Dt3qu0NQo5KpHN4R1jn2G71VHMfJwGEwZisU2e9Pz3h316dvpt97XbNcxLTgUCz9UpleUNXWAeygFCrPGTpWFv1Qn3JxS4W1xI" + "W5W/dHymYM5ElSMhtF+PFounb/IKbxKJThTUkxx3FWwYt00q7nMOilx2t6odQue/bTaENXKw304l1X5aiEl2S4+C0pIEzkHpbMp+5bmLw1+M8FNRkzlEngnPPATaJQSNOqTHTwVmK+" + "fAVSESminLM1TAOg0EZUw0pLTl3ka+scMp9kmxkFKLr3YRip0Uy0JMSnfefWxGezotf3sbV4afJZrnuVnKyanaK33korbN4LMIhvBgAAAAAAAAAAAAAAAAAAAAAAAAAA70="); byte[] frameBytes = Convert.FromBase64String( "ATY1rLR4nQ4QwXhw4XJl6ySogJUFZcuIAUNgcEbcZcV/Sv/eef6lFhyx3B47w/OXGGObRDlCsR/uPHfVvU9fxW5k5xlnnXqNVjqxb8hJ/xJBvp843OlgkuI1GLtI7Wj4HIvyoce" + "JR4X0SirJDVWBqYECkvxdrOeUqizOSb1N3Tb3rWzRLOdKa1Jly6FoRgJlo97WTmoz5TfAfOzcIKdYxI2wr1Q0KrV3NKbhhlZGQk8hjihclexIJbruvxd1viyUEO/Gq7vT3OCDKqtO6" + "g62RHdoeEWzokcvxDBWCK6yPf0fwWtnw27cO3eq7Q1Cjkqkc3hHWOfYbvVUcx8nAYTBmKxTZ70/PeHfXp2+m33tds1zEtOBQLP1SmV5Q1dYB7KAUKs8ZOlYW/VCfcnFLhbXEhblb90f" + "KZgzkSVIyG0X48Wi6dv8gpvEolOFNSTHHcVbBi3TSrucw6KXHa3qh1C579tNoQ1crDfTiXVflqISXZLj4LSkgTOQelsyn7luYvDX4zwU1GTOUSeCc88BNolBI06pMdPBWYr58BVIRKaK" + "cszVMA6DQRlTDSktOXeRr6xwyn2SbGQUouvdhGKnRTLQkxKd959bEZ7Oi1/extXhp8lmue5WcrJqdorfeSits3gswiG8GAAAAAAAAAAAAAAAAAAAAAAAAAADvQ=="); RawAACFrame frame = null; var parser = new AACAudioPayloadParser(testCodecInfo); parser.FrameGenerated = rawFrame => frame = (RawAACFrame)rawFrame; parser.Parse(TimeSpan.Zero, new ArraySegment <byte>(testBytes), true); Assert.IsNotNull(frame); Assert.AreEqual(FrameType.Audio, frame.Type); Assert.IsTrue(frame.ConfigSegment.SequenceEqual(testCodecInfo.ConfigBytes)); Assert.IsTrue(frame.FrameSegment.SequenceEqual(frameBytes)); }
public void Parse_SDPWithAACTrack_ReturnsWithAACCodecTrack() { var configBytes = new byte[] { 0x12, 0x10 }; string testInput = "m=audio 0 RTP/AVP 96\r\n" + "b=AS:128\r\n" + "a=rtpmap:96 MPEG4-GENERIC/44100/2\r\n" + "a=fmtp:96 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1210\r\n" + "a=control:streamid=0\r\n"; var testBytes = Encoding.ASCII.GetBytes(testInput); var parser = new SdpParser(); RtspMediaTrackInfo audioTrack = parser.Parse(testBytes).Where(t => t is RtspMediaTrackInfo) .Cast <RtspMediaTrackInfo>().First(); AACCodecInfo codecInfo = (AACCodecInfo)audioTrack.Codec; Assert.AreEqual(3, codecInfo.IndexDeltaLength); Assert.AreEqual(3, codecInfo.IndexLength); Assert.AreEqual(13, codecInfo.SizeLength); Assert.IsTrue(configBytes.SequenceEqual(codecInfo.ConfigBytes)); }
private static void ParseAACFormatAttributes(string[] formatAttributes, AACCodecInfo aacCodecInfo) { string sizeLengthParameter = formatAttributes.FirstOrDefault(fa => fa.StartsWith("sizeLength", StringComparison.InvariantCultureIgnoreCase)); if (sizeLengthParameter == null) { throw new SdpParserException("SizeLength parameters is not found"); } string indexLengthParameter = formatAttributes.FirstOrDefault(fa => fa.StartsWith("indexLength", StringComparison.InvariantCultureIgnoreCase)); if (indexLengthParameter == null) { throw new SdpParserException("IndexLength parameters is not found"); } string indexDeltaLengthParameter = formatAttributes.FirstOrDefault(fa => fa.StartsWith("indexDeltaLength", StringComparison.InvariantCultureIgnoreCase)); if (indexDeltaLengthParameter == null) { throw new SdpParserException("IndexDeltaLength parameters is not found"); } aacCodecInfo.SizeLength = int.Parse(GetFormatParameterValue(sizeLengthParameter)); aacCodecInfo.IndexLength = int.Parse(GetFormatParameterValue(indexLengthParameter)); aacCodecInfo.IndexDeltaLength = int.Parse(GetFormatParameterValue(indexDeltaLengthParameter)); string configParameter = formatAttributes.FirstOrDefault(fa => fa.StartsWith("config", StringComparison.InvariantCultureIgnoreCase)); if (configParameter != null) { aacCodecInfo.ConfigBytes = Hex.StringToByteArray(GetFormatParameterValue(configParameter)); } }
public void Parse_TestData_ReturnsValidFrame() { var testCodecInfo = new AACCodecInfo { ConfigBytes = new byte[] { 20, 8 }, IndexDeltaLength = 3, IndexLength = 3, SizeLength = 13 }; byte[] testBytes = Convert.FromBase64String( "ABAPyAE2Nay0eJ0OEMF4cOFyZeskqICVBWXLiAFDYHBG3GXFf0r/3nn+pRYcsdweO8Pzlxhjm0Q5QrEf7jx31b1PX8VuZOcZZ516jVY6sW/ISf8SQb6fONzpYJLiNRi7SO1o+" + "ByL8qHHiUeF9EoqyQ1VgamBApL8XaznlKoszkm9Td02961s0SznSmtSZcuhaEYCZaPe1k5qM+U3wHzs3CCnWMSNsK9UNCq1dzSm4YZWRkJPIY4oXJXsSCW67r8Xdb4slBDvxqu709z" + "ggyqrTuoOtkR3aHhFs6JHL8QwVgiusj39H8FrZ8Nu3Dt3qu0NQo5KpHN4R1jn2G71VHMfJwGEwZisU2e9Pz3h316dvpt97XbNcxLTgUCz9UpleUNXWAeygFCrPGTpWFv1Qn3JxS4W1xI" + "W5W/dHymYM5ElSMhtF+PFounb/IKbxKJThTUkxx3FWwYt00q7nMOilx2t6odQue/bTaENXKw304l1X5aiEl2S4+C0pIEzkHpbMp+5bmLw1+M8FNRkzlEngnPPATaJQSNOqTHTwVmK+" + "fAVSESminLM1TAOg0EZUw0pLTl3ka+scMp9kmxkFKLr3YRip0Uy0JMSnfefWxGezotf3sbV4afJZrnuVnKyanaK33korbN4LMIhvBgAAAAAAAAAAAAAAAAAAAAAAAAAA70="); byte[] frameBytes = Convert.FromBase64String( "D8gBNjWstHidDhDBeHDhcmXrJKiAlQVly4gBQ2BwRtxlxX9K/955/qUWHLHcHjvD85cYY5tEOUKxH+48d9W9T1/FbmTnGWedeo1" + "WOrFvyEn/EkG+nzjc6WCS4jUYu0jtaPgci/Khx4lHhfRKKskNVYGpgQKS/F2s55SqLM5JvU3dNvetbNEs50prUmXLoWhGAmWj3tZO" + "ajPlN8B87Nwgp1jEjbCvVDQqtXc0puGGVkZCTyGOKFyV7Egluu6/F3W+LJQQ78aru9Pc4IMqq07qDrZEd2h4RbOiRy/EMFYIrrI9/R/" + "Ba2fDbtw7d6rtDUKOSqRzeEdY59hu9VRzHycBhMGYrFNnvT894d9enb6bfe12zXMS04FAs/VKZXlDV1gHsoBQqzxk6Vhb9UJ9ycUuFt" + "cSFuVv3R8pmDORJUjIbRfjxaLp2/yCm8SiU4U1JMcdxVsGLdNKu5zDopcdreqHULnv202hDVysN9OJdV+WohJdkuPgtKSBM5B6WzKfuW" + "5i8NfjPBTUZM5RJ4JzzwE2iUEjTqkx08FZivnwFUhEpopyzNUwDoNBGVMNKS05d5GvrHDKfZJsZBSi692EYqdFMtCTEp33n1sRns6LX97" + "G1eGnyWa57lZysmp2it95KK2zeCzCIbwYAAAAAAAAAAAAAAAAAAAAAAAAAA=="); RawAACFrame frame = null; var parser = new AACAudioPayloadParser(testCodecInfo); parser.FrameGenerated = rawFrame => frame = (RawAACFrame)rawFrame; parser.Parse(TimeSpan.Zero, new ArraySegment <byte>(testBytes), true); Assert.IsNotNull(frame); Assert.AreEqual(FrameType.Audio, frame.Type); Assert.IsTrue(frame.ConfigSegment.SequenceEqual(testCodecInfo.ConfigBytes)); Assert.IsTrue(frame.FrameSegment.SequenceEqual(frameBytes)); }
public AACAudioPayloadParser(AACCodecInfo codecInfo) { _codecInfo = codecInfo ?? throw new ArgumentNullException(nameof(codecInfo)); }