package Ġcom . ped ro . rt sp . rtp . packets Ċ Ċ import Ġandroid . media . Media Codec Ċ import Ġandroid . util . Log Ċ import Ġcom . ped ro . rt sp . rt sp . R tp Frame Ċ import Ġcom . ped ro . rt sp . utils . R tp Constants Ċ import Ġjava . nio . ByteBuffer Ċ import Ġkotlin . experimental . and Ċ Ċ /** Ċ Ġ* ĠCreated Ġby Ġped ro Ġon Ġ 2 7 / 1 1 / 1 8 . Ċ Ġ* Ċ Ġ* ĠRFC Ġ 3 9 8 4 Ċ Ġ*/ Ċ open Ġclass ĠH 2 6 4 Packet ( sp s : ĠByteArray , Ġp ps : ĠByteArray , Ġprivate Ġval Ġvideo Packet Callback : ĠVideo Packet Callback ) Ġ: ĠBase Packet ( R tp Constants . clock Video Frequency , ĊĠĠĠ ĠR tp Constants . payload Type Ġ+ ĠR tp Constants . track Video ) Ġ{ ĊĊĠ Ġprivate Ġval Ġheader Ġ= ĠByteArray ( 5 ) ĊĠ Ġprivate Ġvar Ġst ap A : ĠByteArray ? Ġ= Ġnull ĊĠ Ġprivate Ġvar Ġsend Key Frame Ġ= Ġfalse ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġchannel Identifier Ġ= ĠR tp Constants . track Video ĊĠĠĠ Ġset S ps P ps ( sp s , Ġp ps ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġcreate And Send Packet ( byte Buffer : ĠByteBuffer , Ġbuffer Info : ĠMedia Codec . Buffer Info ) Ġ{ ĊĠĠĠ Ġif Ġ( buffer Info . size Ġ< Ġ 5 ) Ġreturn ĊĠĠĠ Ġ// ĠWe Ġread Ġa ĠN AL Ġunits Ġfrom ĠByteBuffer Ġand Ġwe Ġsend Ġthem ĊĠĠĠ Ġ// ĠN AL Ġunits Ġare Ġprece ded Ġwith Ġ 0 x 0 0 0 0 0 0 0 1 ĊĠĠĠ Ġbyte Buffer . rewind () ĊĠĠĠ Ġbyte Buffer . get ( header , Ġ 0 , Ġ 5 ) ĊĠĠĠ Ġval Ġts Ġ= Ġbuffer Info . presentation Time Us Ġ* Ġ 1 0 0 0 L ĊĠĠĠ Ġval Ġn alu Length Ġ= Ġbuffer Info . size Ġ- Ġbyte Buffer . position () Ġ+ Ġ 1 ĊĠĠĠ Ġval Ġtype : ĠInt Ġ= Ġ( header [ 4 ] Ġand Ġ 0 x 1 F ). toInt () ĊĠĠĠ Ġif Ġ( type Ġ== ĠR tp Constants . IDR Ġ|| Ġbuffer Info . flags Ġ== ĠMedia Codec . BUFFER _ FLAG _ KEY _ FRAME ) Ġ{ ĊĠĠĠĠĠ Ġ// fix Ġmalformed Ġkey frame Ġheader Ġif Ġnecessary ĊĠĠĠĠĠ Ġif Ġ( type Ġ!= ĠR tp Constants . IDR ) Ġheader [ 4 ] Ġ= ĠR tp Constants . IDR . to Byte () ĊĠĠĠĠĠ Ġst ap A ?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= Ġget Buffer ( it . size Ġ+ ĠR tp Constants . R TP _ HEADER _ LENGTH ) ĊĠĠĠĠĠĠĠ Ġval Ġr tp Ts Ġ= Ġupdate TimeStamp ( buffer , Ġts ) ĊĠĠĠĠĠĠĠ Ġmark Packet ( buffer ) Ġ// mark Ġend Ġframe ĊĠĠĠĠĠĠĠ ĠSystem . arraycopy ( it , Ġ 0 , Ġbuffer , ĠR tp Constants . R TP _ HEADER _ LENGTH , Ġit . size ) ĊĠĠĠĠĠĠĠ Ġupdate Seq ( buffer ) ĊĠĠĠĠĠĠĠ Ġval Ġr tp Frame Ġ= ĠR tp Frame ( buffer , Ġr tp Ts , Ġit . size Ġ+ ĠR tp Constants . R TP _ HEADER _ LENGTH , Ġr tp Port , Ġr tcp Port , Ġchannel Identifier ) ĊĠĠĠĠĠĠĠ Ġvideo Packet Callback . on Video Frame Created ( rtp Frame ) ĊĠĠĠĠĠĠĠ Ġsend Key Frame Ġ= Ġtrue ĊĠĠĠĠĠ Ġ} Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . i ( TAG , Ġ" can 't Ġcreate Ġkey Ġframe Ġbecause Ġset S ps P ps Ġwas Ġnot Ġcalled ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( send Key Frame ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠSmall ĠN AL Ġunit Ġ=> ĠSingle ĠN AL Ġunit ĊĠĠĠĠĠ Ġif Ġ( nal u Length Ġ<= Ġmax Packet Size Ġ- ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ- Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcont Ġ= Ġn alu Length Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġval Ġlength Ġ= Ġif Ġ( cont Ġ< Ġbuffer Info . size Ġ- Ġbyte Buffer . position ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcont ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġbuffer Info . size Ġ- Ġbyte Buffer . position () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= Ġget Buffer ( length Ġ+ ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġbuffer [ R tp Constants . R TP _ HEADER _ LENGTH ] Ġ= Ġheader [ 4 ] ĊĠĠĠĠĠĠĠ Ġbyte Buffer . get ( buffer , ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 1 , Ġlength ) ĊĠĠĠĠĠĠĠ Ġval Ġr tp Ts Ġ= Ġupdate TimeStamp ( buffer , Ġts ) ĊĠĠĠĠĠĠĠ Ġmark Packet ( buffer ) Ġ// mark Ġend Ġframe ĊĠĠĠĠĠĠĠ Ġupdate Seq ( buffer ) ĊĠĠĠĠĠĠĠ Ġval Ġr tp Frame Ġ= ĠR tp Frame ( buffer , Ġr tp Ts , Ġn alu Length Ġ+ ĠR tp Constants . R TP _ HEADER _ LENGTH , Ġr tp Port , Ġr tcp Port , Ġchannel Identifier ) ĊĠĠĠĠĠĠĠ Ġvideo Packet Callback . on Video Frame Created ( rtp Frame ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSet ĠF U - A Ġheader ĊĠĠĠĠĠĠĠ Ġheader [ 1 ] Ġ= Ġheader [ 4 ] Ġand Ġ 0 x 1 F Ġ// ĠF U Ġheader Ġtype ĊĠĠĠĠĠĠĠ Ġheader [ 1 ] Ġ= Ġheader [ 1 ]. plus ( 0 x 8 0 ). to Byte () Ġ Ġ// Ġset Ġstart Ġbit Ġto Ġ 1 ĊĠĠĠĠĠĠĠ Ġ// ĠSet ĠF U - A Ġindicator ĊĠĠĠĠĠĠĠ Ġheader [ 0 ] Ġ= Ġheader [ 4 ] Ġand Ġ 0 x 6 0 Ġand Ġ 0 xFF . to Byte () Ġ// ĠF U Ġindicator ĠN RI ĊĠĠĠĠĠĠĠ Ġheader [ 0 ] Ġ= Ġheader [ 0 ]. plus ( 2 8 ). to Byte () ĊĠĠĠĠĠĠĠ Ġvar Ġsum Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġwhile Ġ( sum Ġ< Ġn alu Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġcont Ġ= Ġif Ġ( nal u Length Ġ- Ġsum Ġ> Ġmax Packet Size Ġ- ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ- Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Packet Size Ġ- ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ- Ġ 2 ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġn alu Length Ġ- Ġsum ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġlength Ġ= Ġif Ġ( cont Ġ< Ġbuffer Info . size Ġ- Ġbyte Buffer . position ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcont ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer Info . size Ġ- Ġbyte Buffer . position () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= Ġget Buffer ( length Ġ+ ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠ Ġbuffer [ R tp Constants . R TP _ HEADER _ LENGTH ] Ġ= Ġheader [ 0 ] ĊĠĠĠĠĠĠĠĠĠ Ġbuffer [ R tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 1 ] Ġ= Ġheader [ 1 ] ĊĠĠĠĠĠĠĠĠĠ Ġval Ġr tp Ts Ġ= Ġupdate TimeStamp ( buffer , Ġts ) ĊĠĠĠĠĠĠĠĠĠ Ġbyte Buffer . get ( buffer , ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 2 , Ġlength ) ĊĠĠĠĠĠĠĠĠĠ Ġsum Ġ+= Ġlength ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠLast Ġpacket Ġbefore Ġnext ĠN AL ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( sum Ġ>= Ġn alu Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEnd Ġbit Ġon ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuffer [ R tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 1 ] Ġ= Ġbuffer [ R tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 1 ]. plus ( 0 x 4 0 ). to Byte () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmark Packet ( buffer ) Ġ// mark Ġend Ġframe ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġupdate Seq ( buffer ) ĊĠĠĠĠĠĠĠĠĠ Ġval Ġr tp Frame Ġ= ĠR tp Frame ( buffer , Ġr tp Ts , Ġlength Ġ+ ĠR tp Constants . R TP _ HEADER _ LENGTH Ġ+ Ġ 2 , Ġr tp Port , Ġr tcp Port , Ġchannel Identifier ) ĊĠĠĠĠĠĠĠĠĠ Ġvideo Packet Callback . on Video Frame Created ( rtp Frame ) ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠSwitch Ġstart Ġbit ĊĠĠĠĠĠĠĠĠĠ Ġheader [ 1 ] Ġ= Ġheader [ 1 ] Ġand Ġ 0 x 7 F ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠLog . i ( TAG , Ġ" waiting Ġfor Ġkey frame ") ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġset S ps P ps ( sp s : ĠByteArray , Ġp ps : ĠByteArray ) Ġ{ ĊĠĠĠ Ġst ap A Ġ= ĠByteArray ( sp s . size Ġ+ Ġp ps . size Ġ+ Ġ 5 ) ĊĠĠĠ Ġst ap A ?. let Ġ{ ĊĠĠĠĠĠ Ġ// ĠST AP - A ĠN AL Ġheader Ġis Ġ 2 4 ĊĠĠĠĠĠ Ġit [ 0 ] Ġ= Ġ 2 4 ĊĊĠĠĠĠĠ Ġ// ĠWrite ĠN AL U Ġ 1 Ġsize Ġinto Ġthe Ġarray Ġ( NAL U Ġ 1 Ġis Ġthe ĠS PS ). ĊĠĠĠĠĠ Ġit [ 1 ] Ġ= Ġ( sp s . size Ġshr Ġ 8 ). to Byte () ĊĠĠĠĠĠ Ġit [ 2 ] Ġ= Ġ( sp s . size Ġand Ġ 0 xFF ). to Byte () ĊĊĠĠĠĠĠ Ġ// ĠWrite ĠN AL U Ġ 2 Ġsize Ġinto Ġthe Ġarray Ġ( NAL U Ġ 2 Ġis Ġthe ĠP PS ). ĊĠĠĠĠĠ Ġit [ sp s . size Ġ+ Ġ 3 ] Ġ= Ġ( pp s . size Ġshr Ġ 8 ). to Byte () ĊĠĠĠĠĠ Ġit [ sp s . size Ġ+ Ġ 4 ] Ġ= Ġ( pp s . size Ġand Ġ 0 xFF ). to Byte () ĊĊĠĠĠĠĠ Ġ// ĠWrite ĠN AL U Ġ 1 Ġinto Ġthe Ġarray , Ġthen Ġwrite ĠN AL U Ġ 2 Ġinto Ġthe Ġarray . ĊĠĠĠĠĠ ĠSystem . arraycopy ( sp s , Ġ 0 , Ġit , Ġ 3 , Ġs ps . size ) ĊĠĠĠĠĠ ĠSystem . arraycopy ( pp s , Ġ 0 , Ġit , Ġ 5 Ġ+ Ġs ps . size , Ġp ps . size ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġreset () Ġ{ ĊĠĠĠ Ġsuper . reset () ĊĠĠĠ Ġsend Key Frame Ġ= Ġfalse ĊĠ Ġ} Ċ }