WebP encoder: use WebPAnimEncoder API when available.
WebPAnimEncoder API is a combination of encoder (WebPEncoder) and muxer (WebPMux). It performs several optimizations to make it more efficient than the combination of WebPEncode() and native ffmpeg muxer. When WebPAnimEncoder API is used: - In the encoder layer: we use WebPAnimEncoderAdd() instead of WebPEncode(). - The muxer layer: works like a raw muxer. On the other hand, when WebPAnimEncoder API isn't available, the old code is used as it is: - In the codec layer: WebPEncode is used to encode each frame - In the muxer layer: ffmpeg muxer is used Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
ebb0ca3d70
commit
02cf59f3a6
@ -21,6 +21,7 @@ version <next>:
|
||||
- Automatically rotate videos based on metadata in ffmpeg
|
||||
- improved Quickdraw compatibility
|
||||
- VP9 high bit-depth and extended colorspaces decoding support
|
||||
- WebPAnimEncoder API when available for encoding and muxing WebP
|
||||
|
||||
|
||||
version 2.6:
|
||||
|
9
configure
vendored
9
configure
vendored
@ -1695,6 +1695,7 @@ HEADERS_LIST="
|
||||
udplite_h
|
||||
unistd_h
|
||||
valgrind_valgrind_h
|
||||
webp_mux_h
|
||||
windows_h
|
||||
winsock2_h
|
||||
"
|
||||
@ -1897,6 +1898,7 @@ CONFIG_EXTRA="
|
||||
intrax8
|
||||
jpegtables
|
||||
lgplv3
|
||||
libwebp_anim
|
||||
llauddsp
|
||||
llviddsp
|
||||
lpc
|
||||
@ -2451,6 +2453,7 @@ libvpx_vp9_decoder_deps="libvpx"
|
||||
libvpx_vp9_encoder_deps="libvpx"
|
||||
libwavpack_encoder_deps="libwavpack"
|
||||
libwebp_encoder_deps="libwebp"
|
||||
libwebp_anim_encoder_deps="libwebp"
|
||||
libx264_encoder_deps="libx264"
|
||||
libx264rgb_encoder_deps="libx264"
|
||||
libx264rgb_encoder_select="libx264_encoder"
|
||||
@ -5102,7 +5105,11 @@ 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 && {
|
||||
enabled libwebp_encoder && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion;
|
||||
enabled libwebp_anim_encoder && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion &&
|
||||
{ use_pkg_config "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit ||
|
||||
{ disable libwebp_anim_encoder && 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"; } } &&
|
||||
|
@ -784,6 +784,7 @@ OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o libvpx.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o libvpx.o
|
||||
OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o
|
||||
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o
|
||||
OBJS-$(CONFIG_LIBX265_ENCODER) += libx265.o
|
||||
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o
|
||||
|
@ -540,6 +540,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_ANIM, libwebp_anim); /* preferred over libwebp */
|
||||
REGISTER_ENCODER(LIBWEBP, libwebp);
|
||||
REGISTER_ENCODER(LIBX264, libx264);
|
||||
REGISTER_ENCODER(LIBX264RGB, libx264rgb);
|
||||
|
146
libavcodec/libwebpenc_animencoder.c
Normal file
146
libavcodec/libwebpenc_animencoder.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* WebP encoding support via libwebp
|
||||
* Copyright (c) 2015 Urvang Joshi
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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.
|
||||
*
|
||||
* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* WebP encoder using libwebp (WebPAnimEncoder API)
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libwebpenc_common.h"
|
||||
|
||||
#if HAVE_WEBP_MUX_H
|
||||
#include <webp/mux.h>
|
||||
#endif
|
||||
|
||||
typedef struct LibWebPAnimContext {
|
||||
LibWebPContextCommon cc;
|
||||
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
|
||||
} LibWebPAnimContext;
|
||||
|
||||
static av_cold int libwebp_anim_encode_init(AVCodecContext *avctx)
|
||||
{
|
||||
int ret = ff_libwebp_encode_init_common(avctx);
|
||||
if (!ret) {
|
||||
LibWebPAnimContext *s = avctx->priv_data;
|
||||
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;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int libwebp_anim_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
const AVFrame *frame, int *got_packet) {
|
||||
LibWebPAnimContext *s = avctx->priv_data;
|
||||
int ret;
|
||||
|
||||
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 {
|
||||
int timestamp_ms;
|
||||
WebPPicture *pic = NULL;
|
||||
AVFrame *alt_frame = NULL;
|
||||
ret = ff_libwebp_get_frame(avctx, &s->cc, frame, &alt_frame, &pic);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
timestamp_ms =
|
||||
avctx->time_base.num * frame->pts * 1000 / avctx->time_base.den;
|
||||
ret = WebPAnimEncoderAdd(s->enc, pic, timestamp_ms, &s->cc.config);
|
||||
if (!ret) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Encoding WebP frame failed with error: %d\n",
|
||||
pic->error_code);
|
||||
ret = ff_libwebp_error_to_averror(pic->error_code);
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkt->pts = pkt->dts = frame->pts;
|
||||
s->prev_frame_pts = frame->pts; // Save for next frame.
|
||||
ret = 0;
|
||||
*got_packet = 1;
|
||||
|
||||
end:
|
||||
WebPPictureFree(pic);
|
||||
av_freep(&pic);
|
||||
av_frame_free(&alt_frame);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static int libwebp_anim_encode_close(AVCodecContext *avctx)
|
||||
{
|
||||
int ret = ff_libwebp_encode_close_common(avctx);
|
||||
if (!ret) {
|
||||
LibWebPAnimContext *s = avctx->priv_data;
|
||||
WebPAnimEncoderDelete(s->enc);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVCodec ff_libwebp_anim_encoder = {
|
||||
.name = "libwebp_anim",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("libwebp WebP image"),
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = AV_CODEC_ID_WEBP,
|
||||
.priv_data_size = sizeof(LibWebPAnimContext),
|
||||
.init = libwebp_anim_encode_init,
|
||||
.encode2 = libwebp_anim_encode_frame,
|
||||
.close = libwebp_anim_encode_close,
|
||||
.capabilities = CODEC_CAP_DELAY,
|
||||
.pix_fmts = (const enum AVPixelFormat[]) {
|
||||
AV_PIX_FMT_RGB32,
|
||||
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
|
||||
AV_PIX_FMT_NONE
|
||||
},
|
||||
.priv_class = &class,
|
||||
.defaults = libwebp_defaults,
|
||||
};
|
@ -29,8 +29,8 @@
|
||||
#include "libavutil/version.h"
|
||||
|
||||
#define LIBAVCODEC_VERSION_MAJOR 56
|
||||
#define LIBAVCODEC_VERSION_MINOR 39
|
||||
#define LIBAVCODEC_VERSION_MICRO 101
|
||||
#define LIBAVCODEC_VERSION_MINOR 40
|
||||
#define LIBAVCODEC_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||
LIBAVCODEC_VERSION_MINOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user