On 22/11/13 03:12, Justin Ruggles wrote:
> ---
> Changelog | 1 +
> configure | 4 +
> doc/general.texi | 4 +-
> libavcodec/Makefile | 1 +
> libavcodec/allcodecs.c | 1 +
> libavcodec/libwebpenc.c | 203
> ++++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/version.h | 2 +-
> libavformat/img2enc.c | 2 +-
> 8 files changed, 214 insertions(+), 4 deletions(-)
> create mode 100644 libavcodec/libwebpenc.c
>
> diff --git a/Changelog b/Changelog
> index 1e58a2c..79f19a1 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -48,6 +48,7 @@ version 10:
> - setsar/setdar filters now support variables in ratio expressions
> - dar variable in the scale filter now returns the actual DAR (i.e. a * sar)
> - VP9 decoder
> +- WebP encoding via libwebp
>
>
> version 9:
> diff --git a/configure b/configure
> index 05dbca7..e7f41dd 100755
> --- a/configure
> +++ b/configure
> @@ -202,6 +202,7 @@ External library support:
> --enable-libvorbis enable Vorbis encoding via libvorbis [no]
> --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no]
> --enable-libwavpack enable wavpack encoding via libwavpack [no]
> + --enable-libwebp enable WebP encoding via libwebp [no]
> --enable-libx264 enable H.264 encoding via x264 [no]
> --enable-libxavs enable AVS encoding via xavs [no]
> --enable-libxvid enable Xvid encoding via xvidcore,
> @@ -1069,6 +1070,7 @@ EXTERNAL_LIBRARY_LIST="
> libvorbis
> libvpx
> libwavpack
> + libwebp
> libx264
> libxavs
> libxvid
> @@ -1808,6 +1810,7 @@ libvpx_vp8_encoder_deps="libvpx"
> libvpx_vp9_decoder_deps="libvpx"
> libvpx_vp9_encoder_deps="libvpx"
> libwavpack_encoder_deps="libwavpack"
> +libwebp_encoder_deps="libwebp"
> libx264_encoder_deps="libx264"
> libxavs_encoder_deps="libxavs"
> libxvid_encoder_deps="libxvid"
> @@ -3837,6 +3840,7 @@ 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" -lvpx || disable libvpx_vp9_encoder; } }
> enabled libwavpack && require libwavpack wavpack/wavpack.h
> WavpackOpenFileOutput -lwavpack
> +enabled libwebp && require_pkg_config libwebp webp/encode.h
> WebPGetEncoderVersion
> enabled libx264 && require libx264 x264.h x264_encoder_encode
> -lx264 &&
> { check_cpp_condition x264.h "X264_BUILD >=
> 118" ||
> die "ERROR: libx264 version must be >=
> 0.118."; }
> diff --git a/doc/general.texi b/doc/general.texi
> index c1809e2..a1996d0 100644
> --- a/doc/general.texi
> +++ b/doc/general.texi
> @@ -415,8 +415,8 @@ following image formats are supported:
> @tab YUV, JPEG and some extension is not supported yet.
> @item Truevision Targa @tab X @tab X
> @tab Targa (.TGA) image format
> -@item WebP @tab @tab X
> - @tab WebP image format
> +@item WebP @tab E @tab X
> + @tab WebP image format, encoding supported through external library
> libwebp
> @item XBM @tab X @tab
> @tab X BitMap image format
> @item XWD @tab X @tab X
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 1674d47..6413e24 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -614,6 +614,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o
> OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o
> OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o
> OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o
> +OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc.o
> OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
> OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
> OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index 6453e30..89dc34a 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -437,6 +437,7 @@ void avcodec_register_all(void)
> REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8);
> REGISTER_ENCDEC (LIBVPX_VP9, libvpx_vp9);
> REGISTER_ENCODER(LIBWAVPACK, libwavpack);
> + REGISTER_ENCODER(LIBWEBP, libwebp);
> REGISTER_ENCODER(LIBX264, libx264);
> REGISTER_ENCODER(LIBXAVS, libxavs);
> REGISTER_ENCODER(LIBXVID, libxvid);
> diff --git a/libavcodec/libwebpenc.c b/libavcodec/libwebpenc.c
> new file mode 100644
> index 0000000..d762eb1
> --- /dev/null
> +++ b/libavcodec/libwebpenc.c
> @@ -0,0 +1,203 @@
> +/*
> + * WebP encoding support via libwebp
> + * Copyright (c) 2013 Justin Ruggles <[email protected]>
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +/**
> + * @file
> + * WebP encoder using libwebp
> + */
> +
> +#include <webp/encode.h>
> +
> +#include "libavutil/common.h"
> +#include "libavutil/opt.h"
> +#include "avcodec.h"
> +#include "internal.h"
> +
> +typedef struct {
> + AVClass *avclass; // class for AVOptions
> + int lossless; // use lossless encoding
> + float quality; // lossy quality 0 - 100
> + int method; // algorithmic complexity 0=fast to 6=slow
> + int preset; // configuration preset
> + WebPConfig config; // libwebp configuration
> +} LibWebPContext;
> +
> +static av_cold int libwebp_encode_init(AVCodecContext *avctx)
> +{
> + LibWebPContext *s = avctx->priv_data;
> + int ret;
> +
> + if (s->preset >= WEBP_PRESET_DEFAULT) {
> + ret = WebPConfigPreset(&s->config, s->preset, s->quality);
> + if (!ret)
> + return AVERROR_UNKNOWN;
ENOSYS
> + s->lossless = s->config.lossless;
> + s->quality = s->config.quality;
> + s->method = s->config.method;
> + } else {
> + ret = WebPConfigInit(&s->config);
> + if (!ret)
> + return AVERROR_UNKNOWN;
ENOMEM
> + ret = WebPPictureInit(&pic);
> + if (!ret)
> + return AVERROR_UNKNOWN;
ENOMEM
> + pic.width = avctx->width;
> + pic.height = avctx->height;
> +
> + if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
> + if (!s->lossless) {
> + av_log(avctx, AV_LOG_WARNING,
> + "Using libwebp for RGB-to-YUV conversion\n");
> + }
> + pic.use_argb = 1;
> + pic.argb = (uint32_t *)frame->data[0];
> + pic.argb_stride = frame->linesize[0] / 4;
> + } else {
> + if (avctx->pix_fmt == AV_PIX_FMT_YUV420P)
> + pic.colorspace = WEBP_YUV420;
> + else
> + pic.colorspace = WEBP_YUV420A;
> + 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];
> +
> + /* 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 here as a convenience. */
> + if (s->lossless) {
> + WebPPicture rgb_pic;
> +
> + av_log(avctx, AV_LOG_WARNING,
> + "Using libwebp for YUV-to-RGB conversion\n");
> +
> + ret = WebPPictureCopy(&pic, &rgb_pic);
> + if (!ret) {
> + av_log(avctx, AV_LOG_ERROR,
> + "WebPPictureCopy() failed with error: %d\n",
> + pic.error_code);
> + return AVERROR_UNKNOWN;
> + }
> + ret = WebPPictureYUVAToARGB(&rgb_pic);
> + if (!ret) {
> + av_log(avctx, AV_LOG_ERROR,
> + "WebPPictureYUVAToARGB() failed with error: %d\n",
> + pic.error_code);
> + return AVERROR_UNKNOWN;
> + }
> + pic = rgb_pic;
> + }
> + }
> +
> + 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",
> + pic.error_code);
> + return AVERROR_UNKNOWN;
> + }
> +
> + ret = av_new_packet(pkt, mw.size);
> + if (ret < 0)
> + return ret;
> + memcpy(pkt->data, mw.mem, mw.size);
> +
> + pkt->flags |= AV_PKT_FLAG_KEY;
> + *got_packet = 1;
> +
> + return 0;
> +}
> +
> +#define OFFSET(x) offsetof(LibWebPContext, x)
> +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
> +static const AVOption options[] = {
> + { "lossless", "Use lossless mode", OFFSET(lossless),
> AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE
> },
> + { "method", "quality/speed trade-off", OFFSET(method),
> AV_OPT_TYPE_INT, { .i64 = 4 }, 0, 6, VE
> },
> + { "quality", "lossy quality", OFFSET(quality),
> AV_OPT_TYPE_FLOAT, { .dbl = 75 }, 0, 100, VE
> },
> + { "preset", "Configuration preset", OFFSET(preset),
> AV_OPT_TYPE_INT, { .i64 = -1 }, -1, WEBP_PRESET_TEXT, VE,
> "preset" },
> + { "none", "do not use a preset", 0,
> AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "preset" },
> + { "default", "default preset", 0,
> AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_DEFAULT }, 0, 0, VE, "preset" },
> + { "picture", "digital picture, like portrait, inner shot", 0,
> AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_PICTURE }, 0, 0, VE, "preset" },
> + { "photo", "outdoor photograph, with natural lighting", 0,
> AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_PHOTO }, 0, 0, VE, "preset" },
> + { "drawing", "hand or line drawing, with high-contrast details", 0,
> AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_DRAWING }, 0, 0, VE, "preset" },
> + { "icon", "small-sized colorful images", 0,
> AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_ICON }, 0, 0, VE, "preset" },
> + { "text", "text-like", 0,
> AV_OPT_TYPE_CONST, { .i64 = WEBP_PRESET_TEXT }, 0, 0, VE, "preset" },
> + { NULL },
> +};
> +
> +static const AVClass class = {
> + .class_name = "libwebp",
> + .item_name = av_default_item_name,
> + .option = options,
> + .version = LIBAVUTIL_VERSION_INT,
> +};
> +
> +AVCodec ff_libwebp_encoder = {
> + .name = "libwebp",
> + .long_name = NULL_IF_CONFIG_SMALL("libwebp WebP image"),
> + .type = AVMEDIA_TYPE_VIDEO,
> + .id = AV_CODEC_ID_WEBP,
> + .priv_data_size = sizeof(LibWebPContext),
> + .init = libwebp_encode_init,
> + .encode2 = libwebp_encode_frame,
> + .pix_fmts = (const enum AVPixelFormat[]) {
> + AV_PIX_FMT_RGB32,
> + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
> + AV_PIX_FMT_NONE
> + },
> + .priv_class = &class,
> +};
> diff --git a/libavcodec/version.h b/libavcodec/version.h
> index c828dc8..c5a777b 100644
> --- a/libavcodec/version.h
> +++ b/libavcodec/version.h
> @@ -27,7 +27,7 @@
> */
>
> #define LIBAVCODEC_VERSION_MAJOR 55
> -#define LIBAVCODEC_VERSION_MINOR 28
> +#define LIBAVCODEC_VERSION_MINOR 29
> #define LIBAVCODEC_VERSION_MICRO 0
>
> #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
> index 7b94869..4cc5c3f 100644
> --- a/libavformat/img2enc.c
> +++ b/libavformat/img2enc.c
> @@ -148,7 +148,7 @@ AVOutputFormat ff_image2_muxer = {
> .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
> .extensions = "bmp,dpx,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
> "ppm,sgi,tga,tif,tiff,jp2,xwd,sun,ras,rs,im1,im8,im24,"
> - "sunras,xbm",
> + "sunras,webp,xbm",
> .priv_data_size = sizeof(VideoMuxData),
> .video_codec = AV_CODEC_ID_MJPEG,
> .write_header = write_header,
>
Beside those nits looks fine to me.
lu
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel