From c1cb78d574c0429aa5e3ff3a2b3886e4bc153212 Mon Sep 17 00:00:00 2001 From: bbergeron Date: Wed, 3 Apr 2024 17:32:01 -0400 Subject: Reset Git repo and use a pseudonym to sign commits I used to sign my commits with my real name and my personal email address, which I wanted scrubbed off the "B." pseudosphere. Re-creating a new git repository was safer than simpler than re-writing the history (although the latter could've also worked but, oh well). --- audio/encoder.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 audio/encoder.c (limited to 'audio/encoder.c') diff --git a/audio/encoder.c b/audio/encoder.c new file mode 100644 index 0000000..17cf2d2 --- /dev/null +++ b/audio/encoder.c @@ -0,0 +1,69 @@ +#include "encoder.h" +#include + +int encoder_init (struct Encoder *encoder, const AVCodecParameters *codecpar, AVDictionary **opts) +{ + /* NOTE: While encoder->time_base "MUST be set by user" when encoding + * (quoted from the official FFMPEG documentation), avcodec_open2 actually + * discard it's value and set it to '1/sample_rate'. + * + * NOTE: The assert at the end of this section serves to protect cybd in + * case the FFMPEG devs update their code to implement some funny behaviors. + */ + int err; + AVCodecContext *avctx; + const AVCodec *codec; + + if ((codec = avcodec_find_encoder(codecpar->codec_id)) == NULL) { + err = AVERROR_ENCODER_NOT_FOUND; + goto error; + } + + if ((avctx = avcodec_alloc_context3(codec)) == NULL) + return AVERROR(ENOMEM); + + if ((err = avcodec_parameters_to_context(avctx, codecpar)) < 0) + goto error; + + if ((err = avcodec_open2(avctx, codec, opts))) + goto error; + + /* Because some code rely on avctx's time base to be 1/sample_rate, and + * because this behavious currently appears undocumented, I placed some + * assert here to catch up if anything changes up with ffmpeg. */ + assert(avctx->time_base.num == 1); + assert(avctx->time_base.den == avctx->sample_rate); + encoder->avctx = avctx; + encoder->pts = 0; + return 0; + +error: + avcodec_free_context(&avctx); + return err; +} + +int encoder_init_for_stream (struct Encoder *encoder, const AVStream *stream, AVDictionary **opts) +{ + return encoder_init(encoder, stream->codecpar, opts); +} + +int encoder_send (struct Encoder *encoder, const AVFrame *frame) +{ + return avcodec_send_frame(encoder->avctx, frame); +} + +int encoder_convert (struct Encoder *encoder, AVPacket *pkt_out) +{ + int err; + err = avcodec_receive_packet(encoder->avctx, pkt_out); + if (err < 0) return err; + // Manually setting pts because FFMPEG doesn't do it consistantly + //pkt_out->pts = encoder->pts; + //encoder->pts += pkt_out->duration; + return 0; +} + +void encoder_free (struct Encoder *encoder) +{ + avcodec_free_context(&encoder->avctx); +} -- cgit v1.2.3