summaryrefslogtreecommitdiff
path: root/src/codec
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/codec.h47
-rw-r--r--src/codec/ffmpeg/avio.c12
-rw-r--r--src/codec/ffmpeg/avio.h5
-rw-r--r--src/codec/ffmpeg/common.c4
-rw-r--r--src/codec/ffmpeg/decoder.c4
-rw-r--r--src/codec/ffmpeg/decoder.h4
-rw-r--r--src/codec/ffmpeg/demuxer.c7
-rw-r--r--src/codec/ffmpeg/encoder.c25
-rw-r--r--src/codec/ffmpeg/encoder.h2
-rw-r--r--src/codec/ffmpeg/meson.build20
-rw-r--r--src/codec/ffmpeg/packet_ext.c18
-rw-r--r--src/codec/ffmpeg/packet_ext.h3
-rw-r--r--src/codec/ffmpeg/resampler.c33
13 files changed, 133 insertions, 51 deletions
diff --git a/src/codec/codec.h b/src/codec/codec.h
index 14727d3..16e408c 100644
--- a/src/codec/codec.h
+++ b/src/codec/codec.h
@@ -35,8 +35,8 @@ enum {
enum {
CAMU_STREAM_UNKNOWN = AVMEDIA_TYPE_UNKNOWN,
- CAMU_STREAM_AUDIO = AVMEDIA_TYPE_AUDIO, // 1
CAMU_STREAM_VIDEO = AVMEDIA_TYPE_VIDEO, // 0
+ CAMU_STREAM_AUDIO = AVMEDIA_TYPE_AUDIO, // 1
CAMU_STREAM_SUBTITLE = AVMEDIA_TYPE_SUBTITLE,
CAMU_STREAM_ATTACHMENT = AVMEDIA_TYPE_ATTACHMENT
};
@@ -77,12 +77,13 @@ enum {
CAMU_SEEK_SIZE = 0x10000
};
+// Using values from FFmpeg for potentially less confusing errors.
enum {
CAMU_STREAM_UNKNOWN = -1,
- CAMU_STREAM_AUDIO,
- CAMU_STREAM_VIDEO,
- CAMU_STREAM_SUBTITLE,
- CAMU_STREAM_ATTACHMENT
+ CAMU_STREAM_VIDEO = 0,
+ CAMU_STREAM_AUDIO = 1,
+ CAMU_STREAM_SUBTITLE = 3,
+ CAMU_STREAM_ATTACHMENT = 4
};
enum {
@@ -126,7 +127,11 @@ struct camu_audio_format {
s32 format;
s32 sample_rate;
#ifdef CAMU_HAVE_FFMPEG
+#ifndef CAMU_OLD_FFMPEG
AVChannelLayout channel_layout;
+#else
+ u64 channel_layout;
+#endif
#endif
s32 channel_count;
};
@@ -239,17 +244,49 @@ static inline bool camu_resampler_format_matches(struct camu_resampler_format *f
return fmt->in.format == fmt->req.format
&& fmt->in.sample_rate == fmt->req.sample_rate
#ifdef CAMU_HAVE_FFMPEG
+#ifndef CAMU_OLD_FFMPEG
&& av_channel_layout_compare(&fmt->in.channel_layout, &fmt->req.channel_layout) == 0
+#else
+ && fmt->in.channel_layout == fmt->req.channel_layout
+#endif
#endif
&& fmt->in.channel_count == fmt->req.channel_count;
}
+#ifndef CAMU_OLD_FFMPEG
+#define AV_CODECPAR_CHANNEL_LAYOUT(codecpar) ((codecpar)->ch_layout)
+#define AV_CODECPAR_CHANNELS(codecpar) ((codecpar)->ch_layout.nb_channels)
+static inline void camu_default_channel_layout(AVChannelLayout *ch_layout, s32 channels)
+{
+ av_channel_layout_default(ch_layout, channels);
+}
+static inline void camu_copy_channel_layout(AVChannelLayout *dest, AVChannelLayout *src)
+{
+ av_channel_layout_copy(dest, src);
+}
+#else
+#define AV_CODECPAR_CHANNEL_LAYOUT(codecpar) ((codecpar)->channel_layout)
+#define AV_CODECPAR_CHANNELS(codecpar) ((codecpar)->channels)
+static inline void camu_default_channel_layout(u64 *channel_layout, s32 channels)
+{
+ *channel_layout = av_get_default_channel_layout(channels);
+}
+static inline void camu_copy_channel_layout(u64 *dest, u64 *src)
+{
+ *dest = *src;
+}
+#endif
+
static inline void camu_audio_format_copy(struct camu_audio_format *dest, struct camu_audio_format *src)
{
dest->format = src->format;
dest->sample_rate = src->sample_rate;
#ifdef CAMU_HAVE_FFMPEG
+#ifndef CAMU_OLD_FFMPEG
av_channel_layout_copy(&dest->channel_layout, &src->channel_layout);
+#else
+ dest->channel_layout = src->channel_layout;
+#endif
#endif
dest->channel_count = src->channel_count;
}
diff --git a/src/codec/ffmpeg/avio.c b/src/codec/ffmpeg/avio.c
index 154152e..86130d8 100644
--- a/src/codec/ffmpeg/avio.c
+++ b/src/codec/ffmpeg/avio.c
@@ -2,20 +2,20 @@
#include "../../cache/handle.h"
-s32 camu_avio_read(void *data, u8 *buf, s32 count)
+s32 camu_avio_read(void *opaque, u8 *buf, s32 count)
{
- struct cch_handle *handle = (struct cch_handle *)data;
+ struct cch_handle *handle = (struct cch_handle *)opaque;
return cch_handle_read(handle, buf, count);
}
-s32 camu_avio_write(void *data, const u8 *buf, s32 count)
+s32 camu_avio_write(void *opaque, u8 *buf, s32 count)
{
- struct cch_handle *handle = (struct cch_handle *)data;
+ struct cch_handle *handle = (struct cch_handle *)opaque;
return cch_handle_write(handle, buf, count);
}
-s64 camu_avio_seek(void *data, s64 offset, s32 whence)
+s64 camu_avio_seek(void *opaque, s64 offset, s32 whence)
{
- struct cch_handle *handle = (struct cch_handle *)data;
+ struct cch_handle *handle = (struct cch_handle *)opaque;
return (s64)cch_handle_seek(handle, offset, whence);
}
diff --git a/src/codec/ffmpeg/avio.h b/src/codec/ffmpeg/avio.h
index 04aeeb4..bb67c58 100644
--- a/src/codec/ffmpeg/avio.h
+++ b/src/codec/ffmpeg/avio.h
@@ -2,5 +2,6 @@
#include <al/types.h>
-s32 camu_avio_read(void *data, u8 *buf, s32 buf_size);
-s64 camu_avio_seek(void *data, s64 offset, s32 whence);
+s32 camu_avio_read(void *opaque, u8 *buf, s32 buf_size);
+s32 camu_avio_write(void *opaque, u8 *buf, s32 count);
+s64 camu_avio_seek(void *opaque, s64 offset, s32 whence);
diff --git a/src/codec/ffmpeg/common.c b/src/codec/ffmpeg/common.c
index 259ba90..5226df6 100644
--- a/src/codec/ffmpeg/common.c
+++ b/src/codec/ffmpeg/common.c
@@ -2,6 +2,7 @@
#include <al/log.h>
#include <al/lib.h>
#include <libavutil/log.h>
+#include <libavformat/avformat.h>
#include "common.h"
@@ -55,5 +56,8 @@ void camu_ff_set_log_callback(void (*callback)(void *, s32, const char *, va_lis
void camu_ff_common_init(void)
{
log_info("Using FFmpeg version "FFMPEG_VERSION".");
+#ifdef CAMU_OLD_FFMPEG
+ av_register_all();
+#endif
camu_ff_set_log_callback(av_log_callback);
}
diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c
index c22d1c1..e097e0c 100644
--- a/src/codec/ffmpeg/decoder.c
+++ b/src/codec/ffmpeg/decoder.c
@@ -10,11 +10,11 @@
#endif
#ifdef CAMU_FF_DECODER_HWACCEL
-#if defined CAMU_RENDERER_VULKAN
+#if defined STELA_API_VULKAN
static const char *hwdevces[] = { "vulkan" };
#elif defined NAUNET_ON_WINDOWS
static const char *hwdevces[] = { "d3d11va" };
-#elif defined CAMU_RENDERER_OPENGL
+#elif defined STELA_API_OPENGL
static const char *hwdevces[] = { "vaapi" };
#endif
diff --git a/src/codec/ffmpeg/decoder.h b/src/codec/ffmpeg/decoder.h
index ab60ef3..4797060 100644
--- a/src/codec/ffmpeg/decoder.h
+++ b/src/codec/ffmpeg/decoder.h
@@ -4,8 +4,8 @@
#include "../codec.h"
-#ifndef CAMU_SINK_NO_VIDEO
-//#define CAMU_FF_DECODER_HWACCEL
+#ifdef CAMU_USE_HWACCEL
+#define CAMU_FF_DECODER_HWACCEL
#endif
struct camu_ff_decoder {
diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c
index bf2039f..a5821a2 100644
--- a/src/codec/ffmpeg/demuxer.c
+++ b/src/codec/ffmpeg/demuxer.c
@@ -88,6 +88,13 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl
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;
+#ifdef CAMU_OLD_FFMPEG
+ // This is probably not correct.
+ if (stream->codecpar->channel_layout == 0) {
+ stream->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;
+ stream->codecpar->channels = 2;
+ }
+#endif
u64 duration = 0;
if (type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_SUBTITLE) {
// Try to detect attached images.
diff --git a/src/codec/ffmpeg/encoder.c b/src/codec/ffmpeg/encoder.c
index 50e80e4..5d90785 100644
--- a/src/codec/ffmpeg/encoder.c
+++ b/src/codec/ffmpeg/encoder.c
@@ -32,7 +32,7 @@ bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char
}
enc->codec_context->sample_rate = 48000;
- av_channel_layout_default(&enc->codec_context->ch_layout, CHANNELS);
+ camu_default_channel_layout(&AV_CODECPAR_CHANNEL_LAYOUT(enc->codec_context), CHANNELS);
enc->codec_context->sample_fmt = AV_SAMPLE_FMT_FLT;
enc->codec_context->bit_rate = bitrate;
enc->codec_context->frame_size = SAMPLES_PER_FRAME;
@@ -62,19 +62,20 @@ bool camu_ff_encoder_init(struct camu_ff_encoder *enc, char *encoder_name, char
av_dict_free(&opts);
AVCodecContext *out_codec = enc->codec_context;
+ AVFrame *frame = av_frame_alloc();
+ frame->format = out_codec->sample_fmt;
+ frame->sample_rate = out_codec->sample_rate;
+ camu_copy_channel_layout(&AV_CODECPAR_CHANNEL_LAYOUT(frame), &AV_CODECPAR_CHANNEL_LAYOUT(out_codec));
+ av_samples_alloc(frame->data, NULL, AV_CODECPAR_CHANNELS(out_codec), SAMPLES_PER_FRAME, frame->format, 1);
+ frame->nb_samples = SAMPLES_PER_FRAME;
+ frame->pts = 0;
- enc->fmt.req.format = out_codec->sample_fmt;
- enc->fmt.req.sample_rate = out_codec->sample_rate;
- av_channel_layout_copy(&enc->fmt.req.channel_layout, &out_codec->ch_layout);
- enc->fmt.req.channel_count = out_codec->ch_layout.nb_channels;
+ enc->fmt.format = frame->format;
+ enc->fmt.sample_rate = frame->sample_rate;
+ camu_copy_channel_layout(&enc->fmt.channel_layout, &AV_CODECPAR_CHANNEL_LAYOUT(frame));
+ enc->fmt.channel_count = AV_CODECPAR_CHANNELS(frame);
- enc->frame = av_frame_alloc();
- enc->frame->format = enc->fmt.req.format;
- enc->frame->sample_rate = enc->fmt.req.sample_rate;
- av_channel_layout_copy(&enc->frame->ch_layout, &enc->fmt.req.channel_layout);
- av_samples_alloc(enc->frame->data, NULL, enc->frame->ch_layout.nb_channels, SAMPLES_PER_FRAME, enc->frame->format, 1);
- enc->frame->nb_samples = SAMPLES_PER_FRAME;
- enc->frame->pts = 0;
+ enc->frame = frame;
return true;
err:
diff --git a/src/codec/ffmpeg/encoder.h b/src/codec/ffmpeg/encoder.h
index 5f7d06f..3ace4d8 100644
--- a/src/codec/ffmpeg/encoder.h
+++ b/src/codec/ffmpeg/encoder.h
@@ -9,7 +9,7 @@ struct camu_ff_encoder {
AVCodecContext *codec_context;
const AVOutputFormat *output_format;
- struct camu_resampler_format fmt;
+ struct camu_audio_format fmt;
AVFrame *frame;
void (*callback)(void *, AVPacket *);
diff --git a/src/codec/ffmpeg/meson.build b/src/codec/ffmpeg/meson.build
index eb68fad..56a75b2 100644
--- a/src/codec/ffmpeg/meson.build
+++ b/src/codec/ffmpeg/meson.build
@@ -3,6 +3,9 @@ ffmpeg_src = [
'packet_ext.c',
]
ffmpeg_args = ['-DCAMU_HAVE_FFMPEG']
+if get_option('codec-hwaccel').enabled()
+ ffmpeg_args += ['-DCAMU_USE_HWACCEL']
+endif
ffmpeg_deps = []
ffmpeg_server_src = [
@@ -16,8 +19,7 @@ ffmpeg_client_src = [
ffmpeg_src,
'decoder.c',
'resampler.c',
- 'scaler.c',
- 'encoder.c'
+ 'scaler.c'
]
ffmpeg_client_deps = []
@@ -38,7 +40,12 @@ libavcodec = dependency('libavcodec', required: false)
libswresample = dependency('libswresample', required: false)
libswscale = dependency('libswscale', required: false)
if not (libavutil.found() and libavformat.found() and libavcodec.found() and libswresample.found() and libswscale.found())
- ffmpeg_proj = subproject('ffmpeg', required: false)
+ if get_option('win32-compat')
+ ffmpeg_proj = subproject('ffmpeg-compat', required: false)
+ ffmpeg_args += ['-DCAMU_OLD_FFMPEG']
+ else
+ ffmpeg_proj = subproject('ffmpeg', required: false)
+ endif
if ffmpeg_proj.found()
libavutil = ffmpeg_proj.get_variable('avutil')
libavformat = ffmpeg_proj.get_variable('avformat')
@@ -48,9 +55,12 @@ if not (libavutil.found() and libavformat.found() and libavcodec.found() and lib
libswscale = ffmpeg_proj.get_variable('swscale')
# Only used to set include dirs for FFmpeg.
ffmpeg_deps += [ffmpeg_proj.get_variable('ffmpeg_include')]
- # We explicitly enable zlib in the FFmpeg build.
+ # We explicitly enable zlib and maybe bzlib in the FFmpeg build.
ffmpeg_deps += [dependency('zlib')]
- if is_windows
+ if not get_option('sink-only')
+ ffmpeg_deps += [dependency('bzip2')]
+ endif
+ if is_windows and not get_option('win32-compat')
# Extra static dependencies for Windows.
ffmpeg_client_deps += [compiler.find_library('bcrypt')]
elif is_android
diff --git a/src/codec/ffmpeg/packet_ext.c b/src/codec/ffmpeg/packet_ext.c
index acf5bbd..a1a6a5e 100644
--- a/src/codec/ffmpeg/packet_ext.c
+++ b/src/codec/ffmpeg/packet_ext.c
@@ -16,7 +16,7 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->width);
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->height);
NNWT_PACKET_WRITE_TYPE(packet, AVRational, codecpar->sample_aspect_ratio);
-#if LIBAVCODEC_VERSION_INT >= 60
+#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= 60
NNWT_PACKET_WRITE_TYPE(packet, AVRational, codecpar->framerate);
#endif
NNWT_PACKET_WRITE_TYPE(packet, enum AVFieldOrder, codecpar->field_order);
@@ -26,6 +26,7 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame
NNWT_PACKET_WRITE_TYPE(packet, enum AVColorSpace, codecpar->color_space);
NNWT_PACKET_WRITE_TYPE(packet, enum AVChromaLocation, codecpar->chroma_location);
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->video_delay);
+#ifndef CAMU_OLD_FFMPEG
// Incomplete.
NNWT_PACKET_WRITE_TYPE(packet, enum AVChannelOrder, codecpar->ch_layout.order);
if (codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) {
@@ -33,6 +34,10 @@ void nn_packet_write_av_codec_parameters(struct nn_packet *packet, AVCodecParame
} else {
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->ch_layout.nb_channels);
}
+#else
+ NNWT_PACKET_WRITE_TYPE(packet, u64, codecpar->channel_layout);
+ NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->channels);
+#endif
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->sample_rate);
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->block_align);
NNWT_PACKET_WRITE_TYPE(packet, s32, codecpar->frame_size);
@@ -98,7 +103,9 @@ void nn_packet_write_av_packet(struct nn_packet *packet, AVPacket *pkt)
}
NNWT_PACKET_WRITE_TYPE(packet, s64, pkt->duration);
NNWT_PACKET_WRITE_TYPE(packet, s64, pkt->pos);
+#ifndef CAMU_OLD_FFMPEG
NNWT_PACKET_WRITE_TYPE(packet, AVRational, pkt->time_base);
+#endif
}
void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParameters *codecpar)
@@ -120,7 +127,7 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->width);
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->height);
NNWT_PACKET_READ_TYPE(packet, AVRational, codecpar->sample_aspect_ratio);
-#if LIBAVCODEC_VERSION_INT >= 60
+#if !defined CAMU_OLD_FFMPEG && LIBAVCODEC_VERSION_INT >= 60
NNWT_PACKET_READ_TYPE(packet, AVRational, codecpar->framerate);
#endif
NNWT_PACKET_READ_TYPE(packet, enum AVFieldOrder, codecpar->field_order);
@@ -130,6 +137,7 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet
NNWT_PACKET_READ_TYPE(packet, enum AVColorSpace, codecpar->color_space);
NNWT_PACKET_READ_TYPE(packet, enum AVChromaLocation, codecpar->chroma_location);
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->video_delay);
+#ifndef CAMU_OLD_FFMPEG
enum AVChannelOrder order;
NNWT_PACKET_READ_TYPE(packet, enum AVChannelOrder, order);
if (order == AV_CHANNEL_ORDER_NATIVE) {
@@ -141,6 +149,10 @@ void nn_packet_read_av_codec_parameters(struct nn_packet *packet, AVCodecParamet
NNWT_PACKET_READ_TYPE(packet, s32, nb_channels);
av_channel_layout_default(&codecpar->ch_layout, nb_channels);
}
+#else
+ NNWT_PACKET_READ_TYPE(packet, u64, codecpar->channel_layout);
+ NNWT_PACKET_READ_TYPE(packet, s32, codecpar->channels);
+#endif
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->sample_rate);
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->block_align);
NNWT_PACKET_READ_TYPE(packet, s32, codecpar->frame_size);
@@ -214,5 +226,7 @@ void nn_packet_read_av_packet(struct nn_packet *packet, AVPacket *pkt)
}
NNWT_PACKET_READ_TYPE(packet, s64, pkt->duration);
NNWT_PACKET_READ_TYPE(packet, s64, pkt->pos);
+#ifndef CAMU_OLD_FFMPEG
NNWT_PACKET_READ_TYPE(packet, AVRational, pkt->time_base);
+#endif
}
diff --git a/src/codec/ffmpeg/packet_ext.h b/src/codec/ffmpeg/packet_ext.h
index fab9b36..540cdcb 100644
--- a/src/codec/ffmpeg/packet_ext.h
+++ b/src/codec/ffmpeg/packet_ext.h
@@ -1,8 +1,7 @@
#pragma once
#include <nnwt/packet.h>
-#include <libavcodec/packet.h>
-#include <libavcodec/codec_par.h>
+#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
diff --git a/src/codec/ffmpeg/resampler.c b/src/codec/ffmpeg/resampler.c
index eacc75b..48cca8e 100644
--- a/src/codec/ffmpeg/resampler.c
+++ b/src/codec/ffmpeg/resampler.c
@@ -12,26 +12,35 @@ static bool ff_resampler_init(struct camu_resampler *resamp, struct camu_resampl
camu_audio_format_copy(&av->fmt, &fmt->req);
- s32 ret = swr_alloc_set_opts2(&av->resample_context,
- &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) {
- log_error("Failed to configure resampler context.");
- return false;
- }
+ SwrContext *swr = swr_alloc();
+
+#ifndef CAMU_OLD_FFMPEG
+ av_opt_set_chlayout(swr, "in_chlayout", &fmt->in.channel_layout, 0);
+ av_opt_set_chlayout(swr, "out_chlayout", &fmt->req.channel_layout, 0);
+#else
+ av_opt_set_channel_layout(swr, "in_channel_layout", fmt->in.channel_layout, 0);
+ av_opt_set_channel_layout(swr, "out_channel_layout", fmt->req.channel_layout, 0);
+#endif
+ av_opt_set_int(swr, "in_sample_rate", fmt->in.sample_rate, 0);
+ av_opt_set_int(swr, "out_sample_rate", fmt->req.sample_rate, 0);
+ av_opt_set_sample_fmt(swr, "in_sample_fmt", fmt->in.format, 0);
+ av_opt_set_sample_fmt(swr, "out_sample_fmt", fmt->req.format, 0);
#ifdef CAMU_HAVE_SOXR
// Slower but more accurate resampler.
- av_opt_set_int(av->resample_context, "resampler", SWR_ENGINE_SOXR, 0);
+ av_opt_set_int(swr, "resampler", SWR_ENGINE_SOXR, 0);
log_info("Using SoX resampler.");
#endif
- if (swr_init(av->resample_context) != 0) {
- swr_free(&av->resample_context);
- log_error("Failed to init resampler context.");
+ s32 ret = swr_init(swr);
+ if (ret != 0) {
+ swr_free(&swr);
+ log_error("Failed to init resampler context (%s).", av_err2str(ret));
return false;
}
+ av->resample_context = swr;
+
return true;
}
@@ -44,7 +53,7 @@ static inline void alloc_sample_data(struct camu_ff_resampler *av, s32 sample_co
{
if (av->sample_count >= sample_count) return;
free_sample_data(av);
- s32 nb_channels = av->fmt.channel_layout.nb_channels;
+ s32 nb_channels = av->fmt.channel_count;
av_samples_alloc(av->data, NULL, nb_channels, sample_count, av->fmt.format, 32);
av->sample_count = sample_count;
}