diff --git a/configure b/configure
index ede517e..86ed118 100755
--- a/configure
+++ b/configure
@@ -1677,6 +1677,7 @@ HEADERS_LIST="
     termios_h
     udplite_h
     unistd_h
+    webp_mux_h
     windows_h
     winsock2_h
 "
@@ -4984,7 +4985,9 @@ enabled libvpx            && {
     enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; }
     enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VP9E_SET_AQ_MODE" -lvpx || disable libvpx_vp9_encoder; } }
 enabled libwavpack        && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput  -lwavpack
-enabled libwebp           && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
+enabled libwebp           && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion &&
+                             { use_pkg_config "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit ||
+                               warn "using libwebp without libwebpmux"; }
 enabled libx264           && { use_pkg_config x264 "stdint.h x264.h" x264_encoder_encode ||
                                { require libx264 x264.h x264_encoder_encode -lx264 &&
                                  warn "using libx264 without pkg-config"; } } &&
diff --git a/libavcodec/libwebpenc.c b/libavcodec/libwebpenc.c
index 95d56ac..68959a3 100644
--- a/libavcodec/libwebpenc.c
+++ b/libavcodec/libwebpenc.c
@@ -24,8 +24,17 @@
  * WebP encoder using libwebp
  */
 
+#include "config.h"
+
 #include <webp/encode.h>
 
+#if HAVE_WEBP_MUX_H
+#include <webp/mux.h>
+#if (WEBP_MUX_ABI_VERSION >= 0x0105)
+#define USE_WEBP_ANIMENCODER
+#endif
+#endif
+
 #include "libavutil/common.h"
 #include "libavutil/frame.h"
 #include "libavutil/imgutils.h"
@@ -44,6 +53,11 @@ typedef struct LibWebPContext {
     AVFrame *ref;
     int cr_size;
     int cr_threshold;
+#ifdef USE_WEBP_ANIMENCODER
+    WebPAnimEncoder *enc;   // the main AnimEncoder object
+    int64_t prev_frame_pts; // pts of the previously encoded frame.
+    int done;               // If true, we have assembled the bitstream already
+#endif
 } LibWebPContext;
 
 static int libwebp_error_to_averror(int err)
@@ -96,6 +110,19 @@ static av_cold int libwebp_encode_init(AVCodecContext *avctx)
             return AVERROR(EINVAL);
     }
 
+#ifdef USE_WEBP_ANIMENCODER
+    {
+      WebPAnimEncoderOptions enc_options;
+      WebPAnimEncoderOptionsInit(&enc_options);
+      // TODO(urvang): Expose some options on command-line perhaps.
+      s->enc = WebPAnimEncoderNew(avctx->width, avctx->height, &enc_options);
+      if (!s->enc)
+          return AVERROR(EINVAL);
+      s->prev_frame_pts = -1;
+      s->done = 0;
+    }
+#endif
+
     av_log(avctx, AV_LOG_DEBUG, "%s - quality=%.1f method=%d\n",
            s->lossless ? "Lossless" : "Lossy", s->quality,
            avctx->compression_level);
@@ -107,10 +134,40 @@ static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                 const AVFrame *frame, int *got_packet)
 {
     LibWebPContext *s  = avctx->priv_data;
+    int ret;
+
+#ifdef USE_WEBP_ANIMENCODER
+    if (!frame) {
+        if (s->done) {  // Second flush: return empty package to denote finish.
+            *got_packet = 0;
+            return 0;
+        } else {  // First flush: assemble bitstream and return it.
+            WebPData assembled_data = { 0 };
+            ret = WebPAnimEncoderAssemble(s->enc, &assembled_data);
+            if (ret) {
+                ret = ff_alloc_packet(pkt, assembled_data.size);
+                if (ret < 0)
+                    return ret;
+                memcpy(pkt->data, assembled_data.bytes, assembled_data.size);
+                s->done = 1;
+                pkt->flags |= AV_PKT_FLAG_KEY;
+                pkt->pts = pkt->dts = s->prev_frame_pts + 1;
+                *got_packet = 1;
+                return 0;
+            } else {
+                av_log(s, AV_LOG_ERROR,
+                       "WebPAnimEncoderAssemble() failed with error: %d\n",
+                       VP8_ENC_ERROR_OUT_OF_MEMORY);
+                return AVERROR(ENOMEM);
+            }
+        }
+    } else {
+#endif
         AVFrame *alt_frame = NULL;
         WebPPicture *pic = NULL;
+#ifndef USE_WEBP_ANIMENCODER
         WebPMemoryWriter mw = { 0 };
-    int ret;
+#endif
 
         if (avctx->width > WEBP_MAX_DIMENSION || avctx->height > WEBP_MAX_DIMENSION) {
             av_log(avctx, AV_LOG_ERROR, "Picture size is too large. Max is %dx%d.\n",
@@ -269,46 +326,63 @@ static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 #endif
             }
         }
-
+#ifdef USE_WEBP_ANIMENCODER
+        {
+            const int timestamp_ms =
+                avctx->time_base.num * frame->pts * 1000 / avctx->time_base.den;
+            ret = WebPAnimEncoderAdd(s->enc, pic, timestamp_ms, &s->config);
+        }
+#else
         WebPMemoryWriterInit(&mw);
         pic->custom_ptr = &mw;
         pic->writer     = WebPMemoryWrite;
-
         ret = WebPEncode(&s->config, pic);
+#endif
         if (!ret) {
-        av_log(avctx, AV_LOG_ERROR, "WebPEncode() failed with error: %d\n",
+            av_log(avctx, AV_LOG_ERROR,
+                   "Encoding WebP frame failed with error: %d\n",
                    pic->error_code);
             ret = libwebp_error_to_averror(pic->error_code);
             goto end;
         }
 
+#ifdef USE_WEBP_ANIMENCODER
+        pkt->pts = pkt->dts = frame->pts;
+        s->prev_frame_pts = frame->pts;  // Save for next frame.
+        ret = 0;
+#else
         ret = ff_alloc_packet(pkt, mw.size);
         if (ret < 0)
             goto end;
         memcpy(pkt->data, mw.mem, mw.size);
-
         pkt->flags |= AV_PKT_FLAG_KEY;
+#endif
         *got_packet = 1;
 
 end:
+#ifndef USE_WEBP_ANIMENCODER
 #if (WEBP_ENCODER_ABI_VERSION > 0x0203)
         WebPMemoryWriterClear(&mw);
 #else
         free(mw.mem); /* must use free() according to libwebp documentation */
 #endif
+#endif
         WebPPictureFree(pic);
         av_freep(&pic);
         av_frame_free(&alt_frame);
-
         return ret;
+#ifdef USE_WEBP_ANIMENCODER
+    }
+#endif
 }
 
 static int libwebp_encode_close(AVCodecContext *avctx)
 {
     LibWebPContext *s  = avctx->priv_data;
-
+#ifdef USE_WEBP_ANIMENCODER
+    WebPAnimEncoderDelete(s->enc);
+#endif
     av_frame_free(&s->ref);
-
     return 0;
 }
 
@@ -353,6 +427,9 @@ AVCodec ff_libwebp_encoder = {
     .init           = libwebp_encode_init,
     .encode2        = libwebp_encode_frame,
     .close          = libwebp_encode_close,
+#ifdef USE_WEBP_ANIMENCODER
+    .capabilities   = CODEC_CAP_DELAY,
+#endif
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB32,
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
diff --git a/libavformat/webpenc.c b/libavformat/webpenc.c
index ee110de..0162eff 100644
--- a/libavformat/webpenc.c
+++ b/libavformat/webpenc.c
@@ -22,12 +22,25 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
+#include "config.h"
 #include "internal.h"
 
+#if CONFIG_LIBWEBP
+#include <webp/encode.h>
+#if HAVE_WEBP_MUX_H
+#include <webp/mux.h>
+#if (WEBP_MUX_ABI_VERSION >= 0x0105)
+#define USE_WEBP_ANIMENCODER
+#endif
+#endif
+#endif
+
 typedef struct WebpContext{
     AVClass *class;
     int frame_count;
+#ifndef USE_WEBP_ANIMENCODER
     AVPacket last_pkt;
+#endif
     int loop;
 } WebpContext;
 
@@ -44,13 +57,40 @@ static int webp_write_header(AVFormatContext *s)
         av_log(s, AV_LOG_ERROR, "Only WebP is supported\n");
         return AVERROR(EINVAL);
     }
-    avpriv_set_pts_info(st, 24, 1, 1000);
 
+#ifndef USE_WEBP_ANIMENCODER
+    avpriv_set_pts_info(st, 24, 1, 1000);
     avio_write(s->pb, "RIFF\0\0\0\0WEBP", 12);
+#endif
+
+    return 0;
+}
 
+#ifdef USE_WEBP_ANIMENCODER
+
+static int webp_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    if (pkt->size) {
+        avio_write(s->pb, pkt->data, pkt->size);
+    } else {
+        WebpContext *w = s->priv_data;
+        ++w->frame_count;
+    }
     return 0;
 }
 
+static int webp_write_trailer(AVFormatContext *s)
+{
+    WebpContext *w = s->priv_data;
+    if (w->frame_count > 1 && w->loop != 0) {  // Write loop count.
+        avio_seek(s->pb, 42, SEEK_SET);
+        avio_wl16(s->pb, w->loop);
+    }
+    return 0;
+}
+
+#else
+
 static int flush(AVFormatContext *s, int trailer, int64_t pts)
 {
     WebpContext *w = s->priv_data;
@@ -141,6 +181,8 @@ static int webp_write_trailer(AVFormatContext *s)
     return 0;
 }
 
+#endif
+
 #define OFFSET(x) offsetof(WebpContext, x)
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
