From 2f9a0945bfeee3296cec3d38d094e4c49f9cb65f Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Sat, 25 May 2024 20:22:59 -0400 Subject: wip Signed-off-by: Andrew Opalach --- src/codec/ffmpeg/avio.c | 2 +- src/codec/ffmpeg/encoder.c | 66 ++++++++++++++++++++++++++-------------------- src/codec/ffmpeg/encoder.h | 1 + 3 files changed, 40 insertions(+), 29 deletions(-) (limited to 'src/codec') diff --git a/src/codec/ffmpeg/avio.c b/src/codec/ffmpeg/avio.c index 12dd468..143bc1f 100644 --- a/src/codec/ffmpeg/avio.c +++ b/src/codec/ffmpeg/avio.c @@ -1,6 +1,6 @@ #include "avio.h" -#include "../cache/handle.h" +#include "../../cache/handle.h" s32 camu_avio_read(void *data, u8 *buf, s32 buf_size) { diff --git a/src/codec/ffmpeg/encoder.c b/src/codec/ffmpeg/encoder.c index 9ceaa99..4617baf 100644 --- a/src/codec/ffmpeg/encoder.c +++ b/src/codec/ffmpeg/encoder.c @@ -15,6 +15,20 @@ #define FRAME_SIZE 20 #define CHANNELS 2 +static void free_frame_data(struct camu_ff_encoder *enc) +{ + if (enc->frame && enc->frame->nb_samples > 0) av_freep(&enc->frame->data[0]); +} + +static void alloc_frame_data(struct camu_ff_encoder *enc, s32 frame_size) +{ + if (enc->frame->nb_samples >= frame_size) return; + free_frame_data(enc); + s32 nb_channels = enc->frame->ch_layout.nb_channels; + av_samples_alloc(enc->frame->data, NULL, nb_channels, frame_size, enc->frame->format, 0); + enc->frame->nb_samples = frame_size; +} + bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char *ext) { al_memset(enc, 0, sizeof(struct camu_ff_encoder)); @@ -99,20 +113,6 @@ void camu_ff_encoder_push(struct camu_ff_encoder *enc, u8 **data, s32 sample_cou av_audio_fifo_write(enc->audio_fifo, (void **)data, sample_count); } -static void free_frame_data(struct camu_ff_encoder *enc) -{ - if (enc->frame && enc->frame->nb_samples > 0) av_freep(&enc->frame->data[0]); -} - -static void alloc_frame_data(struct camu_ff_encoder *enc, s32 frame_size) -{ - if (enc->frame->nb_samples >= frame_size) return; - free_frame_data(enc); - s32 nb_channels = enc->frame->ch_layout.nb_channels; - av_samples_alloc(enc->frame->data, NULL, nb_channels, frame_size, enc->frame->format, 0); - enc->frame->nb_samples = frame_size; -} - static bool receive_packets(struct camu_ff_encoder *enc) { s32 ret; @@ -141,10 +141,15 @@ static s32 send_frame(struct camu_ff_encoder *enc, AVFrame *in_frame) return ret; } +static s32 read_frame(struct camu_ff_encoder *enc, s32 frame_size) +{ + alloc_frame_data(enc, frame_size); + return av_audio_fifo_read(enc->audio_fifo, (void **)enc->frame->data, frame_size); +} + bool camu_ff_encoder_process(struct camu_ff_encoder *enc, bool flush) { s32 samples_available = av_audio_fifo_size(enc->audio_fifo); - if (samples_available == 0 && flush) { // Flush encoder. send_frame(enc, NULL); @@ -154,29 +159,34 @@ bool camu_ff_encoder_process(struct camu_ff_encoder *enc, bool flush) } s32 frame_size = enc->codec_context->frame_size; - if (samples_available == 0 || (samples_available < frame_size && !flush)) { return false; } - if (samples_available < frame_size) frame_size = samples_available; - - alloc_frame_data(enc, frame_size); - av_audio_fifo_read(enc->audio_fifo, (void **)enc->frame->data, frame_size); - s32 ret; do { - ret = send_frame(enc, enc->frame); - // TODO: Check ret < 0 ? - if (!receive_packets(enc)) return false; - } while (ret == AVERROR(EAGAIN)); - - enc->frame->pts += frame_size; + if (samples_available < frame_size) frame_size = samples_available; + read_frame(enc, frame_size); + samples_available -= frame_size; + do { + ret = send_frame(enc, enc->frame); + if (ret < 0) break; + if (!receive_packets(enc)) return false; + } while (ret == AVERROR(EAGAIN)); + if (ret < 0) break; + enc->frame->pts += frame_size; + } while (samples_available > 0); - // ret < 0 means encoder erroed while sending frame. + // ret < 0 means encoder errored while sending frame. return ret == 0; } +void camu_ff_encoder_reset(struct camu_ff_encoder *enc) +{ + avcodec_flush_buffers(enc->codec_context); + av_audio_fifo_reset(enc->audio_fifo); +} + void camu_ff_encoder_close(struct camu_ff_encoder *enc) { if (enc->codec_context) avcodec_free_context(&enc->codec_context); diff --git a/src/codec/ffmpeg/encoder.h b/src/codec/ffmpeg/encoder.h index 6cba9ac..9bfe8ea 100644 --- a/src/codec/ffmpeg/encoder.h +++ b/src/codec/ffmpeg/encoder.h @@ -23,4 +23,5 @@ struct camu_ff_encoder { bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char *ext); void camu_ff_encoder_push(struct camu_ff_encoder *enc, u8 **data, s32 sample_count); bool camu_ff_encoder_process(struct camu_ff_encoder *enc, bool flush); +void camu_ff_encoder_reset(struct camu_ff_encoder *enc); void camu_ff_encoder_close(struct camu_ff_encoder *enc); -- cgit v1.2.3-101-g0448