summaryrefslogtreecommitdiff
path: root/src/codec
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/codec.h30
-rw-r--r--src/codec/ffmpeg/scaler.c61
-rw-r--r--src/codec/ffmpeg/scaler.h19
-rw-r--r--src/codec/stb_image/impl.c12
4 files changed, 76 insertions, 46 deletions
diff --git a/src/codec/codec.h b/src/codec/codec.h
index 9528522..68f45f6 100644
--- a/src/codec/codec.h
+++ b/src/codec/codec.h
@@ -112,14 +112,18 @@ struct camu_audio_format {
s32 channel_count;
};
+struct camu_video_format {
+ s32 width;
+ s32 height;
+ s32 format;
+};
+
struct camu_codec_stream {
u8 mode;
u8 type;
u64 duration;
struct {
- s32 width;
- s32 height;
- s32 format;
+ struct camu_video_format fmt;
} video;
struct {
struct camu_audio_format fmt;
@@ -192,6 +196,19 @@ struct camu_resampler {
void (*free)(struct camu_resampler **);
};
+struct camu_scaler_format {
+ bool scaler_needed;
+ struct camu_video_format in;
+ struct camu_video_format req;
+};
+
+struct camu_scaler {
+ bool (*init)(struct camu_scaler *, struct camu_scaler_format *);
+ bool (*scale)(struct camu_scaler *, const u8 **in_slice, s32 *in_strides);
+ AVFrame *(*get_frame)(struct camu_scaler *);
+ void (*free)(struct camu_scaler **);
+};
+
AL_UNUSED_FUNCTION_PUSH
static inline bool camu_resampler_format_matches(struct camu_resampler_format *fmt)
@@ -279,6 +296,13 @@ static inline f64 camu_audio_format_bytes_to_sec(struct camu_audio_format *fmt,
return samples / (f64)fmt->sample_rate;
}
+static inline void camu_video_format_copy(struct camu_video_format *dest, struct camu_video_format *src)
+{
+ dest->width = src->width;
+ dest->height = src->height;
+ dest->format = src->format;
+}
+
static const char *camu_pixel_format_name(s32 format)
{
switch (format) {
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);
diff --git a/src/codec/stb_image/impl.c b/src/codec/stb_image/impl.c
index 98d9e2c..ac1cbc5 100644
--- a/src/codec/stb_image/impl.c
+++ b/src/codec/stb_image/impl.c
@@ -40,9 +40,10 @@ static bool stbi_demuxer_init(struct camu_demuxer *demux, struct cch_handle *han
struct camu_codec_stream stream = { 0 };
stream.mode = CAMU_NORMAL;
stream.type = CAMU_STREAM_VIDEO;
- stream.video.width = w;
- stream.video.height = h;
- stream.video.format = camu_pixel_format_from_channels(channels);
+ struct camu_video_format *fmt = &stream.video.fmt;
+ fmt->width = w;
+ fmt->height = h;
+ fmt->format = camu_pixel_format_from_channels(channels);
al_array_push(stb->demux.streams, stream);
@@ -106,7 +107,8 @@ static s32 stbi_decoder_push(struct camu_decoder *dec, struct camu_codec_packet
u8 *data = aki_buffer_get_ptr(packet->buffer, 0);
u8 *pixels = stbi_load_from_memory(data, packet->buffer->size, &w, &h, &channels, 0);
if (!pixels) return CAMU_ERR_ERROR;
- al_assert(w == stb->stream->video.width && h == stb->stream->video.height);
+ struct camu_video_format *fmt = &stb->stream->video.fmt;
+ al_assert(w == fmt->width && h == fmt->height);
struct camu_codec_frame *frame = al_alloc_object(struct camu_codec_frame);
frame->mode = CAMU_NORMAL;
@@ -115,7 +117,7 @@ static s32 stbi_decoder_push(struct camu_decoder *dec, struct camu_codec_packet
frame->video.width = w;
frame->video.height = h;
frame->format = camu_pixel_format_from_channels(channels);
- al_assert(frame->format == stb->stream->video.format);
+ al_assert(frame->format == fmt->format);
frame->pts = 0.0;
stb->callback(stb->userdata, frame);