ijksdl_codec_android_mediacodec.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*****************************************************************************
  2. * ijksdl_codec_android_mediacodec.c
  3. *****************************************************************************
  4. *
  5. * Copyright (c) 2014 Bilibili
  6. * copyright (c) 2014 Zhang Rui <bbcallen@gmail.com>
  7. *
  8. * This file is part of ijkPlayer.
  9. *
  10. * ijkPlayer is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2.1 of the License, or (at your option) any later version.
  14. *
  15. * ijkPlayer is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with ijkPlayer; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. */
  24. #include "ijksdl_codec_android_mediacodec.h"
  25. #include <assert.h>
  26. #include "ijksdl/ijksdl_log.h"
  27. #include "ijksdl_codec_android_mediacodec_internal.h"
  28. static volatile int g_amediacodec_object_serial;
  29. typedef struct SDL_AMediaCodec_Common
  30. {
  31. SDL_AMediaCodec_FakeFifo fake_fifo;
  32. } SDL_AMediaCodec_Common;
  33. int SDL_AMediaCodec_create_object_serial()
  34. {
  35. int object_serial = __sync_add_and_fetch(&g_amediacodec_object_serial, 1);
  36. if (object_serial == 0)
  37. object_serial = __sync_add_and_fetch(&g_amediacodec_object_serial, 1);
  38. return object_serial;
  39. }
  40. // FIXME: release SDL_AMediaCodec
  41. sdl_amedia_status_t SDL_AMediaCodec_delete(SDL_AMediaCodec* acodec)
  42. {
  43. if (!acodec)
  44. return SDL_AMEDIA_OK;
  45. assert(acodec->func_delete);
  46. return acodec->func_delete(acodec);
  47. }
  48. sdl_amedia_status_t SDL_AMediaCodec_deleteP(SDL_AMediaCodec** acodec)
  49. {
  50. if (!acodec)
  51. return SDL_AMEDIA_OK;
  52. sdl_amedia_status_t ret = SDL_AMediaCodec_delete(*acodec);
  53. *acodec = NULL;
  54. return ret;
  55. }
  56. sdl_amedia_status_t SDL_AMediaCodec_configure(
  57. SDL_AMediaCodec* acodec,
  58. const SDL_AMediaFormat* aformat,
  59. ANativeWindow* surface,
  60. SDL_AMediaCrypto *crypto,
  61. uint32_t flags)
  62. {
  63. assert(acodec->func_configure);
  64. sdl_amedia_status_t ret = acodec->func_configure(acodec, aformat, surface, crypto, flags);
  65. acodec->is_configured = true;
  66. acodec->is_started = false;
  67. return ret;
  68. }
  69. sdl_amedia_status_t SDL_AMediaCodec_configure_surface(
  70. JNIEnv*env,
  71. SDL_AMediaCodec* acodec,
  72. const SDL_AMediaFormat* aformat,
  73. jobject android_surface,
  74. SDL_AMediaCrypto *crypto,
  75. uint32_t flags)
  76. {
  77. assert(acodec->func_configure_surface);
  78. sdl_amedia_status_t ret = acodec->func_configure_surface(env, acodec, aformat, android_surface, crypto, flags);
  79. acodec->is_configured = true;
  80. acodec->is_started = false;
  81. return ret;
  82. }
  83. void SDL_AMediaCodec_increaseReference(SDL_AMediaCodec *acodec)
  84. {
  85. assert(acodec);
  86. int ref_count = __sync_add_and_fetch(&acodec->ref_count, 1);
  87. ALOGD("%s(): ref=%d\n", __func__, ref_count);
  88. }
  89. void SDL_AMediaCodec_decreaseReference(SDL_AMediaCodec *acodec)
  90. {
  91. if (!acodec)
  92. return;
  93. int ref_count = __sync_sub_and_fetch(&acodec->ref_count, 1);
  94. ALOGD("%s(): ref=%d\n", __func__, ref_count);
  95. if (ref_count == 0) {
  96. if (SDL_AMediaCodec_isStarted(acodec)) {
  97. SDL_AMediaCodec_stop(acodec);
  98. }
  99. SDL_AMediaCodec_delete(acodec);
  100. }
  101. }
  102. void SDL_AMediaCodec_decreaseReferenceP(SDL_AMediaCodec **acodec)
  103. {
  104. if (!acodec)
  105. return;
  106. SDL_AMediaCodec_decreaseReference(*acodec);
  107. *acodec = NULL;
  108. }
  109. bool SDL_AMediaCodec_isConfigured(SDL_AMediaCodec *acodec)
  110. {
  111. return acodec->is_configured;
  112. }
  113. bool SDL_AMediaCodec_isStarted(SDL_AMediaCodec *acodec)
  114. {
  115. return acodec->is_started;
  116. }
  117. sdl_amedia_status_t SDL_AMediaCodec_start(SDL_AMediaCodec* acodec)
  118. {
  119. assert(acodec->func_start);
  120. sdl_amedia_status_t amc_ret = acodec->func_start(acodec);
  121. if (amc_ret == SDL_AMEDIA_OK) {
  122. acodec->is_started = true;
  123. }
  124. return amc_ret;
  125. }
  126. sdl_amedia_status_t SDL_AMediaCodec_stop(SDL_AMediaCodec* acodec)
  127. {
  128. assert(acodec->func_stop);
  129. acodec->is_started = false;
  130. SDL_AMediaCodec_FakeFifo_abort(&acodec->common->fake_fifo);
  131. return acodec->func_stop(acodec);
  132. }
  133. sdl_amedia_status_t SDL_AMediaCodec_flush(SDL_AMediaCodec* acodec)
  134. {
  135. assert(acodec->func_flush);
  136. SDL_AMediaCodec_FakeFifo_flush(&acodec->common->fake_fifo);
  137. return acodec->func_flush(acodec);
  138. }
  139. ssize_t SDL_AMediaCodec_writeInputData(SDL_AMediaCodec* acodec, size_t idx, const uint8_t *data, size_t size)
  140. {
  141. assert(acodec->func_writeInputData);
  142. return acodec->func_writeInputData(acodec, idx, data, size);
  143. }
  144. ssize_t SDL_AMediaCodec_dequeueInputBuffer(SDL_AMediaCodec* acodec, int64_t timeoutUs)
  145. {
  146. assert(acodec->func_dequeueInputBuffer);
  147. return acodec->func_dequeueInputBuffer(acodec, timeoutUs);
  148. }
  149. sdl_amedia_status_t SDL_AMediaCodec_queueInputBuffer(SDL_AMediaCodec* acodec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
  150. {
  151. assert(acodec->func_queueInputBuffer);
  152. if (flags & AMEDIACODEC__BUFFER_FLAG_FAKE_FRAME) {
  153. return SDL_AMediaCodec_FakeFifo_queueInputBuffer(&acodec->common->fake_fifo, idx, offset, size, time, flags);
  154. }
  155. return acodec->func_queueInputBuffer(acodec, idx, offset, size, time, flags);
  156. }
  157. ssize_t SDL_AMediaCodec_dequeueOutputBuffer(SDL_AMediaCodec* acodec, SDL_AMediaCodecBufferInfo *info, int64_t timeoutUs)
  158. {
  159. assert(acodec->func_dequeueOutputBuffer);
  160. return acodec->func_dequeueOutputBuffer(acodec, info, timeoutUs);
  161. }
  162. SDL_AMediaFormat* SDL_AMediaCodec_getOutputFormat(SDL_AMediaCodec* acodec)
  163. {
  164. assert(acodec->func_getOutputFormat);
  165. return acodec->func_getOutputFormat(acodec);
  166. }
  167. sdl_amedia_status_t SDL_AMediaCodec_releaseOutputBuffer(SDL_AMediaCodec* acodec, size_t idx, bool render)
  168. {
  169. assert(acodec->func_releaseOutputBuffer);
  170. return acodec->func_releaseOutputBuffer(acodec, idx, render);
  171. }
  172. bool SDL_AMediaCodec_isInputBuffersValid(SDL_AMediaCodec* acodec)
  173. {
  174. assert(acodec->func_isInputBuffersValid);
  175. return acodec->func_isInputBuffersValid(acodec);
  176. }
  177. int SDL_AMediaCodec_getSerial(SDL_AMediaCodec* acodec)
  178. {
  179. if (!acodec)
  180. return 0;
  181. return acodec->object_serial;
  182. }
  183. bool SDL_AMediaCodec_isSameSerial(SDL_AMediaCodec* acodec, int acodec_serial)
  184. {
  185. if (acodec == NULL)
  186. return false;
  187. return acodec->object_serial == acodec_serial;
  188. }
  189. SDL_AMediaCodec *SDL_AMediaCodec_CreateInternal(size_t opaque_size)
  190. {
  191. SDL_AMediaCodec *acodec = (SDL_AMediaCodec*) mallocz(sizeof(SDL_AMediaCodec));
  192. if (!acodec)
  193. return NULL;
  194. acodec->mutex = SDL_CreateMutex();
  195. if (acodec->mutex == NULL)
  196. goto fail;
  197. acodec->opaque = mallocz(opaque_size);
  198. if (!acodec->opaque)
  199. goto fail;
  200. acodec->common = mallocz(sizeof(SDL_AMediaCodec_Common));
  201. if (!acodec->common)
  202. goto fail;
  203. SDL_AMediaCodec_FakeFifo_init(&acodec->common->fake_fifo);
  204. return acodec;
  205. fail:
  206. SDL_AMediaCodec_FreeInternal(acodec);
  207. return NULL;
  208. }
  209. void SDL_AMediaCodec_FreeInternal(SDL_AMediaCodec *acodec)
  210. {
  211. if (!acodec)
  212. return;
  213. if (acodec->common) {
  214. SDL_AMediaCodec_FakeFifo_destroy(&acodec->common->fake_fifo);
  215. free(acodec->common);
  216. }
  217. free(acodec->opaque);
  218. if (acodec->mutex)
  219. SDL_DestroyMutexP(&acodec->mutex);
  220. memset(acodec, 0, sizeof(SDL_AMediaCodec));
  221. free(acodec);
  222. }
  223. void SDL_AMediaCodecFake_abort(SDL_AMediaCodec* acodec)
  224. {
  225. SDL_AMediaCodec_FakeFifo_abort(&acodec->common->fake_fifo);
  226. }
  227. void SDL_AMediaCodecFake_flushFakeFrames(SDL_AMediaCodec* acodec)
  228. {
  229. SDL_AMediaCodec_FakeFifo_flush(&acodec->common->fake_fifo);
  230. }
  231. sdl_amedia_status_t SDL_AMediaCodecFake_queueFakeFrame(SDL_AMediaCodec* acodec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
  232. {
  233. return SDL_AMediaCodec_FakeFifo_queueInputBuffer(&acodec->common->fake_fifo, idx, offset, size, time, flags);
  234. }
  235. ssize_t SDL_AMediaCodecFake_dequeueOutputBuffer(SDL_AMediaCodec* acodec, SDL_AMediaCodecBufferInfo *info, int64_t timeoutUs)
  236. {
  237. if (SDL_AMediaCodec_FakeFifo_size(&acodec->common->fake_fifo) > 0) {
  238. ssize_t ret = SDL_AMediaCodec_FakeFifo_dequeueOutputBuffer(&acodec->common->fake_fifo, info, 0);
  239. if (ret >= 0)
  240. return ret;
  241. }
  242. assert(acodec->func_dequeueOutputBuffer);
  243. return acodec->func_dequeueOutputBuffer(acodec, info, timeoutUs);
  244. }
  245. ssize_t SDL_AMediaCodecFake_dequeueFakeFrameOnly(SDL_AMediaCodec* acodec, SDL_AMediaCodecBufferInfo *info, int64_t timeoutUs)
  246. {
  247. return SDL_AMediaCodec_FakeFifo_dequeueOutputBuffer(&acodec->common->fake_fifo, info, 0);
  248. }