summaryrefslogtreecommitdiff
path: root/src/codec/ffmpeg
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec/ffmpeg')
-rw-r--r--src/codec/ffmpeg/avio.c2
-rw-r--r--src/codec/ffmpeg/encoder.c66
-rw-r--r--src/codec/ffmpeg/encoder.h1
3 files changed, 40 insertions, 29 deletions
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);