Hi,

$subject

$attached says:
------------------------------------------------------------------------
This API is available at head (MUX_ABI_VERSION >= 0x0104), is stable,
 and will be made official in future release.
For compatibility, the previous code is left as fallback.

Dont' forget to use --enable-libwebp as ./configure option.

This new code handles video, so that something like
   ffmpeg -i video.mp4 -y anim.webp
should just work.

-loop option is also supported.
------------------------------------------------------------------------

Comments welcome!
skal/
From dcad4a82df4d0e63f187e51c858038ea4508e4b6 Mon Sep 17 00:00:00 2001
From: Urvang Joshi <urv...@google.com>
Date: Fri, 27 Mar 2015 10:42:57 +0100
Subject: [PATCH] use WebPAnimEncoder API to generate animated WebP

This API is available at head (MUX_ABI_VERSION >= 0x0104), is stable,
 and will be made official in future release.
For compatibility, the previous code is left as fallback.

Dont' forget to use --enable-libwebp as ./configure option.

This new code handles video, so that something like
   ffmpeg -i video.mp4 -y anim.webp
should just work.

-loop option is also supported.
---
 configure               |   4 +-
 libavcodec/libwebpenc.c | 399 +++++++++++++++++++++++++++++-------------------
 libavformat/webpenc.c   |  41 ++++-
 3 files changed, 281 insertions(+), 163 deletions(-)

diff --git a/configure b/configure
index a96bfb7..4843079 100755
--- a/configure
+++ b/configure
@@ -4985,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.3.0" webp/mux.h WebPGetMuxVersion ||
+                               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..0726d1f 100644
--- a/libavcodec/libwebpenc.c
+++ b/libavcodec/libwebpenc.c
@@ -26,6 +26,13 @@
 
 #include <webp/encode.h>
 
+#if (WEBP_ENCODER_ABI_VERSION >= 0x0206)
+#include <webp/mux.h>
+#if (WEBP_MUX_ABI_VERSION >= 0x0104)
+#define USE_WEBP_ANIMENCODER
+#endif
+#endif
+
 #include "libavutil/common.h"
 #include "libavutil/frame.h"
 #include "libavutil/imgutils.h"
@@ -44,6 +51,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 +108,20 @@ 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);
+      // Ensures 'pts - prev_frame_pts' works correctly for first frame, too.
+      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,100 +133,114 @@ static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                 const AVFrame *frame, int *got_packet)
 {
     LibWebPContext *s  = avctx->priv_data;
-    AVFrame *alt_frame = NULL;
-    WebPPicture *pic = NULL;
-    WebPMemoryWriter mw = { 0 };
     int ret;
 
-    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",
-               WEBP_MAX_DIMENSION, WEBP_MAX_DIMENSION);
-        return AVERROR(EINVAL);
-    }
-
-    pic = av_malloc(sizeof(*pic));
-    if (!pic)
-        return AVERROR(ENOMEM);
-
-    ret = WebPPictureInit(pic);
-    if (!ret) {
-        ret = AVERROR_UNKNOWN;
-        goto end;
-    }
-    pic->width  = avctx->width;
-    pic->height = avctx->height;
-
-    if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
-        if (!s->lossless) {
-            /* libwebp will automatically convert RGB input to YUV when
-               encoding lossy. */
-            if (!s->conversion_warning) {
-                av_log(avctx, AV_LOG_WARNING,
-                       "Using libwebp for RGB-to-YUV conversion. You may want "
-                       "to consider passing in YUV instead for lossy "
-                       "encoding.\n");
-                s->conversion_warning = 1;
+#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);
             }
         }
-        pic->use_argb    = 1;
-        pic->argb        = (uint32_t *)frame->data[0];
-        pic->argb_stride = frame->linesize[0] / 4;
     } else {
-        if (frame->linesize[1] != frame->linesize[2] || s->cr_threshold) {
-            if (!s->chroma_warning && !s->cr_threshold) {
-                av_log(avctx, AV_LOG_WARNING,
-                       "Copying frame due to differing chroma linesizes.\n");
-                s->chroma_warning = 1;
-            }
-            alt_frame = av_frame_alloc();
-            if (!alt_frame) {
-                ret = AVERROR(ENOMEM);
-                goto end;
+#endif
+        AVFrame *alt_frame = NULL;
+        WebPPicture *pic = NULL;
+#ifndef USE_WEBP_ANIMENCODER
+        WebPMemoryWriter mw = { 0 };
+#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",
+                   WEBP_MAX_DIMENSION, WEBP_MAX_DIMENSION);
+            return AVERROR(EINVAL);
+        }
+
+        pic = av_malloc(sizeof(*pic));
+        if (!pic)
+            return AVERROR(ENOMEM);
+
+        ret = WebPPictureInit(pic);
+        if (!ret) {
+            ret = AVERROR_UNKNOWN;
+            goto end;
+        }
+        pic->width  = avctx->width;
+        pic->height = avctx->height;
+
+        if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
+            if (!s->lossless) {
+                /* libwebp will automatically convert RGB input to YUV when
+                   encoding lossy. */
+                if (!s->conversion_warning) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "Using libwebp for RGB-to-YUV conversion. You may want "
+                           "to consider passing in YUV instead for lossy "
+                           "encoding.\n");
+                    s->conversion_warning = 1;
+                }
             }
-            alt_frame->width  = frame->width;
-            alt_frame->height = frame->height;
-            alt_frame->format = frame->format;
-            if (s->cr_threshold)
-                alt_frame->format = AV_PIX_FMT_YUVA420P;
-            ret = av_frame_get_buffer(alt_frame, 32);
-            if (ret < 0)
-                goto end;
-            alt_frame->format = frame->format;
-            av_frame_copy(alt_frame, frame);
-            frame = alt_frame;
-            if (s->cr_threshold) {
-                int x,y, x2, y2, p;
-                int bs = s->cr_size;
-
-                if (!s->ref) {
-                    s->ref = av_frame_clone(frame);
-                    if (!s->ref) {
-                        ret = AVERROR(ENOMEM);
-                        goto end;
-                    }
+            pic->use_argb    = 1;
+            pic->argb        = (uint32_t *)frame->data[0];
+            pic->argb_stride = frame->linesize[0] / 4;
+        } else {
+            if (frame->linesize[1] != frame->linesize[2] || s->cr_threshold) {
+                if (!s->chroma_warning && !s->cr_threshold) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "Copying frame due to differing chroma linesizes.\n");
+                    s->chroma_warning = 1;
+                }
+                alt_frame = av_frame_alloc();
+                if (!alt_frame) {
+                    ret = AVERROR(ENOMEM);
+                    goto end;
                 }
+                alt_frame->width  = frame->width;
+                alt_frame->height = frame->height;
+                alt_frame->format = frame->format;
+                if (s->cr_threshold)
+                    alt_frame->format = AV_PIX_FMT_YUVA420P;
+                ret = av_frame_get_buffer(alt_frame, 32);
+                if (ret < 0)
+                    goto end;
+                alt_frame->format = frame->format;
+                av_frame_copy(alt_frame, frame);
+                frame = alt_frame;
+                if (s->cr_threshold) {
+                    int x,y, x2, y2, p;
+                    int bs = s->cr_size;
 
-                alt_frame->format = AV_PIX_FMT_YUVA420P;
-                for (y = 0; y < frame->height; y+= bs) {
-                    for (x = 0; x < frame->width; x+= bs) {
-                        int skip;
-                        int sse = 0;
-                        for (p = 0; p < 3; p++) {
-                            int bs2 = bs >> !!p;
-                            int w = FF_CEIL_RSHIFT(frame->width , !!p);
-                            int h = FF_CEIL_RSHIFT(frame->height, !!p);
-                            int xs = x >> !!p;
-                            int ys = y >> !!p;
-                            for (y2 = ys; y2 < FFMIN(ys + bs2, h); y2++) {
-                                for (x2 = xs; x2 < FFMIN(xs + bs2, w); x2++) {
-                                    int diff =  frame->data[p][frame->linesize[p] * y2 + x2]
-                                              -s->ref->data[p][frame->linesize[p] * y2 + x2];
-                                    sse += diff*diff;
-                                }
-                            }
+                    if (!s->ref) {
+                        s->ref = av_frame_clone(frame);
+                        if (!s->ref) {
+                            ret = AVERROR(ENOMEM);
+                            goto end;
                         }
-                        skip = sse < s->cr_threshold && frame->data[3] != s->ref->data[3];
-                        if (!skip)
+                    }
+
+                    alt_frame->format = AV_PIX_FMT_YUVA420P;
+                    for (y = 0; y < frame->height; y+= bs) {
+                        for (x = 0; x < frame->width; x+= bs) {
+                            int skip;
+                            int sse = 0;
                             for (p = 0; p < 3; p++) {
                                 int bs2 = bs >> !!p;
                                 int w = FF_CEIL_RSHIFT(frame->width , !!p);
@@ -208,107 +248,141 @@ static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                 int xs = x >> !!p;
                                 int ys = y >> !!p;
                                 for (y2 = ys; y2 < FFMIN(ys + bs2, h); y2++) {
-                                    memcpy(&s->ref->data[p][frame->linesize[p] * y2 + xs],
-                                            & frame->data[p][frame->linesize[p] * y2 + xs], FFMIN(bs2, w-xs));
+                                    for (x2 = xs; x2 < FFMIN(xs + bs2, w); x2++) {
+                                        int diff =  frame->data[p][frame->linesize[p] * y2 + x2]
+                                                  -s->ref->data[p][frame->linesize[p] * y2 + x2];
+                                        sse += diff*diff;
+                                    }
+                                }
+                            }
+                            skip = sse < s->cr_threshold && frame->data[3] != s->ref->data[3];
+                            if (!skip)
+                                for (p = 0; p < 3; p++) {
+                                    int bs2 = bs >> !!p;
+                                    int w = FF_CEIL_RSHIFT(frame->width , !!p);
+                                    int h = FF_CEIL_RSHIFT(frame->height, !!p);
+                                    int xs = x >> !!p;
+                                    int ys = y >> !!p;
+                                    for (y2 = ys; y2 < FFMIN(ys + bs2, h); y2++) {
+                                        memcpy(&s->ref->data[p][frame->linesize[p] * y2 + xs],
+                                                & frame->data[p][frame->linesize[p] * y2 + xs], FFMIN(bs2, w-xs));
+                                    }
                                 }
+                            for (y2 = y; y2 < FFMIN(y+bs, frame->height); y2++) {
+                                memset(&frame->data[3][frame->linesize[3] * y2 + x],
+                                        skip ? 0 : 255,
+                                        FFMIN(bs, frame->width-x));
                             }
-                        for (y2 = y; y2 < FFMIN(y+bs, frame->height); y2++) {
-                            memset(&frame->data[3][frame->linesize[3] * y2 + x],
-                                    skip ? 0 : 255,
-                                    FFMIN(bs, frame->width-x));
                         }
                     }
                 }
             }
-        }
-
-        pic->use_argb  = 0;
-        pic->y         = frame->data[0];
-        pic->u         = frame->data[1];
-        pic->v         = frame->data[2];
-        pic->y_stride  = frame->linesize[0];
-        pic->uv_stride = frame->linesize[1];
-        if (frame->format == AV_PIX_FMT_YUVA420P) {
-            pic->colorspace = WEBP_YUV420A;
-            pic->a          = frame->data[3];
-            pic->a_stride   = frame->linesize[3];
-            if (alt_frame)
-                WebPCleanupTransparentArea(pic);
-        } else {
-            pic->colorspace = WEBP_YUV420;
-        }
 
-        if (s->lossless) {
-            /* We do not have a way to automatically prioritize RGB over YUV
-               in automatic pixel format conversion based on whether we're
-               encoding lossless or lossy, so we do conversion with libwebp as
-               a convenience. */
-            if (!s->conversion_warning) {
-                av_log(avctx, AV_LOG_WARNING,
-                       "Using libwebp for YUV-to-RGB conversion. You may want "
-                       "to consider passing in RGB instead for lossless "
-                       "encoding.\n");
-                s->conversion_warning = 1;
+            pic->use_argb  = 0;
+            pic->y         = frame->data[0];
+            pic->u         = frame->data[1];
+            pic->v         = frame->data[2];
+            pic->y_stride  = frame->linesize[0];
+            pic->uv_stride = frame->linesize[1];
+            if (frame->format == AV_PIX_FMT_YUVA420P) {
+                pic->colorspace = WEBP_YUV420A;
+                pic->a          = frame->data[3];
+                pic->a_stride   = frame->linesize[3];
+                if (alt_frame)
+                    WebPCleanupTransparentArea(pic);
+            } else {
+                pic->colorspace = WEBP_YUV420;
             }
 
+            if (s->lossless) {
+                /* We do not have a way to automatically prioritize RGB over YUV
+                   in automatic pixel format conversion based on whether we're
+                   encoding lossless or lossy, so we do conversion with libwebp as
+                   a convenience. */
+                if (!s->conversion_warning) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "Using libwebp for YUV-to-RGB conversion. You may want "
+                           "to consider passing in RGB instead for lossless "
+                           "encoding.\n");
+                    s->conversion_warning = 1;
+                }
+
 #if (WEBP_ENCODER_ABI_VERSION <= 0x201)
-            /* libwebp should do the conversion automatically, but there is a
-               bug that causes it to return an error instead, so a work-around
-               is required.
-               See https://code.google.com/p/webp/issues/detail?id=178 */
-            pic->memory_ = (void*)1;  /* something non-null */
-            ret = WebPPictureYUVAToARGB(pic);
-            if (!ret) {
-                av_log(avctx, AV_LOG_ERROR,
-                       "WebPPictureYUVAToARGB() failed with error: %d\n",
-                       pic->error_code);
-                ret = libwebp_error_to_averror(pic->error_code);
-                goto end;
+                /* libwebp should do the conversion automatically, but there is a
+                   bug that causes it to return an error instead, so a work-around
+                   is required.
+                   See https://code.google.com/p/webp/issues/detail?id=178 */
+                pic->memory_ = (void*)1;  /* something non-null */
+                ret = WebPPictureYUVAToARGB(pic);
+                if (!ret) {
+                    av_log(avctx, AV_LOG_ERROR,
+                           "WebPPictureYUVAToARGB() failed with error: %d\n",
+                           pic->error_code);
+                    ret = libwebp_error_to_averror(pic->error_code);
+                    goto end;
+                }
+                pic->memory_ = NULL;  /* restore pointer */
+#endif
             }
-            pic->memory_ = NULL;  /* restore pointer */
+        }
+#ifdef USE_WEBP_ANIMENCODER
+        {
+            const int pts_diff = frame->pts - s->prev_frame_pts;
+            const int duration =
+                avctx->time_base.num * pts_diff * 1000 / avctx->time_base.den;
+            ret = WebPAnimEncoderAdd(s->enc, pic, duration, &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,
+                   "Encoding WebP frame failed with error: %d\n",
+                   pic->error_code);
+            ret = libwebp_error_to_averror(pic->error_code);
+            goto end;
         }
-    }
-
-    WebPMemoryWriterInit(&mw);
-    pic->custom_ptr = &mw;
-    pic->writer     = WebPMemoryWrite;
-
-    ret = WebPEncode(&s->config, pic);
-    if (!ret) {
-        av_log(avctx, AV_LOG_ERROR, "WebPEncode() failed with error: %d\n",
-               pic->error_code);
-        ret = libwebp_error_to_averror(pic->error_code);
-        goto end;
-    }
 
-    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;
-    *got_packet = 1;
+#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);
+        WebPMemoryWriterClear(&mw);
 #else
-    free(mw.mem); /* must use free() according to libwebp documentation */
+        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
-    WebPPictureFree(pic);
-    av_freep(&pic);
-    av_frame_free(&alt_frame);
-
-    return ret;
 }
 
 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..d4411a9 100644
--- a/libavformat/webpenc.c
+++ b/libavformat/webpenc.c
@@ -24,10 +24,20 @@
 #include "avformat.h"
 #include "internal.h"
 
+#include <webp/encode.h>
+#if (WEBP_ENCODER_ABI_VERSION >= 0x0206)
+#include <webp/mux.h>
+#if (WEBP_MUX_ABI_VERSION >= 0x0104)
+#define USE_WEBP_ANIMENCODER
+#endif
+#endif
+
 typedef struct WebpContext{
     AVClass *class;
     int frame_count;
+#ifndef USE_WEBP_ANIMENCODER
     AVPacket last_pkt;
+#endif
     int loop;
 } WebpContext;
 
@@ -44,13 +54,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 +178,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[] = {
-- 
2.2.0.rc0.207.ga3a616c

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to