diff options
| author | 2024-04-09 11:24:01 -0400 | |
|---|---|---|
| committer | 2024-04-09 11:24:01 -0400 | |
| commit | 02f3d3565602146bbbfce85b2719246f24036cb9 (patch) | |
| tree | c6588ffe297b777e36260effa4fa42b958ca6ba3 /src/codec/libav | |
| parent | bbf3314165182e402ff25acccddc004a87f81ef0 (diff) | |
| download | camu-02f3d3565602146bbbfce85b2719246f24036cb9.tar.gz camu-02f3d3565602146bbbfce85b2719246f24036cb9.tar.bz2 camu-02f3d3565602146bbbfce85b2719246f24036cb9.zip | |
Massive restructure and many changes
- The server-side list concept is still a wip
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/codec/libav')
| -rw-r--r-- | src/codec/libav/avio.c | 13 | ||||
| -rw-r--r-- | src/codec/libav/avio.h | 10 | ||||
| -rw-r--r-- | src/codec/libav/common.c | 6 | ||||
| -rw-r--r-- | src/codec/libav/common.h | 6 | ||||
| -rw-r--r-- | src/codec/libav/decoder.c | 166 | ||||
| -rw-r--r-- | src/codec/libav/decoder.h | 20 | ||||
| -rw-r--r-- | src/codec/libav/demuxer.c | 183 | ||||
| -rw-r--r-- | src/codec/libav/demuxer.h | 19 | ||||
| -rw-r--r-- | src/codec/libav/encoder.c | 186 | ||||
| -rw-r--r-- | src/codec/libav/encoder.h | 26 | ||||
| -rw-r--r-- | src/codec/libav/packet_ext.c | 168 | ||||
| -rw-r--r-- | src/codec/libav/packet_ext.h | 20 | ||||
| -rw-r--r-- | src/codec/libav/resampler.c | 162 | ||||
| -rw-r--r-- | src/codec/libav/resampler.h | 40 | ||||
| -rw-r--r-- | src/codec/libav/scaler.c | 84 | ||||
| -rw-r--r-- | src/codec/libav/scaler.h | 24 |
16 files changed, 0 insertions, 1133 deletions
diff --git a/src/codec/libav/avio.c b/src/codec/libav/avio.c deleted file mode 100644 index 97f66da..0000000 --- a/src/codec/libav/avio.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "avio.h" - -s32 camu_avio_read(void *data, u8 *buf, s32 buf_size) -{ - struct cch_handle *handle = (struct cch_handle *)data; - return cch_handle_read(handle, buf, buf_size); -} - -s64 camu_avio_seek(void *data, s64 offset, s32 whence) -{ - struct cch_handle *handle = (struct cch_handle *)data; - return (s64)cch_handle_seek(handle, offset, whence); -} diff --git a/src/codec/libav/avio.h b/src/codec/libav/avio.h deleted file mode 100644 index 09df4ec..0000000 --- a/src/codec/libav/avio.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include <libavutil/error.h> -#include <libavformat/avio.h> - -#include "../../codec/codec.h" -#include "../../cache/handle.h" - -s32 camu_avio_read(void *data, u8 *buf, s32 buf_size); -s64 camu_avio_seek(void *data, s64 offset, s32 whence); diff --git a/src/codec/libav/common.c b/src/codec/libav/common.c deleted file mode 100644 index 8ce6667..0000000 --- a/src/codec/libav/common.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "common.h" - -void camu_lav_set_log_callback(void (*callback)(void *, int, const char *, va_list)) -{ - av_log_set_callback(callback); -} diff --git a/src/codec/libav/common.h b/src/codec/libav/common.h deleted file mode 100644 index 854e4c7..0000000 --- a/src/codec/libav/common.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include <al/types.h> -#include <libavutil/log.h> - -void camu_lav_set_log_callback(void (*callback)(void *, int, const char *, va_list)); diff --git a/src/codec/libav/decoder.c b/src/codec/libav/decoder.c deleted file mode 100644 index e732be9..0000000 --- a/src/codec/libav/decoder.c +++ /dev/null @@ -1,166 +0,0 @@ -#include <libavutil/cpu.h> -#include <al/lib.h> -#include <al/log.h> - -//#include "../../render/renderer.h" - -#include "decoder.h" - -static void close_internal(struct camu_lav_decoder *av) -{ - if (av->codec_context) { - avcodec_close(av->codec_context); - avcodec_free_context(&av->codec_context); - } -} - -static bool lav_decoder_init(struct camu_decoder *dec, struct camu_renderer *renderer, struct camu_stream *stream) -{ - struct camu_lav_decoder *av = (struct camu_lav_decoder *)dec; - - AVCodecParameters *codecpar = stream->av.stream->codecpar; - const AVCodec *codec = avcodec_find_decoder(codecpar->codec_id); - - if (!codec) { - al_log_error("lav_decoder", "Failed to find decoder."); - goto err; - } - - av->codec_context = avcodec_alloc_context3(codec); - - if (!av->codec_context) { - al_log_error("lav_decoder", "Failed to alloc codec context."); - goto err; - } - - if (avcodec_parameters_to_context(av->codec_context, codecpar) < 0) { - al_log_error("lav_decoder", "Failed to copy codec parameters."); - goto err; - } - - /* - s32 cpus = av_cpu_count(); - cpus = (cpus > 16) ? 4 : cpus / 4; - if (cpus == 0) cpus = 1; - av->codec_context->thread_count = cpus; - al_log_debug("lav_decoder", "Using %i threads for decoder.", cpus); - */ - - (void)renderer; - /* - if (renderer && renderer->get_buffer2 && codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - av->codec_context->get_buffer2 = renderer->get_buffer2; - av->codec_context->opaque = renderer->opaque; - } - */ - - if (avcodec_open2(av->codec_context, codec, NULL) < 0) { - al_log_error("lav_decoder", "Failed to open codec (%s).", codec->name); - goto err; - } - - al_log_info("lav_decoder", "Codec: %s (%s) %ldkbps.", codec->name, codec->long_name, codecpar->bit_rate / 1000); - - av->time_base = stream->av.stream->time_base; - av->last_pts = 0; - av->last_duration = 0; - //av->seek_pos = -1; - - return true; -err: - close_internal(av); - return false; -} - -static void lav_decoder_set_callback(struct camu_decoder *dec, void (*callback)(void *, struct camu_frame *), void *userdata) -{ - struct camu_lav_decoder *av = (struct camu_lav_decoder *)dec; - av->callback = callback; - av->userdata = userdata; -} - -static s32 send_packet(struct camu_lav_decoder *av, AVPacket *pkt) -{ - /* - if (pkt && av->seek_pos >= 0 && pkt->pts + pkt->duration < av->seek_pos) { - av->codec_context->skip_frame = AVDISCARD_NONKEY; - } else { - av->codec_context->skip_frame = AVDISCARD_NONE; - } - */ - - s32 ret = avcodec_send_packet(av->codec_context, pkt); - if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { - al_log_error("lav_decoder", "Error sending packet to decoder: (%s).", av_err2str(ret)); - } - - return ret; -} - -static s32 lav_decoder_push(struct camu_decoder *dec, struct camu_packet *packet) -{ - struct camu_lav_decoder *av = (struct camu_lav_decoder *)dec; - return send_packet(av, (packet) ? packet->av.pkt : NULL); -} - -static void lav_decoder_flush(struct camu_decoder *dec) -{ - struct camu_lav_decoder *av = (struct camu_lav_decoder *)dec; - avcodec_flush_buffers(av->codec_context); -} - -static s32 receive_frames(struct camu_lav_decoder *av) -{ - s32 ret; - do { - struct camu_frame *frame = al_alloc_object(struct camu_frame); - frame->type = CAMU_FFMPEG_COMPAT; - frame->av.frame = av_frame_alloc(); - ret = avcodec_receive_frame(av->codec_context, frame->av.frame); - if (ret < 0) { - av_frame_free(&frame->av.frame); - al_free(frame); - if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break; - al_log_error("lav_decoder", "Error receiving packet from decoder: (%s).", av_err2str(ret)); - continue; - } - // Track pts and duration of the previous frame so we can handle multiple frames - // in a single packet. - //if (av->codec_context->codec_type == AVMEDIA_TYPE_AUDIO) { - // if (frame->av.frame->best_effort_timestamp < 0) { - // frame->av.frame->best_effort_timestamp = av->last_pts + av->last_duration; - // } - // av->last_pts = frame->av.frame->best_effort_timestamp; - // av->last_duration = av_get_audio_frame_duration(av->codec_context, frame->av.frame->linesize[0]) - // / (av->codec_context->sample_rate * av->time_base.num / (f64)av->time_base.den); - //} - av->callback(av->userdata, frame); - } while (1); - return ret; -} - -static s32 lav_decoder_process(struct camu_decoder *dec) -{ - struct camu_lav_decoder *av = (struct camu_lav_decoder *)dec; - return receive_frames(av); -} - -static void lav_decoder_free(struct camu_decoder **dec) -{ - struct camu_lav_decoder *av = (struct camu_lav_decoder *)*dec; - close_internal(av); - al_free(av); - *dec = NULL; -} - -struct camu_decoder *camu_lav_decoder_create(void) -{ - struct camu_lav_decoder *av = al_alloc_object(struct camu_lav_decoder); - av->dec.init = lav_decoder_init; - av->dec.set_callback = lav_decoder_set_callback; - av->dec.push = lav_decoder_push; - av->dec.process = lav_decoder_process; - av->dec.flush = lav_decoder_flush; - av->dec.free = lav_decoder_free; - return (struct camu_decoder *)av; -} diff --git a/src/codec/libav/decoder.h b/src/codec/libav/decoder.h deleted file mode 100644 index 44105ce..0000000 --- a/src/codec/libav/decoder.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <al/types.h> - -#include <libavcodec/avcodec.h> - -#include "../codec.h" - -struct camu_lav_decoder { - struct camu_decoder dec; - AVCodecContext *codec_context; - AVRational time_base; - s64 last_pts; - s64 last_duration; - //s64 seek_pos; - void (*callback)(void *, struct camu_frame *); - void *userdata; -}; - -struct camu_decoder *camu_lav_decoder_create(void); diff --git a/src/codec/libav/demuxer.c b/src/codec/libav/demuxer.c deleted file mode 100644 index 2169816..0000000 --- a/src/codec/libav/demuxer.c +++ /dev/null @@ -1,183 +0,0 @@ -#include <al/log.h> - -#include "demuxer.h" -#include "avio.h" - -#define BUF_SIZE 16384 - -static void close_internal(struct camu_lav_demuxer *av) -{ - if (av->io_context) { - av_free(av->io_context->buffer); - avio_context_free(&av->io_context); - } - if (av->format_context) { - avformat_flush(av->format_context); - avformat_close_input(&av->format_context); - avformat_free_context(av->format_context); - } -} - -static bool lav_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handle) -{ - struct camu_lav_demuxer *av = (struct camu_lav_demuxer *)demux; - - av->format_context = avformat_alloc_context(); - if (!av->format_context) { - al_log_error("lav_demuxer", "Failed to create format context."); - goto err; - } - - u8 *buf = (u8 *)av_malloc(BUF_SIZE); - av->io_context = avio_alloc_context(buf, BUF_SIZE, 0, handle, camu_avio_read, NULL, camu_avio_seek); - if (!av->io_context) { - al_log_error("lav_demuxer", "Failed to create custom io context."); - goto err; - } - - if (!cch_handle_can_seek(handle)) { - // This should always be unset if we know we cannot seek. - // But, should also never be unset if we *do* want to seek because it - // disables long seeks (Not tested in a long time). - av->io_context->seekable &= ~AVIO_SEEKABLE_NORMAL; - } else { - av->io_context->seekable |= AVIO_SEEKABLE_NORMAL; - } - - av->format_context->pb = av->io_context; - av->format_context->flags |= AVFMT_FLAG_CUSTOM_IO; - - if (avformat_open_input(&av->format_context, "", 0, 0) < 0) { - al_log_error("lav_demuxer", "Failed to open input."); - goto err; - } - - if (avformat_find_stream_info(av->format_context, 0) < 0) { - al_log_error("lav_demux", "Failed to find stream info."); - goto err; - } - - if (!av->format_context->nb_streams) { - al_log_error("lav_demux", "No streams found."); - goto err; - } - -#define GUESS_STREAM_IS_IMAGE(stream) \ - (stream->duration >= 0 && stream->nb_frames <= 1 && (stream->avg_frame_rate.den == 0 && stream->r_frame_rate.den > 0)) - - av->duration = 0; - - for (u32 i = 0; i < av->format_context->nb_streams; i++) { - AVStream *stream = av->format_context->streams[i]; - enum AVMediaType type = stream->codecpar->codec_type; - // Try to detect attached images. - if (type == AVMEDIA_TYPE_VIDEO && GUESS_STREAM_IS_IMAGE(stream)) { - al_log_info("lav_demux", "Guessing that stream #%u is an image.", i); - stream->duration = 0; - } else if (stream->duration < 0) { - al_log_warn("lav_demux", "Stream #%u has an invalid duration (%ld).", i, stream->duration); - if (av->format_context->duration < 0) { - stream->duration = 0; - } else { - stream->duration = av_rescale_q(av->format_context->duration, AV_TIME_BASE_Q, stream->time_base); - } - al_log_info("lav_demux", "Setting stream #%u to a duration of %.3fs.", i, stream->duration * av_q2d(stream->time_base)); - } - if (stream->start_time < 0) stream->start_time = 0; - s64 duration = av_rescale_q(stream->duration, stream->time_base, AV_TIME_BASE_Q); - al_assert(duration >= 0); - if ((u64)duration > av->duration) av->duration = (u64)duration; - al_array_push(av->demux.streams, ((struct camu_stream){ - .type = CAMU_FFMPEG_COMPAT, - .av.stream = stream - })); - } - - av_format_inject_global_side_data(av->format_context); - - //av_dump_format(av->format_context, 0, "", 0); - - av->eof = false; - - return true; -err: - close_internal(av); - return false; -} - -static bool subscribed_to_index(struct camu_demuxer *demux, s32 index) -{ - s32 subscribed; - al_array_foreach(demux->subscribed, i, subscribed) { - if (subscribed == index) return true; - } - return false; -} - -static s32 lav_demuxer_get_packet(struct camu_demuxer *demux, struct camu_packet *packet) -{ - struct camu_lav_demuxer *av = (struct camu_lav_demuxer *)demux; - packet->type = CAMU_FFMPEG_COMPAT; - s32 ret = 0; - do { - ret = av_read_frame(av->format_context, packet->av.pkt); - if (ret == AVERROR_EOF) { - av->eof = true; - break; - } - if (ret < 0) { - al_log_error("lav_demuxer", "Failed to read frame (%s).", av_err2str(ret)); - continue; - } - if (!subscribed_to_index(demux, packet->av.pkt->stream_index)) { - av_packet_unref(packet->av.pkt); - continue; - } - break; - } while (1); - return ret; -} - -static u64 lav_demuxer_get_duration(struct camu_demuxer *demux) -{ - struct camu_lav_demuxer *av = (struct camu_lav_demuxer *)demux; - return av->duration; -} - -static bool lav_demuxer_seek(struct camu_demuxer *demux, u64 pos) -{ - struct camu_lav_demuxer *av = (struct camu_lav_demuxer *)demux; - if (pos > av->duration) pos = av->duration; - s64 ts = av_rescale_q((s64)pos, (AVRational){ 1, 1000000 }, AV_TIME_BASE_Q); - if (av->eof) { - avformat_flush(av->format_context); - av->eof = false; - } - if (avformat_seek_file(av->format_context, -1, INT64_MIN, ts, ts, AVSEEK_FLAG_BACKWARD) >= 0) { - return true; - } - return false; -} - -static void lav_demuxer_free(struct camu_demuxer **demux) -{ - struct camu_lav_demuxer *av = (struct camu_lav_demuxer *)*demux; - close_internal(av); - al_array_free(av->demux.streams); - al_free(av); - *demux = NULL; -} - -struct camu_demuxer *camu_lav_demuxer_create(void) -{ - struct camu_lav_demuxer *av = al_alloc_object(struct camu_lav_demuxer); - av->demux.type = CAMU_FFMPEG_COMPAT; - al_array_init(av->demux.streams); - al_array_init(av->demux.subscribed); - av->demux.init = lav_demuxer_init; - av->demux.get_packet = lav_demuxer_get_packet; - av->demux.get_duration = lav_demuxer_get_duration; - av->demux.seek = lav_demuxer_seek; - av->demux.free = lav_demuxer_free; - return (struct camu_demuxer *)av; -} diff --git a/src/codec/libav/demuxer.h b/src/codec/libav/demuxer.h deleted file mode 100644 index 9b2d093..0000000 --- a/src/codec/libav/demuxer.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include <al/types.h> -#include <al/lib.h> -#include <al/array.h> - -#include <libavformat/avformat.h> - -#include "../codec.h" - -struct camu_lav_demuxer { - struct camu_demuxer demux; - AVIOContext *io_context; - AVFormatContext *format_context; - u64 duration; - bool eof; -}; - -struct camu_demuxer *camu_lav_demuxer_create(void); diff --git a/src/codec/libav/encoder.c b/src/codec/libav/encoder.c deleted file mode 100644 index 4f3fa80..0000000 --- a/src/codec/libav/encoder.c +++ /dev/null @@ -1,186 +0,0 @@ -#include <libavcodec/avcodec.h> -#include <libavcodec/codec.h> -#include <libavformat/avformat.h> -#include <libavutil/audio_fifo.h> -#include <libavutil/channel_layout.h> -#include <libavutil/error.h> -#include <libavutil/frame.h> -#include <libavutil/samplefmt.h> -#include <al/lib.h> -#include <al/log.h> - -#include "encoder.h" - -#define BITRATE 256000 -#define FRAME_SIZE 20 -#define CHANNELS 2 - -bool camu_lav_encoder_init(struct camu_lav_encoder *enc, char *encoder_name, char *ext) -{ - al_memset(enc, 0, sizeof(struct camu_lav_encoder)); - - const AVCodec *codec = avcodec_find_encoder_by_name(encoder_name); - - if (!codec) { - al_log_error("lav_encoder", "Failed to find codec with name: %s.", encoder_name); - goto err; - } - - enc->codec_context = avcodec_alloc_context3(codec); - - if (!enc->codec_context) { - al_log_error("lav_encoder", "Failed to alloc codec context."); - goto err; - } - - enc->codec_context->sample_rate = 48000; - av_channel_layout_default(&enc->codec_context->ch_layout, CHANNELS); - enc->codec_context->sample_fmt = AV_SAMPLE_FMT_FLT; - enc->codec_context->bit_rate = BITRATE; - enc->codec_context->frame_size = FRAME_SIZE; - enc->codec_context->time_base = (AVRational){ 1, enc->codec_context->sample_rate }; - enc->codec_context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - - enc->output_format = av_guess_format(ext, NULL, NULL); - if (enc->output_format && enc->output_format->flags & AVFMT_GLOBALHEADER) { - enc->codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - } - - AVDictionary *opts = NULL; - av_dict_set(&opts, "b", "256k", 0); - av_dict_set(&opts, "vbr", "off", 0); - av_dict_set(&opts, "compression_level", "10", 0); - av_dict_set(&opts, "frame_duration", "20", 0); - av_dict_set(&opts, "application", "audio", 0); - - if (avcodec_open2(enc->codec_context, codec, &opts) < 0) { - al_log_error("lav_encoder", "Failed to open codec."); - av_dict_free(&opts); - goto err; - } - - av_dict_free(&opts); - - AVCodecContext *out_codec = enc->codec_context; - - av_channel_layout_copy(&enc->fmt.req_channel_layout, &out_codec->ch_layout); - enc->fmt.req_sample_rate = out_codec->sample_rate; - enc->fmt.req_format = out_codec->sample_fmt; - - enc->audio_fifo = av_audio_fifo_alloc(enc->fmt.req_format, - enc->fmt.req_channel_layout.nb_channels, 1); - - if (!enc->audio_fifo) { - al_log_error("lav_encoder", "Failed to alloc fifo."); - goto err; - } - - enc->frame = av_frame_alloc(); - enc->frame->nb_samples = 0; - enc->frame->sample_rate = enc->fmt.req_sample_rate; - av_channel_layout_copy(&enc->frame->ch_layout, &enc->fmt.req_channel_layout); - enc->frame->format = enc->fmt.req_format; - enc->frame->pts = 0; - - return true; -err: - camu_lav_encoder_close(enc); - return false; -} - -void camu_lav_encoder_push(struct camu_lav_encoder *enc, u8 **data, s32 sample_count) -{ - s32 alloc_size = av_audio_fifo_size(enc->audio_fifo) + sample_count; - if (av_audio_fifo_space(enc->audio_fifo) < alloc_size) { - if (av_audio_fifo_realloc(enc->audio_fifo, alloc_size) < 0) { - al_assert(false); - } - } - av_audio_fifo_write(enc->audio_fifo, (void **)data, sample_count); -} - -static void free_frame_data(struct camu_lav_encoder *enc) -{ - if (enc->frame && enc->frame->nb_samples > 0) av_freep(&enc->frame->data[0]); -} - -static void alloc_frame_data(struct camu_lav_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_lav_encoder *enc) -{ - s32 ret; - AVPacket pkt = { 0 }; - - do { - ret = avcodec_receive_packet(enc->codec_context, &pkt); - if (ret < 0) break; - enc->callback(enc->userdata, &pkt); - } while (1); - - if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { - al_log_error("lav_encoder", "Error receiving packet from encoder: (%s).", av_err2str(ret)); - return false; - } - - return true; -} - -static s32 send_frame(struct camu_lav_encoder *enc, AVFrame *in_frame) -{ - s32 ret = avcodec_send_frame(enc->codec_context, in_frame); - if (ret < 0 && ret != AVERROR_EOF) { - al_log_error("lav_encoder", "Error sending frame to encoder: (%s).", av_err2str(ret)); - } - return ret; -} - -bool camu_lav_encoder_process(struct camu_lav_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); - receive_packets(enc); - // This should guarantee that there are not packets left. - return false; - } - - 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; - - // ret < 0 means encoder erroed while sending frame. - return ret == 0; -} - -void camu_lav_encoder_close(struct camu_lav_encoder *enc) -{ - if (enc->codec_context) avcodec_free_context(&enc->codec_context); - if (enc->audio_fifo) av_audio_fifo_free(enc->audio_fifo); - free_frame_data(enc); - if (enc->frame) av_frame_free(&enc->frame); -} diff --git a/src/codec/libav/encoder.h b/src/codec/libav/encoder.h deleted file mode 100644 index b5a707a..0000000 --- a/src/codec/libav/encoder.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include <libavcodec/avcodec.h> -#include <libavformat/avformat.h> -#include <libavutil/audio_fifo.h> -#include <libavutil/rational.h> - -#include "resampler.h" - -struct camu_lav_encoder { - AVCodecContext *codec_context; - const AVOutputFormat *output_format; - - struct camu_lav_resample_fmt fmt; - - AVFrame *frame; - AVAudioFifo *audio_fifo; - - void (*callback)(void *, AVPacket *); - void *userdata; -}; - -bool camu_lav_encoder_init(struct camu_lav_encoder *enc, char *encoder_name, char *ext); -void camu_lav_encoder_push(struct camu_lav_encoder *enc, u8 **data, s32 sample_count); -bool camu_lav_encoder_process(struct camu_lav_encoder *enc, bool flush); -void camu_lav_encoder_close(struct camu_lav_encoder *enc); diff --git a/src/codec/libav/packet_ext.c b/src/codec/libav/packet_ext.c deleted file mode 100644 index 8fe4c39..0000000 --- a/src/codec/libav/packet_ext.c +++ /dev/null @@ -1,168 +0,0 @@ -#include "packet_ext.h" - -void aki_packet_write_av_codec_parameters(struct aki_packet *packet, AVCodecParameters *codecpar) -{ - AKI_PACKET_WRITE_TYPE(packet, enum AVMediaType, codecpar->codec_type); - AKI_PACKET_WRITE_TYPE(packet, enum AVCodecID, codecpar->codec_id); - AKI_PACKET_WRITE_TYPE(packet, u32, codecpar->codec_tag); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->extradata_size); - AKI_PACKET_WRITE_DATA(packet, codecpar->extradata, codecpar->extradata_size); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->format); - AKI_PACKET_WRITE_TYPE(packet, s64, codecpar->bit_rate); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->bits_per_coded_sample); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->bits_per_raw_sample); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->profile); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->level); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->width); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->height); - AKI_PACKET_WRITE_TYPE(packet, AVRational, codecpar->sample_aspect_ratio); - AKI_PACKET_WRITE_TYPE(packet, enum AVFieldOrder, codecpar->field_order); - AKI_PACKET_WRITE_TYPE(packet, enum AVColorRange, codecpar->color_range); - AKI_PACKET_WRITE_TYPE(packet, enum AVColorPrimaries, codecpar->color_primaries); - AKI_PACKET_WRITE_TYPE(packet, enum AVColorTransferCharacteristic, codecpar->color_trc); - AKI_PACKET_WRITE_TYPE(packet, enum AVColorSpace, codecpar->color_space); - AKI_PACKET_WRITE_TYPE(packet, enum AVChromaLocation, codecpar->chroma_location); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->video_delay); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->sample_rate); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->block_align); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->frame_size); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->initial_padding); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->trailing_padding); - AKI_PACKET_WRITE_TYPE(packet, s32, codecpar->seek_preroll); - AKI_PACKET_WRITE_TYPE(packet, AVChannelLayout, codecpar->ch_layout); -} - -void aki_packet_write_av_rational(struct aki_packet *packet, AVRational rational) -{ - AKI_PACKET_WRITE_TYPE(packet, AVRational, rational); -} - -void aki_packet_write_av_codec_id(struct aki_packet *packet, enum AVCodecID codec_id) -{ - AKI_PACKET_WRITE_TYPE(packet, enum AVCodecID, codec_id); -} - -void aki_packet_write_av_stream(struct aki_packet *packet, AVStream *stream) -{ - AKI_PACKET_WRITE_TYPE(packet, s32, stream->index); - aki_packet_write_av_codec_parameters(packet, stream->codecpar); - aki_packet_write_av_rational(packet, stream->time_base); - AKI_PACKET_WRITE_TYPE(packet, s64, stream->duration); - AKI_PACKET_WRITE_TYPE(packet, s64, stream->start_time); - AKI_PACKET_WRITE_TYPE(packet, s64, stream->nb_frames); - if (stream->avg_frame_rate.den == 0) { - // r_frame_rate.den == 0 handled on the client. - aki_packet_write_av_rational(packet, stream->r_frame_rate); - } else { - aki_packet_write_av_rational(packet, stream->avg_frame_rate); - } -} - -void aki_packet_write_av_packet(struct aki_packet *packet, AVPacket *pkt) -{ - AKI_PACKET_WRITE_TYPE(packet, s64, pkt->pts); - AKI_PACKET_WRITE_TYPE(packet, s64, pkt->dts); - AKI_PACKET_WRITE_TYPE(packet, s32, pkt->size); - AKI_PACKET_WRITE_DATA(packet, pkt->data, pkt->size); - AKI_PACKET_WRITE_TYPE(packet, s32, pkt->stream_index); - AKI_PACKET_WRITE_TYPE(packet, s32, pkt->flags); - AKI_PACKET_WRITE_TYPE(packet, s32, pkt->side_data_elems); - for (s32 i = 0; i < pkt->side_data_elems; i++) { - AKI_PACKET_WRITE_TYPE(packet, size_t, pkt->side_data[i].size); - AKI_PACKET_WRITE_DATA(packet, pkt->side_data[i].data, pkt->side_data[i].size); - AKI_PACKET_WRITE_TYPE(packet, enum AVPacketSideDataType, pkt->side_data[i].type); - } - AKI_PACKET_WRITE_TYPE(packet, s64, pkt->duration); - AKI_PACKET_WRITE_TYPE(packet, s64, pkt->pos); - AKI_PACKET_WRITE_TYPE(packet, AVRational, pkt->time_base); -} - -void aki_packet_read_av_codec_parameters(struct aki_packet *packet, AVCodecParameters *codecpar) -{ - AKI_PACKET_READ_TYPE(packet, enum AVMediaType, codecpar->codec_type); - AKI_PACKET_READ_TYPE(packet, enum AVCodecID, codecpar->codec_id); - AKI_PACKET_READ_TYPE(packet, u32, codecpar->codec_tag); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->extradata_size); - codecpar->extradata = av_malloc(codecpar->extradata_size); - u8 *extradata; - AKI_PACKET_READ_DATA(packet, codecpar->extradata_size, extradata); - al_memcpy(codecpar->extradata, extradata, codecpar->extradata_size); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->format); - AKI_PACKET_READ_TYPE(packet, s64, codecpar->bit_rate); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->bits_per_coded_sample); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->bits_per_raw_sample); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->profile); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->level); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->width); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->height); - AKI_PACKET_READ_TYPE(packet, AVRational, codecpar->sample_aspect_ratio); - AKI_PACKET_READ_TYPE(packet, enum AVFieldOrder, codecpar->field_order); - AKI_PACKET_READ_TYPE(packet, enum AVColorRange, codecpar->color_range); - AKI_PACKET_READ_TYPE(packet, enum AVColorPrimaries, codecpar->color_primaries); - AKI_PACKET_READ_TYPE(packet, enum AVColorTransferCharacteristic, codecpar->color_trc); - AKI_PACKET_READ_TYPE(packet, enum AVColorSpace, codecpar->color_space); - AKI_PACKET_READ_TYPE(packet, enum AVChromaLocation, codecpar->chroma_location); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->video_delay); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->sample_rate); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->block_align); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->frame_size); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->initial_padding); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->trailing_padding); - AKI_PACKET_READ_TYPE(packet, s32, codecpar->seek_preroll); - AKI_PACKET_READ_TYPE(packet, AVChannelLayout, codecpar->ch_layout); -} - -AVRational aki_packet_read_av_rational(struct aki_packet *packet) -{ - AVRational r; - AKI_PACKET_READ_TYPE(packet, AVRational, r); - return r; -} - -enum AVCodecID aki_packet_read_av_codec_id(struct aki_packet *packet) -{ - enum AVCodecID id; - AKI_PACKET_READ_TYPE(packet, enum AVCodecID, id); - return id; -} - -AVStream *aki_packet_read_av_stream(AVFormatContext *format_context, const AVCodec *codec, struct aki_packet *packet) -{ - AVStream *stream = avformat_new_stream(format_context, codec); - AKI_PACKET_READ_TYPE(packet, s32, stream->index); - aki_packet_read_av_codec_parameters(packet, stream->codecpar); - stream->time_base = aki_packet_read_av_rational(packet); - AKI_PACKET_READ_TYPE(packet, s64, stream->duration); - AKI_PACKET_READ_TYPE(packet, s64, stream->start_time); - AKI_PACKET_READ_TYPE(packet, s64, stream->nb_frames); - stream->avg_frame_rate = aki_packet_read_av_rational(packet); - return stream; -} - -AVPacket *aki_packet_read_av_packet(struct aki_packet *packet) -{ - AVPacket *pkt = av_packet_alloc(); - AKI_PACKET_READ_TYPE(packet, s64, pkt->pts); - AKI_PACKET_READ_TYPE(packet, s64, pkt->dts); - AKI_PACKET_READ_TYPE(packet, s32, pkt->size); - AKI_PACKET_READ_DATA(packet, pkt->size, pkt->data); - AKI_PACKET_READ_TYPE(packet, s32, pkt->stream_index); - AKI_PACKET_READ_TYPE(packet, s32, pkt->flags); - s32 side_data_elems; - AKI_PACKET_READ_TYPE(packet, s32, side_data_elems); - pkt->side_data_elems = 0; - for (s32 i = 0; i < side_data_elems; i++) { - size_t size; - u8 *data; - enum AVPacketSideDataType type; - AKI_PACKET_READ_TYPE(packet, s32, size); - AKI_PACKET_READ_DATA(packet, size, data); - AKI_PACKET_READ_TYPE(packet, enum AVPacketSideDataType, type); - u8 *side_data = av_packet_new_side_data(pkt, type, size); - al_memcpy(side_data, data, size); - } - AKI_PACKET_READ_TYPE(packet, s64, pkt->duration); - AKI_PACKET_READ_TYPE(packet, s64, pkt->pos); - AKI_PACKET_READ_TYPE(packet, AVRational, pkt->time_base); - return pkt; -} diff --git a/src/codec/libav/packet_ext.h b/src/codec/libav/packet_ext.h deleted file mode 100644 index ff6e337..0000000 --- a/src/codec/libav/packet_ext.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <aki/common.h> -#include <aki/event_loop.h> - -#include <libavcodec/packet.h> -#include <libavcodec/codec_par.h> -#include <libavformat/avformat.h> - -void aki_packet_write_av_codec_parameters(struct aki_packet *packet, AVCodecParameters *codecpar); -void aki_packet_write_av_rational(struct aki_packet *packet, AVRational rational); -void aki_packet_write_av_codec_id(struct aki_packet *packet, enum AVCodecID codec_id); -void aki_packet_write_av_stream(struct aki_packet *packet, AVStream *stream); -void aki_packet_write_av_packet(struct aki_packet *packet, AVPacket *pkt); - -void aki_packet_read_av_codec_parameters(struct aki_packet *packet, AVCodecParameters *codecpar); -AVRational aki_packet_read_av_rational(struct aki_packet *packet); -enum AVCodecID aki_packet_read_av_codec_id(struct aki_packet *packet); -AVStream *aki_packet_read_av_stream(AVFormatContext *format_context, const AVCodec *codec, struct aki_packet *packet); -AVPacket *aki_packet_read_av_packet(struct aki_packet *packet); diff --git a/src/codec/libav/resampler.c b/src/codec/libav/resampler.c deleted file mode 100644 index 229c68c..0000000 --- a/src/codec/libav/resampler.c +++ /dev/null @@ -1,162 +0,0 @@ -#include <libavutil/channel_layout.h> -#include <libavutil/frame.h> -#include <libavutil/opt.h> -#include <libavutil/samplefmt.h> -#include <libswresample/swresample.h> -#include <al/lib.h> -#include <al/log.h> - -#include "resampler.h" - -static bool in_req_matches(struct camu_lav_resample_fmt *fmt) -{ - return (fmt->in_format == fmt->req_format) && - (av_channel_layout_compare(&fmt->in_channel_layout, &fmt->req_channel_layout) == 0) && - (fmt->in_sample_rate == fmt->req_sample_rate); -} - -bool camu_lav_resampler_init(struct camu_lav_resampler *resamp, struct camu_lav_resample_fmt *fmt) -{ - al_memset(resamp, 0, sizeof(struct camu_lav_resampler)); - - fmt->resampler_needed = !in_req_matches(fmt); - if (!fmt->resampler_needed) return true; - - camu_lav_resample_fmt_copy(&resamp->fmt, fmt); - - SwrContext *ctx = NULL; - s32 ret = swr_alloc_set_opts2(&ctx, - &fmt->req_channel_layout, - fmt->req_format, - fmt->req_sample_rate, - &fmt->in_channel_layout, - fmt->in_format, - fmt->in_sample_rate, - 0, - NULL); - - if (ret != 0) { - al_log_error("lav_resampler", "Failed to configure resampler context."); - return false; - } - - // Slower but more accurate resampler. - //av_opt_set_int(ctx, "resampler", SWR_ENGINE_SOXR, 0); - - if (swr_init(ctx) != 0) { - swr_free(&ctx); - al_log_error("lav_resampler", "Failed to open resampler context."); - return false; - } - - resamp->resample_context = ctx; - - return true; -} - -s32 camu_lav_resampler_sample_count(struct camu_lav_resampler *resamp, s32 in_samples) -{ - return swr_get_out_samples(resamp->resample_context, in_samples); - //return av_rescale_rnd(swr_get_delay(resamp->resample_context, resamp->fmt.req_sample_rate) + - // in_samples, resamp->fmt.in_sample_rate, resamp->fmt.req_sample_rate, AV_ROUND_UP); -} - -static inline void free_sample_data(struct camu_lav_resampler *resamp) -{ - if (resamp->data[0]) av_freep(&resamp->data[0]); -} - -static inline void alloc_sample_data(struct camu_lav_resampler *resamp, s32 sample_count) -{ - if (resamp->sample_count >= sample_count) return; - free_sample_data(resamp); - s32 nb_channels = resamp->fmt.req_channel_layout.nb_channels; - av_samples_alloc(resamp->data, NULL, nb_channels, sample_count, resamp->fmt.req_format, 32); - resamp->sample_count = sample_count; -} - -s32 camu_lav_resampler_convert(struct camu_lav_resampler *resamp, const u8 **in_data, s32 in_samples) -{ - al_assert(in_samples > 0); - s32 max_resample_count = camu_lav_resampler_sample_count(resamp, in_samples); - alloc_sample_data(resamp, max_resample_count); - s32 resample_count = swr_convert(resamp->resample_context, resamp->data, - max_resample_count, in_data, in_samples); - if (resample_count < 0) { - al_log_error("lav_resampler", "Failed to convert samples (%i).", resample_count); - } - return resample_count; -} - -u8 **camu_lav_resampler_get_data(struct camu_lav_resampler *resamp) -{ - return (u8 **)resamp->data; -} - -void camu_lav_resampler_close(struct camu_lav_resampler *resamp) -{ - if (resamp->resample_context) { - swr_close(resamp->resample_context); - swr_free(&resamp->resample_context); - } - free_sample_data(resamp); -} - -void camu_lav_resample_fmt_copy(struct camu_lav_resample_fmt *dest, struct camu_lav_resample_fmt *src) -{ - dest->resampler_needed = src->resampler_needed; - dest->in_format = src->in_format; - av_channel_layout_copy(&dest->in_channel_layout, &src->in_channel_layout); - dest->in_sample_rate = src->in_sample_rate; - dest->req_format = src->req_format; - av_channel_layout_copy(&dest->req_channel_layout, &src->req_channel_layout); - dest->req_sample_rate = src->req_sample_rate; -} - -size_t camu_lav_resample_fmt_bytes_per_sample(struct camu_lav_resample_fmt *fmt) -{ - return (size_t)av_get_bytes_per_sample(fmt->req_format); -} - -size_t camu_lav_resample_fmt_samples_to_bytes(struct camu_lav_resample_fmt *fmt, size_t samples) -{ - s32 size, nb_channels = fmt->req_channel_layout.nb_channels; - if (av_samples_get_buffer_size(&size, nb_channels, (s32)samples, fmt->req_format, 1) < 0) { - return 0; - } - return (size_t)size; -} - -size_t camu_lav_resample_fmt_samples_to_usec(struct camu_lav_resample_fmt *fmt, size_t samples) -{ - return samples / (fmt->req_sample_rate / 1000000.0); -} - -f64 camu_lav_resample_fmt_samples_to_sec(struct camu_lav_resample_fmt *fmt, size_t samples) -{ - return samples / (f64)fmt->req_sample_rate; -} - -size_t camu_lav_resample_fmt_usec_to_bytes(struct camu_lav_resample_fmt *fmt, size_t usec) -{ - size_t samples = usec * (fmt->req_sample_rate / 1000000.0); - return samples * (camu_lav_resample_fmt_bytes_per_sample(fmt) * fmt->req_channel_layout.nb_channels); -} - -size_t camu_lav_resample_fmt_sec_to_bytes(struct camu_lav_resample_fmt *fmt, f64 sec) -{ - size_t samples = sec * fmt->req_sample_rate; - return samples * (camu_lav_resample_fmt_bytes_per_sample(fmt) * fmt->req_channel_layout.nb_channels); -} - -size_t camu_lav_resample_fmt_bytes_to_usec(struct camu_lav_resample_fmt *fmt, size_t bytes) -{ - size_t samples = bytes / (camu_lav_resample_fmt_bytes_per_sample(fmt) * fmt->req_channel_layout.nb_channels); - return samples / (fmt->req_sample_rate / 1000000.0); -} - -f64 camu_lav_resample_fmt_bytes_to_sec(struct camu_lav_resample_fmt *fmt, size_t bytes) -{ - size_t samples = bytes / (camu_lav_resample_fmt_bytes_per_sample(fmt) * fmt->req_channel_layout.nb_channels); - return samples / ((f64)fmt->req_sample_rate); -} diff --git a/src/codec/libav/resampler.h b/src/codec/libav/resampler.h deleted file mode 100644 index 92525b2..0000000 --- a/src/codec/libav/resampler.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include <libswresample/swresample.h> -#include <libavutil/opt.h> -#include <al/types.h> - -struct camu_lav_resample_fmt { - bool resampler_needed; - enum AVSampleFormat in_format; - enum AVSampleFormat req_format; - s32 in_channel_count; - s32 req_channel_count; - AVChannelLayout in_channel_layout; - AVChannelLayout req_channel_layout; - s32 in_sample_rate; - s32 req_sample_rate; -}; - -struct camu_lav_resampler { - SwrContext *resample_context; - struct camu_lav_resample_fmt fmt; - u8 *data[AV_NUM_DATA_POINTERS]; - s32 sample_count; -}; - -bool camu_lav_resampler_init(struct camu_lav_resampler *resamp, struct camu_lav_resample_fmt *fmt); -s32 camu_lav_resampler_sample_count(struct camu_lav_resampler *resamp, s32 in_samples); -s32 camu_lav_resampler_convert(struct camu_lav_resampler *resamp, const u8 **in_data, s32 in_samples); -u8 **camu_lav_resampler_get_data(struct camu_lav_resampler *resamp); -void camu_lav_resampler_close(struct camu_lav_resampler *resamp); - -void camu_lav_resample_fmt_copy(struct camu_lav_resample_fmt *dest, struct camu_lav_resample_fmt *src); -size_t camu_lav_resample_fmt_bytes_per_sample(struct camu_lav_resample_fmt *fmt); -size_t camu_lav_resample_fmt_samples_to_bytes(struct camu_lav_resample_fmt *fmt, size_t samples); -size_t camu_lav_resample_fmt_samples_to_usec(struct camu_lav_resample_fmt *fmt, size_t samples); -f64 camu_lav_resample_fmt_samples_to_sec(struct camu_lav_resample_fmt *fmt, size_t samples); -size_t camu_lav_resample_fmt_usec_to_bytes(struct camu_lav_resample_fmt *fmt, size_t usec); -size_t camu_lav_resample_fmt_sec_to_bytes(struct camu_lav_resample_fmt *fmt, f64 sec); -size_t camu_lav_resample_fmt_bytes_to_usec(struct camu_lav_resample_fmt *fmt, size_t bytes); -f64 camu_lav_resample_fmt_bytes_to_sec(struct camu_lav_resample_fmt *fmt, size_t bytes); diff --git a/src/codec/libav/scaler.c b/src/codec/libav/scaler.c deleted file mode 100644 index 882116f..0000000 --- a/src/codec/libav/scaler.c +++ /dev/null @@ -1,84 +0,0 @@ -#include <al/lib.h> -#include <al/log.h> -#include <libavutil/imgutils.h> -#include <libavcodec/avcodec.h> - -#include "scaler.h" - -static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, s32 width, s32 height) -{ - AVFrame *frame = av_frame_alloc(); - if (!frame) return NULL; - s32 ret = av_image_alloc(frame->data, frame->linesize, width, height, pix_fmt, 32); - if (ret < 0) { - al_log_error("lav_scaler", "Failed to allocate picture buffer (%s).", av_err2str(ret)); - return NULL; - } - /* - s32 size = av_image_get_buffer_size(pix_fmt, width, height, 1); - u8 *buffer = (u8 *)av_malloc(size); - if (!buffer) { - av_free(frame); - return NULL; - } - s32 ret = av_image_fill_arrays(frame->data, frame->linesize, buffer, pix_fmt, width, height, 1); - if (ret < 0) { - al_log_error("lav_scaler", "Failed to allocate picture buffer (%s).", av_err2str(ret)); - av_free(frame); - return NULL; - } - */ - frame->width = width; - frame->height = height; - frame->format = pix_fmt; - return frame; -} - -bool camu_lav_scaler_init(struct camu_lav_scaler *scale, struct camu_lav_scale_fmt *fmt) -{ - al_memset(scale, 0, sizeof(struct camu_lav_scaler)); - - 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; - } - - 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) { - al_log_error("lav_scaler", "Failed to create scaler context."); - return false; - } - - scale->frame = alloc_picture(fmt->req_format, fmt->req_width, fmt->req_height); - if (!scale->frame) { - al_log_error("lav_scaler", "Failed to allocate frame."); - return false; - } - - fmt->scaler_needed = true; - - scale->fmt = *fmt; - - return true; -} - -bool camu_lav_scaler_scale(struct camu_lav_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) { - al_log_error("lav_scaler", "Failed to scale frame (%s).", av_err2str(ret)); - return false; - } - return true; -} - -void camu_lav_scaler_close(struct camu_lav_scaler *scale) -{ - av_freep(&scale->frame->data[0]); - av_frame_free(&scale->frame); - sws_freeContext(scale->scaler_context); -} diff --git a/src/codec/libav/scaler.h b/src/codec/libav/scaler.h deleted file mode 100644 index 4d54085..0000000 --- a/src/codec/libav/scaler.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include <libswscale/swscale.h> -#include <al/types.h> - -struct camu_lav_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; -}; - -struct camu_lav_scaler { - struct SwsContext *scaler_context; - struct camu_lav_scale_fmt fmt; - AVFrame *frame; -}; - -bool camu_lav_scaler_init(struct camu_lav_scaler *scale, struct camu_lav_scale_fmt *fmt); -bool camu_lav_scaler_scale(struct camu_lav_scaler *scale, const u8 **in_slice, s32 *in_strides); -void camu_lav_scaler_close(struct camu_lav_scaler *scale); |