ijksdl_vout_overlay_android_mediacodec.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*****************************************************************************
  2. * ijksdl_vout_overlay_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_vout_overlay_android_mediacodec.h"
  25. #include <assert.h>
  26. #include "ijksdl/ijksdl_stdinc.h"
  27. #include "ijksdl/ijksdl_mutex.h"
  28. #include "ijksdl/ijksdl_vout_internal.h"
  29. #include "ijksdl/ijksdl_video.h"
  30. #include "ijksdl_vout_android_nativewindow.h"
  31. #include "ijksdl_codec_android_mediacodec.h"
  32. #include "ijksdl_inc_internal_android.h"
  33. #ifndef AMCTRACE
  34. #define AMCTRACE(...)
  35. #endif
  36. typedef struct SDL_VoutOverlay_Opaque {
  37. SDL_mutex *mutex;
  38. SDL_Vout *vout;
  39. SDL_AMediaCodec *acodec;
  40. SDL_AMediaCodecBufferProxy *buffer_proxy;
  41. Uint16 pitches[AV_NUM_DATA_POINTERS];
  42. Uint8 *pixels[AV_NUM_DATA_POINTERS];
  43. } SDL_VoutOverlay_Opaque;
  44. static int overlay_lock(SDL_VoutOverlay *overlay)
  45. {
  46. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  47. return SDL_LockMutex(opaque->mutex);
  48. }
  49. static int overlay_unlock(SDL_VoutOverlay *overlay)
  50. {
  51. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  52. return SDL_UnlockMutex(opaque->mutex);
  53. }
  54. static void overlay_unref(SDL_VoutOverlay *overlay)
  55. {
  56. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  57. SDL_VoutAndroid_releaseBufferProxyP(opaque->vout, &opaque->buffer_proxy, false);
  58. }
  59. static void overlay_free_l(SDL_VoutOverlay *overlay)
  60. {
  61. AMCTRACE("SDL_Overlay(mediacodec): overlay_free_l(%p)\n", overlay);
  62. if (!overlay)
  63. return;
  64. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  65. if (!opaque)
  66. return;
  67. overlay_unref(overlay);
  68. if (opaque->mutex)
  69. SDL_DestroyMutex(opaque->mutex);
  70. SDL_VoutOverlay_FreeInternal(overlay);
  71. }
  72. static SDL_Class g_vout_overlay_amediacodec_class = {
  73. .name = "AndroidMediaCodecVoutOverlay",
  74. };
  75. inline static bool check_object(SDL_VoutOverlay* object, const char *func_name)
  76. {
  77. if (!object || !object->opaque || !object->opaque_class) {
  78. ALOGE("%s.%s: invalid pipeline\n", object->opaque_class->name, func_name);
  79. return false;
  80. }
  81. if (object->opaque_class != &g_vout_overlay_amediacodec_class) {
  82. ALOGE("%s.%s: unsupported method\n", object->opaque_class->name, func_name);
  83. return false;
  84. }
  85. return true;
  86. }
  87. static int func_fill_frame(SDL_VoutOverlay *overlay, const AVFrame *frame)
  88. {
  89. assert(frame->format == IJK_AV_PIX_FMT__ANDROID_MEDIACODEC);
  90. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  91. if (!check_object(overlay, __func__))
  92. return -1;
  93. if (opaque->buffer_proxy)
  94. SDL_VoutAndroid_releaseBufferProxyP(opaque->vout, (SDL_AMediaCodecBufferProxy **)&opaque->buffer_proxy, false);
  95. opaque->acodec = SDL_VoutAndroid_peekAMediaCodec(opaque->vout);
  96. // TODO: ref-count buffer_proxy?
  97. opaque->buffer_proxy = (SDL_AMediaCodecBufferProxy *)frame->opaque;
  98. overlay->opaque_class = &g_vout_overlay_amediacodec_class;
  99. overlay->format = SDL_FCC__AMC;
  100. overlay->planes = 1;
  101. overlay->pixels[0] = NULL;
  102. overlay->pixels[1] = NULL;
  103. overlay->pitches[0] = 0;
  104. overlay->pitches[1] = 0;
  105. overlay->is_private = 1;
  106. overlay->w = (int)frame->width;
  107. overlay->h = (int)frame->height;
  108. return 0;
  109. }
  110. SDL_VoutOverlay *SDL_VoutAMediaCodec_CreateOverlay(int width, int height, SDL_Vout *vout)
  111. {
  112. SDLTRACE("SDL_VoutAMediaCodec_CreateOverlay(w=%d, h=%d, fmt=_AMC vout=%p)\n",
  113. width, height, vout);
  114. SDL_VoutOverlay *overlay = SDL_VoutOverlay_CreateInternal(sizeof(SDL_VoutOverlay_Opaque));
  115. if (!overlay) {
  116. ALOGE("overlay allocation failed");
  117. return NULL;
  118. }
  119. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  120. opaque->mutex = SDL_CreateMutex();
  121. opaque->vout = vout;
  122. opaque->acodec = NULL;
  123. opaque->buffer_proxy = NULL;
  124. overlay->opaque_class = &g_vout_overlay_amediacodec_class;
  125. overlay->format = SDL_FCC__AMC;
  126. overlay->pitches = opaque->pitches;
  127. overlay->pixels = opaque->pixels;
  128. overlay->w = width;
  129. overlay->h = height;
  130. overlay->is_private = 1;
  131. overlay->free_l = overlay_free_l;
  132. overlay->lock = overlay_lock;
  133. overlay->unlock = overlay_unlock;
  134. overlay->unref = overlay_unref;
  135. overlay->func_fill_frame = func_fill_frame;
  136. if (!opaque->mutex) {
  137. ALOGE("SDL_CreateMutex failed");
  138. goto fail;
  139. }
  140. return overlay;
  141. fail:
  142. overlay_free_l(overlay);
  143. return NULL;
  144. }
  145. bool SDL_VoutOverlayAMediaCodec_isKindOf(SDL_VoutOverlay *overlay)
  146. {
  147. return check_object(overlay, __func__);
  148. }
  149. int SDL_VoutOverlayAMediaCodec_releaseFrame_l(SDL_VoutOverlay *overlay, SDL_AMediaCodec *acodec, bool render)
  150. {
  151. if (!check_object(overlay, __func__))
  152. return -1;
  153. SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
  154. return SDL_VoutAndroid_releaseBufferProxyP_l(opaque->vout, &opaque->buffer_proxy, render);
  155. }