ijksdl_codec_android_mediacodec_internal.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2015 Bilibili
  3. * copyright (c) 2015 Zhang Rui <bbcallen@gmail.com>
  4. *
  5. * This file is part of ijkPlayer.
  6. *
  7. * ijkPlayer is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * ijkPlayer is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with ijkPlayer; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "ijksdl_codec_android_mediacodec_internal.h"
  22. #include "ijksdl/ijksdl_log.h"
  23. #include "ijksdl/ijksdl_mutex.h"
  24. #include "ijksdl/ijksdl_timer.h"
  25. #include "ijksdl_codec_android_mediadef.h"
  26. #define FAK_TRACE(...)
  27. //#define FAK_TRACE ALOGE
  28. sdl_amedia_status_t SDL_AMediaCodec_FakeFifo_init(SDL_AMediaCodec_FakeFifo *fifo)
  29. {
  30. memset(fifo, 0, sizeof(SDL_AMediaCodec_FakeFifo));
  31. fifo->mutex = SDL_CreateMutex();
  32. fifo->wakeup_enqueue_cond = SDL_CreateCond();
  33. fifo->wakeup_dequeue_cond = SDL_CreateCond();
  34. return SDL_AMEDIA_OK;
  35. }
  36. void SDL_AMediaCodec_FakeFifo_abort(SDL_AMediaCodec_FakeFifo *fifo)
  37. {
  38. SDL_LockMutex(fifo->mutex);
  39. fifo->should_abort = 1;
  40. SDL_CondSignal(fifo->wakeup_enqueue_cond);
  41. SDL_CondSignal(fifo->wakeup_dequeue_cond);
  42. SDL_UnlockMutex(fifo->mutex);
  43. }
  44. void SDL_AMediaCodec_FakeFifo_destroy(SDL_AMediaCodec_FakeFifo *fifo)
  45. {
  46. if (!fifo)
  47. return;
  48. if (fifo->mutex)
  49. SDL_AMediaCodec_FakeFifo_abort(fifo);
  50. SDL_DestroyMutexP(&fifo->mutex);
  51. SDL_DestroyCondP(&fifo->wakeup_enqueue_cond);
  52. SDL_DestroyCondP(&fifo->wakeup_dequeue_cond);
  53. memset(fifo, 0, sizeof(SDL_AMediaCodec_FakeFifo));
  54. }
  55. ssize_t SDL_AMediaCodec_FakeFifo_dequeueInputBuffer(SDL_AMediaCodec_FakeFifo* fifo, int64_t timeoutUs)
  56. {
  57. int ret_index = -1;
  58. if (fifo->should_abort)
  59. return SDL_AMEDIA_ERROR_UNKNOWN;
  60. SDL_LockMutex(fifo->mutex);
  61. if (!fifo->should_abort) {
  62. if (fifo->size >= FAKE_BUFFER_QUEUE_SIZE) {
  63. SDL_CondWaitTimeout(fifo->wakeup_enqueue_cond, fifo->mutex, timeoutUs / 1000);
  64. }
  65. if (fifo->size < FAKE_BUFFER_QUEUE_SIZE) {
  66. ret_index = fifo->end;
  67. }
  68. }
  69. SDL_UnlockMutex(fifo->mutex);
  70. if (fifo->should_abort)
  71. return -1;
  72. return ret_index;
  73. }
  74. sdl_amedia_status_t SDL_AMediaCodec_FakeFifo_queueInputBuffer(SDL_AMediaCodec_FakeFifo *fifo, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
  75. {
  76. if (fifo->should_abort)
  77. return SDL_AMEDIA_ERROR_UNKNOWN;
  78. SDL_LockMutex(fifo->mutex);
  79. if (fifo->size >= FAKE_BUFFER_QUEUE_SIZE) {
  80. SDL_UnlockMutex(fifo->mutex);
  81. return SDL_AMEDIA_ERROR_UNKNOWN;
  82. }
  83. SDL_AMediaCodec_FakeFrame *fake = &fifo->fakes[fifo->end];
  84. fake->info.offset = offset;
  85. fake->info.size = size;
  86. fake->info.presentationTimeUs = time;
  87. fake->info.flags = flags;
  88. fake->index = fifo->end;
  89. FAK_TRACE("%s, %d, %lld", __func__, fifo->end, time);
  90. fifo->end = (fifo->end + 1) % FAKE_BUFFER_QUEUE_SIZE;
  91. fifo->size++;
  92. SDL_CondSignal(fifo->wakeup_dequeue_cond);
  93. SDL_UnlockMutex(fifo->mutex);
  94. return SDL_AMEDIA_OK;
  95. }
  96. ssize_t SDL_AMediaCodec_FakeFifo_dequeueOutputBuffer(SDL_AMediaCodec_FakeFifo *fifo, SDL_AMediaCodecBufferInfo *info, int64_t timeoutUs)
  97. {
  98. if (fifo->should_abort)
  99. return -1;
  100. int64_t timeoutMs = (timeoutUs + 999) / 1000;
  101. ssize_t dequeue_ret = -1;
  102. uint64_t wait_start = SDL_GetTickHR();
  103. int64_t to_wait = timeoutMs;
  104. SDL_LockMutex(fifo->mutex);
  105. while (!fifo->should_abort) {
  106. if (fifo->size > 0) {
  107. SDL_AMediaCodec_FakeFrame *fake = &fifo->fakes[fifo->begin];
  108. *info = fake->info;
  109. info->flags |= AMEDIACODEC__BUFFER_FLAG_FAKE_FRAME;
  110. dequeue_ret = fake->index;
  111. FAK_TRACE("%s, [%d]%lld", __func__, fifo->begin, info->presentationTimeUs);
  112. fifo->begin = (fifo->begin + 1) % FAKE_BUFFER_QUEUE_SIZE;
  113. fifo->size--;
  114. SDL_CondSignal(fifo->wakeup_enqueue_cond);
  115. break;
  116. }
  117. SDL_CondWaitTimeout(fifo->wakeup_dequeue_cond, fifo->mutex, to_wait);
  118. if (to_wait >= 0) {
  119. uint64_t now = SDL_GetTickHR();
  120. if (now < wait_start) {
  121. // tick overflow
  122. dequeue_ret = -1;
  123. break;
  124. } else {
  125. uint64_t elapsed = now - wait_start;
  126. if (elapsed >= timeoutMs) {
  127. // timeout
  128. dequeue_ret = -1;
  129. break;
  130. } else {
  131. to_wait = timeoutMs - elapsed;
  132. }
  133. }
  134. }
  135. }
  136. SDL_UnlockMutex(fifo->mutex);
  137. if (fifo->should_abort)
  138. return -1;
  139. return dequeue_ret;
  140. }
  141. void SDL_AMediaCodec_FakeFifo_flush(SDL_AMediaCodec_FakeFifo *fifo)
  142. {
  143. if (fifo->should_abort)
  144. return;
  145. SDL_LockMutex(fifo->mutex);
  146. fifo->begin = 0;
  147. fifo->end = 0;
  148. fifo->size = 0;
  149. SDL_UnlockMutex(fifo->mutex);
  150. }
  151. int SDL_AMediaCodec_FakeFifo_size(SDL_AMediaCodec_FakeFifo *fifo)
  152. {
  153. return fifo->size;
  154. }