11use decoder:: { DecoderResource , RawFrame } ;
22use encoder:: { EncodedFrame , EncoderRateControl , EncoderResource , EncoderTune } ;
33use rustler:: { Atom , Binary , Env , Error , ResourceArc , Term } ;
4+ use std:: sync:: Arc ;
5+ use vk_video:: VulkanDevice ;
6+
7+ rustler:: atoms! {
8+ ok,
9+ }
410
511pub mod decoder;
612pub mod encoder;
713
814pub enum Resource {
915 Encoder ( EncoderResource ) ,
1016 Decoder ( DecoderResource ) ,
17+ Device ( DeviceResource ) ,
18+ }
19+
20+ pub struct DeviceResource {
21+ pub device : Arc < VulkanDevice > ,
1122}
1223
24+ impl std:: panic:: RefUnwindSafe for DeviceResource { }
25+
1326impl Resource {
1427 pub fn encoder ( & self ) -> Option < & EncoderResource > {
1528 match self {
1629 Self :: Encoder ( encoder_resource) => Some ( encoder_resource) ,
17- Self :: Decoder ( _ ) => None ,
30+ _ => None ,
1831 }
1932 }
2033
2134 pub fn decoder ( & self ) -> Option < & DecoderResource > {
2235 match self {
2336 Self :: Decoder ( decoder_resource) => Some ( decoder_resource) ,
24- Self :: Encoder ( _) => None ,
37+ _ => None ,
38+ }
39+ }
40+
41+ pub fn device ( & self ) -> Option < & DeviceResource > {
42+ match self {
43+ Self :: Device ( device_resource) => Some ( device_resource) ,
44+ _ => None ,
2545 }
2646 }
2747}
2848
49+ #[ allow( non_local_definitions) ]
2950fn load ( env : Env , _: Term ) -> bool {
3051 rustler:: resource!( Resource , env)
3152}
3253
3354#[ rustler:: nif( schedule = "DirtyIo" ) ]
34- fn new_decoder ( ) -> Result < ( Atom , ResourceArc < Resource > ) , Error > {
35- decoder:: new ( )
55+ fn create_device ( ) -> Result < ( Atom , ResourceArc < Resource > ) , Error > {
56+ let instance = vk_video:: VulkanInstance :: new ( )
57+ . map_err ( |err| Error :: RaiseTerm ( Box :: new ( err. to_string ( ) ) ) ) ?;
58+ let adapter = instance
59+ . create_adapter ( None )
60+ . map_err ( |err| Error :: RaiseTerm ( Box :: new ( err. to_string ( ) ) ) ) ?;
61+ let device = adapter
62+ . create_device ( wgpu:: Features :: empty ( ) , wgpu:: Limits :: default ( ) )
63+ . map_err ( |err| Error :: RaiseTerm ( Box :: new ( err. to_string ( ) ) ) ) ?;
64+
65+ let device_resource = ResourceArc :: new ( Resource :: Device ( DeviceResource { device } ) ) ;
66+ Ok ( ( ok ( ) , device_resource) )
67+ }
68+
69+ #[ rustler:: nif( schedule = "DirtyIo" ) ]
70+ fn new_decoder (
71+ env : Env ,
72+ resource : ResourceArc < Resource > ,
73+ ) -> Result < ( Atom , ResourceArc < Resource > ) , Error > {
74+ decoder:: new ( env, resource)
3675}
3776
3877#[ rustler:: nif( schedule = "DirtyIo" ) ]
@@ -55,13 +94,15 @@ pub fn flush_decoder(
5594
5695#[ rustler:: nif( schedule = "DirtyIo" ) ]
5796fn new_encoder (
97+ env : Env ,
98+ resource : ResourceArc < Resource > ,
5899 width : u32 ,
59100 height : u32 ,
60101 frame_rate : ( u32 , u32 ) ,
61102 tune : EncoderTune ,
62103 rate_control : EncoderRateControl ,
63104) -> Result < ( Atom , ResourceArc < Resource > ) , Error > {
64- encoder:: new ( width, height, frame_rate, tune, rate_control)
105+ encoder:: new ( env , resource , width, height, frame_rate, tune, rate_control)
65106}
66107
67108#[ rustler:: nif( schedule = "DirtyIo" ) ]
@@ -74,4 +115,17 @@ fn encode<'a>(
74115 encoder:: encode ( env, resource, bytes, pts_ns)
75116}
76117
118+ #[ rustler:: nif( schedule = "DirtyIo" ) ]
119+ fn destroy < ' a > ( env : Env < ' a > , resource : ResourceArc < Resource > ) -> Result < Atom , Error > {
120+ if let Resource :: Encoder ( encoder) = & * resource {
121+ let mut encoder = encoder
122+ . encoder_mutex
123+ . lock ( )
124+ . map_err ( |err| Error :: RaiseTerm ( Box :: new ( err. to_string ( ) ) ) ) ?;
125+ * encoder = None ;
126+ }
127+
128+ Ok ( ok ( ) )
129+ }
130+
77131rustler:: init!( "Elixir.Membrane.VKVideo.Native" , load = load) ;
0 commit comments