Skip to content

Commit 4dfe86c

Browse files
authored
Merge pull request #1 from cadubentzen/discord
Add Discord patches
2 parents 5ff6d69 + 6761a45 commit 4dfe86c

File tree

25 files changed

+635
-65
lines changed

25 files changed

+635
-65
lines changed

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ edition = "2021"
99

1010
[features]
1111
default = []
12-
backend = ["anyhow", "byteorder", "thiserror", "crc32fast", "nix", "gbm", "gbm-sys", "drm", "drm-fourcc", "zerocopy"]
12+
backend = ["anyhow", "byteorder", "thiserror", "crc32fast", "nix", "drm", "drm-fourcc", "zerocopy"]
1313
vaapi = ["libva", "backend"]
1414
v4l2 = ["v4l2r", "backend"]
15+
gbm = ["dep:gbm", "gbm-sys"]
16+
h265 = []
17+
av1 = []
18+
c2-wrapper = ["backend"]
1519

1620
[dependencies]
1721
anyhow = { version = "1.0.75", optional = true }
1822
byteorder = { version = "1.4.3", optional = true }
19-
libva = { version = "0.0.12", package = "cros-libva", optional = true }
23+
libva = { version = "0.0.13", package = "cros-libva", optional = true }
2024
v4l2r = { version = "0.0.5", package = "v4l2r", optional = true }
2125
log = { version = "0", features = ["release_max_level_debug"] }
2226
thiserror = { version = "1.0.58", optional = true }

src/backend/v4l2/encoder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ where
523523
"bitrate mode",
524524
match rate_control {
525525
RateControl::ConstantBitrate(_) => VideoBitrateMode::ConstantBitrate,
526+
RateControl::VariableBitrate { .. } => todo!(),
526527
RateControl::ConstantQuality(_) => VideoBitrateMode::ConstantQuality,
527528
},
528529
)?;
@@ -1217,6 +1218,7 @@ pub(crate) mod tests {
12171218
timestamp: self.counter,
12181219
layout: self.frame_layout.clone(),
12191220
force_keyframe: false,
1221+
force_idr: false,
12201222
};
12211223

12221224
let handle = TestMmapFrame { meta: meta.clone(), frame_count: self.max_count };
@@ -1326,6 +1328,7 @@ pub(crate) mod tests {
13261328
timestamp: self.counter,
13271329
layout: layout.clone(),
13281330
force_keyframe: false,
1331+
force_idr: false,
13291332
};
13301333

13311334
let frame = DmabufFrame { fds, layout };

src/backend/vaapi/decoder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl<V: VideoFrame> VaapiDecodedHandle<V> {
191191
}
192192

193193
pub struct VaapiBackend<V: VideoFrame> {
194-
pub display: Rc<Display>,
194+
pub display: Arc<Display>,
195195
pub context: Rc<Context>,
196196
stream_info: StreamInfo,
197197
// TODO: We should try to support context reuse
@@ -200,7 +200,7 @@ pub struct VaapiBackend<V: VideoFrame> {
200200
}
201201

202202
impl<V: VideoFrame> VaapiBackend<V> {
203-
pub(crate) fn new(display: Rc<libva::Display>, supports_context_reuse: bool) -> Self {
203+
pub(crate) fn new(display: Arc<libva::Display>, supports_context_reuse: bool) -> Self {
204204
let init_stream_info = StreamInfo {
205205
format: DecodedFormat::NV12,
206206
coded_resolution: Resolution::from((16, 16)),

src/backend/vaapi/encoder.rs

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use std::any::Any;
66
use std::marker::PhantomData;
77
use std::rc::Rc;
8+
use std::sync::Arc;
89

910
use anyhow::anyhow;
1011
use libva::Config;
@@ -17,6 +18,7 @@ use libva::PictureEnd;
1718
use libva::Surface;
1819
use libva::SurfaceMemoryDescriptor;
1920
use libva::UsageHint;
21+
use libva::VAEntrypoint;
2022
use libva::VAEntrypoint::VAEntrypointEncSlice;
2123
use libva::VAEntrypoint::VAEntrypointEncSliceLP;
2224
use libva::VAProfile;
@@ -52,11 +54,14 @@ impl From<libva::VaError> for StatelessBackendError {
5254
pub(crate) fn tunings_to_libva_rc<const CLAMP_MIN_QP: u32, const CLAMP_MAX_QP: u32>(
5355
tunings: &Tunings,
5456
) -> StatelessBackendResult<libva::EncMiscParameterRateControl> {
55-
let bits_per_second = tunings.rate_control.bitrate_target().unwrap_or(0);
57+
let bits_per_second = tunings.rate_control.bitrate_maximum().unwrap_or(0);
58+
let target_bits_per_second = tunings.rate_control.bitrate_target().unwrap_or(bits_per_second);
59+
5660
let bits_per_second = u32::try_from(bits_per_second).map_err(|e| anyhow::anyhow!(e))?;
61+
let target_bits_per_second =
62+
u32::try_from(target_bits_per_second).map_err(|e| anyhow::anyhow!(e))?;
5763

58-
// At the moment we don't support variable bitrate therefore target 100%
59-
const TARGET_PERCENTAGE: u32 = 100;
64+
let target_percentage: u32 = 100 * target_bits_per_second / bits_per_second;
6065

6166
// Window size in ms that the RC should apply to
6267
const WINDOW_SIZE: u32 = 1_500;
@@ -70,10 +75,10 @@ pub(crate) fn tunings_to_libva_rc<const CLAMP_MIN_QP: u32, const CLAMP_MAX_QP: u
7075
const RESET: u32 = 0;
7176

7277
// Don't skip frames
73-
const DISABLE_FRAME_SKIP: u32 = 1;
78+
const DISABLE_FRAME_SKIP: u32 = 0;
7479

7580
// Allow bit stuffing
76-
const DISABLE_BIT_STUFFING: u32 = 0;
81+
const DISABLE_BIT_STUFFING: u32 = 1;
7782

7883
// Use default
7984
const MB_RATE_CONTROL: u32 = 0;
@@ -113,7 +118,7 @@ pub(crate) fn tunings_to_libva_rc<const CLAMP_MIN_QP: u32, const CLAMP_MAX_QP: u
113118

114119
Ok(libva::EncMiscParameterRateControl::new(
115120
bits_per_second,
116-
TARGET_PERCENTAGE,
121+
target_percentage,
117122
WINDOW_SIZE,
118123
initial_qp,
119124
min_qp,
@@ -161,7 +166,8 @@ where
161166
/// VA context used for encoding.
162167
context: Rc<Context>,
163168

164-
_va_profile: VAProfile::Type,
169+
va_profile: VAProfile::Type,
170+
entrypoint: VAEntrypoint::Type,
165171
scratch_pool: VaSurfacePool<()>,
166172
_phantom: PhantomData<(M, H)>,
167173
}
@@ -172,7 +178,7 @@ where
172178
H: std::borrow::Borrow<Surface<M>>,
173179
{
174180
pub fn new(
175-
display: Rc<Display>,
181+
display: Arc<Display>,
176182
va_profile: VAProfile::Type,
177183
fourcc: Fourcc,
178184
coded_size: Resolution,
@@ -185,6 +191,7 @@ where
185191
.ok_or_else(|| StatelessBackendError::UnsupportedFormat)?;
186192

187193
let rt_format = format_map.rt_format;
194+
let entrypoint = if low_power { VAEntrypointEncSliceLP } else { VAEntrypointEncSlice };
188195

189196
let va_config = display.create_config(
190197
vec![
@@ -198,7 +205,7 @@ where
198205
},
199206
],
200207
va_profile,
201-
if low_power { VAEntrypointEncSliceLP } else { VAEntrypointEncSlice },
208+
entrypoint,
202209
)?;
203210

204211
let context = display.create_context::<M>(
@@ -210,7 +217,7 @@ where
210217
)?;
211218

212219
let mut scratch_pool = VaSurfacePool::new(
213-
Rc::clone(&display),
220+
Arc::clone(&display),
214221
rt_format,
215222
Some(UsageHint::USAGE_HINT_ENCODER),
216223
coded_size,
@@ -223,7 +230,8 @@ where
223230
va_config,
224231
context,
225232
scratch_pool,
226-
_va_profile: va_profile,
233+
va_profile,
234+
entrypoint,
227235
_phantom: Default::default(),
228236
})
229237
}
@@ -271,6 +279,51 @@ where
271279

272280
Ok(Reconstructed(surface))
273281
}
282+
283+
pub(crate) fn supports_max_frame_size(&self) -> StatelessBackendResult<bool> {
284+
let display = self.context().display();
285+
let mut attrs = [libva::VAConfigAttrib {
286+
type_: libva::VAConfigAttribType::VAConfigAttribMaxFrameSize,
287+
value: 0,
288+
}];
289+
290+
display.get_config_attributes(self.va_profile, self.entrypoint, &mut attrs)?;
291+
292+
if attrs[0].value == libva::VA_ATTRIB_NOT_SUPPORTED {
293+
return Ok(false);
294+
}
295+
Ok(true)
296+
}
297+
298+
pub(crate) fn supports_quality_range(&self, quality: u32) -> StatelessBackendResult<bool> {
299+
let display = self.context().display();
300+
let mut attrs = [libva::VAConfigAttrib {
301+
type_: libva::VAConfigAttribType::VAConfigAttribEncQualityRange,
302+
value: 0,
303+
}];
304+
305+
display.get_config_attributes(self.va_profile, self.entrypoint, &mut attrs)?;
306+
307+
if attrs[0].value == libva::VA_ATTRIB_NOT_SUPPORTED || quality > attrs[0].value {
308+
return Ok(false);
309+
}
310+
Ok(true)
311+
}
312+
313+
pub(crate) fn supports_packed_header(&self, header: u32) -> StatelessBackendResult<bool> {
314+
let display = self.context().display();
315+
let mut attrs = [libva::VAConfigAttrib {
316+
type_: libva::VAConfigAttribType::VAConfigAttribEncPackedHeaders,
317+
value: 0,
318+
}];
319+
320+
display.get_config_attributes(self.va_profile, self.entrypoint, &mut attrs)?;
321+
322+
if attrs[0].value == libva::VA_ATTRIB_NOT_SUPPORTED || (header & attrs[0].value) == 0 {
323+
return Ok(false);
324+
}
325+
Ok(true)
326+
}
274327
}
275328

276329
impl<M, Handle> StatelessEncoderBackendImport<Handle, Handle> for VaapiBackend<M, Handle>
@@ -491,6 +544,7 @@ pub(crate) mod tests {
491544
layout: self.frame_layout.clone(),
492545
force_keyframe: false,
493546
timestamp: self.counter,
547+
force_idr: false,
494548
};
495549

496550
self.counter += 1;

src/backend/vaapi/surface_pool.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::collections::BTreeMap;
88
use std::collections::VecDeque;
99
use std::rc::Rc;
1010
use std::rc::Weak;
11+
use std::sync::Arc;
1112

1213
use libva::Display;
1314
use libva::Surface;
@@ -79,7 +80,7 @@ impl<M: SurfaceMemoryDescriptor> Drop for PooledVaSurface<M> {
7980
}
8081

8182
struct VaSurfacePoolInner<M: SurfaceMemoryDescriptor> {
82-
display: Rc<Display>,
83+
display: Arc<Display>,
8384
rt_format: u32,
8485
usage_hint: Option<libva::UsageHint>,
8586
coded_resolution: Resolution,
@@ -133,7 +134,7 @@ impl<M: SurfaceMemoryDescriptor> VaSurfacePool<M> {
133134
/// * `usage_hint` - hint about how the surfaces from this pool will be used.
134135
/// * `coded_resolution` - resolution of the surfaces.
135136
pub fn new(
136-
display: Rc<Display>,
137+
display: Arc<Display>,
137138
rt_format: u32,
138139
usage_hint: Option<libva::UsageHint>,
139140
coded_resolution: Resolution,

src/bitstream_utils.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,15 +510,18 @@ impl<W: Write> BitWriter<W> {
510510
}
511511

512512
/// Immediately outputs any cached bits to [`std::io::Write`]
513-
pub fn flush(&mut self) -> BitWriterResult<()> {
513+
/// and returns the number of trailing bits in the last byte.
514+
pub fn flush(&mut self) -> BitWriterResult<u8> {
515+
let mut num_trailing_bits = 0;
514516
if self.nth_bit != 0 {
515517
self.out.write_all(&[self.curr_byte])?;
518+
num_trailing_bits = 8 - self.nth_bit;
516519
self.nth_bit = 0;
517520
self.curr_byte = 0;
518521
}
519522

520523
self.out.flush()?;
521-
Ok(())
524+
Ok(num_trailing_bits)
522525
}
523526

524527
/// Returns `true` if ['Self`] hold data that wasn't written to [`std::io::Write`]

src/c2_wrapper/c2_decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::decoder::StreamInfo;
3232
use crate::image_processing::convert_video_frame;
3333
use crate::video_frame::frame_pool::FramePool;
3434
use crate::video_frame::frame_pool::PooledVideoFrame;
35-
#[cfg(feature = "vaapi")]
35+
#[cfg(feature = "gbm")]
3636
use crate::video_frame::gbm_video_frame::{GbmDevice, GbmUsage, GbmVideoFrame};
3737
#[cfg(feature = "v4l2")]
3838
use crate::video_frame::v4l2_mmap_video_frame::V4l2MmapVideoFrame;
@@ -62,7 +62,7 @@ pub trait C2DecoderBackend {
6262
) -> Result<DynStatelessVideoDecoder<V>, String>;
6363
}
6464

65-
#[cfg(feature = "vaapi")]
65+
#[cfg(feature = "gbm")]
6666
type AuxiliaryVideoFrame = GbmVideoFrame;
6767
#[cfg(feature = "v4l2")]
6868
type AuxiliaryVideoFrame = V4l2MmapVideoFrame;
@@ -189,7 +189,7 @@ where
189189
),
190190
)
191191
} else {
192-
#[cfg(feature = "vaapi")]
192+
#[cfg(feature = "gbm")]
193193
{
194194
let gbm_device = Arc::new(
195195
GbmDevice::open(PathBuf::from("/dev/dri/renderD128"))

src/c2_wrapper/c2_encoder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ where
250250
timestamp: job.timestamp,
251251
layout: Default::default(),
252252
force_keyframe: false,
253+
force_idr: false,
253254
};
254255
#[cfg(feature = "vaapi")]
255256
let encode_result = self.encoder.encode(meta, frame);

src/codec/h264/nalu_writer.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,20 @@ impl<W: Write> NaluWriter<W> {
177177
/// Writes a H.264 NALU header.
178178
pub fn write_header(&mut self, idc: u8, _type: u8) -> NaluWriterResult<()> {
179179
self.0.flush()?;
180-
self.0.inner_mut().write_header(idc, _type)?;
180+
let _num_bytes = self.0.inner_mut().write_header(idc, _type)?;
181+
// self.0.bits_written += num_bytes * 8;
181182
Ok(())
182183
}
183184

184185
/// Returns `true` if next bits will be aligned to 8
185186
pub fn aligned(&self) -> bool {
186187
!self.0.has_data_pending()
187188
}
189+
190+
/// Returns the number of trailing bits in the last byte.
191+
pub fn flush(&mut self) -> NaluWriterResult<u8> {
192+
Ok(self.0.flush()?)
193+
}
188194
}
189195

190196
#[cfg(test)]

0 commit comments

Comments
 (0)