summaryrefslogtreecommitdiff
path: root/src/codec/ffmpeg
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2024-10-28 13:08:13 -0400
committerAndrew Opalach <andrew@akon.city> 2024-10-28 13:23:02 -0400
commit846e17728f2ed2af3672987ef61853f0bc96c224 (patch)
treee8e81fc8a2a7de208bd9ba397ef3928d33110824 /src/codec/ffmpeg
parentd6735566cebf82a5d22a3ade22b9acd52fbe11a5 (diff)
downloadcamu-846e17728f2ed2af3672987ef61853f0bc96c224.tar.gz
camu-846e17728f2ed2af3672987ef61853f0bc96c224.tar.bz2
camu-846e17728f2ed2af3672987ef61853f0bc96c224.zip
Refactor video buffer and scaler, better A/V sync
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/codec/ffmpeg')
-rw-r--r--src/codec/ffmpeg/scaler.c61
-rw-r--r--src/codec/ffmpeg/scaler.h19
2 files changed, 42 insertions, 38 deletions
diff --git a/src/codec/ffmpeg/scaler.c b/src/codec/ffmpeg/scaler.c
index 9b5c5e0..d233268 100644
--- a/src/codec/ffmpeg/scaler.c
+++ b/src/codec/ffmpeg/scaler.c
@@ -34,51 +34,64 @@ static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, s32 width, s32 height)
return frame;
}
-bool camu_ff_scaler_init(struct camu_ff_scaler *scale, struct camu_ff_scale_fmt *fmt)
+static bool ff_scaler_init(struct camu_scaler *scale, struct camu_scaler_format *fmt)
{
- al_memset(scale, 0, sizeof(struct camu_ff_scaler));
+ struct camu_ff_scaler *av = (struct camu_ff_scaler *)scale;
+ al_assert(fmt->scaler_needed);
- if (fmt->in_width == fmt->req_width && fmt->in_height == fmt->req_height &&
- fmt->in_format == fmt->req_format) {
- fmt->scaler_needed = false;
- return true;
- }
+ av->fmt = *fmt;
s32 flags = SWS_BITEXACT;
- scale->scaler_context = sws_getContext(fmt->in_width, fmt->in_height, fmt->in_format,
- fmt->req_width, fmt->req_height, fmt->req_format, flags, NULL, NULL, NULL);
- if (!scale->scaler_context) {
+ av->scaler_context = sws_getContext(fmt->in.width, fmt->in.height, fmt->in.format,
+ fmt->req.width, fmt->req.height, fmt->req.format, flags, NULL, NULL, NULL);
+ if (!av->scaler_context) {
al_log_error("ff_scaler", "Failed to create scaler context.");
return false;
}
- scale->frame = alloc_picture(fmt->req_format, fmt->req_width, fmt->req_height);
- if (!scale->frame) {
+ av->frame = alloc_picture(fmt->req.format, fmt->req.width, fmt->req.height);
+ if (!av->frame) {
al_log_error("ff_scaler", "Failed to allocate frame.");
return false;
}
- fmt->scaler_needed = true;
-
- scale->fmt = *fmt;
-
return true;
}
-bool camu_ff_scaler_scale(struct camu_ff_scaler *scale, const u8 **in_slice, s32 *in_strides)
+static bool ff_scaler_scale(struct camu_scaler *scale, const u8 **in_slice, s32 *in_strides)
{
- s32 ret = sws_scale(scale->scaler_context, in_slice, in_strides, 0, scale->fmt.in_height,
- scale->frame->data, scale->frame->linesize);
- if (ret != scale->fmt.req_height) {
+ struct camu_ff_scaler *av = (struct camu_ff_scaler *)scale;
+ s32 ret = sws_scale(av->scaler_context, in_slice, in_strides, 0, av->fmt.in.height,
+ av->frame->data, av->frame->linesize);
+ if (ret != av->fmt.req.height) {
al_log_error("ff_scaler", "Failed to scale frame (%s).", av_err2str(ret));
return false;
}
return true;
}
-void camu_ff_scaler_close(struct camu_ff_scaler *scale)
+static AVFrame *ff_scaler_get_frame(struct camu_scaler *scale)
+{
+ struct camu_ff_scaler *av = (struct camu_ff_scaler *)scale;
+ return av->frame;
+}
+
+static void ff_scaler_free(struct camu_scaler **scale)
+{
+ struct camu_ff_scaler *av = (struct camu_ff_scaler *)*scale;
+ av_freep(&av->frame->data[0]);
+ av_frame_free(&av->frame);
+ sws_freeContext(av->scaler_context);
+ al_free(av);
+ *scale = NULL;
+}
+
+struct camu_scaler *camu_ff_scaler_create(void)
{
- av_freep(&scale->frame->data[0]);
- av_frame_free(&scale->frame);
- sws_freeContext(scale->scaler_context);
+ struct camu_ff_scaler *av = al_alloc_object(struct camu_ff_scaler);
+ av->scale.init = ff_scaler_init;
+ av->scale.scale = ff_scaler_scale;
+ av->scale.get_frame = ff_scaler_get_frame;
+ av->scale.free = ff_scaler_free;
+ return (struct camu_scaler *)av;
}
diff --git a/src/codec/ffmpeg/scaler.h b/src/codec/ffmpeg/scaler.h
index 3e53fbb..a4effb3 100644
--- a/src/codec/ffmpeg/scaler.h
+++ b/src/codec/ffmpeg/scaler.h
@@ -1,24 +1,15 @@
#pragma once
-#include <libswscale/swscale.h>
#include <al/types.h>
+#include <libswscale/swscale.h>
-struct camu_ff_scale_fmt {
- s32 in_width;
- s32 in_height;
- enum AVPixelFormat in_format;
- s32 req_width;
- s32 req_height;
- enum AVPixelFormat req_format;
- bool scaler_needed;
-};
+#include "../codec.h"
struct camu_ff_scaler {
+ struct camu_scaler scale;
struct SwsContext *scaler_context;
- struct camu_ff_scale_fmt fmt;
+ struct camu_scaler_format fmt;
AVFrame *frame;
};
-bool camu_ff_scaler_init(struct camu_ff_scaler *scale, struct camu_ff_scale_fmt *fmt);
-bool camu_ff_scaler_scale(struct camu_ff_scaler *scale, const u8 **in_slice, s32 *in_strides);
-void camu_ff_scaler_close(struct camu_ff_scaler *scale);
+struct camu_scaler *camu_ff_scaler_create(void);