You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	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:
		
				
					committed by
					
						 Michael Niedermayer
						Michael Niedermayer
					
				
			
			
				
	
			
			
			
						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, \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user