/* Ċ Ġ* ĠThis Ġfile Ġis Ġpart Ġof Ġbeat - drop per , Ġlicensed Ġunder Ġthe ĠMIT ĠLicense Ġ( MIT ). Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) ĠOct av ia ĠT og ami Ġ< https :// oct yl . net > Ċ Ġ* ĠCopyright Ġ( c ) Ġcontributors Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ċ Ġ* Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN Ċ Ġ* ĠTHE ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġnet . oct yl . beat drop per . util Ċ Ċ import Ġorg . byte deco . ffmpeg . av codec . AV Codec Context Ċ import Ġorg . byte deco . ffmpeg . av format . AV Format Context Ċ import Ġorg . byte deco . ffmpeg . av format . AV Stream Ċ import Ġorg . byte deco . ffmpeg . av util . AV Dictionary Ċ import Ġorg . byte deco . ffmpeg . av util . AV Frame Ċ import Ġorg . byte deco . ffmpeg . global . av codec . AV _ CODEC _ CAP _ VARIABLE _ FRAME _ SIZE Ċ import Ġorg . byte deco . ffmpeg . global . av codec . AV _ CODEC _ FLAG _ GLOBAL _ HEADER Ċ import Ġorg . byte deco . ffmpeg . global . av codec . AV _ CODEC _ FLAG _ Q SCALE Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av _ packet _ alloc Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av _ packet _ free Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av _ packet _ re scale _ ts Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av _ packet _ unref Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ alloc _ context 3 Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ find _ encoder Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ free _ context Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ get _ name Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ open 2 Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ parameters _ from _ context Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ receive _ packet Ċ import Ġorg . byte deco . ffmpeg . global . av codec . av codec _ send _ frame Ċ import Ġorg . byte deco . ffmpeg . global . av format . AV FMT _ GLOBAL HEADER Ċ import Ġorg . byte deco . ffmpeg . global . av format . av _ inter leaved _ write _ frame Ċ import Ġorg . byte deco . ffmpeg . global . av format . av _ write _ tr ailer Ċ import Ġorg . byte deco . ffmpeg . global . av format . av format _ alloc _ output _ context 2 Ċ import Ġorg . byte deco . ffmpeg . global . av format . av format _ free _ context Ċ import Ġorg . byte deco . ffmpeg . global . av format . av format _ new _ stream Ċ import Ġorg . byte deco . ffmpeg . global . av format . av format _ write _ header Ċ import Ġorg . byte deco . ffmpeg . global . av util . A VER ROR _ EOF Ċ import Ġorg . byte deco . ffmpeg . global . av util . AV _ CH _ LAYOUT _ STER EO Ċ import Ġorg . byte deco . ffmpeg . global . av util . AV _ OPT _ SEARCH _ CHILD REN Ċ import Ġorg . byte deco . ffmpeg . global . av util . FF _ QP 2 L AMBDA Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ frame _ alloc Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ frame _ free Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ frame _ get _ buffer Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ frame _ make _ writable Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ get _ bytes _ per _ sample Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ get _ plan ar _ sample _ fmt Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ make _ q Ċ import Ġorg . byte deco . ffmpeg . global . av util . av _ opt _ set _ int Ċ import Ġorg . byte deco . ffmpeg . presets . av util Ċ import Ġorg . lwjgl . system . Memory Util Ċ import Ġjava . io . IOException Ċ import Ġjava . io . OutputStream Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ Ċ /** Ċ Ġ* ĠAn Ġinput Ġstream Ġbased Ġon Ġpip ing Ġanother Ġstream Ġthrough ĠFF mpeg . Ċ Ġ*/ Ċ class ĠFF mpeg OutputStream ( ĊĠĠĠ Ġcodec Id : ĠInt , ĊĠĠĠ Ġcontainer Name : ĠString , ĊĠĠĠ Ġsample Rate : ĠInt , ĊĠĠĠ Ġav io Callbacks : ĠAv io Callbacks Ċ ) Ġ: ĊĠĠĠ ĠOutputStream () Ġ{ ĊĠĠĠ Ġprivate Ġval Ġcloser Ġ= ĠAuto Closer () ĊĊĠĠĠ Ġ// Ġallocate Ġjust Ġa Ġpointer , Ġno Ġactual Ġobject ĊĠĠĠ Ġprivate Ġval Ġctx Ġ= ĠAV Format Context ( null ) ĊĠĠĠ Ġprivate Ġval Ġcodec Ctx : ĠAV Codec Context ĊĠĠĠ Ġprivate Ġval Ġclosed Ġ= ĠAtomic Boolean () ĊĠĠĠ Ġprivate Ġval Ġaudio Stream : ĠAV Stream ĊĠĠĠ Ġprivate Ġval Ġoutput Frame : ĠAV Frame ĊĠĠĠ Ġprivate Ġval Ġres ampler : ĠRes ampler ĊĠĠĠ Ġprivate Ġval Ġoutput Buffer : ĠByteBuffer ĊĠĠĠ Ġprivate Ġvar Ġpts : ĠLong Ġ= Ġ 0 ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġerror Ġ= Ġav format _ alloc _ output _ context 2 ( ctx , Ġnull , Ġcontainer Name , Ġnull ) ĊĠĠĠĠĠĠĠ Ġcheck ( error Ġ== Ġ 0 ) Ġ{ Ġ" Error Ġalloc ating Ġoutput Ġcontext : Ġ" Ġ+ Ġav Err 2 Str ( error ) Ġ} ĊĠĠĠĠĠĠĠ Ġcloser . register ( ctx , Ġ{ Ġs Ġ-> Ġav format _ free _ context ( s ) Ġ}) ĊĊĠĠĠĠĠĠĠ Ġval Ġav io Ctx Ġ= Ġcloser . register ( av io Callbacks ). allocate Context ( 4 0 9 6 , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġerror (" Unable Ġto Ġallocate ĠIO Ġcontext ") ĊĠĠĠĠĠĠĠ Ġcloser . register ( av io Ctx ) ĊĠĠĠĠĠĠĠ Ġctx . pb ( av io Ctx ) ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( av io Ctx . seek able () Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDisable Ġa Ġwarning Ġfrom ĠFL AC Ġencoder , Ġwe Ġdon 't Ġcare . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġav _ opt _ set _ int ( ctx , Ġ" write _ header ", Ġ 0 , ĠAV _ OPT _ SEARCH _ CHILD REN ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcodec Ġ= Ġav codec _ find _ encoder ( codec Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġerror (" Could Ġnot Ġfind Ġencoder Ġfor Ġ" Ġ+ Ġav codec _ get _ name ( codec Id )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsupported Fm ts Ġ= Ġcodec . sample _ fm ts () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdesired Format Ġ= Ġgenerate Sequence ( 0 L ) Ġ{ Ġit Ġ+ Ġ 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġsupported Fm ts [ it ] Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take While Ġ{ Ġfmt Ġ-> Ġfmt Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. max By OrNull Ġ{ Ġfmt Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= Ġav _ get _ bytes _ per _ sample ( fmt ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġplan ar Ġ= Ġwhen Ġ( av _ get _ plan ar _ sample _ fmt ( fmt )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbase Score Ġ= Ġwhen Ġ( bytes ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprefer Ġ 2 Ġbytes Ġ/ Ġ 1 6 Ġbits Ġ( our Ġcurrent Ġformat ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 2 Ġ-> ĠInt . MAX _ VALUE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġbytes Ġ* Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprefer Ġnon - plan ar Ġslightly ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbase Score Ġ- Ġplan ar ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġerror (" No Ġformats Ġavailable ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġaudio Stream Ġ= Ġav format _ new _ stream ( ctx , Ġcodec ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġerror (" Unable Ġto Ġallocate Ġaudio Ġstream ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaudio Stream . id ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaudio Stream . time _ base ( av _ make _ q ( 1 , Ġsample Rate )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcodec Ctx Ġ= Ġcloser . register ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġav codec _ alloc _ context 3 ( codec ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġav ctx Ġ-> Ġav codec _ free _ context ( av ctx ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ?: Ġerror (" Unable Ġto Ġallocate Ġcodec Ġcontext ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcodec Ctx ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sample _ fmt ( desired Format ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sample _ rate ( sample Rate ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. channels ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. channel _ layout ( AV _ CH _ LAYOUT _ STER EO ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. time _ base ( av _ make _ q ( 1 , Ġsample Rate )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġset Ġ- q : a Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcodec Ctx . flags ( codec Ctx . flags () Ġor ĠAV _ CODEC _ FLAG _ Q SCALE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcodec Ctx . global _ quality ( FF _ QP 2 L AMBDA Ġ* Ġ 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ctx . o format (). flags () Ġand ĠAV FMT _ GLOBAL HEADER Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcodec Ctx . flags ( AV _ CODEC _ FLAG _ GLOBAL _ HEADER ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Ġ= Ġav codec _ open 2 ( codec Ctx , Ġcodec , Ġnull Ġas ĠAV Dictionary ?) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( error Ġ== Ġ 0 ) Ġ{ Ġ" Unable Ġto Ġopen Ġcodec : Ġ" Ġ+ Ġav Err 2 Str ( error ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġav codec _ parameters _ from _ context ( audio Stream . codec par (), Ġcodec Ctx ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnb Samples Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( codec . capabilities () Ġand ĠAV _ CODEC _ CAP _ VARIABLE _ FRAME _ SIZE ) Ġ!= Ġ 0 Ġ-> Ġ 8 1 9 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcodec Ctx . frame _ size () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Frame Ġ= Ġcloser . register ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġav _ frame _ alloc (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġframe Ġ-> Ġav _ frame _ free ( frame ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ?: Ġerror (" Unable Ġto Ġallocate Ġoutput Ġframe ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinput Format Ġ= Ġinternal Format ( sample Rate ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Frame ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set From ( input Format ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. nb _ samples ( nb Samples ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Ġ= Ġav _ frame _ get _ buffer ( output Frame , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( error Ġ== Ġ 0 ) Ġ{ Ġ" Unable Ġto Ġget Ġoutput Ġbuffer : Ġ" Ġ+ Ġav Err 2 Str ( error ) Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġres ampler Ġ= Ġcloser . register ( Res ampler ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Format , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFormat ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchannel Layout Ġ= Ġcodec Ctx . channel _ layout (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsample Format Ġ= Ġcodec Ctx . sample _ fmt (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtime Base Ġ= Ġaudio Stream . time _ base (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsample Rate Ġ= Ġsample Rate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffer Ġ= ĠMemory Util . mem Alloc ( Short . SIZE _ BYTES Ġ* Ġoutput Frame . nb _ samples () Ġ* Ġcodec Ctx . channels ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcloser . register ( output Buffer , Ġ{ Ġptr Ġ-> ĠMemory Util . mem Free ( ptr ) Ġ}) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Ġ= Ġav format _ write _ header ( ctx , Ġnull Ġas ĠAV Dictionary ?) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Unable Ġto Ġwrite Ġheader : Ġ" Ġ+ Ġav Err 2 Str ( error )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclose Sil ently ( t ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġt ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġoverride Ġfun Ġwrite ( b : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoutput Buffer . put ( b . to Byte ()) ĊĠĠĠĠĠĠĠ Ġif Ġ(! output Buffer . has Remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflush () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġoverride Ġfun Ġwrite ( b : ĠByteArray , Ġoff : ĠInt , Ġlen : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Offset Ġ= Ġoff ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Len Ġ= Ġlen ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġcurrent Len . coerce At Most ( output Buffer . remaining ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Buffer . put ( b , Ġcurrent Offset , Ġsize ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! output Buffer . has Remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflush () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Offset Ġ+= Ġsize ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Len Ġ-= Ġsize ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Len Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġhave Ġconsumed Ġall Ġthe Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġotherwise , Ġloop Ġto Ġfill Ġour Ġbuffer Ġagain ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġoverride Ġfun Ġflush () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( output Buffer . has Remaining ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbuffer Ġmust Ġbe Ġfull , Ġotherwise Ġthe Ġframe Ġis Ġtoo Ġsmall ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġforced Flush () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġforced Flush () Ġ{ ĊĠĠĠĠĠĠĠ Ġoutput Buffer . flip () ĊĠĠĠĠĠĠĠ Ġval Ġerror Ġ= Ġav _ frame _ make _ writable ( output Frame ) ĊĠĠĠĠĠĠĠ Ġif Ġ( error Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Unable Ġto Ġmake Ġoutput Ġframe Ġwrite able : Ġ" Ġ+ Ġav Err 2 Str ( error )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġlength Ġ= Ġoutput Buffer . remaining () ĊĠĠĠĠĠĠĠ ĠMemory Util . mem Copy ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMemory Util . mem Address ( output Buffer ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Frame . data ( 0 ). address (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlength . to Long () ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġoutput Buffer . clear () ĊĠĠĠĠĠĠĠ Ġoutput Frame . pts ( pts ) ĊĠĠĠĠĠĠĠ Ġpts Ġ+= Ġlength Ġ/ Ġ( java . lang . Short . BYTES Ġ* Ġcodec Ctx . channels ()). to Long () ĊĠĠĠĠĠĠĠ Ġfor Ġ( next Ġin Ġres ampler . push Frame ( output Frame )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflush Frame ( next ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( length Ġ< Ġoutput Buffer . capacity ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( next Ġin Ġres ampler . push Final Frame ( pts )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflush Frame ( next ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġflush Frame ( frame : ĠAV Frame ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġerror Ġ= Ġav codec _ send _ frame ( codec Ctx , Ġframe ) ĊĠĠĠĠĠĠĠ Ġif Ġ( error Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Unable Ġto Ġencode Ġframe : Ġ" Ġ+ Ġav Err 2 Str ( error )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġoutput Packet Ġ= Ġav _ packet _ alloc () ĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Ġ= Ġav codec _ receive _ packet ( codec Ctx , Ġoutput Packet ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error Ġ== Ġav util . A VER ROR _ E AG AIN () Ġ|| Ġerror Ġ== ĠA VER ROR _ EOF ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġneed Ġmore Ġinput ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Error Ġencoding Ġaudio Ġframe : Ġ" Ġ+ Ġav Err 2 Str ( error )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġav _ packet _ re scale _ ts ( output Packet , Ġcodec Ctx . time _ base (), Ġaudio Stream . time _ base ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Packet . stream _ index ( audio Stream . index ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Ġ= Ġav _ inter leaved _ write _ frame ( ctx , Ġoutput Packet ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġav _ packet _ unref ( output Packet ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Error Ġwriting Ġaudio Ġframe : Ġ" Ġ+ Ġav Err 2 Str ( error )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġav _ packet _ free ( output Packet ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclose Sil ently ( cause : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( suppress : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcause . add Sup pressed ( suppress ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġcheck Ġif Ġalready Ġclosed ĊĠĠĠĠĠĠĠ Ġif Ġ( closed . get ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġtry Ġto Ġacquire Ġexclusive Ġclose Ġ" lock " ĊĠĠĠĠĠĠĠ Ġif Ġ(! closed . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġsupp ressed : ĠThrowable ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġflush , Ġeven Ġif Ġless Ġthan Ġnb _ samples ĊĠĠĠĠĠĠĠĠĠĠĠ Ġforced Flush () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflush Frame ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Ġ= Ġav _ inter leaved _ write _ frame ( ctx , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Error Ġwriting Ġaudio Ġframe : Ġ" Ġ+ Ġav Err 2 Str ( error )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġav _ write _ tr ailer ( ctx ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsupp ressed Ġ= Ġt ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcloser . close () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sup pressed Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt . add Sup pressed ( sup pressed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRe throw . re throw IO ( t ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( sup pressed Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRe throw . re throw IO ( sup pressed ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ