You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.2KB

  1. /*
  2. * WebP encoding support via libwebp
  3. * Copyright (c) 2013 Justin Ruggles <justin.ruggles@gmail.com>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * 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. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * 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
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * WebP encoder using libwebp (WebPEncode API)
  24. */
  25. #include "libwebpenc_common.h"
  26. typedef LibWebPContextCommon LibWebPContext;
  27. static av_cold int libwebp_encode_init(AVCodecContext *avctx)
  28. {
  29. return ff_libwebp_encode_init_common(avctx);
  30. }
  31. static int libwebp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
  32. const AVFrame *frame, int *got_packet)
  33. {
  34. LibWebPContext *s = avctx->priv_data;
  35. WebPPicture *pic = NULL;
  36. AVFrame *alt_frame = NULL;
  37. WebPMemoryWriter mw = { 0 };
  38. int ret = ff_libwebp_get_frame(avctx, s, frame, &alt_frame, &pic);
  39. if (ret < 0)
  40. goto end;
  41. WebPMemoryWriterInit(&mw);
  42. pic->custom_ptr = &mw;
  43. pic->writer = WebPMemoryWrite;
  44. ret = WebPEncode(&s->config, pic);
  45. if (!ret) {
  46. av_log(avctx, AV_LOG_ERROR, "WebPEncode() failed with error: %d\n",
  47. pic->error_code);
  48. ret = ff_libwebp_error_to_averror(pic->error_code);
  49. goto end;
  50. }
  51. ret = ff_alloc_packet2(avctx, pkt, mw.size, mw.size);
  52. if (ret < 0)
  53. goto end;
  54. memcpy(pkt->data, mw.mem, mw.size);
  55. pkt->flags |= AV_PKT_FLAG_KEY;
  56. *got_packet = 1;
  57. end:
  58. #if (WEBP_ENCODER_ABI_VERSION > 0x0203)
  59. WebPMemoryWriterClear(&mw);
  60. #else
  61. free(mw.mem); /* must use free() according to libwebp documentation */
  62. #endif
  63. WebPPictureFree(pic);
  64. av_freep(&pic);
  65. av_frame_free(&alt_frame);
  66. return ret;
  67. }
  68. static int libwebp_encode_close(AVCodecContext *avctx)
  69. {
  70. LibWebPContextCommon *s = avctx->priv_data;
  71. av_frame_free(&s->ref);
  72. return 0;
  73. }
  74. static const AVClass class = {
  75. .class_name = "libwebp",
  76. .item_name = av_default_item_name,
  77. .option = options,
  78. .version = LIBAVUTIL_VERSION_INT,
  79. };
  80. AVCodec ff_libwebp_encoder = {
  81. .name = "libwebp",
  82. .long_name = NULL_IF_CONFIG_SMALL("libwebp WebP image"),
  83. .type = AVMEDIA_TYPE_VIDEO,
  84. .id = AV_CODEC_ID_WEBP,
  85. .priv_data_size = sizeof(LibWebPContext),
  86. .init = libwebp_encode_init,
  87. .encode2 = libwebp_encode_frame,
  88. .close = libwebp_encode_close,
  89. .pix_fmts = (const enum AVPixelFormat[]) {
  90. AV_PIX_FMT_RGB32,
  91. AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
  92. AV_PIX_FMT_NONE
  93. },
  94. .priv_class = &class,
  95. .defaults = libwebp_defaults,
  96. .wrapper_name = "libwebp",
  97. };