framepool.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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/avutil.h"
  23. #include "libavutil/buffer.h"
  24. #include "libavutil/frame.h"
  25. #include "libavutil/imgutils.h"
  26. #include "libavutil/mem.h"
  27. #include "libavutil/pixfmt.h"
  28. struct FFFramePool {
  29. enum AVMediaType type;
  30. /* video */
  31. int width;
  32. int height;
  33. /* audio */
  34. int planes;
  35. int channels;
  36. int nb_samples;
  37. /* common */
  38. int format;
  39. int align;
  40. int linesize[4];
  41. AVBufferPool *pools[4];
  42. };
  43. FFFramePool *ff_frame_pool_video_init(AVBufferRef* (*alloc)(int size),
  44. int width,
  45. int height,
  46. enum AVPixelFormat format,
  47. int align)
  48. {
  49. int i, ret;
  50. FFFramePool *pool;
  51. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
  52. if (!desc)
  53. return NULL;
  54. pool = av_mallocz(sizeof(FFFramePool));
  55. if (!pool)
  56. return NULL;
  57. pool->type = AVMEDIA_TYPE_VIDEO;
  58. pool->width = width;
  59. pool->height = height;
  60. pool->format = format;
  61. pool->align = align;
  62. if ((ret = av_image_check_size2(width, height, INT64_MAX, format, 0, NULL)) < 0) {
  63. goto fail;
  64. }
  65. if (!pool->linesize[0]) {
  66. for(i = 1; i <= align; i += i) {
  67. ret = av_image_fill_linesizes(pool->linesize, pool->format,
  68. FFALIGN(pool->width, i));
  69. if (ret < 0) {
  70. goto fail;
  71. }
  72. if (!(pool->linesize[0] & (pool->align - 1)))
  73. break;
  74. }
  75. for (i = 0; i < 4 && pool->linesize[i]; i++) {
  76. pool->linesize[i] = FFALIGN(pool->linesize[i], pool->align);
  77. }
  78. }
  79. for (i = 0; i < 4 && pool->linesize[i]; i++) {
  80. int h = FFALIGN(pool->height, 32);
  81. if (i == 1 || i == 2)
  82. h = AV_CEIL_RSHIFT(h, desc->log2_chroma_h);
  83. pool->pools[i] = av_buffer_pool_init(pool->linesize[i] * h + 16 + 16 - 1,
  84. alloc);
  85. if (!pool->pools[i])
  86. goto fail;
  87. }
  88. if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
  89. desc->flags & FF_PSEUDOPAL) {
  90. pool->pools[1] = av_buffer_pool_init(AVPALETTE_SIZE, alloc);
  91. if (!pool->pools[1])
  92. goto fail;
  93. }
  94. return pool;
  95. fail:
  96. ff_frame_pool_uninit(&pool);
  97. return NULL;
  98. }
  99. FFFramePool *ff_frame_pool_audio_init(AVBufferRef* (*alloc)(int size),
  100. int channels,
  101. int nb_samples,
  102. enum AVSampleFormat format,
  103. int align)
  104. {
  105. int ret, planar;
  106. FFFramePool *pool;
  107. pool = av_mallocz(sizeof(FFFramePool));
  108. if (!pool)
  109. return NULL;
  110. planar = av_sample_fmt_is_planar(format);
  111. pool->type = AVMEDIA_TYPE_AUDIO;
  112. pool->planes = planar ? channels : 1;
  113. pool->channels = channels;
  114. pool->nb_samples = nb_samples;
  115. pool->format = format;
  116. pool->align = align;
  117. ret = av_samples_get_buffer_size(&pool->linesize[0], channels,
  118. nb_samples, format, 0);
  119. if (ret < 0)
  120. goto fail;
  121. pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL);
  122. if (!pool->pools[0])
  123. goto fail;
  124. return pool;
  125. fail:
  126. ff_frame_pool_uninit(&pool);
  127. return NULL;
  128. }
  129. int ff_frame_pool_get_video_config(FFFramePool *pool,
  130. int *width,
  131. int *height,
  132. enum AVPixelFormat *format,
  133. int *align)
  134. {
  135. if (!pool)
  136. return AVERROR(EINVAL);
  137. av_assert0(pool->type == AVMEDIA_TYPE_VIDEO);
  138. *width = pool->width;
  139. *height = pool->height;
  140. *format = pool->format;
  141. *align = pool->align;
  142. return 0;
  143. }
  144. int ff_frame_pool_get_audio_config(FFFramePool *pool,
  145. int *channels,
  146. int *nb_samples,
  147. enum AVSampleFormat *format,
  148. int *align)
  149. {
  150. if (!pool)
  151. return AVERROR(EINVAL);
  152. av_assert0(pool->type == AVMEDIA_TYPE_AUDIO);
  153. *channels = pool->channels;
  154. *nb_samples = pool->nb_samples;
  155. *format = pool->format;
  156. *align = pool->align;
  157. return 0;
  158. }
  159. AVFrame *ff_frame_pool_get(FFFramePool *pool)
  160. {
  161. int i;
  162. AVFrame *frame;
  163. const AVPixFmtDescriptor *desc;
  164. frame = av_frame_alloc();
  165. if (!frame) {
  166. return NULL;
  167. }
  168. switch(pool->type) {
  169. case AVMEDIA_TYPE_VIDEO:
  170. desc = av_pix_fmt_desc_get(pool->format);
  171. if (!desc) {
  172. goto fail;
  173. }
  174. frame->width = pool->width;
  175. frame->height = pool->height;
  176. frame->format = pool->format;
  177. for (i = 0; i < 4; i++) {
  178. frame->linesize[i] = pool->linesize[i];
  179. if (!pool->pools[i])
  180. break;
  181. frame->buf[i] = av_buffer_pool_get(pool->pools[i]);
  182. if (!frame->buf[i])
  183. goto fail;
  184. frame->data[i] = frame->buf[i]->data;
  185. }
  186. if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
  187. desc->flags & FF_PSEUDOPAL) {
  188. enum AVPixelFormat format =
  189. pool->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : pool->format;
  190. av_assert0(frame->data[1] != NULL);
  191. if (avpriv_set_systematic_pal2((uint32_t *)frame->data[1], format) < 0)
  192. goto fail;
  193. }
  194. frame->extended_data = frame->data;
  195. break;
  196. case AVMEDIA_TYPE_AUDIO:
  197. frame->nb_samples = pool->nb_samples;
  198. frame->channels = pool->channels;
  199. frame->format = pool->format;
  200. frame->linesize[0] = pool->linesize[0];
  201. if (pool->planes > AV_NUM_DATA_POINTERS) {
  202. frame->extended_data = av_mallocz_array(pool->planes,
  203. sizeof(*frame->extended_data));
  204. frame->nb_extended_buf = pool->planes - AV_NUM_DATA_POINTERS;
  205. frame->extended_buf = av_mallocz_array(frame->nb_extended_buf,
  206. sizeof(*frame->extended_buf));
  207. if (!frame->extended_data || !frame->extended_buf)
  208. goto fail;
  209. } else {
  210. frame->extended_data = frame->data;
  211. av_assert0(frame->nb_extended_buf == 0);
  212. }
  213. for (i = 0; i < FFMIN(pool->planes, AV_NUM_DATA_POINTERS); i++) {
  214. frame->buf[i] = av_buffer_pool_get(pool->pools[0]);
  215. if (!frame->buf[i])
  216. goto fail;
  217. frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
  218. }
  219. for (i = 0; i < frame->nb_extended_buf; i++) {
  220. frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]);
  221. if (!frame->extended_buf[i])
  222. goto fail;
  223. frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
  224. }
  225. break;
  226. default:
  227. av_assert0(0);
  228. }
  229. return frame;
  230. fail:
  231. av_frame_free(&frame);
  232. return NULL;
  233. }
  234. void ff_frame_pool_uninit(FFFramePool **pool)
  235. {
  236. int i;
  237. if (!pool || !*pool)
  238. return;
  239. for (i = 0; i < 4; i++) {
  240. av_buffer_pool_uninit(&(*pool)->pools[i]);
  241. }
  242. av_freep(pool);
  243. }