From bb8dc49245a411244bd128d494c69d2ae7c81b45 Mon Sep 17 00:00:00 2001 From: tilpner Date: Thu, 16 Mar 2023 17:06:17 +0100 Subject: [PATCH] feat(codec): allow codec context creation with specified codec For some codecs (x264) it's necessary to set the codec while the context is being created, otherwise the codec-specific defaults aren't applied. --- src/codec/context.rs | 9 +++++++++ src/codec/decoder/decoder.rs | 7 +++++++ src/codec/encoder/encoder.rs | 13 ++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/codec/context.rs b/src/codec/context.rs index 09bd241..79407c0 100644 --- a/src/codec/context.rs +++ b/src/codec/context.rs @@ -38,6 +38,15 @@ impl Context { } } + pub fn for_codec(codec: &Codec) -> Self { + unsafe { + Context { + ptr: avcodec_alloc_context3(codec.as_ptr()), + owner: None, + } + } + } + pub fn decoder(self) -> Decoder { Decoder(self) } diff --git a/src/codec/decoder/decoder.rs b/src/codec/decoder/decoder.rs index 18b6bd8..4a19fd6 100644 --- a/src/codec/decoder/decoder.rs +++ b/src/codec/decoder/decoder.rs @@ -13,6 +13,13 @@ use crate::{ pub struct Decoder(pub Context); impl Decoder { + pub fn new(codec: D) -> Result { + let codec = codec.decoder().ok_or(Error::DecoderNotFound)?; + let context = Context::for_codec(&codec); + + Ok(Decoder(context)) + } + pub fn open(mut self) -> Result { unsafe { match avcodec_open2(self.as_mut_ptr(), ptr::null(), ptr::null_mut()) { diff --git a/src/codec/encoder/encoder.rs b/src/codec/encoder/encoder.rs index b932290..57b5ac4 100644 --- a/src/codec/encoder/encoder.rs +++ b/src/codec/encoder/encoder.rs @@ -5,11 +5,22 @@ use std::{ }; use super::{audio, subtitle, video}; -use crate::{codec::Context, ffi::*, media, packet, Error, Frame, Rational}; +use crate::{ + codec::{traits, Context}, + ffi::*, + media, packet, Error, Frame, Rational, +}; pub struct Encoder(pub Context); impl Encoder { + pub fn new(codec: E) -> Result { + let codec = codec.encoder().ok_or(Error::EncoderNotFound)?; + let context = Context::for_codec(&codec); + + Ok(Encoder(context)) + } + pub fn video(mut self) -> Result { match self.medium() { media::Type::Unknown => {