@@ -6,12 +6,13 @@ using JT1078.Flv.Extensions; | |||
namespace JT1078.Flv.Test | |||
{ | |||
public class FlvMuxer_Test | |||
public class FlvEncoderTest | |||
{ | |||
[Fact] | |||
public void FlvMuxer_Test_1() { | |||
FlvMuxer flvMuxer = new FlvMuxer(); | |||
var buff = flvMuxer.FlvFirstFrame(); | |||
public void FlvMuxer_Test_1() | |||
{ | |||
FlvEncoder encoder = new FlvEncoder(); | |||
var buff = encoder.FlvFirstFrame(); | |||
var hex= buff.ToHexString(); | |||
} | |||
} |
@@ -0,0 +1,78 @@ | |||
using JT1078.Protocol; | |||
using JT1078.Flv.Extensions; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Text; | |||
using JT1078.Flv.H264; | |||
using Xunit; | |||
using System.Linq; | |||
using JT1078.Flv.MessagePack; | |||
using Newtonsoft.Json; | |||
namespace JT1078.Flv.Test.H264 | |||
{ | |||
public class H264DecoderTest | |||
{ | |||
[Fact] | |||
public void ParseNALUTest1() | |||
{ | |||
Flv.H264.H264Decoder demuxer = new Flv.H264.H264Decoder(); | |||
var hexData = "3031636481e2274b01234567899901100000016cd3ed2fa900500050037f0000000161e022bfb28b470069769838a02eb3b5cc4bccd7b37eb98cd65b2a76ce85a6c82876385a8f646da3d0abb6af58ad1dc7db5dab9719577d9968f7efc9836f4bc8fb7e32f5689b190e9e6e07d2f4448efff9147175f22a4b0f83fd24374b881dddcac5998ab9b03d991eb0045ed98826699a5601cdd6bd1e4b3ca53c175ef36e9f46969018c01b7754304790a17888072647e4c473182f05922770f5aff81e02ea46637b5e90b4382f100a2b55c5f49e0fa0b8203804dcd7714fac1dbd15d0583f8ebdfdf980770d58b38349ad7ec5682f01dae88b2117c6f3b3b58b642354bc23735d9c269028df9774e8182f5d636cec09829886de3ee83406e035bffcce3ed24af0f9a2dee150fab93303f2139c8525eeb89516df169137ef46ed99962343ea7b078bcddd284e44be62936a6c44042d89acb17973eb65e1c21faee6d221627ba834d369f4c023acc122d7d3dd3f55a6c4fb2ba2854498d4041ea00b1252c6d9eb57ac0b10313e8905843054dfbf4c847180aee40980bdfe5cb53133214c77c8e95ebe7601cd0d331f75281d1fadd122985133e74855e13cbb10220bc6e0c946b519b35d933a29e38e175b1398dc0946fc58ec7b686b3aac4bfa9e42bb8e643be04dc55036289c7d378fe37c6c3e1fc06015f8b402a65afac23d78d9fb5e3e0115195c11227ee6f261b67834b51bc665e8a6803af835b5032786e58e7f66049dc767520bae35d527a72458834a846dcd1cccf198d772d3ce0a2db5eb1d8270c483840309e224b2798d9271b30729e0c4f51eb7798d0dd0d8adb3d246e686b42e47f351c482dda833747649e421bbbe04098ca220d4e0e60a3b2854029c95c70394a2991314c50199f2158b68635a622f55ebda0b5e41328843552723fba1d5228963e8562c9105838ec9d341fef19b33a438d903ebcef32cec2ad39fd32aff14c79f07de4ca75e65d20f6ee36e464ee3e5c27871ab594ae3a0b43583c6f4d55ac8b71090fca9a1f4379576e07678983935d6f3a236504c2e4d31f99d62c999f41c11b06c41a6adb07b6e62f50ec5c8dbdb6641c5bc55a695f0f7b4f4d430c1e2f38a77edfc3513f943e1c1d4c0a81ef6c26cc4e7b157d318b49802ea94aa8ab38dadd4986e5330ab49daaec010123c39da63943bfe63bdd1cdd6beec19e1469b989ac10877a24065d7b01ff9cee35632e97243eb7acd79ce9d188b786e44bbe0e922be205c1224a41f387fae0f20d4a203d0ba64a366b8adbe2b80".ToHexBytes(); | |||
JT1078Package package = JT1078Serializer.Deserialize(hexData); | |||
var nalus = demuxer.ParseNALU(package); | |||
Assert.Single(nalus); | |||
var nalu = nalus[0]; | |||
Assert.Equal(0, nalu.NALUHeader.ForbiddenZeroBit); | |||
Assert.Equal(3, nalu.NALUHeader.NalRefIdc); | |||
Assert.Equal(1, nalu.NALUHeader.NalUnitType); | |||
} | |||
[Fact] | |||
public void ParseNALUTest2() | |||
{ | |||
JT1078Package Package=null; | |||
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078.txt")); | |||
int mergeBodyLength = 0; | |||
foreach (var line in lines) | |||
{ | |||
var data = line.Split(','); | |||
var bytes = data[5].ToHexBytes(); | |||
JT1078Package package = JT1078Serializer.Deserialize(bytes); | |||
mergeBodyLength += package.DataBodyLength; | |||
Package = JT1078Serializer.Merge(package); | |||
} | |||
Flv.H264.H264Decoder decoder = new Flv.H264.H264Decoder(); | |||
var nalus = decoder.ParseNALU(Package); | |||
Assert.Equal(4, nalus.Count); | |||
//SPS -> 7 | |||
var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7); | |||
Assert.NotNull(spsNALU); | |||
spsNALU.RawData = decoder.DiscardEmulationPreventionBytes(spsNALU.RawData); | |||
//"Z00AFJWoWCWQ" | |||
var spsRawDataHex = JsonConvert.SerializeObject(spsNALU.RawData); | |||
ExpGolombReader h264GolombReader = new ExpGolombReader(spsNALU.RawData); | |||
//(77, 20, 0, 352, 288) | |||
var spsInfo = h264GolombReader.ReadSPS(); | |||
Assert.Equal(77, spsInfo.profileIdc); | |||
Assert.Equal(20, spsInfo.levelIdc); | |||
Assert.Equal(0u, spsInfo.profileCompat); | |||
Assert.Equal(288, spsInfo.height); | |||
Assert.Equal(352, spsInfo.width); | |||
//PPS -> 8 | |||
var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8); | |||
Assert.NotNull(ppsNALU); | |||
//IDR -> 5 关键帧 | |||
var idrNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 5); | |||
Assert.NotNull(idrNALU); | |||
//SEI -> 6 | |||
var seiNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 6); | |||
Assert.NotNull(seiNALU); | |||
} | |||
} | |||
} |
@@ -0,0 +1,8 @@ | |||
012345678999,0,1,视频I帧,分包处理时的第一个包,303163648162000001234567899901010000016cd3a9b9f20000000003b600000001674d001495a85825900000000168ee3c800000000106e5013c800000000165b8000028f10bffab7d4ef364e8a2c87f9b90c26e8065ef699b0f3bf22e8c6501f7ef3b0fbd19fe1939cf7a7838f1d84b88a4209bf029065cbc4eeafb98f5925e66e9c6b5f399b7218a1555039a95b921b83f6221fe0ceb0ee6daeb19e08968d8217f7095e3bed833215d59a93179667811c81a02ee82b170ac0e28d19b1a3ee21cfacffeec402074cfc6e0b478874387554f0fa5557ef805223885a674bb97892878fbda3a9e29b4f309bf0b29d2745b9eec49dbd9158a9bd746655bbf8e903f4bec96131970b188caa74d233a471c58c0c60603a80a0e6519d7dd2c9eb577cb0df24ea7d72f39521f90afcb396166015273add9d1d7e47bc2973e39f17e4cfd641eca8149136bac8e3be5450a9f9e304f2495067b5c3b5b9dc886dc2f01fd418aaa67121c6fb094b1cbf2dbf07e346d4071b75e9c77a52db90606c219e826c96e427444e4ac0d0df32e3c04ba32b615853feafc6beb82667e46424d0e173767a34639df3c6e25b112cfd80ef6159ca1a23aa96e932c8989239ef0cc80929facf99f6bcdb110afb179c01199897785c9f07beea5d8097b9a4f6c94251958552c0aca330c7fe995712b8311cdbbf4627562cfd8e3dcade064ff7a59f9564e3773fc108a4fb8de2bfaada56ef6fdac74a5b7cd442dc701edd06e865401029a230ec348235e0e0608b3c66630dc069e02ebd3c9bf2bc1e90141e5c77d7ff69b62db661b2ffc02ce1edc6b09a4a3c455b6daad227ea251d8f3cab5bcca5898edc310ea4bb2477337f92d39f18bc258f04f4d3a5881c71b3d13ae5e393340cd1288863071419ceb6416e917e0e0553b340bf4a381f6ee71ab083bf119e5b69791a60851e995e8313a62916f835c1538a8f3d775a7cfd6ab9ba106f2a19eb1ba802724c1641e0bde105e392bfa437a188df395e9d287d436b208481307e97728a18117ef43577ff1e922c824f996d60ae0d6d9390ff97ee90691c2710899784adbe7ff6ca7f487f7ceea7f855eeb18f3f250ebaef9efeb97a9bead5b80de5069627d5f4fed615f0c7ed87965857f744fd7ff8f4d2b79f0d7b7f865fa26cc77eea03701266318ec3399bbcabe93d9a97f7b4f3bb9ac27aff8a529d4310216c8e9a6ca49e47e4371bc2cd551e6b3d4f56925fc9fbebb72041a31066ebc37cc61a7c1396ac48e864d7e8fb644a5fa49b73f8c7befdc4f05c88291623e5e3d0f4bd54b9b2c478467ac5e42a8080eabd37672f35903f4f44d2827d96960d76ab8bc86e0ff4a29afd4ae2ef5dd3d2825786e1229f26b797e35 | |||
012345678999,1,1,视频I帧,分包处理时的中间包,303163648162000101234567899901030000016cd3a9b9f20000000003b6a6fb10545aee778627f92f2bd15c71782be2793bb2ba0cc97d44bf79f7bc7c4186c9c806ce7bfff616c79758a53564d306fd770055679467f94f232149a8232e4b0866a2049ba007d64657886dd689222152226874b4ecb0d5f936807fa704d84567405cb49570de8e990ff4748fe6abcd1a0a9982a78b487ec56278c3334fc4579e75708abed0175ee5baa548deb84d0af5cc9cb918bf851f8e78867968f32f6fa9ebd2b93554636813274839d6944529f204559ff388d6ea4c63adb0d8ddf9ddb27cd7ebe33287a6139688225d0aa5256af74fd0d9358f7bc072abf4a3f1d59ad318aef1453ce4a229781420056e89e5ab9dccacd69ac688e590e6ffbbbc79ba2d83da0d9d9f80d55b295a1bc5b2df2699a75d95638da525b70c93d9fb48c8bd6a8d53adfa9c7f3c1ee7ad5d8429e28bea5c6c033762b6398528dd7bf05e3fc134a83f9ef2543d581b4f45ce17813035ce0432b69ad4d1d22c12003e442631bac549a8e0a2b1fb4a7da58e91122ba67537e7d02d66f6d4971e8c080f1855156490ef5c16299f84d04f2600b54972ffaa15e70d3ded386cd2ebb4321070c76530b5c0ede147d63d6d1779f5bac91d95bc8725e8b1605db7cd92f0a3b142394dec894ce3910462b375e8cbd70ae493dd0ecb143997673468b9add2f81001b3cae5d51ee197ba68edfffd1a3ffdd0e1f167bb0137f6049ad3470998ad8df7c78c414f79d39e6490715d71100eb6ae8d3e8ad4783a7d24a5594ffa10fa0dbb30a41d2fa62304eff3477b82f5aff028629accd32a5940c2d2657443f0fde5a6bb06bc3c82e6dac6e51b0b476a804aba5c84565f79ca99561f735dcc5a18001f043491ad0e2a0c2c65afea3fee2bb158f50cc8eb071308b12b580e0c6bfefeb9f9fc0fed333276cb2ff27e04dcc2399bbee6562952268af2d1e05f0b301f7fc261ce1a8d8c0cbade4eddc4cdff8f62aac0f6807d47771cfaf33d3700856ceaea66892e43fcb83b7a9e32ae1b759dc7ec581747f1c2cb7a32c69e91a7124294d53087f6b2dc1ad63fb2ecf04a16b548902402f38e7ecf6d7fede301f83b76f1f329a60c6863dfec8c3a7984bc1abf6481eae4f7d8218b882818482e424a0ca645f6b0445c5a9e239a2b4bc3d6a70c3f3f51fb6346b3ce643421a7697e43b5e0fd4ba2c519b6cc62ee6ac7dff3c81a7d0ee4eb291de62edba5e05212e82e968f85b78dcb875b67a9198eefea0960d4873d92a8b32fb88236b207157e5453a96fd5792da527bd1b195f426351b516c21900631a571c6d02b144c88ab72b35ed300d99cef12c1a3ccf95ebe305ed4513431661be9245c4a4ba62 | |||
012345678999,2,1,视频I帧,分包处理时的中间包,303163648162000201234567899901030000016cd3a9b9f20000000003b6da72bd536f42168e2c3d18a96c3aea86ae57cb5fb116978ff2481a70efc9da6397ffc9c6b52ffd524c68f50b01ad81fb0740d9334df9a632d21aa1bf0addc4d21f4dc00d61533748f4c42b045ffd65f62d32f86f269c4cf1842558f3ca2450e404e589c4d271d570e052b2d451ea2978641d44398d98c65967e5f0c61f23d8b7e7aca9ae900926739d85231edabc08fdb6670dafc84ddbbd3d824c33140359573ab1c2942f0aa05f9eb08ff94d9964995ae63599f9e26c606ba6f009d0cf6693c984cbfed2ea7a822cc9543ac76e00788ebe0b449c93b4961c45bf7ff82d40bb4c7c3a3dde1a8820fd5832834ddb5a6210cdf0dffdf48d84a7596eae5f653309da08dc592a406d9f55c511d858fdc575b930773b59be022bf7776294e3e5ef9b9386191fe2c8c1d38708dff87ddff23cfeb8b42154adfd598a92979fa59b40c7900d7c3df8a53d08836c38c5134a7abc7eafc8c10cdb60366286ddfcb7c193999ddc95af2f6c76ff158213a19b63f79cce1fe1fcc6b949ecea7d1853936047503594676466bc70dd61127986aab961834419b17ae6ed63c87f06bc7e2c1e3b1358dfe822c86577b5fac89f957a90fbcd39f67378cc1cc22a56d081e3fb1a5e6060152aee2331c297c3646cc604e13a7a4a383a37d417acb7d1076a79ca794ab16a7ca56a31a8e4dc032025ec5181038f034a502fba62ad21e5990c0235d6d26faaf693a89dfba3d07f75759b8155532b91b84f03b0f134af30e2b007e68a6da50c8a040e4e9e7d0b53f381b6b7ab3de85f28cb3b51fd23b89865d833861423a3b194bfb8c8e5fe566ffb018b6295c076940696e726658370289a4cfd66ae566a024d1ff94c5d65d9bfed4fe89df67839904785796ceb6264dc0ff4b103acaf05a65a6fbeb9e15db3a06b33df4e1f8365868e8cf1b13734ec27e23879f061d833182fe9d034d559a56d6da5708896bc6a0b5914261d20923f496cda936f108adf7164861b577af5ba7116d3ede71b16465fb462fce107844cf3583a9997a03415680458b097ed95bf06fb0d3df2d991d2437460005412429e120e55aa79bdc2f1783bb45db8f6008581bd07d1a3282ee7c0e0c4d6b2fb546daeb2cef04937e799c7d96962dc51237963dce7345161a2b905ba89046db6435890d09500babd98d13c26bcf86f6b5214082d28b76bb7ad1c4f81edfff93a5895eed2ebba9250fccdda3f53f020a089246bc00cd0de21b9169cbd1df9849b2893ed774a1d149c50da0287c25271823c99de17236b6544c1e5a009416ada3e57474944d3f94ed16cfd7473629e77be9a349027e0d8f7e796384664c0285a77 | |||
012345678999,3,1,视频I帧,分包处理时的中间包,303163648162000301234567899901030000016cd3a9b9f20000000003b6b83940b4220e76c108af6432deb4d1a5ececc2906174181c9d85828a5df10e8046a276ce933e0720f7dd4bd234baf61d98adbd8d623be2c7e8c5d3272d41af666f44dd4bf0d5ecf47ccb0bda03299a2d70cb76ba7b73ae0c92e38e2af9c1c8848996666d2741efe033e46a01a19e6f9fe8c90e088ad0d034d53cce3bacf1b87b8f46b31087f21cbff177d2fa17aab609e0c1dabcda428830bd23df87cbe245b34407c6593e6179985db026112eb853a0b1d79f46a9691ee7aebb78009f145f04946ea8c60f01cf0e6c9bea1e7fdfc6307615aedde4f7941ffc1be711dea15c84c519dc860824cdc6eb96b64d74c0d5b9fba8c552f3b89eb396872b66c9813ad672fa8fc7a560f75d105e82c926ebee8964f3a59ddc43be18db374e9abcaeb9c8fda71a3d8015683bdb6a4b764f3e4927d53390ac1eb275bd972263667fab4d400852f88af663c353cfe7bd6b81eb03535c2d06584810dfc792f6bc45e52c0103b4e1192a726810186dc3aebe061b353650c7194feec03c37d2ed164758358c5da6aa1bdf9ccae2f45d5bd582cc62d05836380b2eb468160dc1cbd2f8cb94c62248d57baee18f9913f6cfea4909c69f128d1997640d1a038bb1617b52ab13a173e1e87c74d7965df57c6b1baf1f540b16f258e5e691640e93be9bf895703c0f5367099d28a683fa5e912e4b67b18b0a057b1b2dd90b8462bcc27da028e9695ff56969f979c7ea426fa66e282a235fa903f15e8c88d38e35a1f139189fd9243f0f8c83e527d2a420dca72d00e011219787622b3d8923bcea01e1a189a5520bed58dc4544201364ab3dc780df66a29ffe99e270dfc01d3f63357d8b8aabd804a2f625d028d143b6d753ee97976c66afa4c74e28c7a72b5f71a0113c16147dc64746ee04a9fe6487b31b64a8ae97c44f5a61d687f6cd3a758b8e66affd89943596371e335bab26093d74a24dec39b59eab7787e7a440ca7a54e0e49c71ea61b831892bc6d677c2a0b4b04cb3e2e2d26abce88b699789f398f76d61d25f3dfeed422a3036f768a5c15d3c8a1bd6a92aa1149d12175798c774444ab38fc4fb98eea46a2ccdd11112a819f934d616d2b64997c0143755d9f501d1b669d3d2763dc52d6c1f3677e2a20c9faf2667fd19b8e4744ba4ba5f2e86624e30ec0d62db62b23592d47060b9127951edcfd47caf675fba395743b5f226d6ed9930deca235a50fa54cfce12337001dda783763ffe3f04953782653131b815edb764195df6989ad0bd7505a7d932af322dc1281cf0bf3bc5b68f496bbc82f68720aa9f4d9814ad2225f665a566a9bd3cf241edae6f8baa6998fede4f29ba02 | |||
012345678999,4,1,视频I帧,分包处理时的中间包,303163648162000401234567899901030000016cd3a9b9f20000000003b68cd389cf09725debb677ef3dfe230a2c1dfc885f5dca8b786d1771884264710f4efecf75d2c3f3725a483f24827ee312aa764670c3ab6cbe396ade145be1560b05f910eefefec0837fb06cd596e0328b22b40484f127b87626e2b764f1c4bca5ba363104e3ee3a6b154b808a219c1caec5ab6bec1ac908a3805faebec1b8f9ea32e6767f5dfb682b919c50ed48b6b91ef4b7c975c566a69beb752a9ff94131fba6cf514486ec4e2757d3c7ae598ce57ac222a4f75be28cd3eed5e5da199b4c979f249d9289869158dc58d7814f303d82fe9373dca42b854e59721d375f511c2381a5dbe3e31f49d6b37c21214bc63d5d28ab26db4b2fb180c36fa028aa74db1a1c1411cfc18938e53009db5f111ee019cf253370c976f27895f5b804dc03b0057175b1ce50bd16335c294fd8a78c0a89e7399271063e920eb77071b45cbb2f4430047ee26a344283ad335890a8de2620fb9da09277957196a9e79c619223329e57c15aea41cc2695bf05a0f029be0f6000014435c986b8a5ffc8b52179ca6eeacd5c805c8cb7362de0bdf7cca9f18a01c35fb18ab977f85e1e5f1f27ee76ef70bd84c068d28977f3ccafd8a81cb38680a05ddc3785d250251a94d88520fe173b3bda7848cafb7b297e411d409c8fc0f0f985c6fef482693c07cacbffc55d0bb2f677632a57a30b8d40a3b6bb31ff275d3dda834d7446bb1bbfbeaf2a17fe6f2918596c6ed7b0a8f6b414feea8abd29e8743bddb42dc1efa835349865f0840b087e2e2133de268f033ea045868f67b3dfced98893c6bd218a12f1aab8c309ce4aa944188fa17f389f00e6fb4a67c4d3d3f31a8701539888f5527440a4aefd62274635d959dea1c1540301e28d44e8007fe1aebad312eec1d4d669019a84ca7fc494966ebbe44af78b85839aa85503c0068dbd04d5154271df30afd3f4de35f25a9013e0e27e252aed301d4effec8fa3886d26277422a0921bef1c4183dc58ce8a9c83b5d4e163a3fd3279a7dffc65d54b75f5a21309241faca8bc5d369111e696430ddd4ee3f0ca0e5d6d275544fa67a1f528a502aca99a20de523118e7c57f727516127ea84cdb88d86096acdd6fac1e506b6ec7d51a57b552a88a9034ab867b604777286db7b4ed89cdb964ce5a115ca2051f2c1e04fd6ec9f258ba99361e4364ee3bb383bd96b73e67e965c9f538e98a610b1b4d05b20a04b7647c26c9333f067b5acfca527ad50939ea7255a685a07ea419d8092ca595f65d38fd9017c5595b58d7bc08ad26e13e661b0464bf8a4a604374dc5394b0291fd059e8ff1d6817c111fe3c2f00c8608a890dc4cf7a33b8e5b4d0e563e7 | |||
012345678999,5,1,视频I帧,分包处理时的中间包,303163648162000501234567899901030000016cd3a9b9f20000000003b6bd62450f77815accb275c1bc47c7284ad621e7e28ac088c68a30f5dad7a227bce3939e352c58937c7ccfba6d591015ffed083cd74a5eb012838bb1b41a8f325e6b796970a086d9eca960d10b418596261cba541f5297b440de7f2a7f58964e94ef9e254df3587b1fcfd11f7d5e1a6609af2af348f1e6c388cf2a81f37fde1a9d70ffc7fbdb2068a2efb661138c54607e040026207ce5974828444f140ba4690fab448d214a823b569f2cefb1781d21270b47fcdee652d2692ad588e061f22f680603143f50c4fba609cfa6cc45224bab6e954138299fb641e489c68252f80ddd805588404e5fae0dd58eac966d5a19e8bd14988685f6f1bc6ef0031c2b6053982ffc962e68b4aa1a70e7fb47a91261f0acb0d17d59b3ce17804ec16f5c88d730aa7f2bc71ba22937a3aa1ef1958e6316d1a4341ff8deedf85d5d87ffd88ed791cd9ced372fccdf4726e9f0bbf539689a41f14fee3f2183907a5f693267f7e1dd2dbd64ff4e2f717cfb699e998318504d9a2427dfcb6235c3f4aecec5335cef12755f5080e46d600227222b32971c216025e4e392bee8ed19a9100f2c01009691d199ae675b84fee831c1a64a0d1fd47b56bb5dc09da50891ed1774e8a44aa8750b8f41c912379c4bb6f0e7174cdd7c53a6a4b0938f7619b9c13c15fc4bce96c710372121bb93b1d92e1b0985fb34703748801a0782cb11bb607a316f1aa214f8ffe8fb904e2cd21ffa8d498b3188c19d4fe7705ffd62bdc36743da944de3626dce65e492d9500a0ffd13bd9d602cec65581bf4f64a57ce8cffb4687b6f202792dc92599dfab07066803586f14ccf0a2e6398752332fc3e30cb2553e0d97bd01d3212d12750a1fd0d6ff98b4b38b2bef39190c7a415daf9fbf2004cdbe6b31416a0667f6d02abe531a756c59d52f0ae6caa47a0394eb18fe93a14c3227b491a8a000e70b56227dcbce2e477125a8f8807626b16e0a915622172412aad1c4f502997e28aea12c39c5eacc308d9e49c440b3ffac3179b2737e280a6f2968f8e9721b9e8fb8228322e9a01c8331a4dbd55b30040dd25148acef58e63e12942276a4a41ba153efeea2a0b9cc474436238c24080d19427132ea61391146a9912c89cdd6e7edc6914f621e13723b165870c6b244664f1546d10ad0738349f8c78111f9cd04e55a9efc9887e945d296f857fc6e58a8fba4ab88661d8ad68ba78a173a834c9d980a60e917b468b3b3e6e67c8ab9cb35d0df8d2d762596668d41d3d02dfc4178c4d252cd8ea356bf64660c9fc6eb7baa402681b55d3bfdf7df687ef6352cdb4051ffaa7eaebc1c6a6189f023b14d64ef33f5f26ea | |||
012345678999,6,1,视频I帧,分包处理时的中间包,303163648162000601234567899901030000016cd3a9b9f20000000003b6797a9891e014bade387cb3b9676209b9cf5d74f32447df99a5b4fe27de8d2b96d49bff6d51c111c596752ad81bba368df135bcfc094b7f03189f8e1b99ddc6797bf983765c4d3d9ee4b312f1591730b2dc58572de846542a98a04d590e6ff2732055979b4a8bf2319e21e939bf6d22bbd70d03dfbc47d3d51942deee740e1a0d65771445687359a163d3c46a3be755680785df058473f52222838f98c48693ab9b63f24ad7ce245de4f2b610ab504ac1f642665978cea5cd33e7ddb42456e0fb493425c38b7194911a716c3b374087a20cfb6dd1763644716dfe1fb90e47f4812306febb1b1b61950c0e372fd286cadcbdae825a424f0ad36cbfbada872cfda67cb6d0940094d3e700ab47f6597a7d4a8583888c783d39be12c1780424ad8bcb330f8d84ea74c39f78da72a2d276539fb8d4f9bb9f99ac3e9cbc2f514432bfd9f0b5001f6cbdb88b8623a551a3b55b50f0139a5803a6af6547bc18f706d1027966d5fe04b4c6d9602376ba4d6bf74cc37ef7cc5ee5d3fe39b1aaf047e26315a4aa4cde6ccf38d51ef14c8acab63262fa0731b4a45dde09bfcbddbb79d29a10a0ffdcca4886cb90d46c74f61ddfacca9e94fc82ca6ffb892bc80cf24f3070c4fc6536547df2d667d8488de5cb977dda8dd1a08b83839a451431a198bfaba058fff2a1ac8711bbe8bcef215cdacf474a031cc7e157ccc63292a767eb184cc1c1aa3111c69372e13ab80abdd4743b29c2d94f6170f249f5c9f3ed25b1e59c1554cbc10397974089c0ae1775467bb54807eeebf8d3ba4335ba5f223113a22a1c442d0721a2c72d51ef1cb927e4eb0b4134f01d3855dd317bf33c706832f1d2859853b6210cf2f781d80904cbddbeb2baf44d28790024fbd317a825c98df2f346682092e95f3572f9442bc8762d5753f23f49d377a0f46202615eff594f054d1e5c16ff1066ae1b79e4b0257c4b9a257e9f3c9c9eecbfc6f501b9849197ffe8ff88a9af96da80805bf62ac17e792208ca66212d06300d4cffc5e5463c60f5e44b0d113be35829bfb15680d4de81f3588dfd8adee8564884b1ca68a3aba8115f06aa41f642c70fb4374568509c9666211c97c44a05d67ea5e5562f5cfc6fdd076f5ffebc3c37b4e6d7fe235f9670f2261a6745425e91bdab2e14cf666686472651b9b43524d3ef5ac1c4e432fbb2fb99b8ba166c9d343a30ed3a711c5d2fe545902ec57c642d2148c5c0b9bf0bec37ec6986cf1c33ae7bf2ec5ef1f11351e9ee58ecfe5503d8225e28412fdc3a721eb1cef93445fd49dd14cc15fb891027aeb6077fa85c6cc0059404bbf8862b52933ee9ed3da24b505ee110 | |||
012345678999,7,1,视频I帧,分包处理时的最后一个包,3031636481e2000701234567899901020000016cd3a9b9f20000000003a4e012eba47e69c63ce2b050264c0949e7e4dfe5e0e1323c0c71b7760f4b3f692f7507e01c5cd56f0b518d4c9539b500510ec53fe955f86698ed65f4546663bb4fac1fcc73f9c462ad8c2f1365c7bad60d76bb50d33588ff7db86d16611feed8007bcc8f2355c1454ad286ba15fee4d374ec91909f2936a67b5de74700d273f272bc5a6d52dd342a6368471cdeba191b8ba9ddc9bdce8a93063a909d2167b19b27a8cd7e2634f630bff1faf36fd6fb1108a9dc8e51fe949f4fbaaeaaa98ec8147087e5c60c65b1f355d4e62577f72b450d7d3fc878c1fb90e1be03c6f1166f738e60db958ec0cc320d6f66225861a695350dd8c84bc5ddb0d35ea8d4d4e40bd79a3e73d86cdce986ee25af6eb5447f45af3c35c11e114ee82e8da7b6aff97ad9118a732bf1489f6ad2abc4123814b4b8b0ae9400996840d66ecd7574ac539bd3ed252da0136a920844d751b5cba2a515a492e943f5d709376d0f297195d29c4316664bfc83d8aebae02e997578f3697327e6c03c2d2681767adcce4523f15331c1f4778300600e74c259666ea6893471d6b5f764d81a78c4983dbc8d75c7c09c585f8a44b71fe63c1eacf9661f646f7cea999b21c920f1a806e8f388efe2be388b2770d02cce2508b76fe0ed8a5a4afd46ab989ed553c0059d09a883dd42ced5f91d95337c475e5324803db33f61e71fc59d98894f56c19843557da9df9663438ed4678645943c2d2e2b7395464e384f00f83d7a1f3f3d748720856c9b261058c277f0ea18457355644c0d46619d658ec2e0316b643863734c3f12d9dffec598beeaf2bf3b5bd8cebc62a772e4690d14cbc0dcaabc5a9e3a865f2871fb38d7da0117ecb6ef3479b0fbb5d21e4d822e025fa149e880b87f3dcc764996284f8a19dd9eefb02afd88057ea943ab91bcf6627e94e5ae739e72dc0fa8e43bb50770e0369a8b144635dc623d93b3a55619c02c766cc75219efbbe7ff032e8d078e485aeaa2e0cbea63cb7887830dec58993f11049b22b2961ed5bf4d4878b3fb7c379b546c9a375134f48b15a1971ce9bc3fd7a7f2c0fe1010e28e0ac11b3365c102a0cc041eb12e0cc7372e6cc1dc7c6f7ddcf6fb0563eebbd3cd747a029693e0ad9784a775a4c334eeac3f3cc69551b77a5b2b9fd581fd0a3a8e87e7f96fe24e669c17d48ff5d9298330f47fd7c3361e74a3d3cf27fc474b6a6af8357812c5c663634cf9b70f1f1330a2750a04e996597f4e1d84650435c9d02788b4315d16f464312afc818d5c3ad87c7deefab369d3be3e84d30fbd728f4d5beb648db98e5ec39abb29990980 |
@@ -2,8 +2,6 @@ | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp3.0</TargetFramework> | |||
<IsPackable>false</IsPackable> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
@@ -17,4 +15,14 @@ | |||
<ProjectReference Include="..\JT1078.Flv\JT1078.Flv.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="Metadata\" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Update="H264\JT1078.txt"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
</Project> |
@@ -1,28 +0,0 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT1078.Flv.Enums | |||
{ | |||
public enum Amf3Type : byte | |||
{ | |||
Undefined, | |||
Null, | |||
False, | |||
True, | |||
Integer, | |||
Double, | |||
String, | |||
XmlDocument, | |||
Date, | |||
Array, | |||
Object, | |||
Xml, | |||
ByteArray, | |||
VectorInt, | |||
VectorUInt, | |||
VectorDouble, | |||
VectorObject, | |||
Dictionary | |||
} | |||
} |
@@ -5,7 +5,7 @@ using System.Text; | |||
namespace JT1078.Flv | |||
{ | |||
public class FlvMuxer | |||
public class FlvEncoder | |||
{ | |||
private static readonly FlvHeader VideoFlvHeader = new FlvHeader(true, false); | |||
public byte[] FlvFirstFrame() | |||
@@ -20,7 +20,7 @@ namespace JT1078.Flv | |||
//flv body PreviousTagSize awalys 0 | |||
flvMessagePackWriter.WriteUInt32(0); | |||
//flv body tag | |||
//flv body tag header | |||
//flv body tag body | |||
@@ -39,6 +39,9 @@ namespace JT1078.Flv | |||
{ | |||
FlvMessagePackWriter flvMessagePackWriter = new FlvMessagePackWriter(buffer); | |||
#warning 目前只支持视频 | |||
// NalUnitType == 1 | |||
//flv body | |||
//flv body PreviousTagSize | |||
@@ -9,7 +9,7 @@ using System.Text; | |||
namespace JT1078.Flv.H264 | |||
{ | |||
public class H264Demuxer | |||
public class H264Decoder | |||
{ | |||
public List<H264NALU> ParseNALU(JT1078Package package) | |||
{ | |||
@@ -71,7 +71,7 @@ namespace JT1078.Flv.H264 | |||
{ | |||
H264NALU nALU = new H264NALU(); | |||
nALU.SIM = package.SIM; | |||
nALU.Label3 = package.Label3; | |||
nALU.DataType = package.Label3.DataType; | |||
nALU.LogicChannelNumber = package.LogicChannelNumber; | |||
nALU.LastFrameInterval = package.LastFrameInterval; | |||
nALU.LastIFrameInterval = package.LastIFrameInterval; | |||
@@ -103,14 +103,19 @@ namespace JT1078.Flv.H264 | |||
/// </summary> | |||
/// <param name="h264NALU"></param> | |||
/// <returns></returns> | |||
public void NALUTypeFilter(H264NALU h264NALU) | |||
private void NALUTypeFilter(H264NALU h264NALU) | |||
{ | |||
switch (h264NALU.NALUHeader.NalUnitType) | |||
{ | |||
//IPB帧 | |||
case 1: | |||
break; | |||
//IDR | |||
case 5: | |||
break; | |||
//SEI | |||
case 6: | |||
h264NALU.RawData = DiscardEmulationPreventionBytes(h264NALU.RawData); | |||
@@ -1,4 +1,4 @@ | |||
using JT1078.Protocol; | |||
using JT1078.Protocol.Enums; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
@@ -22,18 +22,8 @@ namespace JT1078.Flv.H264 | |||
public byte LogicChannelNumber { get; set; } | |||
/// <summary> | |||
/// 数据类型 | |||
/// 0000:视频I帧 | |||
/// 0001:视频P帧 | |||
/// 0010:视频B帧 | |||
/// 0011:音频帧 | |||
/// 0100:透传数据 | |||
/// | |||
/// 0000:原子包,不可被拆分 | |||
/// 0001:分包处理时的第一个包 | |||
/// 0010:分包处理是的最后一个包 | |||
/// 0011:分包处理时间的中间包 | |||
/// </summary> | |||
public JT1078Label3 Label3 { get; set; } | |||
public JT1078DataType DataType { get; set; } | |||
/// <summary> | |||
/// 该帧与上一个关键帧之间的时间间隔,单位毫秒(ms), | |||
/// 当数据类型为非视频帧时,则没有该字段 | |||
@@ -1,7 +1,7 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks> | |||
<TargetFrameworks>netstandard2.0;netstandard2.1;</TargetFrameworks> | |||
<LangVersion>8.0</LangVersion> | |||
</PropertyGroup> | |||
@@ -17,4 +17,10 @@ | |||
<ProjectReference Include="..\JT1078.Protocol\JT1078.Protocol.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Update="JT1078.txt"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,8 @@ | |||
012345678999,0,1,视频I帧,分包处理时的第一个包,303163648162000001234567899901010000016cd3a9b9f20000000003b600000001674d001495a85825900000000168ee3c800000000106e5013c800000000165b8000028f10bffab7d4ef364e8a2c87f9b90c26e8065ef699b0f3bf22e8c6501f7ef3b0fbd19fe1939cf7a7838f1d84b88a4209bf029065cbc4eeafb98f5925e66e9c6b5f399b7218a1555039a95b921b83f6221fe0ceb0ee6daeb19e08968d8217f7095e3bed833215d59a93179667811c81a02ee82b170ac0e28d19b1a3ee21cfacffeec402074cfc6e0b478874387554f0fa5557ef805223885a674bb97892878fbda3a9e29b4f309bf0b29d2745b9eec49dbd9158a9bd746655bbf8e903f4bec96131970b188caa74d233a471c58c0c60603a80a0e6519d7dd2c9eb577cb0df24ea7d72f39521f90afcb396166015273add9d1d7e47bc2973e39f17e4cfd641eca8149136bac8e3be5450a9f9e304f2495067b5c3b5b9dc886dc2f01fd418aaa67121c6fb094b1cbf2dbf07e346d4071b75e9c77a52db90606c219e826c96e427444e4ac0d0df32e3c04ba32b615853feafc6beb82667e46424d0e173767a34639df3c6e25b112cfd80ef6159ca1a23aa96e932c8989239ef0cc80929facf99f6bcdb110afb179c01199897785c9f07beea5d8097b9a4f6c94251958552c0aca330c7fe995712b8311cdbbf4627562cfd8e3dcade064ff7a59f9564e3773fc108a4fb8de2bfaada56ef6fdac74a5b7cd442dc701edd06e865401029a230ec348235e0e0608b3c66630dc069e02ebd3c9bf2bc1e90141e5c77d7ff69b62db661b2ffc02ce1edc6b09a4a3c455b6daad227ea251d8f3cab5bcca5898edc310ea4bb2477337f92d39f18bc258f04f4d3a5881c71b3d13ae5e393340cd1288863071419ceb6416e917e0e0553b340bf4a381f6ee71ab083bf119e5b69791a60851e995e8313a62916f835c1538a8f3d775a7cfd6ab9ba106f2a19eb1ba802724c1641e0bde105e392bfa437a188df395e9d287d436b208481307e97728a18117ef43577ff1e922c824f996d60ae0d6d9390ff97ee90691c2710899784adbe7ff6ca7f487f7ceea7f855eeb18f3f250ebaef9efeb97a9bead5b80de5069627d5f4fed615f0c7ed87965857f744fd7ff8f4d2b79f0d7b7f865fa26cc77eea03701266318ec3399bbcabe93d9a97f7b4f3bb9ac27aff8a529d4310216c8e9a6ca49e47e4371bc2cd551e6b3d4f56925fc9fbebb72041a31066ebc37cc61a7c1396ac48e864d7e8fb644a5fa49b73f8c7befdc4f05c88291623e5e3d0f4bd54b9b2c478467ac5e42a8080eabd37672f35903f4f44d2827d96960d76ab8bc86e0ff4a29afd4ae2ef5dd3d2825786e1229f26b797e35 | |||
012345678999,1,1,视频I帧,分包处理时的中间包,303163648162000101234567899901030000016cd3a9b9f20000000003b6a6fb10545aee778627f92f2bd15c71782be2793bb2ba0cc97d44bf79f7bc7c4186c9c806ce7bfff616c79758a53564d306fd770055679467f94f232149a8232e4b0866a2049ba007d64657886dd689222152226874b4ecb0d5f936807fa704d84567405cb49570de8e990ff4748fe6abcd1a0a9982a78b487ec56278c3334fc4579e75708abed0175ee5baa548deb84d0af5cc9cb918bf851f8e78867968f32f6fa9ebd2b93554636813274839d6944529f204559ff388d6ea4c63adb0d8ddf9ddb27cd7ebe33287a6139688225d0aa5256af74fd0d9358f7bc072abf4a3f1d59ad318aef1453ce4a229781420056e89e5ab9dccacd69ac688e590e6ffbbbc79ba2d83da0d9d9f80d55b295a1bc5b2df2699a75d95638da525b70c93d9fb48c8bd6a8d53adfa9c7f3c1ee7ad5d8429e28bea5c6c033762b6398528dd7bf05e3fc134a83f9ef2543d581b4f45ce17813035ce0432b69ad4d1d22c12003e442631bac549a8e0a2b1fb4a7da58e91122ba67537e7d02d66f6d4971e8c080f1855156490ef5c16299f84d04f2600b54972ffaa15e70d3ded386cd2ebb4321070c76530b5c0ede147d63d6d1779f5bac91d95bc8725e8b1605db7cd92f0a3b142394dec894ce3910462b375e8cbd70ae493dd0ecb143997673468b9add2f81001b3cae5d51ee197ba68edfffd1a3ffdd0e1f167bb0137f6049ad3470998ad8df7c78c414f79d39e6490715d71100eb6ae8d3e8ad4783a7d24a5594ffa10fa0dbb30a41d2fa62304eff3477b82f5aff028629accd32a5940c2d2657443f0fde5a6bb06bc3c82e6dac6e51b0b476a804aba5c84565f79ca99561f735dcc5a18001f043491ad0e2a0c2c65afea3fee2bb158f50cc8eb071308b12b580e0c6bfefeb9f9fc0fed333276cb2ff27e04dcc2399bbee6562952268af2d1e05f0b301f7fc261ce1a8d8c0cbade4eddc4cdff8f62aac0f6807d47771cfaf33d3700856ceaea66892e43fcb83b7a9e32ae1b759dc7ec581747f1c2cb7a32c69e91a7124294d53087f6b2dc1ad63fb2ecf04a16b548902402f38e7ecf6d7fede301f83b76f1f329a60c6863dfec8c3a7984bc1abf6481eae4f7d8218b882818482e424a0ca645f6b0445c5a9e239a2b4bc3d6a70c3f3f51fb6346b3ce643421a7697e43b5e0fd4ba2c519b6cc62ee6ac7dff3c81a7d0ee4eb291de62edba5e05212e82e968f85b78dcb875b67a9198eefea0960d4873d92a8b32fb88236b207157e5453a96fd5792da527bd1b195f426351b516c21900631a571c6d02b144c88ab72b35ed300d99cef12c1a3ccf95ebe305ed4513431661be9245c4a4ba62 | |||
012345678999,2,1,视频I帧,分包处理时的中间包,303163648162000201234567899901030000016cd3a9b9f20000000003b6da72bd536f42168e2c3d18a96c3aea86ae57cb5fb116978ff2481a70efc9da6397ffc9c6b52ffd524c68f50b01ad81fb0740d9334df9a632d21aa1bf0addc4d21f4dc00d61533748f4c42b045ffd65f62d32f86f269c4cf1842558f3ca2450e404e589c4d271d570e052b2d451ea2978641d44398d98c65967e5f0c61f23d8b7e7aca9ae900926739d85231edabc08fdb6670dafc84ddbbd3d824c33140359573ab1c2942f0aa05f9eb08ff94d9964995ae63599f9e26c606ba6f009d0cf6693c984cbfed2ea7a822cc9543ac76e00788ebe0b449c93b4961c45bf7ff82d40bb4c7c3a3dde1a8820fd5832834ddb5a6210cdf0dffdf48d84a7596eae5f653309da08dc592a406d9f55c511d858fdc575b930773b59be022bf7776294e3e5ef9b9386191fe2c8c1d38708dff87ddff23cfeb8b42154adfd598a92979fa59b40c7900d7c3df8a53d08836c38c5134a7abc7eafc8c10cdb60366286ddfcb7c193999ddc95af2f6c76ff158213a19b63f79cce1fe1fcc6b949ecea7d1853936047503594676466bc70dd61127986aab961834419b17ae6ed63c87f06bc7e2c1e3b1358dfe822c86577b5fac89f957a90fbcd39f67378cc1cc22a56d081e3fb1a5e6060152aee2331c297c3646cc604e13a7a4a383a37d417acb7d1076a79ca794ab16a7ca56a31a8e4dc032025ec5181038f034a502fba62ad21e5990c0235d6d26faaf693a89dfba3d07f75759b8155532b91b84f03b0f134af30e2b007e68a6da50c8a040e4e9e7d0b53f381b6b7ab3de85f28cb3b51fd23b89865d833861423a3b194bfb8c8e5fe566ffb018b6295c076940696e726658370289a4cfd66ae566a024d1ff94c5d65d9bfed4fe89df67839904785796ceb6264dc0ff4b103acaf05a65a6fbeb9e15db3a06b33df4e1f8365868e8cf1b13734ec27e23879f061d833182fe9d034d559a56d6da5708896bc6a0b5914261d20923f496cda936f108adf7164861b577af5ba7116d3ede71b16465fb462fce107844cf3583a9997a03415680458b097ed95bf06fb0d3df2d991d2437460005412429e120e55aa79bdc2f1783bb45db8f6008581bd07d1a3282ee7c0e0c4d6b2fb546daeb2cef04937e799c7d96962dc51237963dce7345161a2b905ba89046db6435890d09500babd98d13c26bcf86f6b5214082d28b76bb7ad1c4f81edfff93a5895eed2ebba9250fccdda3f53f020a089246bc00cd0de21b9169cbd1df9849b2893ed774a1d149c50da0287c25271823c99de17236b6544c1e5a009416ada3e57474944d3f94ed16cfd7473629e77be9a349027e0d8f7e796384664c0285a77 | |||
012345678999,3,1,视频I帧,分包处理时的中间包,303163648162000301234567899901030000016cd3a9b9f20000000003b6b83940b4220e76c108af6432deb4d1a5ececc2906174181c9d85828a5df10e8046a276ce933e0720f7dd4bd234baf61d98adbd8d623be2c7e8c5d3272d41af666f44dd4bf0d5ecf47ccb0bda03299a2d70cb76ba7b73ae0c92e38e2af9c1c8848996666d2741efe033e46a01a19e6f9fe8c90e088ad0d034d53cce3bacf1b87b8f46b31087f21cbff177d2fa17aab609e0c1dabcda428830bd23df87cbe245b34407c6593e6179985db026112eb853a0b1d79f46a9691ee7aebb78009f145f04946ea8c60f01cf0e6c9bea1e7fdfc6307615aedde4f7941ffc1be711dea15c84c519dc860824cdc6eb96b64d74c0d5b9fba8c552f3b89eb396872b66c9813ad672fa8fc7a560f75d105e82c926ebee8964f3a59ddc43be18db374e9abcaeb9c8fda71a3d8015683bdb6a4b764f3e4927d53390ac1eb275bd972263667fab4d400852f88af663c353cfe7bd6b81eb03535c2d06584810dfc792f6bc45e52c0103b4e1192a726810186dc3aebe061b353650c7194feec03c37d2ed164758358c5da6aa1bdf9ccae2f45d5bd582cc62d05836380b2eb468160dc1cbd2f8cb94c62248d57baee18f9913f6cfea4909c69f128d1997640d1a038bb1617b52ab13a173e1e87c74d7965df57c6b1baf1f540b16f258e5e691640e93be9bf895703c0f5367099d28a683fa5e912e4b67b18b0a057b1b2dd90b8462bcc27da028e9695ff56969f979c7ea426fa66e282a235fa903f15e8c88d38e35a1f139189fd9243f0f8c83e527d2a420dca72d00e011219787622b3d8923bcea01e1a189a5520bed58dc4544201364ab3dc780df66a29ffe99e270dfc01d3f63357d8b8aabd804a2f625d028d143b6d753ee97976c66afa4c74e28c7a72b5f71a0113c16147dc64746ee04a9fe6487b31b64a8ae97c44f5a61d687f6cd3a758b8e66affd89943596371e335bab26093d74a24dec39b59eab7787e7a440ca7a54e0e49c71ea61b831892bc6d677c2a0b4b04cb3e2e2d26abce88b699789f398f76d61d25f3dfeed422a3036f768a5c15d3c8a1bd6a92aa1149d12175798c774444ab38fc4fb98eea46a2ccdd11112a819f934d616d2b64997c0143755d9f501d1b669d3d2763dc52d6c1f3677e2a20c9faf2667fd19b8e4744ba4ba5f2e86624e30ec0d62db62b23592d47060b9127951edcfd47caf675fba395743b5f226d6ed9930deca235a50fa54cfce12337001dda783763ffe3f04953782653131b815edb764195df6989ad0bd7505a7d932af322dc1281cf0bf3bc5b68f496bbc82f68720aa9f4d9814ad2225f665a566a9bd3cf241edae6f8baa6998fede4f29ba02 | |||
012345678999,4,1,视频I帧,分包处理时的中间包,303163648162000401234567899901030000016cd3a9b9f20000000003b68cd389cf09725debb677ef3dfe230a2c1dfc885f5dca8b786d1771884264710f4efecf75d2c3f3725a483f24827ee312aa764670c3ab6cbe396ade145be1560b05f910eefefec0837fb06cd596e0328b22b40484f127b87626e2b764f1c4bca5ba363104e3ee3a6b154b808a219c1caec5ab6bec1ac908a3805faebec1b8f9ea32e6767f5dfb682b919c50ed48b6b91ef4b7c975c566a69beb752a9ff94131fba6cf514486ec4e2757d3c7ae598ce57ac222a4f75be28cd3eed5e5da199b4c979f249d9289869158dc58d7814f303d82fe9373dca42b854e59721d375f511c2381a5dbe3e31f49d6b37c21214bc63d5d28ab26db4b2fb180c36fa028aa74db1a1c1411cfc18938e53009db5f111ee019cf253370c976f27895f5b804dc03b0057175b1ce50bd16335c294fd8a78c0a89e7399271063e920eb77071b45cbb2f4430047ee26a344283ad335890a8de2620fb9da09277957196a9e79c619223329e57c15aea41cc2695bf05a0f029be0f6000014435c986b8a5ffc8b52179ca6eeacd5c805c8cb7362de0bdf7cca9f18a01c35fb18ab977f85e1e5f1f27ee76ef70bd84c068d28977f3ccafd8a81cb38680a05ddc3785d250251a94d88520fe173b3bda7848cafb7b297e411d409c8fc0f0f985c6fef482693c07cacbffc55d0bb2f677632a57a30b8d40a3b6bb31ff275d3dda834d7446bb1bbfbeaf2a17fe6f2918596c6ed7b0a8f6b414feea8abd29e8743bddb42dc1efa835349865f0840b087e2e2133de268f033ea045868f67b3dfced98893c6bd218a12f1aab8c309ce4aa944188fa17f389f00e6fb4a67c4d3d3f31a8701539888f5527440a4aefd62274635d959dea1c1540301e28d44e8007fe1aebad312eec1d4d669019a84ca7fc494966ebbe44af78b85839aa85503c0068dbd04d5154271df30afd3f4de35f25a9013e0e27e252aed301d4effec8fa3886d26277422a0921bef1c4183dc58ce8a9c83b5d4e163a3fd3279a7dffc65d54b75f5a21309241faca8bc5d369111e696430ddd4ee3f0ca0e5d6d275544fa67a1f528a502aca99a20de523118e7c57f727516127ea84cdb88d86096acdd6fac1e506b6ec7d51a57b552a88a9034ab867b604777286db7b4ed89cdb964ce5a115ca2051f2c1e04fd6ec9f258ba99361e4364ee3bb383bd96b73e67e965c9f538e98a610b1b4d05b20a04b7647c26c9333f067b5acfca527ad50939ea7255a685a07ea419d8092ca595f65d38fd9017c5595b58d7bc08ad26e13e661b0464bf8a4a604374dc5394b0291fd059e8ff1d6817c111fe3c2f00c8608a890dc4cf7a33b8e5b4d0e563e7 | |||
012345678999,5,1,视频I帧,分包处理时的中间包,303163648162000501234567899901030000016cd3a9b9f20000000003b6bd62450f77815accb275c1bc47c7284ad621e7e28ac088c68a30f5dad7a227bce3939e352c58937c7ccfba6d591015ffed083cd74a5eb012838bb1b41a8f325e6b796970a086d9eca960d10b418596261cba541f5297b440de7f2a7f58964e94ef9e254df3587b1fcfd11f7d5e1a6609af2af348f1e6c388cf2a81f37fde1a9d70ffc7fbdb2068a2efb661138c54607e040026207ce5974828444f140ba4690fab448d214a823b569f2cefb1781d21270b47fcdee652d2692ad588e061f22f680603143f50c4fba609cfa6cc45224bab6e954138299fb641e489c68252f80ddd805588404e5fae0dd58eac966d5a19e8bd14988685f6f1bc6ef0031c2b6053982ffc962e68b4aa1a70e7fb47a91261f0acb0d17d59b3ce17804ec16f5c88d730aa7f2bc71ba22937a3aa1ef1958e6316d1a4341ff8deedf85d5d87ffd88ed791cd9ced372fccdf4726e9f0bbf539689a41f14fee3f2183907a5f693267f7e1dd2dbd64ff4e2f717cfb699e998318504d9a2427dfcb6235c3f4aecec5335cef12755f5080e46d600227222b32971c216025e4e392bee8ed19a9100f2c01009691d199ae675b84fee831c1a64a0d1fd47b56bb5dc09da50891ed1774e8a44aa8750b8f41c912379c4bb6f0e7174cdd7c53a6a4b0938f7619b9c13c15fc4bce96c710372121bb93b1d92e1b0985fb34703748801a0782cb11bb607a316f1aa214f8ffe8fb904e2cd21ffa8d498b3188c19d4fe7705ffd62bdc36743da944de3626dce65e492d9500a0ffd13bd9d602cec65581bf4f64a57ce8cffb4687b6f202792dc92599dfab07066803586f14ccf0a2e6398752332fc3e30cb2553e0d97bd01d3212d12750a1fd0d6ff98b4b38b2bef39190c7a415daf9fbf2004cdbe6b31416a0667f6d02abe531a756c59d52f0ae6caa47a0394eb18fe93a14c3227b491a8a000e70b56227dcbce2e477125a8f8807626b16e0a915622172412aad1c4f502997e28aea12c39c5eacc308d9e49c440b3ffac3179b2737e280a6f2968f8e9721b9e8fb8228322e9a01c8331a4dbd55b30040dd25148acef58e63e12942276a4a41ba153efeea2a0b9cc474436238c24080d19427132ea61391146a9912c89cdd6e7edc6914f621e13723b165870c6b244664f1546d10ad0738349f8c78111f9cd04e55a9efc9887e945d296f857fc6e58a8fba4ab88661d8ad68ba78a173a834c9d980a60e917b468b3b3e6e67c8ab9cb35d0df8d2d762596668d41d3d02dfc4178c4d252cd8ea356bf64660c9fc6eb7baa402681b55d3bfdf7df687ef6352cdb4051ffaa7eaebc1c6a6189f023b14d64ef33f5f26ea | |||
012345678999,6,1,视频I帧,分包处理时的中间包,303163648162000601234567899901030000016cd3a9b9f20000000003b6797a9891e014bade387cb3b9676209b9cf5d74f32447df99a5b4fe27de8d2b96d49bff6d51c111c596752ad81bba368df135bcfc094b7f03189f8e1b99ddc6797bf983765c4d3d9ee4b312f1591730b2dc58572de846542a98a04d590e6ff2732055979b4a8bf2319e21e939bf6d22bbd70d03dfbc47d3d51942deee740e1a0d65771445687359a163d3c46a3be755680785df058473f52222838f98c48693ab9b63f24ad7ce245de4f2b610ab504ac1f642665978cea5cd33e7ddb42456e0fb493425c38b7194911a716c3b374087a20cfb6dd1763644716dfe1fb90e47f4812306febb1b1b61950c0e372fd286cadcbdae825a424f0ad36cbfbada872cfda67cb6d0940094d3e700ab47f6597a7d4a8583888c783d39be12c1780424ad8bcb330f8d84ea74c39f78da72a2d276539fb8d4f9bb9f99ac3e9cbc2f514432bfd9f0b5001f6cbdb88b8623a551a3b55b50f0139a5803a6af6547bc18f706d1027966d5fe04b4c6d9602376ba4d6bf74cc37ef7cc5ee5d3fe39b1aaf047e26315a4aa4cde6ccf38d51ef14c8acab63262fa0731b4a45dde09bfcbddbb79d29a10a0ffdcca4886cb90d46c74f61ddfacca9e94fc82ca6ffb892bc80cf24f3070c4fc6536547df2d667d8488de5cb977dda8dd1a08b83839a451431a198bfaba058fff2a1ac8711bbe8bcef215cdacf474a031cc7e157ccc63292a767eb184cc1c1aa3111c69372e13ab80abdd4743b29c2d94f6170f249f5c9f3ed25b1e59c1554cbc10397974089c0ae1775467bb54807eeebf8d3ba4335ba5f223113a22a1c442d0721a2c72d51ef1cb927e4eb0b4134f01d3855dd317bf33c706832f1d2859853b6210cf2f781d80904cbddbeb2baf44d28790024fbd317a825c98df2f346682092e95f3572f9442bc8762d5753f23f49d377a0f46202615eff594f054d1e5c16ff1066ae1b79e4b0257c4b9a257e9f3c9c9eecbfc6f501b9849197ffe8ff88a9af96da80805bf62ac17e792208ca66212d06300d4cffc5e5463c60f5e44b0d113be35829bfb15680d4de81f3588dfd8adee8564884b1ca68a3aba8115f06aa41f642c70fb4374568509c9666211c97c44a05d67ea5e5562f5cfc6fdd076f5ffebc3c37b4e6d7fe235f9670f2261a6745425e91bdab2e14cf666686472651b9b43524d3ef5ac1c4e432fbb2fb99b8ba166c9d343a30ed3a711c5d2fe545902ec57c642d2148c5c0b9bf0bec37ec6986cf1c33ae7bf2ec5ef1f11351e9ee58ecfe5503d8225e28412fdc3a721eb1cef93445fd49dd14cc15fb891027aeb6077fa85c6cc0059404bbf8862b52933ee9ed3da24b505ee110 | |||
012345678999,7,1,视频I帧,分包处理时的最后一个包,3031636481e2000701234567899901020000016cd3a9b9f20000000003a4e012eba47e69c63ce2b050264c0949e7e4dfe5e0e1323c0c71b7760f4b3f692f7507e01c5cd56f0b518d4c9539b500510ec53fe955f86698ed65f4546663bb4fac1fcc73f9c462ad8c2f1365c7bad60d76bb50d33588ff7db86d16611feed8007bcc8f2355c1454ad286ba15fee4d374ec91909f2936a67b5de74700d273f272bc5a6d52dd342a6368471cdeba191b8ba9ddc9bdce8a93063a909d2167b19b27a8cd7e2634f630bff1faf36fd6fb1108a9dc8e51fe949f4fbaaeaaa98ec8147087e5c60c65b1f355d4e62577f72b450d7d3fc878c1fb90e1be03c6f1166f738e60db958ec0cc320d6f66225861a695350dd8c84bc5ddb0d35ea8d4d4e40bd79a3e73d86cdce986ee25af6eb5447f45af3c35c11e114ee82e8da7b6aff97ad9118a732bf1489f6ad2abc4123814b4b8b0ae9400996840d66ecd7574ac539bd3ed252da0136a920844d751b5cba2a515a492e943f5d709376d0f297195d29c4316664bfc83d8aebae02e997578f3697327e6c03c2d2681767adcce4523f15331c1f4778300600e74c259666ea6893471d6b5f764d81a78c4983dbc8d75c7c09c585f8a44b71fe63c1eacf9661f646f7cea999b21c920f1a806e8f388efe2be388b2770d02cce2508b76fe0ed8a5a4afd46ab989ed553c0059d09a883dd42ced5f91d95337c475e5324803db33f61e71fc59d98894f56c19843557da9df9663438ed4678645943c2d2e2b7395464e384f00f83d7a1f3f3d748720856c9b261058c277f0ea18457355644c0d46619d658ec2e0316b643863734c3f12d9dffec598beeaf2bf3b5bd8cebc62a772e4690d14cbc0dcaabc5a9e3a865f2871fb38d7da0117ecb6ef3479b0fbb5d21e4d822e025fa149e880b87f3dcc764996284f8a19dd9eefb02afd88057ea943ab91bcf6627e94e5ae739e72dc0fa8e43bb50770e0369a8b144635dc623d93b3a55619c02c766cc75219efbbe7ff032e8d078e485aeaa2e0cbea63cb7887830dec58993f11049b22b2961ed5bf4d4878b3fb7c379b546c9a375134f48b15a1971ce9bc3fd7a7f2c0fe1010e28e0ac11b3365c102a0cc041eb12e0cc7372e6cc1dc7c6f7ddcf6fb0563eebbd3cd747a029693e0ad9784a775a4c334eeac3f3cc69551b77a5b2b9fd581fd0a3a8e87e7f96fe24e669c17d48ff5d9298330f47fd7c3361e74a3d3cf27fc474b6a6af8357812c5c663634cf9b70f1f1330a2750a04e996597f4e1d84650435c9d02788b4315d16f464312afc818d5c3ad87c7deefab369d3be3e84d30fbd728f4d5beb648db98e5ec39abb29990980 |
@@ -3,6 +3,7 @@ using Xunit; | |||
using JT808.Protocol.Extensions; | |||
using JT1078.Protocol.Enums; | |||
using System.Linq; | |||
using System.IO; | |||
namespace JT1078.Protocol.Test | |||
{ | |||
@@ -302,5 +303,25 @@ namespace JT1078.Protocol.Test | |||
Assert.Equal(JT1078DataType.视频B帧, label3.DataType); | |||
Assert.Equal(JT1078SubPackageType.分包处理时的最后一个包, label3.SubpackageType); | |||
} | |||
[Fact] | |||
public void MergeTest() | |||
{ | |||
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "JT1078.txt")); | |||
JT1078Package merge=null; | |||
int mergeBodyLength=0; | |||
foreach (var line in lines) | |||
{ | |||
var data = line.Split(','); | |||
var bytes = data[5].ToHexBytes(); | |||
JT1078Package package = JT1078Serializer.Deserialize(bytes); | |||
mergeBodyLength += package.DataBodyLength; | |||
merge = JT1078Serializer.Merge(package); | |||
} | |||
Assert.NotNull(merge); | |||
Assert.Equal(mergeBodyLength, merge.Bodies.Length); | |||
Assert.Equal(JT1078SubPackageType.分包处理时的第一个包, merge.Label3.SubpackageType); | |||
} | |||
} | |||
} |
@@ -1,58 +0,0 @@ | |||
using JT1078.Protocol.Enums; | |||
using System; | |||
using System.Linq; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT1078.Protocol | |||
{ | |||
public static class JT1078Demuxer | |||
{ | |||
private readonly static ConcurrentDictionary<string, JT1078Package> JT1078PackageGroupDict = new ConcurrentDictionary<string, JT1078Package>(StringComparer.OrdinalIgnoreCase); | |||
public static JT1078Package Demuxer(JT1078Package jT1078Package) | |||
{ | |||
string cacheKey = jT1078Package.GetKey(); | |||
if (jT1078Package.Label3.SubpackageType == JT1078SubPackageType.分包处理时的第一个包) | |||
{ | |||
JT1078PackageGroupDict.TryRemove(cacheKey, out _); | |||
JT1078PackageGroupDict.TryAdd(cacheKey, jT1078Package); | |||
return default; | |||
} | |||
else if (jT1078Package.Label3.SubpackageType == JT1078SubPackageType.分包处理时的中间包) | |||
{ | |||
if (JT1078PackageGroupDict.TryGetValue(cacheKey, out var tmpPackage)) | |||
{ | |||
var totalLength = tmpPackage.Bodies.Length + jT1078Package.Bodies.Length; | |||
byte[] poolBytes = JT1078ArrayPool.Rent(totalLength); | |||
Span<byte> tmpSpan = poolBytes; | |||
tmpPackage.Bodies.CopyTo(tmpSpan); | |||
jT1078Package.Bodies.CopyTo(tmpSpan.Slice(tmpPackage.Bodies.Length)); | |||
tmpPackage.Bodies= tmpSpan.Slice(0, totalLength).ToArray(); | |||
JT1078ArrayPool.Return(poolBytes); | |||
JT1078PackageGroupDict[cacheKey] = jT1078Package; | |||
} | |||
return default; | |||
} | |||
else if (jT1078Package.Label3.SubpackageType == JT1078SubPackageType.分包处理时的最后一个包) | |||
{ | |||
if(JT1078PackageGroupDict.TryRemove(cacheKey, out var tmpPackage)) | |||
{ | |||
var totalLength = tmpPackage.Bodies.Length + jT1078Package.Bodies.Length; | |||
byte[] poolBytes = JT1078ArrayPool.Rent(totalLength); | |||
Span<byte> tmpSpan = poolBytes; | |||
tmpPackage.Bodies.CopyTo(tmpSpan); | |||
jT1078Package.Bodies.CopyTo(tmpSpan.Slice(tmpPackage.Bodies.Length)); | |||
tmpPackage.Bodies = tmpSpan.Slice(0, totalLength).ToArray(); | |||
JT1078ArrayPool.Return(poolBytes); | |||
return tmpPackage; | |||
} | |||
return default; | |||
} | |||
else | |||
{ | |||
return jT1078Package; | |||
} | |||
} | |||
} | |||
} |
@@ -1,6 +1,7 @@ | |||
using JT1078.Protocol.Enums; | |||
using JT1078.Protocol.MessagePack; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
@@ -8,6 +9,7 @@ namespace JT1078.Protocol | |||
{ | |||
public static class JT1078Serializer | |||
{ | |||
private readonly static ConcurrentDictionary<string, JT1078Package> JT1078PackageGroupDict = new ConcurrentDictionary<string, JT1078Package>(StringComparer.OrdinalIgnoreCase); | |||
public static byte[] Serialize(JT1078Package package, int minBufferSize = 4096) | |||
{ | |||
byte[] buffer = JT1078ArrayPool.Rent(minBufferSize); | |||
@@ -40,7 +42,6 @@ namespace JT1078.Protocol | |||
JT1078ArrayPool.Return(buffer); | |||
} | |||
} | |||
public static JT1078Package Deserialize(ReadOnlySpan<byte> bytes) | |||
{ | |||
JT1078Package jT1078Package = new JT1078Package(); | |||
@@ -66,5 +67,49 @@ namespace JT1078.Protocol | |||
jT1078Package.Bodies = jT1078MessagePackReader.ReadRemainArray().ToArray(); | |||
return jT1078Package; | |||
} | |||
public static JT1078Package Merge(JT1078Package jT1078Package) | |||
{ | |||
string cacheKey = jT1078Package.GetKey(); | |||
if (jT1078Package.Label3.SubpackageType == JT1078SubPackageType.分包处理时的第一个包) | |||
{ | |||
JT1078PackageGroupDict.TryRemove(cacheKey, out _); | |||
JT1078PackageGroupDict.TryAdd(cacheKey, jT1078Package); | |||
return default; | |||
} | |||
else if (jT1078Package.Label3.SubpackageType == JT1078SubPackageType.分包处理时的中间包) | |||
{ | |||
if (JT1078PackageGroupDict.TryGetValue(cacheKey, out var tmpPackage)) | |||
{ | |||
var totalLength = tmpPackage.Bodies.Length + jT1078Package.Bodies.Length; | |||
byte[] poolBytes = JT1078ArrayPool.Rent(totalLength); | |||
Span<byte> tmpSpan = poolBytes; | |||
tmpPackage.Bodies.CopyTo(tmpSpan); | |||
jT1078Package.Bodies.CopyTo(tmpSpan.Slice(tmpPackage.Bodies.Length)); | |||
tmpPackage.Bodies = tmpSpan.Slice(0, totalLength).ToArray(); | |||
JT1078ArrayPool.Return(poolBytes); | |||
JT1078PackageGroupDict[cacheKey] = tmpPackage; | |||
} | |||
return default; | |||
} | |||
else if (jT1078Package.Label3.SubpackageType == JT1078SubPackageType.分包处理时的最后一个包) | |||
{ | |||
if (JT1078PackageGroupDict.TryRemove(cacheKey, out var tmpPackage)) | |||
{ | |||
var totalLength = tmpPackage.Bodies.Length + jT1078Package.Bodies.Length; | |||
byte[] poolBytes = JT1078ArrayPool.Rent(totalLength); | |||
Span<byte> tmpSpan = poolBytes; | |||
tmpPackage.Bodies.CopyTo(tmpSpan); | |||
jT1078Package.Bodies.CopyTo(tmpSpan.Slice(tmpPackage.Bodies.Length)); | |||
tmpPackage.Bodies = tmpSpan.Slice(0, totalLength).ToArray(); | |||
JT1078ArrayPool.Return(poolBytes); | |||
return tmpPackage; | |||
} | |||
return default; | |||
} | |||
else | |||
{ | |||
return jT1078Package; | |||
} | |||
} | |||
} | |||
} |