@@ -5,9 +5,10 @@ use std::{
55
66use vvenc_sys:: * ;
77
8- #[ derive( Debug , Clone ) ]
8+ #[ derive( Debug ) ]
99pub struct Encoder {
1010 inner : Arc < Mutex < InnerEncoder > > ,
11+ au : AccessUnit ,
1112}
1213
1314#[ derive( Debug ) ]
@@ -29,25 +30,85 @@ impl Encoder {
2930 return Err ( Error :: Initialize ) ;
3031 } ;
3132 let ret = unsafe { vvenc_encoder_open ( encoder. as_ptr ( ) , & mut config. inner ) } ;
33+ #[ allow( non_upper_case_globals) ]
3234 match ret {
3335 ErrorCodes_VVENC_OK => Ok ( Self {
3436 inner : Arc :: new ( Mutex :: new ( InnerEncoder { encoder } ) ) ,
37+ au : AccessUnit :: new ( & config) ,
3538 } ) ,
3639 _ => Err ( Error :: new ( ret) ) ,
3740 }
3841 }
3942
40- fn with_config ( config : & mut vvenc_config ) -> Result < Self , Error > {
41- let Some ( encoder) = ptr:: NonNull :: new ( unsafe { vvenc_encoder_create ( ) } ) else {
42- return Err ( Error :: Initialize ) ;
43+ pub fn encode < ' a > ( & mut self , frame : Frame < ' a > ) -> Result < Option < & AccessUnit > , Error > {
44+ let mut yuv_buffer = vvencYUVBuffer {
45+ planes : [
46+ vvencYUVPlane {
47+ ptr : frame. planes [ 0 ] . data . as_ptr ( ) as * mut i16 ,
48+ width : frame. planes [ 0 ] . width ,
49+ height : frame. planes [ 0 ] . height ,
50+ stride : frame. planes [ 0 ] . stride ,
51+ } ,
52+ vvencYUVPlane {
53+ ptr : frame. planes [ 1 ] . data . as_ptr ( ) as * mut i16 ,
54+ width : frame. planes [ 1 ] . width ,
55+ height : frame. planes [ 1 ] . height ,
56+ stride : frame. planes [ 1 ] . stride ,
57+ } ,
58+ vvencYUVPlane {
59+ ptr : frame. planes [ 2 ] . data . as_ptr ( ) as * mut i16 ,
60+ width : frame. planes [ 2 ] . width ,
61+ height : frame. planes [ 2 ] . height ,
62+ stride : frame. planes [ 2 ] . stride ,
63+ } ,
64+ ] ,
65+ sequenceNumber : frame. sequence_number ,
66+ cts : frame. cts . unwrap_or ( 0 ) ,
67+ ctsValid : frame. cts . is_some ( ) ,
4368 } ;
44- let ret = unsafe { vvenc_encoder_open ( encoder. as_ptr ( ) , config) } ;
45- match ret {
46- ErrorCodes_VVENC_OK => Ok ( Self {
47- inner : Arc :: new ( Mutex :: new ( InnerEncoder { encoder } ) ) ,
48- } ) ,
49- _ => Err ( Error :: new ( ret) ) ,
69+
70+ let mut encode_done = false ;
71+ let ret = unsafe {
72+ vvenc_encode (
73+ self . inner . lock ( ) . unwrap ( ) . encoder . as_ptr ( ) ,
74+ & mut yuv_buffer,
75+ & mut self . au . inner ,
76+ & mut encode_done,
77+ )
78+ } ;
79+
80+ if ret != ErrorCodes_VVENC_OK {
81+ return Err ( Error :: new ( ret) ) ;
5082 }
83+
84+ // TODO: double check if encode_done handling is correct or if we lose a frame like that
85+ if self . au . inner . payloadUsedSize == 0 {
86+ return Ok ( None ) ;
87+ }
88+
89+ Ok ( Some ( & self . au ) )
90+ }
91+
92+ pub fn flush ( & mut self ) -> Result < Option < & AccessUnit > , Error > {
93+ let mut encode_done = false ;
94+ let ret = unsafe {
95+ vvenc_encode (
96+ self . inner . lock ( ) . unwrap ( ) . encoder . as_ptr ( ) ,
97+ std:: ptr:: null_mut ( ) ,
98+ & mut self . au . inner ,
99+ & mut encode_done,
100+ )
101+ } ;
102+
103+ if ret != ErrorCodes_VVENC_OK {
104+ return Err ( Error :: new ( ret) ) ;
105+ }
106+
107+ if self . au . inner . payloadUsedSize == 0 {
108+ return Ok ( None ) ;
109+ }
110+
111+ Ok ( Some ( & self . au ) )
51112 }
52113}
53114
@@ -147,3 +208,52 @@ impl Error {
147208 }
148209 }
149210}
211+
212+ #[ derive( Debug ) ]
213+ pub struct Frame < ' a > {
214+ pub planes : [ Plane < ' a > ; 3 ] ,
215+ pub sequence_number : u64 ,
216+ pub cts : Option < u64 > ,
217+ }
218+
219+ #[ derive( Debug ) ]
220+ pub struct Plane < ' a > {
221+ pub data : & ' a [ i16 ] ,
222+ pub width : i32 ,
223+ pub height : i32 ,
224+ pub stride : i32 ,
225+ }
226+
227+ #[ derive( Debug ) ]
228+ pub struct AccessUnit {
229+ // FIXME: make inner private
230+ pub inner : vvencAccessUnit ,
231+ }
232+
233+ impl AccessUnit {
234+ fn new ( config : & Config ) -> Self {
235+ // Allocate enough space for the AU payloads from the given config. Same as in EncApp.cpp from libvvenc
236+ #[ allow( non_upper_case_globals) ]
237+ let au_size_scale = match config. inner . m_internChromaFormat {
238+ vvencChromaFormat_VVENC_CHROMA_400 | vvencChromaFormat_VVENC_CHROMA_420 => 2 ,
239+ _ => 3 ,
240+ } ;
241+ let payload_size =
242+ au_size_scale * config. inner . m_SourceHeight * config. inner . m_SourceWidth + 1024 ;
243+ let inner = unsafe {
244+ let mut inner = std:: mem:: zeroed ( ) ;
245+ vvenc_accessUnit_default ( & mut inner) ;
246+ vvenc_accessUnit_alloc_payload ( & mut inner, payload_size) ;
247+ inner
248+ } ;
249+ Self { inner }
250+ }
251+ }
252+
253+ impl Drop for AccessUnit {
254+ fn drop ( & mut self ) {
255+ unsafe {
256+ vvenc_accessUnit_free_payload ( & mut self . inner ) ;
257+ }
258+ }
259+ }
0 commit comments