@@ -8,7 +8,6 @@ use vvenc_sys::*;
88#[ derive( Debug ) ]
99pub struct Encoder {
1010 inner : Arc < Mutex < InnerEncoder > > ,
11- au : AccessUnit ,
1211}
1312
1413#[ derive( Debug ) ]
@@ -34,13 +33,16 @@ impl Encoder {
3433 match ret {
3534 ErrorCodes_VVENC_OK => Ok ( Self {
3635 inner : Arc :: new ( Mutex :: new ( InnerEncoder { encoder } ) ) ,
37- au : AccessUnit :: new ( & config) ,
3836 } ) ,
3937 _ => Err ( Error :: new ( ret) ) ,
4038 }
4139 }
4240
43- pub fn encode < ' a > ( & mut self , frame : Frame < ' a > ) -> Result < Option < & AccessUnit > , Error > {
41+ pub fn encode < ' a , ' b > (
42+ & mut self ,
43+ frame : Frame < ' a > ,
44+ out_data : & ' b mut [ u8 ] ,
45+ ) -> Result < Option < AccessUnit < ' b > > , Error > {
4446 let mut yuv_buffer = vvencYUVBuffer {
4547 planes : [
4648 vvencYUVPlane {
@@ -67,12 +69,13 @@ impl Encoder {
6769 ctsValid : frame. cts . is_some ( ) ,
6870 } ;
6971
72+ let mut au = AccessUnit :: new ( out_data) ;
7073 let mut encode_done = false ;
7174 let ret = unsafe {
7275 vvenc_encode (
7376 self . inner . lock ( ) . unwrap ( ) . encoder . as_ptr ( ) ,
7477 & mut yuv_buffer,
75- & mut self . au . inner ,
78+ & mut au. inner ,
7679 & mut encode_done,
7780 )
7881 } ;
@@ -81,21 +84,17 @@ impl Encoder {
8184 return Err ( Error :: new ( ret) ) ;
8285 }
8386
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 ) )
87+ Ok ( ( !au. payload ( ) . is_empty ( ) ) . then_some ( au) )
9088 }
9189
92- pub fn flush ( & mut self ) -> Result < Option < & AccessUnit > , Error > {
90+ pub fn flush < ' b > ( & mut self , out_data : & ' b mut [ u8 ] ) -> Result < Option < AccessUnit < ' b > > , Error > {
91+ let mut au = AccessUnit :: new ( out_data) ;
9392 let mut encode_done = false ;
9493 let ret = unsafe {
9594 vvenc_encode (
9695 self . inner . lock ( ) . unwrap ( ) . encoder . as_ptr ( ) ,
9796 std:: ptr:: null_mut ( ) ,
98- & mut self . au . inner ,
97+ & mut au. inner ,
9998 & mut encode_done,
10099 )
101100 } ;
@@ -104,11 +103,32 @@ impl Encoder {
104103 return Err ( Error :: new ( ret) ) ;
105104 }
106105
107- if self . au . inner . payloadUsedSize == 0 {
108- return Ok ( None ) ;
106+ Ok ( ( !au. payload ( ) . is_empty ( ) ) . then_some ( au) )
107+ }
108+
109+ pub fn config ( & self ) -> Result < Config , Error > {
110+ let mut inner = unsafe { std:: mem:: zeroed ( ) } ;
111+ let ret =
112+ unsafe { vvenc_get_config ( self . inner . lock ( ) . unwrap ( ) . encoder . as_ptr ( ) , & mut inner) } ;
113+ if ret != ErrorCodes_VVENC_OK {
114+ return Err ( Error :: new ( ret) ) ;
115+ }
116+ Ok ( Config { inner } )
117+ }
118+
119+ pub fn reconfigure ( & mut self , mut config : Config ) -> Result < ( ) , Error > {
120+ let ret = unsafe {
121+ vvenc_reconfig (
122+ self . inner . lock ( ) . unwrap ( ) . encoder . as_ptr ( ) ,
123+ & mut config. inner ,
124+ )
125+ } ;
126+
127+ if ret != ErrorCodes_VVENC_OK {
128+ return Err ( Error :: new ( ret) ) ;
109129 }
110130
111- Ok ( Some ( & self . au ) )
131+ Ok ( ( ) )
112132 }
113133}
114134
@@ -125,9 +145,9 @@ impl Config {
125145 target_bitrate : i32 ,
126146 qp : i32 ,
127147 preset : Preset ,
128- ) -> Self {
129- unsafe {
130- let mut inner = std :: mem :: zeroed ( ) ;
148+ ) -> Result < Self , Error > {
149+ let mut inner = unsafe { std :: mem :: zeroed ( ) } ;
150+ let ret = unsafe {
131151 vvenc_init_default (
132152 & mut inner,
133153 width,
@@ -136,37 +156,38 @@ impl Config {
136156 target_bitrate,
137157 qp,
138158 preset. to_ffi ( ) ,
139- ) ;
140- Self { inner }
159+ )
160+ } ;
161+
162+ if ret != ErrorCodes_VVENC_OK {
163+ return Err ( Error :: new ( ret) ) ;
141164 }
165+
166+ Ok ( Self { inner } )
142167 }
143- }
144168
145- #[ derive( Debug , Clone , Copy , PartialEq ) ]
146- pub enum Preset {
147- Faster ,
148- Fast ,
149- Medium ,
150- Slow ,
151- Slower ,
152- MediumLowDecNrg ,
153- FirstPass ,
154- ToolTest ,
155- }
169+ pub fn source_width ( & self ) -> i32 {
170+ self . inner . m_SourceWidth
171+ }
156172
157- impl Preset {
158- #[ inline]
159- fn to_ffi ( self ) -> vvencPresetMode {
160- match self {
161- Self :: Faster => vvencPresetMode_VVENC_FASTER,
162- Self :: Fast => vvencPresetMode_VVENC_FAST,
163- Self :: Medium => vvencPresetMode_VVENC_MEDIUM,
164- Self :: Slow => vvencPresetMode_VVENC_SLOW,
165- Self :: Slower => vvencPresetMode_VVENC_SLOWER,
166- Self :: MediumLowDecNrg => vvencPresetMode_VVENC_MEDIUM_LOWDECNRG,
167- Self :: FirstPass => vvencPresetMode_VVENC_FIRSTPASS,
168- Self :: ToolTest => vvencPresetMode_VVENC_TOOLTEST,
173+ pub fn source_height ( & self ) -> i32 {
174+ self . inner . m_SourceHeight
175+ }
176+
177+ pub fn chroma_format ( & self ) -> ChromaFormat {
178+ ChromaFormat :: from_ffi ( self . inner . m_internChromaFormat )
179+ }
180+
181+ pub fn set_chroma_format ( & mut self , chroma_format : ChromaFormat ) {
182+ self . inner . m_internChromaFormat = chroma_format. to_ffi ( ) ;
183+ }
184+
185+ pub fn set_preset ( & mut self , preset : Preset ) -> Result < ( ) , Error > {
186+ let ret = unsafe { vvenc_init_preset ( & mut self . inner , preset. to_ffi ( ) ) } ;
187+ if ret != ErrorCodes_VVENC_OK {
188+ return Err ( Error :: new ( ret) ) ;
169189 }
190+ Ok ( ( ) )
170191 }
171192}
172193
@@ -225,35 +246,138 @@ pub struct Plane<'a> {
225246}
226247
227248#[ derive( Debug ) ]
228- pub struct AccessUnit {
229- // FIXME: make inner private
230- pub inner : vvencAccessUnit ,
249+ pub struct AccessUnit < ' a > {
250+ inner : vvencAccessUnit ,
251+ data : & ' a [ u8 ] ,
231252}
232253
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 ;
254+ impl < ' a > AccessUnit < ' a > {
255+ fn new ( data : & ' a mut [ u8 ] ) -> Self {
243256 let inner = unsafe {
244257 let mut inner = std:: mem:: zeroed ( ) ;
245258 vvenc_accessUnit_default ( & mut inner) ;
246- vvenc_accessUnit_alloc_payload ( & mut inner, payload_size) ;
259+ inner. payload = data. as_mut_ptr ( ) ;
260+ inner. payloadSize = data. len ( ) as i32 ;
261+ inner. payloadUsedSize = 0 ;
247262 inner
248263 } ;
249- Self { inner }
264+ Self { inner, data }
265+ }
266+
267+ pub fn payload ( & self ) -> & [ u8 ] {
268+ & self . data [ ..self . inner . payloadUsedSize as usize ]
269+ }
270+
271+ pub fn cts ( & self ) -> Option < u64 > {
272+ self . inner . ctsValid . then_some ( self . inner . cts )
273+ }
274+
275+ pub fn dts ( & self ) -> Option < u64 > {
276+ self . inner . dtsValid . then_some ( self . inner . dts )
277+ }
278+
279+ pub fn rap ( & self ) -> bool {
280+ self . inner . rap
281+ }
282+
283+ pub fn slice_type ( & self ) -> SliceType {
284+ SliceType :: from_ffi ( self . inner . sliceType )
285+ }
286+
287+ pub fn is_ref_pic ( & self ) -> bool {
288+ self . inner . refPic
289+ }
290+
291+ pub fn temporal_layer ( & self ) -> i32 {
292+ self . inner . temporalLayer
293+ }
294+
295+ pub fn poc ( & self ) -> u64 {
296+ self . inner . poc
250297 }
251298}
252299
253- impl Drop for AccessUnit {
254- fn drop ( & mut self ) {
255- unsafe {
256- vvenc_accessUnit_free_payload ( & mut self . inner ) ;
300+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
301+ pub enum Preset {
302+ Faster ,
303+ Fast ,
304+ Medium ,
305+ Slow ,
306+ Slower ,
307+ MediumLowDecNrg ,
308+ FirstPass ,
309+ ToolTest ,
310+ Unknown ( i32 ) ,
311+ }
312+
313+ impl Preset {
314+ #[ inline]
315+ fn to_ffi ( self ) -> vvencPresetMode {
316+ match self {
317+ Self :: Faster => vvencPresetMode_VVENC_FASTER,
318+ Self :: Fast => vvencPresetMode_VVENC_FAST,
319+ Self :: Medium => vvencPresetMode_VVENC_MEDIUM,
320+ Self :: Slow => vvencPresetMode_VVENC_SLOW,
321+ Self :: Slower => vvencPresetMode_VVENC_SLOWER,
322+ Self :: MediumLowDecNrg => vvencPresetMode_VVENC_MEDIUM_LOWDECNRG,
323+ Self :: FirstPass => vvencPresetMode_VVENC_FIRSTPASS,
324+ Self :: ToolTest => vvencPresetMode_VVENC_TOOLTEST,
325+ Self :: Unknown ( value) => value,
326+ }
327+ }
328+ }
329+
330+ #[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
331+ pub enum ChromaFormat {
332+ Chroma400 ,
333+ Chroma420 ,
334+ Chroma422 ,
335+ Chroma444 ,
336+ Unknown ( u32 ) ,
337+ }
338+
339+ impl ChromaFormat {
340+ #[ inline]
341+ fn to_ffi ( self ) -> vvencChromaFormat {
342+ match self {
343+ Self :: Chroma400 => vvencChromaFormat_VVENC_CHROMA_400,
344+ Self :: Chroma420 => vvencChromaFormat_VVENC_CHROMA_420,
345+ Self :: Chroma422 => vvencChromaFormat_VVENC_CHROMA_422,
346+ Self :: Chroma444 => vvencChromaFormat_VVENC_CHROMA_444,
347+ Self :: Unknown ( value) => value,
348+ }
349+ }
350+
351+ #[ inline]
352+ fn from_ffi ( value : vvencChromaFormat ) -> Self {
353+ #[ allow( non_upper_case_globals) ]
354+ match value {
355+ vvencChromaFormat_VVENC_CHROMA_400 => Self :: Chroma400 ,
356+ vvencChromaFormat_VVENC_CHROMA_420 => Self :: Chroma420 ,
357+ vvencChromaFormat_VVENC_CHROMA_422 => Self :: Chroma422 ,
358+ vvencChromaFormat_VVENC_CHROMA_444 => Self :: Chroma444 ,
359+ _ => Self :: Unknown ( value) ,
360+ }
361+ }
362+ }
363+
364+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
365+ pub enum SliceType {
366+ B ,
367+ P ,
368+ I ,
369+ Unknown ( u32 ) ,
370+ }
371+
372+ impl SliceType {
373+ #[ inline]
374+ fn from_ffi ( value : vvencSliceType ) -> Self {
375+ #[ allow( non_upper_case_globals) ]
376+ match value {
377+ vvencSliceType_VVENC_B_SLICE => Self :: B ,
378+ vvencSliceType_VVENC_P_SLICE => Self :: P ,
379+ vvencSliceType_VVENC_I_SLICE => Self :: I ,
380+ _ => Self :: Unknown ( value) ,
257381 }
258382 }
259383}
0 commit comments