]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/libopusenc.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / libopusenc.c
index 50d843ebc5489361efe4d1d4a18e588db31907c8..8c99b26ddf85fab48dd523cb92f9e1cce391347b 100644 (file)
@@ -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;
@@ -94,7 +94,7 @@ static void libopus_write_header(AVCodecContext *avctx, int stream_count,
     bytestream_put_buffer(&p, "OpusHead", 8);
     bytestream_put_byte(&p, 1); /* Version */
     bytestream_put_byte(&p, channels);
-    bytestream_put_le16(&p, avctx->initial_padding); /* Lookahead samples at 48kHz */
+    bytestream_put_le16(&p, avctx->initial_padding * 48000 / avctx->sample_rate); /* Lookahead samples at 48kHz */
     bytestream_put_le32(&p, avctx->sample_rate); /* Original sample rate */
     bytestream_put_le16(&p, 0); /* Gain of 0dB is recommended. */
 
@@ -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" },
@@ -596,7 +581,7 @@ static const int libopus_sample_rates[] = {
     48000, 24000, 16000, 12000, 8000, 0,
 };
 
-AVCodec ff_libopus_encoder = {
+const AVCodec ff_libopus_encoder = {
     .name            = "libopus",
     .long_name       = NULL_IF_CONFIG_SMALL("libopus Opus"),
     .type            = AVMEDIA_TYPE_AUDIO,