X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Flibopusenc.c;h=c642037aac4019f72a11eb33654a937f902a50c0;hb=1c7f252783aec37e4ff8049476386f63afe91756;hp=7c025a66d7778200069cef54ed6914eb12313a32;hpb=762c2b5dcd99a08452299cd1f83070f88115f1f3;p=ffmpeg diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 7c025a66d77..c642037aac4 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -34,6 +34,7 @@ typedef struct LibopusEncOpts { int vbr; int application; int packet_loss; + int fec; int complexity; float frame_duration; int packet_size; @@ -93,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. */ @@ -149,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)); @@ -424,7 +432,6 @@ static av_cold int libopus_encode_init(AVCodecContext *avctx) fail: opus_multistream_encoder_destroy(enc); - av_freep(&avctx->extradata); return ret; } @@ -503,7 +510,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) { @@ -512,7 +518,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); @@ -532,7 +537,6 @@ static av_cold int libopus_encode_close(AVCodecContext *avctx) ff_af_queue_close(&opus->afq); av_freep(&opus->samples); - av_freep(&avctx->extradata); return 0; } @@ -546,6 +550,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" }, @@ -574,7 +579,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,