video-frame.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /******************************************************************************
  2. Copyright (C) 2013 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include "video-frame.h"
  15. #define ALIGN_SIZE(size, align) size = (((size) + (align - 1)) & (~(align - 1)))
  16. /* messy code alarm */
  17. void video_frame_init(struct video_frame *frame, enum video_format format,
  18. uint32_t width, uint32_t height)
  19. {
  20. size_t size;
  21. size_t offsets[MAX_AV_PLANES];
  22. int alignment = base_get_alignment();
  23. if (!frame)
  24. return;
  25. memset(frame, 0, sizeof(struct video_frame));
  26. memset(offsets, 0, sizeof(offsets));
  27. switch (format) {
  28. case VIDEO_FORMAT_NONE:
  29. return;
  30. case VIDEO_FORMAT_I420:
  31. size = width * height;
  32. ALIGN_SIZE(size, alignment);
  33. offsets[0] = size;
  34. size += (width / 2) * (height / 2);
  35. ALIGN_SIZE(size, alignment);
  36. offsets[1] = size;
  37. size += (width / 2) * (height / 2);
  38. ALIGN_SIZE(size, alignment);
  39. frame->data[0] = bmalloc(size);
  40. frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
  41. frame->data[2] = (uint8_t *)frame->data[0] + offsets[1];
  42. frame->linesize[0] = width;
  43. frame->linesize[1] = width / 2;
  44. frame->linesize[2] = width / 2;
  45. break;
  46. case VIDEO_FORMAT_NV12:
  47. size = width * height;
  48. ALIGN_SIZE(size, alignment);
  49. offsets[0] = size;
  50. size += (width / 2) * (height / 2) * 2;
  51. ALIGN_SIZE(size, alignment);
  52. frame->data[0] = bmalloc(size);
  53. frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
  54. frame->linesize[0] = width;
  55. frame->linesize[1] = width;
  56. break;
  57. case VIDEO_FORMAT_Y800:
  58. size = width * height;
  59. ALIGN_SIZE(size, alignment);
  60. frame->data[0] = bmalloc(size);
  61. frame->linesize[0] = width;
  62. break;
  63. case VIDEO_FORMAT_YVYU:
  64. case VIDEO_FORMAT_YUY2:
  65. case VIDEO_FORMAT_UYVY:
  66. size = width * height * 2;
  67. ALIGN_SIZE(size, alignment);
  68. frame->data[0] = bmalloc(size);
  69. frame->linesize[0] = width * 2;
  70. break;
  71. case VIDEO_FORMAT_RGBA:
  72. case VIDEO_FORMAT_BGRA:
  73. case VIDEO_FORMAT_BGRX:
  74. case VIDEO_FORMAT_AYUV:
  75. size = width * height * 4;
  76. ALIGN_SIZE(size, alignment);
  77. frame->data[0] = bmalloc(size);
  78. frame->linesize[0] = width * 4;
  79. break;
  80. case VIDEO_FORMAT_I444:
  81. size = width * height;
  82. ALIGN_SIZE(size, alignment);
  83. frame->data[0] = bmalloc(size * 3);
  84. frame->data[1] = (uint8_t *)frame->data[0] + size;
  85. frame->data[2] = (uint8_t *)frame->data[1] + size;
  86. frame->linesize[0] = width;
  87. frame->linesize[1] = width;
  88. frame->linesize[2] = width;
  89. break;
  90. case VIDEO_FORMAT_BGR3:
  91. size = width * height * 3;
  92. ALIGN_SIZE(size, alignment);
  93. frame->data[0] = bmalloc(size);
  94. frame->linesize[0] = width * 3;
  95. break;
  96. case VIDEO_FORMAT_I422:
  97. size = width * height;
  98. ALIGN_SIZE(size, alignment);
  99. offsets[0] = size;
  100. size += (width / 2) * height;
  101. ALIGN_SIZE(size, alignment);
  102. offsets[1] = size;
  103. size += (width / 2) * height;
  104. ALIGN_SIZE(size, alignment);
  105. frame->data[0] = bmalloc(size);
  106. frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
  107. frame->data[2] = (uint8_t *)frame->data[0] + offsets[1];
  108. frame->linesize[0] = width;
  109. frame->linesize[1] = width / 2;
  110. frame->linesize[2] = width / 2;
  111. break;
  112. case VIDEO_FORMAT_I40A:
  113. size = width * height;
  114. ALIGN_SIZE(size, alignment);
  115. offsets[0] = size;
  116. size += (width / 2) * (height / 2);
  117. ALIGN_SIZE(size, alignment);
  118. offsets[1] = size;
  119. size += (width / 2) * (height / 2);
  120. ALIGN_SIZE(size, alignment);
  121. offsets[2] = size;
  122. size += width * height;
  123. ALIGN_SIZE(size, alignment);
  124. frame->data[0] = bmalloc(size);
  125. frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
  126. frame->data[2] = (uint8_t *)frame->data[0] + offsets[1];
  127. frame->data[3] = (uint8_t *)frame->data[0] + offsets[2];
  128. frame->linesize[0] = width;
  129. frame->linesize[1] = width / 2;
  130. frame->linesize[2] = width / 2;
  131. frame->linesize[3] = width;
  132. break;
  133. case VIDEO_FORMAT_I42A:
  134. size = width * height;
  135. ALIGN_SIZE(size, alignment);
  136. offsets[0] = size;
  137. size += (width / 2) * height;
  138. ALIGN_SIZE(size, alignment);
  139. offsets[1] = size;
  140. size += (width / 2) * height;
  141. ALIGN_SIZE(size, alignment);
  142. offsets[2] = size;
  143. size += width * height;
  144. ALIGN_SIZE(size, alignment);
  145. frame->data[0] = bmalloc(size);
  146. frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
  147. frame->data[2] = (uint8_t *)frame->data[0] + offsets[1];
  148. frame->data[3] = (uint8_t *)frame->data[0] + offsets[2];
  149. frame->linesize[0] = width;
  150. frame->linesize[1] = width / 2;
  151. frame->linesize[2] = width / 2;
  152. frame->linesize[3] = width;
  153. break;
  154. case VIDEO_FORMAT_YUVA:
  155. size = width * height;
  156. ALIGN_SIZE(size, alignment);
  157. offsets[0] = size;
  158. size += width * height;
  159. ALIGN_SIZE(size, alignment);
  160. offsets[1] = size;
  161. size += width * height;
  162. ALIGN_SIZE(size, alignment);
  163. offsets[2] = size;
  164. size += width * height;
  165. ALIGN_SIZE(size, alignment);
  166. frame->data[0] = bmalloc(size);
  167. frame->data[1] = (uint8_t *)frame->data[0] + offsets[0];
  168. frame->data[2] = (uint8_t *)frame->data[0] + offsets[1];
  169. frame->data[3] = (uint8_t *)frame->data[0] + offsets[2];
  170. frame->linesize[0] = width;
  171. frame->linesize[1] = width;
  172. frame->linesize[2] = width;
  173. frame->linesize[3] = width;
  174. break;
  175. }
  176. }
  177. void video_frame_copy(struct video_frame *dst, const struct video_frame *src,
  178. enum video_format format, uint32_t cy)
  179. {
  180. switch (format) {
  181. case VIDEO_FORMAT_NONE:
  182. return;
  183. case VIDEO_FORMAT_I420:
  184. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  185. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2);
  186. memcpy(dst->data[2], src->data[2], src->linesize[2] * cy / 2);
  187. break;
  188. case VIDEO_FORMAT_NV12:
  189. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  190. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2);
  191. break;
  192. case VIDEO_FORMAT_Y800:
  193. case VIDEO_FORMAT_YVYU:
  194. case VIDEO_FORMAT_YUY2:
  195. case VIDEO_FORMAT_UYVY:
  196. case VIDEO_FORMAT_RGBA:
  197. case VIDEO_FORMAT_BGRA:
  198. case VIDEO_FORMAT_BGRX:
  199. case VIDEO_FORMAT_BGR3:
  200. case VIDEO_FORMAT_AYUV:
  201. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  202. break;
  203. case VIDEO_FORMAT_I444:
  204. case VIDEO_FORMAT_I422:
  205. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  206. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy);
  207. memcpy(dst->data[2], src->data[2], src->linesize[2] * cy);
  208. break;
  209. case VIDEO_FORMAT_I40A:
  210. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  211. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy / 2);
  212. memcpy(dst->data[2], src->data[2], src->linesize[2] * cy / 2);
  213. memcpy(dst->data[3], src->data[3], src->linesize[3] * cy);
  214. break;
  215. case VIDEO_FORMAT_I42A:
  216. case VIDEO_FORMAT_YUVA:
  217. memcpy(dst->data[0], src->data[0], src->linesize[0] * cy);
  218. memcpy(dst->data[1], src->data[1], src->linesize[1] * cy);
  219. memcpy(dst->data[2], src->data[2], src->linesize[2] * cy);
  220. memcpy(dst->data[3], src->data[3], src->linesize[3] * cy);
  221. break;
  222. }
  223. }