You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
9.8KB

  1. /*
  2. * Android MediaCodec H.264 decoder
  3. *
  4. * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
  5. *
  6. * This file is part of FFmpeg.
  7. *
  8. * FFmpeg is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * FFmpeg is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with FFmpeg; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include "libavutil/avassert.h"
  25. #include "libavutil/common.h"
  26. #include "libavutil/fifo.h"
  27. #include "libavutil/opt.h"
  28. #include "libavutil/intreadwrite.h"
  29. #include "libavutil/pixfmt.h"
  30. #include "libavutil/atomic.h"
  31. #include "avcodec.h"
  32. #include "internal.h"
  33. #include "mediacodecdec.h"
  34. #include "mediacodec_wrapper.h"
  35. #define CODEC_MIME "video/avc"
  36. typedef struct MediaCodecH264DecContext {
  37. MediaCodecDecContext ctx;
  38. AVBSFContext *bsf;
  39. AVFifoBuffer *fifo;
  40. AVPacket filtered_pkt;
  41. } MediaCodecH264DecContext;
  42. static int h264_extradata_to_annexb_sps_pps(AVCodecContext *avctx,
  43. uint8_t **extradata_annexb, int *extradata_annexb_size,
  44. int *sps_offset, int *sps_size,
  45. int *pps_offset, int *pps_size)
  46. {
  47. uint16_t unit_size;
  48. uint64_t total_size = 0;
  49. uint8_t i, j, unit_nb;
  50. uint8_t sps_seen = 0;
  51. uint8_t pps_seen = 0;
  52. const uint8_t *extradata;
  53. static const uint8_t nalu_header[4] = { 0x00, 0x00, 0x00, 0x01 };
  54. if (avctx->extradata_size < 8) {
  55. av_log(avctx, AV_LOG_ERROR,
  56. "Too small extradata size, corrupted stream or invalid MP4/AVCC bitstream\n");
  57. return AVERROR(EINVAL);
  58. }
  59. *extradata_annexb = NULL;
  60. *extradata_annexb_size = 0;
  61. *sps_offset = *sps_size = 0;
  62. *pps_offset = *pps_size = 0;
  63. extradata = avctx->extradata + 4;
  64. /* skip length size */
  65. extradata++;
  66. for (j = 0; j < 2; j ++) {
  67. if (j == 0) {
  68. /* number of sps unit(s) */
  69. unit_nb = *extradata++ & 0x1f;
  70. } else {
  71. /* number of pps unit(s) */
  72. unit_nb = *extradata++;
  73. }
  74. for (i = 0; i < unit_nb; i++) {
  75. int err;
  76. unit_size = AV_RB16(extradata);
  77. total_size += unit_size + 4;
  78. if (total_size > INT_MAX) {
  79. av_log(avctx, AV_LOG_ERROR,
  80. "Too big extradata size, corrupted stream or invalid MP4/AVCC bitstream\n");
  81. av_freep(extradata_annexb);
  82. return AVERROR(EINVAL);
  83. }
  84. if (extradata + 2 + unit_size > avctx->extradata + avctx->extradata_size) {
  85. av_log(avctx, AV_LOG_ERROR, "Packet header is not contained in global extradata, "
  86. "corrupted stream or invalid MP4/AVCC bitstream\n");
  87. av_freep(extradata_annexb);
  88. return AVERROR(EINVAL);
  89. }
  90. if ((err = av_reallocp(extradata_annexb, total_size)) < 0) {
  91. return err;
  92. }
  93. memcpy(*extradata_annexb + total_size - unit_size - 4, nalu_header, 4);
  94. memcpy(*extradata_annexb + total_size - unit_size, extradata + 2, unit_size);
  95. extradata += 2 + unit_size;
  96. }
  97. if (unit_nb) {
  98. if (j == 0) {
  99. sps_seen = 1;
  100. *sps_size = total_size;
  101. } else {
  102. pps_seen = 1;
  103. *pps_size = total_size - *sps_size;
  104. *pps_offset = *sps_size;
  105. }
  106. }
  107. }
  108. *extradata_annexb_size = total_size;
  109. if (!sps_seen)
  110. av_log(avctx, AV_LOG_WARNING,
  111. "Warning: SPS NALU missing or invalid. "
  112. "The resulting stream may not play.\n");
  113. if (!pps_seen)
  114. av_log(avctx, AV_LOG_WARNING,
  115. "Warning: PPS NALU missing or invalid. "
  116. "The resulting stream may not play.\n");
  117. return 0;
  118. }
  119. static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
  120. {
  121. MediaCodecH264DecContext *s = avctx->priv_data;
  122. ff_mediacodec_dec_close(avctx, &s->ctx);
  123. av_fifo_free(s->fifo);
  124. av_bsf_free(&s->bsf);
  125. av_packet_unref(&s->filtered_pkt);
  126. return 0;
  127. }
  128. static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
  129. {
  130. int ret;
  131. FFAMediaFormat *format = NULL;
  132. MediaCodecH264DecContext *s = avctx->priv_data;
  133. format = ff_AMediaFormat_new();
  134. if (!format) {
  135. av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
  136. ret = AVERROR_EXTERNAL;
  137. goto done;
  138. }
  139. ff_AMediaFormat_setString(format, "mime", CODEC_MIME);
  140. ff_AMediaFormat_setInt32(format, "width", avctx->width);
  141. ff_AMediaFormat_setInt32(format, "height", avctx->height);
  142. if (avctx->extradata[0] == 1) {
  143. uint8_t *extradata = NULL;
  144. int extradata_size = 0;
  145. int sps_offset, sps_size;
  146. int pps_offset, pps_size;
  147. if ((ret = h264_extradata_to_annexb_sps_pps(avctx, &extradata, &extradata_size,
  148. &sps_offset, &sps_size, &pps_offset, &pps_size)) < 0) {
  149. goto done;
  150. }
  151. ff_AMediaFormat_setBuffer(format, "csd-0", extradata + sps_offset, sps_size);
  152. ff_AMediaFormat_setBuffer(format, "csd-1", extradata + pps_offset, pps_size);
  153. av_freep(&extradata);
  154. } else {
  155. ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
  156. }
  157. if ((ret = ff_mediacodec_dec_init(avctx, &s->ctx, CODEC_MIME, format)) < 0) {
  158. goto done;
  159. }
  160. av_log(avctx, AV_LOG_INFO, "MediaCodec started successfully, ret = %d\n", ret);
  161. s->fifo = av_fifo_alloc(sizeof(AVPacket));
  162. if (!s->fifo) {
  163. ret = AVERROR(ENOMEM);
  164. goto done;
  165. }
  166. const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
  167. if(!bsf) {
  168. ret = AVERROR_BSF_NOT_FOUND;
  169. goto done;
  170. }
  171. if ((ret = av_bsf_alloc(bsf, &s->bsf))) {
  172. goto done;
  173. }
  174. if (((ret = avcodec_parameters_from_context(s->bsf->par_in, avctx)) < 0) ||
  175. ((ret = av_bsf_init(s->bsf)) < 0)) {
  176. goto done;
  177. }
  178. av_init_packet(&s->filtered_pkt);
  179. done:
  180. if (format) {
  181. ff_AMediaFormat_delete(format);
  182. }
  183. if (ret < 0) {
  184. mediacodec_decode_close(avctx);
  185. }
  186. return ret;
  187. }
  188. static int mediacodec_process_data(AVCodecContext *avctx, AVFrame *frame,
  189. int *got_frame, AVPacket *pkt)
  190. {
  191. MediaCodecH264DecContext *s = avctx->priv_data;
  192. return ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, pkt);
  193. }
  194. static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
  195. int *got_frame, AVPacket *avpkt)
  196. {
  197. MediaCodecH264DecContext *s = avctx->priv_data;
  198. AVFrame *frame = data;
  199. int ret;
  200. /* buffer the input packet */
  201. if (avpkt->size) {
  202. AVPacket input_ref = { 0 };
  203. if (av_fifo_space(s->fifo) < sizeof(input_ref)) {
  204. ret = av_fifo_realloc2(s->fifo,
  205. av_fifo_size(s->fifo) + sizeof(input_ref));
  206. if (ret < 0)
  207. return ret;
  208. }
  209. ret = av_packet_ref(&input_ref, avpkt);
  210. if (ret < 0)
  211. return ret;
  212. av_fifo_generic_write(s->fifo, &input_ref, sizeof(input_ref), NULL);
  213. }
  214. /* process buffered data */
  215. while (!*got_frame) {
  216. /* prepare the input data -- convert to Annex B if needed */
  217. if (s->filtered_pkt.size <= 0) {
  218. AVPacket input_pkt = { 0 };
  219. av_packet_unref(&s->filtered_pkt);
  220. /* no more data */
  221. if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
  222. return avpkt->size ? avpkt->size :
  223. ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, avpkt);
  224. }
  225. av_fifo_generic_read(s->fifo, &input_pkt, sizeof(input_pkt), NULL);
  226. ret = av_bsf_send_packet(s->bsf, &input_pkt);
  227. if (ret < 0) {
  228. return ret;
  229. }
  230. ret = av_bsf_receive_packet(s->bsf, &s->filtered_pkt);
  231. if (ret == AVERROR(EAGAIN)) {
  232. goto done;
  233. }
  234. /* h264_mp4toannexb is used here and does not requires flushing */
  235. av_assert0(ret != AVERROR_EOF);
  236. if (ret < 0) {
  237. return ret;
  238. }
  239. }
  240. ret = mediacodec_process_data(avctx, frame, got_frame, &s->filtered_pkt);
  241. if (ret < 0)
  242. return ret;
  243. s->filtered_pkt.size -= ret;
  244. s->filtered_pkt.data += ret;
  245. }
  246. done:
  247. return avpkt->size;
  248. }
  249. static void mediacodec_decode_flush(AVCodecContext *avctx)
  250. {
  251. MediaCodecH264DecContext *s = avctx->priv_data;
  252. while (av_fifo_size(s->fifo)) {
  253. AVPacket pkt;
  254. av_fifo_generic_read(s->fifo, &pkt, sizeof(pkt), NULL);
  255. av_packet_unref(&pkt);
  256. }
  257. av_fifo_reset(s->fifo);
  258. av_packet_unref(&s->filtered_pkt);
  259. ff_mediacodec_dec_flush(avctx, &s->ctx);
  260. }
  261. AVCodec ff_h264_mediacodec_decoder = {
  262. .name = "h264_mediacodec",
  263. .long_name = NULL_IF_CONFIG_SMALL("H.264 Android MediaCodec decoder"),
  264. .type = AVMEDIA_TYPE_VIDEO,
  265. .id = AV_CODEC_ID_H264,
  266. .priv_data_size = sizeof(MediaCodecH264DecContext),
  267. .init = mediacodec_decode_init,
  268. .decode = mediacodec_decode_frame,
  269. .flush = mediacodec_decode_flush,
  270. .close = mediacodec_decode_close,
  271. .capabilities = CODEC_CAP_DELAY,
  272. };