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.

103 lines
3.0KB

  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_packet(pkt, 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. return ff_libwebp_encode_close_common(avctx);
  71. }
  72. AVCodec ff_libwebp_encoder = {
  73. .name = "libwebp",
  74. .long_name = NULL_IF_CONFIG_SMALL("libwebp WebP image"),
  75. .type = AVMEDIA_TYPE_VIDEO,
  76. .id = AV_CODEC_ID_WEBP,
  77. .priv_data_size = sizeof(LibWebPContext),
  78. .init = libwebp_encode_init,
  79. .encode2 = libwebp_encode_frame,
  80. .close = libwebp_encode_close,
  81. .pix_fmts = (const enum AVPixelFormat[]) {
  82. AV_PIX_FMT_RGB32,
  83. AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P,
  84. AV_PIX_FMT_NONE
  85. },
  86. .priv_class = &class,
  87. .defaults = libwebp_defaults,
  88. };