framepool.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * Copyright (c) 2015 Matthieu Bouron <matthieu.bouron stupeflix.com>
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "framepool.h"
  21. #include "libavutil/avassert.h"
  22. #include "libavutil/buffer.h"
  23. #include "libavutil/frame.h"
  24. #include "libavutil/imgutils.h"
  25. #include "libavutil/mem.h"
  26. #include "libavutil/pixfmt.h"
  27. struct FFVideoFramePool {
  28. int width;
  29. int height;
  30. int format;
  31. int align;
  32. int linesize[4];
  33. AVBufferPool *pools[4];
  34. };
  35. FFVideoFramePool *ff_video_frame_pool_init(AVBufferRef* (*alloc)(int size),
  36. int width,
  37. int height,
  38. enum AVPixelFormat format,
  39. int align)
  40. {
  41. int i, ret;
  42. FFVideoFramePool *pool;
  43. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
  44. if (!desc)
  45. return NULL;
  46. pool = av_mallocz(sizeof(FFVideoFramePool));
  47. if (!pool)
  48. return NULL;
  49. pool->width = width;
  50. pool->height = height;
  51. pool->format = format;
  52. pool->align = align;
  53. if ((ret = av_image_check_size(width, height, 0, NULL)) < 0) {
  54. goto fail;
  55. }
  56. if (!pool->linesize[0]) {
  57. for(i = 1; i <= align; i += i) {
  58. ret = av_image_fill_linesizes(pool->linesize, pool->format,
  59. FFALIGN(pool->width, i));
  60. if (ret < 0) {
  61. goto fail;
  62. }
  63. if (!(pool->linesize[0] & (pool->align - 1)))
  64. break;
  65. }
  66. for (i = 0; i < 4 && pool->linesize[i]; i++) {
  67. pool->linesize[i] = FFALIGN(pool->linesize[i], pool->align);
  68. }
  69. }
  70. for (i = 0; i < 4 && pool->linesize[i]; i++) {
  71. int h = FFALIGN(pool->height, 32);
  72. if (i == 1 || i == 2)
  73. h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
  74. pool->pools[i] = av_buffer_pool_init(pool->linesize[i] * h + 16 + 16 - 1,
  75. alloc);
  76. if (!pool->pools[i])
  77. goto fail;
  78. }
  79. if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
  80. desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
  81. pool->pools[1] = av_buffer_pool_init(AVPALETTE_SIZE, alloc);
  82. if (!pool->pools[1])
  83. goto fail;
  84. }
  85. return pool;
  86. fail:
  87. ff_video_frame_pool_uninit(&pool);
  88. return NULL;
  89. }
  90. int ff_video_frame_pool_get_config(FFVideoFramePool *pool,
  91. int *width,
  92. int *height,
  93. enum AVPixelFormat *format,
  94. int *align)
  95. {
  96. if (!pool)
  97. return AVERROR(EINVAL);
  98. *width = pool->width;
  99. *height = pool->height;
  100. *format = pool->format;
  101. *align = pool->align;
  102. return 0;
  103. }
  104. AVFrame *ff_video_frame_pool_get(FFVideoFramePool *pool)
  105. {
  106. int i;
  107. AVFrame *frame;
  108. const AVPixFmtDescriptor *desc;
  109. frame = av_frame_alloc();
  110. if (!frame) {
  111. return NULL;
  112. }
  113. desc = av_pix_fmt_desc_get(pool->format);
  114. if (!desc) {
  115. goto fail;
  116. }
  117. frame->width = pool->width;
  118. frame->height = pool->height;
  119. frame->format = pool->format;
  120. for (i = 0; i < 4; i++) {
  121. frame->linesize[i] = pool->linesize[i];
  122. if (!pool->pools[i])
  123. break;
  124. frame->buf[i] = av_buffer_pool_get(pool->pools[i]);
  125. if (!frame->buf[i]) {
  126. goto fail;
  127. }
  128. frame->data[i] = frame->buf[i]->data;
  129. }
  130. if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
  131. desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
  132. enum AVPixelFormat format =
  133. pool->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : pool->format;
  134. av_assert0(frame->data[1] != NULL);
  135. if (avpriv_set_systematic_pal2((uint32_t *)frame->data[1], format) < 0) {
  136. goto fail;
  137. }
  138. }
  139. frame->extended_data = frame->data;
  140. return frame;
  141. fail:
  142. av_frame_free(&frame);
  143. return NULL;
  144. }
  145. void ff_video_frame_pool_uninit(FFVideoFramePool **pool)
  146. {
  147. int i;
  148. if (!pool || !*pool)
  149. return;
  150. for (i = 0; i < 4; i++) {
  151. av_buffer_pool_uninit(&(*pool)->pools[i]);
  152. }
  153. av_freep(pool);
  154. }