X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flibopusenc.c;h=bf2d04b4fb03628a5fee75d81a87611791c34d9d;hb=60e7021064ea9e99854c585d452e89f38635480e;hp=50d843ebc5489361efe4d1d4a18e588db31907c8;hpb=4cd6f08d2005c20a03ccd53a0a6f8a115c5ebe2e;p=ffmpeg diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 50d843ebc54..bf2d04b4fb0 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -27,7 +27,6 @@ #include "bytestream.h" #include "internal.h" #include "libopus.h" -#include "mathops.h" #include "vorbis.h" #include "audio_frame_queue.h" @@ -35,6 +34,7 @@ typedef struct LibopusEncOpts { int vbr; int application; int packet_loss; + int fec; int complexity; float frame_duration; int packet_size; @@ -150,6 +150,13 @@ static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc, "Unable to set expected packet loss percentage: %s\n", opus_strerror(ret)); + ret = opus_multistream_encoder_ctl(enc, + OPUS_SET_INBAND_FEC(opts->fec)); + if (ret != OPUS_OK) + av_log(avctx, AV_LOG_WARNING, + "Unable to set inband FEC: %s\n", + opus_strerror(ret)); + if (avctx->cutoff) { ret = opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(opts->max_bandwidth)); @@ -201,21 +208,6 @@ static int libopus_check_vorbis_layout(AVCodecContext *avctx, int mapping_family return 0; } -static int libopus_check_ambisonics_channels(AVCodecContext *avctx) { - int channels = avctx->channels; - int ambisonic_order = ff_sqrt(channels) - 1; - if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)) && - channels != ((ambisonic_order + 1) * (ambisonic_order + 1) + 2)) { - av_log(avctx, AV_LOG_ERROR, - "Ambisonics coding is only specified for channel counts" - " which can be written as (n + 1)^2 or (n + 1)^2 + 2" - " for nonnegative integer n\n"); - return AVERROR_INVALIDDATA; - } - - return 0; -} - static int libopus_validate_layout_and_get_channel_map( AVCodecContext *avctx, int mapping_family, @@ -247,12 +239,6 @@ static int libopus_validate_layout_and_get_channel_map( channel_map = ff_vorbis_channel_layout_offsets[avctx->channels - 1]; } break; - case 2: - ret = libopus_check_max_channels(avctx, 227); - if (ret == 0) { - ret = libopus_check_ambisonics_channels(avctx); - } - break; case 255: ret = libopus_check_max_channels(avctx, 254); break; @@ -525,7 +511,6 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, // Check if subtraction resulted in an overflow if ((discard_padding < opus->opts.packet_size) != (avpkt->duration > 0)) { av_packet_unref(avpkt); - av_free(avpkt); return AVERROR(EINVAL); } if (discard_padding > 0) { @@ -534,7 +519,6 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, 10); if(!side_data) { av_packet_unref(avpkt); - av_free(avpkt); return AVERROR(ENOMEM); } AV_WL32(side_data + 4, discard_padding); @@ -568,6 +552,7 @@ static const AVOption libopus_options[] = { { "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" }, { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 120.0, FLAGS }, { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, + { "fec", "Enable inband FEC. Expected packet loss must be non-zero", OFFSET(fec), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" }, { "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" }, { "on", "Use variable bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "vbr" },