fix: debian bookworm build
This commit is contained in:
parent
bb11e998e7
commit
8f7c47d4fe
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
**/target
|
||||||
|
test_output/
|
15
Dockerfile.bookworm
Normal file
15
Dockerfile.bookworm
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
FROM rust:bookworm
|
||||||
|
WORKDIR /src
|
||||||
|
COPY . .
|
||||||
|
RUN apt update && apt install -y \
|
||||||
|
build-essential \
|
||||||
|
libavcodec-dev \
|
||||||
|
libavformat-dev \
|
||||||
|
libavutil-dev \
|
||||||
|
libavdevice-dev \
|
||||||
|
libswresample-dev \
|
||||||
|
libswscale-dev \
|
||||||
|
libpipewire-0.3-dev \
|
||||||
|
libasound2-dev \
|
||||||
|
libclang-dev
|
||||||
|
RUN cargo build --release
|
19
build.rs
Normal file
19
build.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// re-export ffmpeg-sys-the-third features
|
||||||
|
// https://github.com/FFmpeg/FFmpeg/blob/master/doc/APIchanges
|
||||||
|
for (name, _value) in env::vars() {
|
||||||
|
if name.starts_with("DEP_FFMPEG_CHECK_") {
|
||||||
|
println!(
|
||||||
|
r#"cargo:rustc-check-cfg=cfg(feature, values("{}"))"#,
|
||||||
|
name["DEP_FFMPEG_CHECK_".len()..name.len()].to_lowercase()
|
||||||
|
);
|
||||||
|
} else if name.starts_with("DEP_FFMPEG_") {
|
||||||
|
println!(
|
||||||
|
r#"cargo:rustc-cfg=feature="{}""#,
|
||||||
|
name["DEP_FFMPEG_".len()..name.len()].to_lowercase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -30,11 +30,12 @@ impl AudioFifo {
|
|||||||
av_audio_fifo_realloc(self.ctx, av_audio_fifo_size(self.ctx) + (*frame).nb_samples);
|
av_audio_fifo_realloc(self.ctx, av_audio_fifo_size(self.ctx) + (*frame).nb_samples);
|
||||||
bail_ffmpeg!(ret);
|
bail_ffmpeg!(ret);
|
||||||
|
|
||||||
ret = av_audio_fifo_write(
|
#[cfg(feature = "avutil_version_greater_than_58_22")]
|
||||||
self.ctx,
|
let buf_ptr = (*frame).extended_data as *const _;
|
||||||
(*frame).extended_data as *const _,
|
#[cfg(not(feature = "avutil_version_greater_than_58_22"))]
|
||||||
(*frame).nb_samples,
|
let buf_ptr = (*frame).extended_data as *mut _;
|
||||||
);
|
|
||||||
|
ret = av_audio_fifo_write(self.ctx, buf_ptr, (*frame).nb_samples);
|
||||||
bail_ffmpeg!(ret);
|
bail_ffmpeg!(ret);
|
||||||
|
|
||||||
if av_audio_fifo_size(self.ctx) >= samples_out as _ {
|
if av_audio_fifo_size(self.ctx) >= samples_out as _ {
|
||||||
@ -47,12 +48,12 @@ impl AudioFifo {
|
|||||||
ret = av_frame_get_buffer(out_frame, 0);
|
ret = av_frame_get_buffer(out_frame, 0);
|
||||||
bail_ffmpeg!(ret, { av_frame_free(&mut out_frame) });
|
bail_ffmpeg!(ret, { av_frame_free(&mut out_frame) });
|
||||||
|
|
||||||
if av_audio_fifo_read(
|
#[cfg(feature = "avutil_version_greater_than_58_22")]
|
||||||
self.ctx,
|
let buf_ptr = (*out_frame).extended_data as *const _;
|
||||||
(*out_frame).extended_data as *mut _,
|
#[cfg(not(feature = "avutil_version_greater_than_58_22"))]
|
||||||
samples_out as _,
|
let buf_ptr = (*out_frame).extended_data as *mut _;
|
||||||
) < samples_out as _
|
|
||||||
{
|
if av_audio_fifo_read(self.ctx, buf_ptr, samples_out as _) < samples_out as _ {
|
||||||
av_frame_free(&mut out_frame);
|
av_frame_free(&mut out_frame);
|
||||||
bail!("Failed to read audio frame");
|
bail!("Failed to read audio frame");
|
||||||
}
|
}
|
||||||
|
10
src/demux.rs
10
src/demux.rs
@ -1,6 +1,9 @@
|
|||||||
use crate::{bail_ffmpeg, cstr, rstr, StreamGroupInfo, StreamGroupType};
|
use crate::{bail_ffmpeg, cstr, rstr};
|
||||||
use crate::{DemuxerInfo, StreamInfo, StreamType};
|
use crate::{DemuxerInfo, StreamInfo, StreamType};
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
|
use crate::{StreamGroupInfo, StreamGroupType};
|
||||||
use anyhow::{bail, Error, Result};
|
use anyhow::{bail, Error, Result};
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_22")]
|
||||||
use ffmpeg_sys_the_third::AVStreamGroupParamsType::AV_STREAM_GROUP_PARAMS_TILE_GRID;
|
use ffmpeg_sys_the_third::AVStreamGroupParamsType::AV_STREAM_GROUP_PARAMS_TILE_GRID;
|
||||||
use ffmpeg_sys_the_third::*;
|
use ffmpeg_sys_the_third::*;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
@ -124,13 +127,16 @@ impl Demuxer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut streams = vec![];
|
let mut streams = vec![];
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
let mut stream_groups = vec![];
|
let mut stream_groups = vec![];
|
||||||
|
|
||||||
let mut n_stream = 0;
|
let mut n_stream = 0;
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
for n in 0..(*self.ctx).nb_stream_groups as usize {
|
for n in 0..(*self.ctx).nb_stream_groups as usize {
|
||||||
let group = *(*self.ctx).stream_groups.add(n);
|
let group = *(*self.ctx).stream_groups.add(n);
|
||||||
n_stream += (*group).nb_streams as usize;
|
n_stream += (*group).nb_streams as usize;
|
||||||
match (*group).type_ {
|
match (*group).type_ {
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_22")]
|
||||||
AV_STREAM_GROUP_PARAMS_TILE_GRID => {
|
AV_STREAM_GROUP_PARAMS_TILE_GRID => {
|
||||||
let tg = (*group).params.tile_grid;
|
let tg = (*group).params.tile_grid;
|
||||||
let codec_par = (*(*(*group).streams.add(0))).codecpar;
|
let codec_par = (*(*(*group).streams.add(0))).codecpar;
|
||||||
@ -216,6 +222,7 @@ impl Demuxer {
|
|||||||
duration: (*self.ctx).duration as f32 / AV_TIME_BASE as f32,
|
duration: (*self.ctx).duration as f32 / AV_TIME_BASE as f32,
|
||||||
bitrate: (*self.ctx).bit_rate as usize,
|
bitrate: (*self.ctx).bit_rate as usize,
|
||||||
streams,
|
streams,
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
groups: stream_groups,
|
groups: stream_groups,
|
||||||
};
|
};
|
||||||
Ok(info)
|
Ok(info)
|
||||||
@ -255,6 +262,7 @@ impl Drop for Demuxer {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_stream_groups() -> Result<()> {
|
fn test_stream_groups() -> Result<()> {
|
||||||
|
@ -4,10 +4,13 @@ use ffmpeg_sys_the_third::AVPictureType::AV_PICTURE_TYPE_NONE;
|
|||||||
use ffmpeg_sys_the_third::{
|
use ffmpeg_sys_the_third::{
|
||||||
av_channel_layout_default, av_d2q, av_inv_q, av_packet_alloc, av_packet_free,
|
av_channel_layout_default, av_d2q, av_inv_q, av_packet_alloc, av_packet_free,
|
||||||
avcodec_alloc_context3, avcodec_find_encoder, avcodec_find_encoder_by_name,
|
avcodec_alloc_context3, avcodec_find_encoder, avcodec_find_encoder_by_name,
|
||||||
avcodec_free_context, avcodec_get_supported_config, avcodec_open2, avcodec_receive_packet,
|
avcodec_free_context, avcodec_open2, avcodec_receive_packet, avcodec_send_frame,
|
||||||
avcodec_send_frame, AVChannelLayout, AVCodec, AVCodecConfig, AVCodecContext, AVCodecID,
|
AVChannelLayout, AVCodec, AVCodecContext, AVCodecID, AVFrame, AVPacket, AVPixelFormat,
|
||||||
AVFrame, AVPacket, AVPixelFormat, AVRational, AVSampleFormat, AVERROR, AVERROR_EOF,
|
AVRational, AVSampleFormat, AVERROR, AVERROR_EOF,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "avcodec_version_greater_than_61_13")]
|
||||||
|
use ffmpeg_sys_the_third::{avcodec_get_supported_config, AVCodecConfig};
|
||||||
|
|
||||||
use libc::EAGAIN;
|
use libc::EAGAIN;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
@ -79,6 +82,7 @@ impl Encoder {
|
|||||||
self.ctx
|
self.ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "avcodec_version_greater_than_61_13")]
|
||||||
/// List supported configs (see [avcodec_get_supported_config])
|
/// List supported configs (see [avcodec_get_supported_config])
|
||||||
pub unsafe fn list_configs<'a, T>(&mut self, cfg: AVCodecConfig) -> Result<&'a [T], Error> {
|
pub unsafe fn list_configs<'a, T>(&mut self, cfg: AVCodecConfig) -> Result<&'a [T], Error> {
|
||||||
let mut dst = ptr::null_mut();
|
let mut dst = ptr::null_mut();
|
||||||
@ -261,6 +265,7 @@ impl Encoder {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::generate_test_frame;
|
use crate::generate_test_frame;
|
||||||
|
use ffmpeg_sys_the_third::AVPixelFormat::AV_PIX_FMT_YUV420P;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encode_png() -> Result<(), Error> {
|
fn test_encode_png() -> Result<(), Error> {
|
||||||
@ -270,8 +275,12 @@ mod tests {
|
|||||||
.with_width((*frame).width)
|
.with_width((*frame).width)
|
||||||
.with_height((*frame).height);
|
.with_height((*frame).height);
|
||||||
|
|
||||||
|
#[cfg(feature = "avcodec_version_greater_than_61_13")]
|
||||||
let pix_fmts: &[AVPixelFormat] =
|
let pix_fmts: &[AVPixelFormat] =
|
||||||
encoder.list_configs(AVCodecConfig::AV_CODEC_CONFIG_PIX_FORMAT)?;
|
encoder.list_configs(AVCodecConfig::AV_CODEC_CONFIG_PIX_FORMAT)?;
|
||||||
|
#[cfg(not(feature = "avcodec_version_greater_than_61_13"))]
|
||||||
|
let pix_fmts = [AV_PIX_FMT_YUV420P];
|
||||||
|
|
||||||
encoder = encoder.with_pix_fmt(pix_fmts[0]).open(None)?;
|
encoder = encoder.with_pix_fmt(pix_fmts[0]).open(None)?;
|
||||||
|
|
||||||
std::fs::create_dir_all("test_output")?;
|
std::fs::create_dir_all("test_output")?;
|
||||||
|
@ -14,7 +14,8 @@ use std::{ptr, slice};
|
|||||||
|
|
||||||
unsafe extern "C" fn write_data<T>(
|
unsafe extern "C" fn write_data<T>(
|
||||||
opaque: *mut libc::c_void,
|
opaque: *mut libc::c_void,
|
||||||
buffer: *const u8,
|
#[cfg(feature = "avformat_version_greater_than_60_12")] buffer: *const u8,
|
||||||
|
#[cfg(not(feature = "avformat_version_greater_than_60_12"))] buffer: *mut u8,
|
||||||
size: libc::c_int,
|
size: libc::c_int,
|
||||||
) -> libc::c_int
|
) -> libc::c_int
|
||||||
where
|
where
|
||||||
|
@ -5,7 +5,6 @@ use ffmpeg_sys_the_third::{
|
|||||||
swr_alloc_set_opts2, swr_convert_frame, swr_free, swr_init, AVChannelLayout, AVFrame,
|
swr_alloc_set_opts2, swr_convert_frame, swr_free, swr_init, AVChannelLayout, AVFrame,
|
||||||
AVSampleFormat, SwrContext,
|
AVSampleFormat, SwrContext,
|
||||||
};
|
};
|
||||||
use libc::malloc;
|
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
@ -40,15 +39,15 @@ impl Resample {
|
|||||||
if !self.ctx.is_null() {
|
if !self.ctx.is_null() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let layout = malloc(size_of::<AVChannelLayout>()) as *mut AVChannelLayout;
|
let mut layout = AVChannelLayout::empty();
|
||||||
av_channel_layout_default(layout, self.channels as libc::c_int);
|
av_channel_layout_default(&mut layout, self.channels as libc::c_int);
|
||||||
|
|
||||||
let ret = swr_alloc_set_opts2(
|
let ret = swr_alloc_set_opts2(
|
||||||
&mut self.ctx,
|
&mut self.ctx,
|
||||||
layout,
|
ptr::addr_of_mut!(layout),
|
||||||
self.format,
|
self.format,
|
||||||
self.sample_rate as libc::c_int,
|
self.sample_rate as libc::c_int,
|
||||||
&(*frame).ch_layout,
|
ptr::addr_of_mut!((*frame).ch_layout),
|
||||||
transmute((*frame).format),
|
transmute((*frame).format),
|
||||||
(*frame).sample_rate,
|
(*frame).sample_rate,
|
||||||
0,
|
0,
|
||||||
@ -63,10 +62,7 @@ impl Resample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Resample an audio frame
|
/// Resample an audio frame
|
||||||
pub unsafe fn process_frame(
|
pub unsafe fn process_frame(&mut self, frame: *mut AVFrame) -> Result<*mut AVFrame, Error> {
|
||||||
&mut self,
|
|
||||||
frame: *mut AVFrame
|
|
||||||
) -> Result<*mut AVFrame, Error> {
|
|
||||||
if !(*frame).hw_frames_ctx.is_null() {
|
if !(*frame).hw_frames_ctx.is_null() {
|
||||||
anyhow::bail!("Hardware frames are not supported in this software re-sampler");
|
anyhow::bail!("Hardware frames are not supported in this software re-sampler");
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use crate::{format_time, rstr};
|
use crate::{format_time, rstr};
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
|
use ffmpeg_sys_the_third::AVStreamGroup;
|
||||||
use ffmpeg_sys_the_third::{
|
use ffmpeg_sys_the_third::{
|
||||||
av_get_pix_fmt_name, av_get_sample_fmt_name, avcodec_get_name, AVMediaType, AVStream,
|
av_get_pix_fmt_name, av_get_sample_fmt_name, avcodec_get_name, AVMediaType, AVStream,
|
||||||
AVStreamGroup,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::intrinsics::transmute;
|
use std::intrinsics::transmute;
|
||||||
|
|
||||||
@ -11,6 +13,7 @@ pub struct DemuxerInfo {
|
|||||||
pub bitrate: usize,
|
pub bitrate: usize,
|
||||||
pub duration: f32,
|
pub duration: f32,
|
||||||
pub streams: Vec<StreamInfo>,
|
pub streams: Vec<StreamInfo>,
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
pub groups: Vec<StreamGroupInfo>,
|
pub groups: Vec<StreamGroupInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +181,7 @@ impl Display for StreamInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum StreamGroupType {
|
pub enum StreamGroupType {
|
||||||
TileGrid {
|
TileGrid {
|
||||||
@ -189,6 +193,7 @@ pub enum StreamGroupType {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct StreamGroupInfo {
|
pub struct StreamGroupInfo {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
@ -198,4 +203,5 @@ pub struct StreamGroupInfo {
|
|||||||
pub(crate) group: *mut AVStreamGroup,
|
pub(crate) group: *mut AVStreamGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "avformat_version_greater_than_60_19")]
|
||||||
unsafe impl Send for StreamGroupInfo {}
|
unsafe impl Send for StreamGroupInfo {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user