fix: debian bookworm build

This commit is contained in:
kieran 2024-11-20 20:53:20 +00:00
parent bb11e998e7
commit 8f7c47d4fe
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
9 changed files with 83 additions and 26 deletions

2
.dockerignore Normal file
View File

@ -0,0 +1,2 @@
**/target
test_output/

15
Dockerfile.bookworm Normal file
View 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
View 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()
);
}
}
}

View File

@ -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");
} }

View File

@ -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<()> {

View File

@ -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")?;

View File

@ -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

View File

@ -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");
} }

View File

@ -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 {}