video: Reuse OpenH264 across decoders and load early
By using the H264Codec struct, we can load OpenH264 early and reuse its instance for all decoders.
This commit is contained in:
parent
1f26edd5b1
commit
7f8beeb1e5
|
@ -1,3 +1,4 @@
|
|||
use crate::decoder::openh264::OpenH264Codec;
|
||||
use crate::decoder::VideoDecoder;
|
||||
use bzip2::read::BzDecoder;
|
||||
use ruffle_render::backend::RenderBackend;
|
||||
|
@ -28,7 +29,7 @@ enum ProxyOrStream {
|
|||
/// except for H.264, for which it uses an external decoder.
|
||||
pub struct ExternalVideoBackend {
|
||||
streams: SlotMap<VideoStreamHandle, ProxyOrStream>,
|
||||
openh264_lib_filepath: Option<PathBuf>,
|
||||
openh264_codec: Option<OpenH264Codec>,
|
||||
software: SoftwareVideoBackend,
|
||||
}
|
||||
|
||||
|
@ -123,9 +124,18 @@ impl ExternalVideoBackend {
|
|||
}
|
||||
|
||||
pub fn new(openh264_lib_filepath: Option<PathBuf>) -> Self {
|
||||
let h264_codec = if let Some(openh264_lib_filepath) = openh264_lib_filepath {
|
||||
tracing::info!("Using OpenH264 at {:?}", openh264_lib_filepath);
|
||||
OpenH264Codec::new(&openh264_lib_filepath)
|
||||
.inspect_err(|err| tracing::error!("Error loading OpenH264: {:?}", err))
|
||||
.ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Self {
|
||||
streams: SlotMap::with_key(),
|
||||
openh264_lib_filepath,
|
||||
openh264_codec: h264_codec,
|
||||
software: SoftwareVideoBackend::new(),
|
||||
}
|
||||
}
|
||||
|
@ -142,10 +152,8 @@ impl VideoBackend for ExternalVideoBackend {
|
|||
filter: VideoDeblocking,
|
||||
) -> Result<VideoStreamHandle, Error> {
|
||||
let proxy_or_stream = if codec == VideoCodec::H264 {
|
||||
let openh264 = &self.openh264_lib_filepath;
|
||||
if let Some(openh264) = openh264 {
|
||||
tracing::info!("Using OpenH264 at {:?}", openh264);
|
||||
let decoder = Box::new(crate::decoder::openh264::H264Decoder::new(openh264));
|
||||
if let Some(h264_codec) = self.openh264_codec.as_ref() {
|
||||
let decoder = Box::new(crate::decoder::openh264::H264Decoder::new(h264_codec));
|
||||
let stream = VideoStream::new(decoder);
|
||||
ProxyOrStream::Owned(stream)
|
||||
} else {
|
||||
|
|
|
@ -63,26 +63,17 @@ pub struct H264Decoder {
|
|||
/// How many bytes are used to store the length of the NALU (1, 2, 3, or 4).
|
||||
length_size: u8,
|
||||
|
||||
openh264: OpenH264,
|
||||
openh264: Arc<OpenH264>,
|
||||
decoder: *mut ISVCDecoder,
|
||||
}
|
||||
|
||||
impl H264Decoder {
|
||||
/// `extradata` should hold "AVCC (MP4) format" decoder configuration, including PPS and SPS.
|
||||
/// Make sure it has any start code emulation prevention "three bytes" removed.
|
||||
pub fn new(openh264_lib_filename: &std::path::Path) -> Self {
|
||||
pub fn new(h264: &OpenH264Codec) -> Self {
|
||||
let openh264 = h264.openh264.clone();
|
||||
let mut decoder: *mut ISVCDecoder = ptr::null_mut();
|
||||
unsafe {
|
||||
let openh264 = OpenH264::new(openh264_lib_filename).unwrap();
|
||||
|
||||
let version = openh264.WelsGetCodecVersion();
|
||||
|
||||
assert_eq!(
|
||||
(version.uMajor, version.uMinor, version.uRevision),
|
||||
(2, 4, 1),
|
||||
"Unexpected OpenH264 version"
|
||||
);
|
||||
|
||||
openh264.WelsCreateDecoder(&mut decoder);
|
||||
|
||||
let decoder_vtbl = (*decoder).as_ref().unwrap();
|
||||
|
|
Loading…
Reference in New Issue