0009-suport-usebuffer-mode-for-encoding.patch 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. diff -Naur a/omx/gstomx.h b/omx/gstomx.h
  2. --- a/omx/gstomx.h 2020-10-26 19:17:03.488452200 +0800
  3. +++ b/omx/gstomx.h 2022-04-24 18:50:01.353690234 +0800
  4. @@ -332,6 +332,7 @@
  5. */
  6. gint settings_cookie;
  7. gint configured_settings_cookie;
  8. + GstBuffer * c_buf;
  9. };
  10. struct _GstOMXComponent {
  11. diff -Naur a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c
  12. --- a/omx/gstomxvideoenc.c 2020-10-26 19:17:03.492452100 +0800
  13. +++ b/omx/gstomxvideoenc.c 2022-04-24 18:53:42.211595096 +0800
  14. @@ -2102,6 +2102,143 @@
  15. return TRUE;
  16. }
  17. +#ifdef USE_OMX_TARGET_STARFIVE
  18. +static GstBuffer *
  19. +gst_omx_try_importing_buffer (GstOMXVideoEnc * self, GstBufferPool * pool,
  20. + GstOMXPort * port, GstVideoInfo * v_info, guint i, GstVideoFrame ** frame)
  21. +{
  22. + GstBufferPoolAcquireParams params = { 0, };
  23. + GstBuffer *buffer = NULL;
  24. + GstMemory *mem;
  25. + GstMapFlags flags = GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF;
  26. + gboolean is_mapped = FALSE;
  27. +
  28. + *frame = NULL;
  29. +
  30. + if (gst_buffer_pool_acquire_buffer (pool, &buffer, &params) != GST_FLOW_OK) {
  31. + GST_INFO_OBJECT (self, "Failed to acquire %d-th buffer", i);
  32. + return NULL;
  33. + }
  34. +
  35. + if (gst_buffer_n_memory (buffer) != 1) {
  36. + GST_INFO_OBJECT (self, "%d-th buffer has more than one memory (%d)", i,
  37. + gst_buffer_n_memory (buffer));
  38. + goto out;
  39. + }
  40. +
  41. + mem = gst_buffer_peek_memory (buffer, 0);
  42. + if (!mem) {
  43. + GST_INFO_OBJECT (self, "Failed to acquire memory of %d-th buffer", i);
  44. + goto out;
  45. + }
  46. +
  47. + if ( !gst_is_dmabuf_memory (mem)) {
  48. + GST_INFO_OBJECT (self,
  49. + " %d-th buffer doesn't contain dmabuf, go to out. port->port_def.nBufferSize: %lu",
  50. + i, port->port_def.nBufferSize);
  51. + goto out;
  52. + }
  53. +
  54. + *frame = g_slice_new0 (GstVideoFrame);
  55. +
  56. + is_mapped = gst_video_frame_map (*frame, v_info, buffer, flags);
  57. + GST_INFO_OBJECT (self, " *frame = %p, mem: %p", *frame, mem);
  58. +
  59. + if (!is_mapped) {
  60. + GST_INFO_OBJECT (self, "Failed to map %d-th buffer", i);
  61. + goto out;
  62. + }
  63. +
  64. + if (GST_VIDEO_FRAME_SIZE (*frame) < port->port_def.nBufferSize) {
  65. + GST_INFO_OBJECT (self,
  66. + "Frame size of %d-th buffer (%" G_GSIZE_FORMAT
  67. + ") is too small for port buffer size (%d)", i,
  68. + GST_VIDEO_FRAME_SIZE (*frame), (guint32) port->port_def.nBufferSize);
  69. + goto out;
  70. + }
  71. +
  72. + return buffer;
  73. +
  74. +out:
  75. + if (*frame) {
  76. + if (is_mapped)
  77. + gst_video_frame_unmap (*frame);
  78. + g_slice_free (GstVideoFrame, *frame);
  79. + *frame = NULL;
  80. + }
  81. + gst_buffer_unref (buffer);
  82. + return NULL;
  83. +}
  84. +#endif
  85. +
  86. +#ifdef USE_OMX_TARGET_STARFIVE
  87. +static gboolean
  88. +gst_omx_video_enc_use_buffers (GstOMXVideoEnc * self)
  89. +{
  90. + GstOMXPort * port = self->enc_in_port;
  91. + GstBufferPool *pool = port->c_buf->pool;
  92. + GstVideoCodecState *input_state = self->input_state;
  93. + GstVideoInfo v_info = input_state->info;
  94. + guint n = port->port_def.nBufferCountActual;
  95. + GList *images = NULL;
  96. + GList *buffers = NULL;
  97. + GList *frames = NULL;
  98. + OMX_ERRORTYPE err = OMX_ErrorNone;
  99. + gboolean is_mapped = FALSE ;
  100. + GST_DEBUG(" nBufferCountActual=%d, nBufferCountMin= %lu", n, port->port_def.nBufferCountMin);
  101. +
  102. + if ( pool != NULL ) {
  103. + guint i;
  104. + for (i = 0; i < n; i++) {
  105. + GstBuffer * buf = NULL;
  106. + GstVideoFrame *frame = NULL;
  107. + buf = gst_omx_try_importing_buffer (self, pool, port, &v_info, i, &frame);
  108. + if (!buf) {
  109. + GST_DEBUG_OBJECT (self, "Failed to import %d-th buffer", i);
  110. + g_list_free (images);
  111. + g_list_free_full (frames, (GDestroyNotify) gst_video_frame_unmap);
  112. + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
  113. + break;
  114. + } else {
  115. + buffers = g_list_append (buffers, buf);
  116. + frames = g_list_append (frames, frame);
  117. + images = g_list_append (images, GST_VIDEO_FRAME_PLANE_DATA (frame, 0));
  118. + GST_DEBUG_OBJECT (self, " pBuffer: %p", GST_VIDEO_FRAME_PLANE_DATA (frame, 0));
  119. + }
  120. + }
  121. + }
  122. +
  123. + if (images) {
  124. + is_mapped = TRUE;
  125. +
  126. + err = gst_omx_port_use_buffers (port, images);
  127. + g_list_free (images);
  128. + g_list_free_full (frames, (GDestroyNotify) gst_video_frame_unmap);
  129. +
  130. + if (err == OMX_ErrorNone) {
  131. + GST_DEBUG_OBJECT (self, "Using %d buffers", n);
  132. + } else {
  133. + GST_INFO_OBJECT (self,
  134. + "Failed to OMX_UseBuffer on port: %s (0x%08x)",
  135. + gst_omx_error_to_string (err), err);
  136. + g_list_free_full (buffers, (GDestroyNotify) gst_buffer_unref);
  137. + return FALSE;
  138. + }
  139. + }
  140. +
  141. + if ( !is_mapped ) {
  142. + GST_WARNING_OBJECT (self, " failed to call UseBuffer, trying to use allocation");
  143. + self->input_dmabuf = FALSE;
  144. + self->input_allocation = GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
  145. + if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone){
  146. + return FALSE;
  147. + }
  148. + }
  149. +
  150. + return TRUE;
  151. +}
  152. +#endif
  153. +
  154. static gboolean
  155. gst_omx_video_enc_allocate_in_buffers (GstOMXVideoEnc * self)
  156. {
  157. @@ -2115,6 +2252,9 @@
  158. return FALSE;
  159. break;
  160. case GST_OMX_BUFFER_ALLOCATION_USE_BUFFER:
  161. +#ifdef USE_OMX_TARGET_STARFIVE
  162. + return gst_omx_video_enc_use_buffers(self);
  163. +#endif
  164. default:
  165. /* Not supported */
  166. g_return_val_if_reached (FALSE);
  167. @@ -2179,8 +2319,18 @@
  168. gst_omx_video_enc_pick_input_allocation_mode (GstOMXVideoEnc * self,
  169. GstBuffer * inbuf)
  170. {
  171. +#ifdef USE_OMX_TARGET_STARFIVE
  172. + if (!gst_omx_is_dynamic_allocation_supported ()){
  173. + if (gst_is_dmabuf_memory (gst_buffer_peek_memory (inbuf, 0))){
  174. + GST_DEBUG_OBJECT (self, "select GST_OMX_BUFFER_ALLOCATION_USE_BUFFER");
  175. + return GST_OMX_BUFFER_ALLOCATION_USE_BUFFER;
  176. + }
  177. + return GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
  178. + }
  179. +#else
  180. if (!gst_omx_is_dynamic_allocation_supported ())
  181. return GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER;
  182. +#endif
  183. if (can_use_dynamic_buffer_mode (self, inbuf)) {
  184. GST_DEBUG_OBJECT (self,
  185. @@ -2272,6 +2422,15 @@
  186. input);
  187. self->input_dmabuf = FALSE;
  188. +#ifdef USE_OMX_TARGET_STARFIVE
  189. + if (self->input_allocation ==
  190. + GST_OMX_BUFFER_ALLOCATION_USE_BUFFER) {
  191. + self->input_dmabuf = TRUE;
  192. + self->enc_in_port->c_buf = input;
  193. + GST_DEBUG_OBJECT (self, "input_dmabuf is true");
  194. + }
  195. +#endif
  196. +
  197. #ifdef USE_OMX_TARGET_ZYNQ_USCALE_PLUS
  198. if (gst_is_dmabuf_memory (gst_buffer_peek_memory (input, 0))) {
  199. if (self->input_allocation ==
  200. @@ -2786,7 +2945,11 @@
  201. }
  202. if (self->enc_in_port->allocation ==
  203. - GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC) {
  204. + GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC
  205. +#ifdef USE_OMX_TARGET_STARFIVE
  206. + || self->enc_in_port->allocation == GST_OMX_BUFFER_ALLOCATION_USE_BUFFER
  207. +#endif
  208. + ) {
  209. if (gst_buffer_n_memory (inbuf) > 1) {
  210. GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
  211. ("input buffer now has more than one memory, can't use dynamic allocation any more"));
  212. @@ -2812,12 +2975,29 @@
  213. gst_buffer_get_size (inbuf));
  214. } else {
  215. /* dmabuf input */
  216. +#ifdef USE_OMX_TARGET_STARFIVE
  217. + if (self->enc_in_port->allocation == GST_OMX_BUFFER_ALLOCATION_USE_BUFFER) {
  218. + GstMemory *mem = gst_buffer_peek_memory (inbuf, 0);
  219. + GST_LOG_OBJECT (self, " mem: %p, inbuf: %p, outbuf: %p", mem, inbuf, outbuf);
  220. + if (!gst_omx_buffer_map_memory (outbuf, mem)) {
  221. + GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),("failed to import"));
  222. + GST_ERROR_OBJECT (self, "failed to import dmabuf %p, inbuf: %p",mem, inbuf);
  223. + return FALSE;
  224. + }
  225. + } else {
  226. + if (!gst_omx_buffer_import_fd (outbuf, inbuf)) {
  227. + GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
  228. + ("failed to import dmabuf"));
  229. + return FALSE;
  230. + }
  231. + }
  232. +#else
  233. if (!gst_omx_buffer_import_fd (outbuf, inbuf)) {
  234. GST_ELEMENT_ERROR (self, STREAM, FORMAT, (NULL),
  235. ("failed to import dmabuf"));
  236. return FALSE;
  237. }
  238. -
  239. +#endif
  240. GST_LOG_OBJECT (self, "Import dmabuf of %" G_GSIZE_FORMAT " bytes",
  241. gst_buffer_get_size (inbuf));
  242. }