objpool.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * This file is part of FFmpeg.
  3. *
  4. * FFmpeg is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * FFmpeg is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with FFmpeg; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <stdint.h>
  19. #include "libavcodec/packet.h"
  20. #include "libavutil/common.h"
  21. #include "libavutil/error.h"
  22. #include "libavutil/frame.h"
  23. #include "libavutil/mem.h"
  24. #include "objpool.h"
  25. struct ObjPool {
  26. void *pool[32];
  27. unsigned int pool_count;
  28. ObjPoolCBAlloc alloc;
  29. ObjPoolCBReset reset;
  30. ObjPoolCBFree free;
  31. };
  32. ObjPool *objpool_alloc(ObjPoolCBAlloc cb_alloc, ObjPoolCBReset cb_reset,
  33. ObjPoolCBFree cb_free)
  34. {
  35. ObjPool *op = av_mallocz(sizeof(*op));
  36. if (!op)
  37. return NULL;
  38. op->alloc = cb_alloc;
  39. op->reset = cb_reset;
  40. op->free = cb_free;
  41. return op;
  42. }
  43. void objpool_free(ObjPool **pop)
  44. {
  45. ObjPool *op = *pop;
  46. if (!op)
  47. return;
  48. for (unsigned int i = 0; i < op->pool_count; i++)
  49. op->free(&op->pool[i]);
  50. av_freep(pop);
  51. }
  52. int objpool_get(ObjPool *op, void **obj)
  53. {
  54. if (op->pool_count) {
  55. *obj = op->pool[--op->pool_count];
  56. op->pool[op->pool_count] = NULL;
  57. } else
  58. *obj = op->alloc();
  59. return *obj ? 0 : AVERROR(ENOMEM);
  60. }
  61. void objpool_release(ObjPool *op, void **obj)
  62. {
  63. if (!*obj)
  64. return;
  65. op->reset(*obj);
  66. if (op->pool_count < FF_ARRAY_ELEMS(op->pool))
  67. op->pool[op->pool_count++] = *obj;
  68. else
  69. op->free(obj);
  70. *obj = NULL;
  71. }
  72. static void *alloc_packet(void)
  73. {
  74. return av_packet_alloc();
  75. }
  76. static void *alloc_frame(void)
  77. {
  78. return av_frame_alloc();
  79. }
  80. static void reset_packet(void *obj)
  81. {
  82. av_packet_unref(obj);
  83. }
  84. static void reset_frame(void *obj)
  85. {
  86. av_frame_unref(obj);
  87. }
  88. static void free_packet(void **obj)
  89. {
  90. AVPacket *pkt = *obj;
  91. av_packet_free(&pkt);
  92. *obj = NULL;
  93. }
  94. static void free_frame(void **obj)
  95. {
  96. AVFrame *frame = *obj;
  97. av_frame_free(&frame);
  98. *obj = NULL;
  99. }
  100. ObjPool *objpool_alloc_packets(void)
  101. {
  102. return objpool_alloc(alloc_packet, reset_packet, free_packet);
  103. }
  104. ObjPool *objpool_alloc_frames(void)
  105. {
  106. return objpool_alloc(alloc_frame, reset_frame, free_frame);
  107. }