feat: test-source fixes

This commit is contained in:
2024-11-13 16:06:52 +00:00
parent 6f618ef58f
commit 0b8742bd25
7 changed files with 71 additions and 32 deletions

View File

@ -64,7 +64,9 @@ impl HlsEgress {
opts.insert("hls_flags".to_string(), "delete_segments".to_string());
let muxer = unsafe {
let mut m = Muxer::new().with_output(&base, Some("hls"), Some(opts))?;
let mut m = Muxer::builder()
.with_output_path(base.to_str().unwrap(), Some("hls"), Some(opts))?
.build()?;
for e in encoded {
m.add_stream_encoder(e)?;
}

View File

@ -1,7 +1,6 @@
use anyhow::Result;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPacket;
use ffmpeg_rs_raw::{Encoder, Muxer};
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use uuid::Uuid;
@ -22,17 +21,13 @@ impl RecorderEgress {
let id = Uuid::new_v4();
let base = PathBuf::from(&config.out_dir).join(id.to_string());
let out_file = base.join("recording.mp4");
let out_file = base.join("recording.ts");
fs::create_dir_all(&base)?;
let mut opt = HashMap::new();
opt.insert(
"movflags".to_string(),
"+dash+delay_moov+skip_sidx+skip_trailer".to_string(),
);
let muxer = unsafe {
let mut m = Muxer::new().with_output(&out_file, None, Some(opt))?;
let mut m = Muxer::builder()
.with_output_path(out_file.to_str().unwrap(), None, None)?
.build()?;
for var in variants {
m.add_stream_encoder(var)?;
}

View File

@ -8,14 +8,14 @@ use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPixelFormat::{AV_PIX_FMT_RGBA, AV_PIX
use ffmpeg_rs_raw::ffmpeg_sys_the_third::{
av_frame_alloc, av_frame_get_buffer, AV_PROFILE_H264_MAIN,
};
use ffmpeg_rs_raw::{Encoder, Scaler};
use ffmpeg_rs_raw::{Encoder, Muxer, Scaler};
use fontdue::layout::{CoordinateSystem, Layout, TextStyle};
use fontdue::Font;
use log::info;
use std::collections::VecDeque;
use ringbuf::traits::{Observer, Split};
use ringbuf::{HeapCons, HeapRb};
use std::io::Read;
use std::ops::Add;
use std::slice;
use std::time::{Duration, Instant};
use tiny_skia::Pixmap;
use warp::Buf;
@ -35,11 +35,12 @@ pub async fn listen(settings: Settings) -> Result<()> {
struct TestPatternSrc {
encoder: Encoder,
scaler: Scaler,
muxer: Muxer,
background: Pixmap,
font: [Font; 1],
frame_no: u64,
start: Instant,
buf: VecDeque<u8>,
reader: HeapCons<u8>,
}
unsafe impl Send for TestPatternSrc {}
@ -69,18 +70,31 @@ impl TestPatternSrc {
let font = include_bytes!("../../SourceCodePro-Regular.ttf") as &[u8];
let font = Font::from_bytes(font, Default::default()).unwrap();
let buf = HeapRb::new(1024 * 1024);
let (writer, reader) = buf.split();
let muxer = unsafe {
let mut m = Muxer::builder()
.with_output_write(writer, Some("mpegts"), None)?
.with_stream_encoder(&encoder)?
.build()?;
m.open()?;
m
};
Ok(Self {
encoder,
scaler,
muxer,
background: pixmap,
font: [font],
frame_no: 0,
start: Instant::now(),
buf: VecDeque::new(),
reader,
})
}
pub unsafe fn next_pkt(&mut self) -> Result<Vec<u8>> {
pub unsafe fn next_pkt(&mut self) -> Result<()> {
let stream_time = Duration::from_secs_f64(self.frame_no as f64 / 30.0);
let real_time = Instant::now().duration_since(self.start);
let wait_time = if stream_time > real_time {
@ -137,28 +151,24 @@ impl TestPatternSrc {
}
}
let mut ret = Vec::new();
// scale/encode
let frame = self
.scaler
.process_frame(src_frame, 1280, 720, AV_PIX_FMT_YUV420P)?;
for pkt in self.encoder.encode_frame(frame)? {
let buf = slice::from_raw_parts((*pkt).data, (*pkt).size as usize);
ret.extend(buf);
self.muxer.write_packet(pkt)?;
}
Ok(ret)
Ok(())
}
}
impl Read for TestPatternSrc {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
unsafe {
while self.buf.len() < buf.len() {
let data = self.next_pkt().map_err(|e| std::io::Error::other(e))?;
self.buf.extend(data);
while self.reader.occupied_len() < buf.len() {
self.next_pkt().map_err(|e| std::io::Error::other(e))?;
}
}
self.buf.copy_to_slice(buf);
Ok(buf.len())
self.reader.read(buf)
}
}

View File

@ -89,7 +89,14 @@ impl PipelineRunner {
let src_index = (*stream).index;
// TODO: For copy streams, skip decoder
for frame in self.decoder.decode_pkt(pkt)? {
let frames = if let Ok(frames) = self.decoder.decode_pkt(pkt) {
frames
} else {
warn!("Error decoding frames");
return Ok(());
};
for frame in frames {
self.frame_ctr += 1;
// Copy frame from GPU if using hwaccel decoding
@ -184,7 +191,7 @@ impl PipelineRunner {
VariantStream::Audio(a) => {
let enc = a.try_into()?;
let rs = Resample::new(
av_get_sample_fmt(cstr!(&a.sample_fmt)),
av_get_sample_fmt(cstr!(a.sample_fmt.as_bytes())),
a.sample_rate as _,
a.channels as _,
);

View File

@ -71,7 +71,7 @@ impl TryInto<Encoder> for &AudioVariant {
.with_sample_rate(self.sample_rate as _)
.with_bitrate(self.bitrate as _)
.with_default_channel_layout(self.channels as _)
.with_sample_format(av_get_sample_fmt(cstr!(&self.sample_fmt)))
.with_sample_format(av_get_sample_fmt(cstr!(self.sample_fmt.as_bytes())))
.open(None)?;
Ok(enc)