pizzicato 0.1.0

[WIP] A library for reading and writing frames to video.
Documentation
use crate::{ Options, Image };

use std::ffi::CString;

use anyhow::Result;

use rsmpeg::avformat::AVFormatContextOutput;
use rsmpeg::ffi;

pub struct Context {
	ctx: AVFormatContextOutput,
	file: String,
}

impl Context {
	pub fn create(file: &str) -> Result<Self> {
		Ok(Self {
			ctx: AVFormatContextOutput::create(
				&*CString::new(file)?,
				None,
			)?,
			file: file.to_string(),
		})
	}

	pub fn video(
		&mut self,
		frames: impl Iterator<Item = impl Image>,
		options: Options,
	) -> Result<()> {
		let codec = guess_codec(
			&self.ctx,
			&self.file,
			ffi::AVMediaType_AVMEDIA_TYPE_VIDEO,
		);

		crate::video::encode(&mut self.ctx, frames, codec, options)
	}

	pub fn audio(
		&mut self,
		file: &str,
	) -> Result<()> {
		let codec = guess_codec(
			&self.ctx,
			&self.file,
			ffi::AVMediaType_AVMEDIA_TYPE_AUDIO,
		);

		crate::audio::transcode(&mut self.ctx, file, codec)
	}
}

fn guess_codec(
	output_ctx: &AVFormatContextOutput,
	file_name: &str,
	media_type: ffi::AVMediaType,
) -> ffi::AVCodecID {
	let mut file_name = file_name.to_string();
	file_name.push('\0');
	let file_name = file_name.as_ptr();

	let oformat = output_ctx.oformat();

	unsafe {
		let mut oformat = (*oformat.as_ptr()).clone();

		rsmpeg::ffi::av_guess_codec(
			&mut oformat,
			std::ptr::null(),
			file_name as *const i8,
			std::ptr::null(),
			media_type,
		)
	}
}