From f381f0dfcfed7bf424f59a71f15e2d1a24315d8a Mon Sep 17 00:00:00 2001 From: Adrien Beraud <adrien.beraud@savoirfairelinux.com> Date: Tue, 10 Oct 2023 14:16:52 -0400 Subject: [PATCH] media decoder: support floating point Change-Id: Ifea0a1ebd9cc36214b0532c01119333cd269f1a0 --- src/media/libav_utils.cpp | 28 ++++++++++++++++++++++++++++ src/media/libav_utils.h | 6 ++++++ src/media/media_decoder.cpp | 16 ++++++++++------ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/media/libav_utils.cpp b/src/media/libav_utils.cpp index 60cee22898..ea22450986 100644 --- a/src/media/libav_utils.cpp +++ b/src/media/libav_utils.cpp @@ -56,6 +56,34 @@ av_frame_new_side_data_from_buf(AVFrame* frame, enum AVFrameSideDataType type, A namespace jami { namespace libav_utils { +AVSampleFormat +choose_sample_fmt(const AVCodec *codec, const AVSampleFormat *preferred_formats, int preferred_formats_count) { + for (int i = 0; i < preferred_formats_count; ++i) { + for (auto it = codec->sample_fmts; *it != -1; ++it) { + if (*it == preferred_formats[i]) + return preferred_formats[i]; + } + } + return AV_SAMPLE_FMT_NONE; +} + +AVSampleFormat +choose_sample_fmt_default(const AVCodec* codec, AVSampleFormat defaultFormat) { + // List of supported formats, current default first + const AVSampleFormat preferred_formats[] = { + defaultFormat, + AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_FLT, + AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_DBL, + AV_SAMPLE_FMT_S32P, + AV_SAMPLE_FMT_S32 + }; + return choose_sample_fmt(codec, preferred_formats, sizeof(preferred_formats) / sizeof(preferred_formats[0])); +} + #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) // protect libav/ffmpeg access static int diff --git a/src/media/libav_utils.h b/src/media/libav_utils.h index 96e96be1af..2439dd6a2c 100644 --- a/src/media/libav_utils.h +++ b/src/media/libav_utils.h @@ -21,6 +21,8 @@ #pragma once +#include <libavutil/samplefmt.h> + #include <vector> #include <map> #include <string> @@ -31,6 +33,7 @@ struct AVDictionary; struct AVFrame; struct AVPixFmtDescriptor; struct AVBufferRef; +struct AVCodec; void av_buffer_unref(AVBufferRef **buf); } @@ -42,6 +45,9 @@ void av_init(); const char* const DEFAULT_H264_PROFILE_LEVEL_ID = "profile-level-id=428029"; const char* const MAX_H264_PROFILE_LEVEL_ID = "profile-level-id=640034"; +enum AVSampleFormat choose_sample_fmt(const AVCodec* codec, const enum AVSampleFormat* preferred_formats, int preferred_formats_count); +enum AVSampleFormat choose_sample_fmt_default(const AVCodec* codec, enum AVSampleFormat defaultFormat); + bool is_yuv_planar(const AVPixFmtDescriptor& desc); std::string getError(int err); diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp index e994f6ca33..a652f97f74 100644 --- a/src/media/media_decoder.cpp +++ b/src/media/media_decoder.cpp @@ -27,6 +27,7 @@ #include "media_io_handle.h" #include "audio/ringbuffer.h" #include "audio/resampler.h" +#include "audio/ringbufferpool.h" #include "decoder_finder.h" #include "manager.h" @@ -147,10 +148,10 @@ MediaDemuxer::openInput(const DeviceParams& params) std::string input = params.input; #endif - JAMI_DBG("Trying to open device %s with format %s, pixel format %s, size %dx%d, rate %lf", - input.c_str(), - params.format.c_str(), - params.pixel_format.c_str(), + JAMI_LOG("Trying to open input {} with format {}, pixel format {}, size {}x{}, rate {}", + input, + params.format, + params.pixel_format, params.width, params.height, params.framerate.real()); @@ -574,13 +575,13 @@ MediaDecoder::prepareDecoderContext() { inputDecoder_ = findDecoder(avStream_->codecpar->codec_id); if (!inputDecoder_) { - JAMI_ERR() << "Unsupported codec"; + JAMI_ERROR("Unsupported codec"); return -1; } decoderCtx_ = avcodec_alloc_context3(inputDecoder_); if (!decoderCtx_) { - JAMI_ERR() << "Failed to create decoder context"; + JAMI_ERROR("Failed to create decoder context"); return -1; } avcodec_parameters_to_context(decoderCtx_, avStream_->codecpar); @@ -597,6 +598,9 @@ MediaDecoder::prepareDecoderContext() if (decoderCtx_->codec_id == AV_CODEC_ID_OPUS) { av_opt_set_int(decoderCtx_, "decode_fec", fecEnabled_ ? 1 : 0, AV_OPT_SEARCH_CHILDREN); } + auto format = libav_utils::choose_sample_fmt_default(inputDecoder_, Manager::instance().getRingBufferPool().getInternalAudioFormat().sampleFormat); + decoderCtx_->sample_fmt = format; + decoderCtx_->request_sample_fmt = format; } return 0; } -- GitLab