blob: d6edd866037b6e1e6a0d0a8a93416dc7320768b3 [file] [log] [blame]
Justin Rugglesbe7c3232013-11-22 16:05:131/*
2 * WebP encoding support via libwebp
3 * Copyright (c) 2013 Justin Ruggles <[email protected]>
4 *
Michael Niedermayer6fe5f772013-12-22 10:53:415 * This file is part of FFmpeg.
Justin Rugglesbe7c3232013-11-22 16:05:136 *
Michael Niedermayer6fe5f772013-12-22 10:53:417 * FFmpeg is free software; you can redistribute it and/or
Justin Rugglesbe7c3232013-11-22 16:05:138 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
Michael Niedermayer6fe5f772013-12-22 10:53:4112 * FFmpeg is distributed in the hope that it will be useful,
Justin Rugglesbe7c3232013-11-22 16:05:1313 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
Michael Niedermayer6fe5f772013-12-22 10:53:4118 * License along with FFmpeg; if not, write to the Free Software
Justin Rugglesbe7c3232013-11-22 16:05:1319 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
Urvang Joshif99fed72015-05-20 00:39:5424 * WebP encoder using libwebp (WebPEncode API)
Justin Rugglesbe7c3232013-11-22 16:05:1325 */
26
Andreas Rheinhardt20f97272022-03-16 20:09:5427#include "codec_internal.h"
Andreas Rheinhardtad26efb2021-04-24 23:43:2628#include "encode.h"
Urvang Joshif99fed72015-05-20 00:39:5429#include "libwebpenc_common.h"
Justin Rugglesbe7c3232013-11-22 16:05:1330
Urvang Joshif99fed72015-05-20 00:39:5431typedef LibWebPContextCommon LibWebPContext;
Justin Rugglesbe7c3232013-11-22 16:05:1332
33static av_cold int libwebp_encode_init(AVCodecContext *avctx)
34{
Urvang Joshif99fed72015-05-20 00:39:5435 return ff_libwebp_encode_init_common(avctx);
Justin Rugglesbe7c3232013-11-22 16:05:1336}
37
38static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
39 const AVFrame *frame, int *got_packet)
40{
41 LibWebPContext *s = avctx->priv_data;
Justin Rugglesbe7c3232013-11-22 16:05:1342 WebPPicture *pic = NULL;
Urvang Joshif99fed72015-05-20 00:39:5443 AVFrame *alt_frame = NULL;
Justin Rugglesbe7c3232013-11-22 16:05:1344 WebPMemoryWriter mw = { 0 };
Justin Rugglesbe7c3232013-11-22 16:05:1345
Urvang Joshif99fed72015-05-20 00:39:5446 int ret = ff_libwebp_get_frame(avctx, s, frame, &alt_frame, &pic);
47 if (ret < 0)
Justin Rugglesbe7c3232013-11-22 16:05:1348 goto end;
Justin Rugglesbe7c3232013-11-22 16:05:1349
50 WebPMemoryWriterInit(&mw);
51 pic->custom_ptr = &mw;
52 pic->writer = WebPMemoryWrite;
53
54 ret = WebPEncode(&s->config, pic);
55 if (!ret) {
56 av_log(avctx, AV_LOG_ERROR, "WebPEncode() failed with error: %d\n",
57 pic->error_code);
Urvang Joshif99fed72015-05-20 00:39:5458 ret = ff_libwebp_error_to_averror(pic->error_code);
Justin Rugglesbe7c3232013-11-22 16:05:1359 goto end;
60 }
61
Andreas Rheinhardtad26efb2021-04-24 23:43:2662 ret = ff_get_encode_buffer(avctx, pkt, mw.size, 0);
Justin Rugglesbe7c3232013-11-22 16:05:1363 if (ret < 0)
64 goto end;
65 memcpy(pkt->data, mw.mem, mw.size);
66
Justin Rugglesbe7c3232013-11-22 16:05:1367 *got_packet = 1;
68
69end:
James Almer7997d782014-08-27 18:39:5070#if (WEBP_ENCODER_ABI_VERSION > 0x0203)
71 WebPMemoryWriterClear(&mw);
72#else
Justin Rugglesbe7c3232013-11-22 16:05:1373 free(mw.mem); /* must use free() according to libwebp documentation */
James Almer7997d782014-08-27 18:39:5074#endif
Justin Rugglesbe7c3232013-11-22 16:05:1375 WebPPictureFree(pic);
76 av_freep(&pic);
77 av_frame_free(&alt_frame);
78
79 return ret;
80}
81
Michael Niedermayer5aaf5df2014-10-31 15:39:5682static int libwebp_encode_close(AVCodecContext *avctx)
83{
James Almer89522542015-05-23 17:24:3484 LibWebPContextCommon *s = avctx->priv_data;
85 av_frame_free(&s->ref);
86
87 return 0;
Michael Niedermayer5aaf5df2014-10-31 15:39:5688}
89
Andreas Rheinhardt20f97272022-03-16 20:09:5490const FFCodec ff_libwebp_encoder = {
91 .p.name = "libwebp",
Andreas Rheinhardt48286d42022-08-29 11:38:0292 CODEC_LONG_NAME("libwebp WebP image"),
Andreas Rheinhardt20f97272022-03-16 20:09:5493 .p.type = AVMEDIA_TYPE_VIDEO,
94 .p.id = AV_CODEC_ID_WEBP,
Anton Khirnov8d73f3c2022-11-27 12:37:1095 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
Andreas Rheinhardt20f97272022-03-16 20:09:5496 .p.pix_fmts = ff_libwebpenc_pix_fmts,
97 .p.priv_class = &ff_libwebpenc_class,
98 .p.wrapper_name = "libwebp",
Andreas Rheinhardt6aad1202022-07-09 20:25:4199 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
Justin Rugglesbe7c3232013-11-22 16:05:13100 .priv_data_size = sizeof(LibWebPContext),
Andreas Rheinhardt19d80772021-06-08 23:33:39101 .defaults = ff_libwebp_defaults,
Justin Rugglesbe7c3232013-11-22 16:05:13102 .init = libwebp_encode_init,
Andreas Rheinhardt4243da42022-03-30 21:28:24103 FF_CODEC_ENCODE_CB(libwebp_encode_frame),
Michael Niedermayer5aaf5df2014-10-31 15:39:56104 .close = libwebp_encode_close,
Justin Rugglesbe7c3232013-11-22 16:05:13105};