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.

648 lines
19KB

  1. /*
  2. * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
  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 "avcodec.h"
  31. #include "decode.h"
  32. #include "h264_parse.h"
  33. #include "hevc_parse.h"
  34. #include "hwaccel.h"
  35. #include "internal.h"
  36. #include "mediacodec_wrapper.h"
  37. #include "mediacodecdec_common.h"
  38. typedef struct MediaCodecH264DecContext {
  39. MediaCodecDecContext *ctx;
  40. AVFifoBuffer *fifo;
  41. AVPacket buffered_pkt;
  42. } MediaCodecH264DecContext;
  43. static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
  44. {
  45. MediaCodecH264DecContext *s = avctx->priv_data;
  46. ff_mediacodec_dec_close(avctx, s->ctx);
  47. s->ctx = NULL;
  48. av_fifo_free(s->fifo);
  49. av_packet_unref(&s->buffered_pkt);
  50. return 0;
  51. }
  52. #if CONFIG_H264_MEDIACODEC_DECODER || CONFIG_HEVC_MEDIACODEC_DECODER
  53. static int h2645_ps_to_nalu(const uint8_t *src, int src_size, uint8_t **out, int *out_size)
  54. {
  55. int i;
  56. int ret = 0;
  57. uint8_t *p = NULL;
  58. static const uint8_t nalu_header[] = { 0x00, 0x00, 0x00, 0x01 };
  59. if (!out || !out_size) {
  60. return AVERROR(EINVAL);
  61. }
  62. p = av_malloc(sizeof(nalu_header) + src_size);
  63. if (!p) {
  64. return AVERROR(ENOMEM);
  65. }
  66. *out = p;
  67. *out_size = sizeof(nalu_header) + src_size;
  68. memcpy(p, nalu_header, sizeof(nalu_header));
  69. memcpy(p + sizeof(nalu_header), src, src_size);
  70. /* Escape 0x00, 0x00, 0x0{0-3} pattern */
  71. for (i = 4; i < *out_size; i++) {
  72. if (i < *out_size - 3 &&
  73. p[i + 0] == 0 &&
  74. p[i + 1] == 0 &&
  75. p[i + 2] <= 3) {
  76. uint8_t *new;
  77. *out_size += 1;
  78. new = av_realloc(*out, *out_size);
  79. if (!new) {
  80. ret = AVERROR(ENOMEM);
  81. goto done;
  82. }
  83. *out = p = new;
  84. i = i + 2;
  85. memmove(p + i + 1, p + i, *out_size - (i + 1));
  86. p[i] = 0x03;
  87. }
  88. }
  89. done:
  90. if (ret < 0) {
  91. av_freep(out);
  92. *out_size = 0;
  93. }
  94. return ret;
  95. }
  96. #endif
  97. #if CONFIG_H264_MEDIACODEC_DECODER
  98. static int h264_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
  99. {
  100. int i;
  101. int ret;
  102. H264ParamSets ps;
  103. const PPS *pps = NULL;
  104. const SPS *sps = NULL;
  105. int is_avc = 0;
  106. int nal_length_size = 0;
  107. memset(&ps, 0, sizeof(ps));
  108. ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
  109. &ps, &is_avc, &nal_length_size, 0, avctx);
  110. if (ret < 0) {
  111. goto done;
  112. }
  113. for (i = 0; i < MAX_PPS_COUNT; i++) {
  114. if (ps.pps_list[i]) {
  115. pps = (const PPS*)ps.pps_list[i]->data;
  116. break;
  117. }
  118. }
  119. if (pps) {
  120. if (ps.sps_list[pps->sps_id]) {
  121. sps = (const SPS*)ps.sps_list[pps->sps_id]->data;
  122. }
  123. }
  124. if (pps && sps) {
  125. uint8_t *data = NULL;
  126. int data_size = 0;
  127. if ((ret = h2645_ps_to_nalu(sps->data, sps->data_size, &data, &data_size)) < 0) {
  128. goto done;
  129. }
  130. ff_AMediaFormat_setBuffer(format, "csd-0", (void*)data, data_size);
  131. av_freep(&data);
  132. if ((ret = h2645_ps_to_nalu(pps->data, pps->data_size, &data, &data_size)) < 0) {
  133. goto done;
  134. }
  135. ff_AMediaFormat_setBuffer(format, "csd-1", (void*)data, data_size);
  136. av_freep(&data);
  137. } else {
  138. av_log(avctx, AV_LOG_ERROR, "Could not extract PPS/SPS from extradata");
  139. ret = AVERROR_INVALIDDATA;
  140. }
  141. done:
  142. ff_h264_ps_uninit(&ps);
  143. return ret;
  144. }
  145. #endif
  146. #if CONFIG_HEVC_MEDIACODEC_DECODER
  147. static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
  148. {
  149. int i;
  150. int ret;
  151. HEVCParamSets ps;
  152. HEVCSEI sei;
  153. const HEVCVPS *vps = NULL;
  154. const HEVCPPS *pps = NULL;
  155. const HEVCSPS *sps = NULL;
  156. int is_nalff = 0;
  157. int nal_length_size = 0;
  158. uint8_t *vps_data = NULL;
  159. uint8_t *sps_data = NULL;
  160. uint8_t *pps_data = NULL;
  161. int vps_data_size = 0;
  162. int sps_data_size = 0;
  163. int pps_data_size = 0;
  164. memset(&ps, 0, sizeof(ps));
  165. memset(&sei, 0, sizeof(sei));
  166. ret = ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size,
  167. &ps, &sei, &is_nalff, &nal_length_size, 0, 1, avctx);
  168. if (ret < 0) {
  169. goto done;
  170. }
  171. for (i = 0; i < HEVC_MAX_VPS_COUNT; i++) {
  172. if (ps.vps_list[i]) {
  173. vps = (const HEVCVPS*)ps.vps_list[i]->data;
  174. break;
  175. }
  176. }
  177. for (i = 0; i < HEVC_MAX_PPS_COUNT; i++) {
  178. if (ps.pps_list[i]) {
  179. pps = (const HEVCPPS*)ps.pps_list[i]->data;
  180. break;
  181. }
  182. }
  183. if (pps) {
  184. if (ps.sps_list[pps->sps_id]) {
  185. sps = (const HEVCSPS*)ps.sps_list[pps->sps_id]->data;
  186. }
  187. }
  188. if (vps && pps && sps) {
  189. uint8_t *data;
  190. int data_size;
  191. if ((ret = h2645_ps_to_nalu(vps->data, vps->data_size, &vps_data, &vps_data_size)) < 0 ||
  192. (ret = h2645_ps_to_nalu(sps->data, sps->data_size, &sps_data, &sps_data_size)) < 0 ||
  193. (ret = h2645_ps_to_nalu(pps->data, pps->data_size, &pps_data, &pps_data_size)) < 0) {
  194. goto done;
  195. }
  196. data_size = vps_data_size + sps_data_size + pps_data_size;
  197. data = av_mallocz(data_size);
  198. if (!data) {
  199. ret = AVERROR(ENOMEM);
  200. goto done;
  201. }
  202. memcpy(data , vps_data, vps_data_size);
  203. memcpy(data + vps_data_size , sps_data, sps_data_size);
  204. memcpy(data + vps_data_size + sps_data_size, pps_data, pps_data_size);
  205. ff_AMediaFormat_setBuffer(format, "csd-0", data, data_size);
  206. av_freep(&data);
  207. } else {
  208. av_log(avctx, AV_LOG_ERROR, "Could not extract VPS/PPS/SPS from extradata");
  209. ret = AVERROR_INVALIDDATA;
  210. }
  211. done:
  212. av_freep(&vps_data);
  213. av_freep(&sps_data);
  214. av_freep(&pps_data);
  215. return ret;
  216. }
  217. #endif
  218. #if CONFIG_MPEG2_MEDIACODEC_DECODER
  219. static int mpeg2_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
  220. {
  221. int ret = 0;
  222. if (avctx->extradata) {
  223. ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
  224. }
  225. return ret;
  226. }
  227. #endif
  228. #if CONFIG_MPEG4_MEDIACODEC_DECODER
  229. static int mpeg4_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
  230. {
  231. int ret = 0;
  232. if (avctx->extradata) {
  233. ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
  234. }
  235. return ret;
  236. }
  237. #endif
  238. #if CONFIG_VP8_MEDIACODEC_DECODER || CONFIG_VP9_MEDIACODEC_DECODER
  239. static int vpx_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
  240. {
  241. int ret = 0;
  242. if (avctx->extradata) {
  243. ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
  244. }
  245. return ret;
  246. }
  247. #endif
  248. static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
  249. {
  250. int ret;
  251. const char *codec_mime = NULL;
  252. FFAMediaFormat *format = NULL;
  253. MediaCodecH264DecContext *s = avctx->priv_data;
  254. format = ff_AMediaFormat_new();
  255. if (!format) {
  256. av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
  257. ret = AVERROR_EXTERNAL;
  258. goto done;
  259. }
  260. switch (avctx->codec_id) {
  261. #if CONFIG_H264_MEDIACODEC_DECODER
  262. case AV_CODEC_ID_H264:
  263. codec_mime = "video/avc";
  264. ret = h264_set_extradata(avctx, format);
  265. if (ret < 0)
  266. goto done;
  267. break;
  268. #endif
  269. #if CONFIG_HEVC_MEDIACODEC_DECODER
  270. case AV_CODEC_ID_HEVC:
  271. codec_mime = "video/hevc";
  272. ret = hevc_set_extradata(avctx, format);
  273. if (ret < 0)
  274. goto done;
  275. break;
  276. #endif
  277. #if CONFIG_MPEG2_MEDIACODEC_DECODER
  278. case AV_CODEC_ID_MPEG2VIDEO:
  279. codec_mime = "video/mpeg2";
  280. ret = mpeg2_set_extradata(avctx, format);
  281. if (ret < 0)
  282. goto done;
  283. break;
  284. #endif
  285. #if CONFIG_MPEG4_MEDIACODEC_DECODER
  286. case AV_CODEC_ID_MPEG4:
  287. codec_mime = "video/mp4v-es",
  288. ret = mpeg4_set_extradata(avctx, format);
  289. if (ret < 0)
  290. goto done;
  291. break;
  292. #endif
  293. #if CONFIG_VP8_MEDIACODEC_DECODER
  294. case AV_CODEC_ID_VP8:
  295. codec_mime = "video/x-vnd.on2.vp8";
  296. ret = vpx_set_extradata(avctx, format);
  297. if (ret < 0)
  298. goto done;
  299. break;
  300. #endif
  301. #if CONFIG_VP9_MEDIACODEC_DECODER
  302. case AV_CODEC_ID_VP9:
  303. codec_mime = "video/x-vnd.on2.vp9";
  304. ret = vpx_set_extradata(avctx, format);
  305. if (ret < 0)
  306. goto done;
  307. break;
  308. #endif
  309. default:
  310. av_assert0(0);
  311. }
  312. ff_AMediaFormat_setString(format, "mime", codec_mime);
  313. ff_AMediaFormat_setInt32(format, "width", avctx->width);
  314. ff_AMediaFormat_setInt32(format, "height", avctx->height);
  315. s->ctx = av_mallocz(sizeof(*s->ctx));
  316. if (!s->ctx) {
  317. av_log(avctx, AV_LOG_ERROR, "Failed to allocate MediaCodecDecContext\n");
  318. ret = AVERROR(ENOMEM);
  319. goto done;
  320. }
  321. if ((ret = ff_mediacodec_dec_init(avctx, s->ctx, codec_mime, format)) < 0) {
  322. s->ctx = NULL;
  323. goto done;
  324. }
  325. av_log(avctx, AV_LOG_INFO, "MediaCodec started successfully, ret = %d\n", ret);
  326. s->fifo = av_fifo_alloc(sizeof(AVPacket));
  327. if (!s->fifo) {
  328. ret = AVERROR(ENOMEM);
  329. goto done;
  330. }
  331. done:
  332. if (format) {
  333. ff_AMediaFormat_delete(format);
  334. }
  335. if (ret < 0) {
  336. mediacodec_decode_close(avctx);
  337. }
  338. return ret;
  339. }
  340. static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
  341. {
  342. MediaCodecH264DecContext *s = avctx->priv_data;
  343. int ret;
  344. int got_frame = 0;
  345. int is_eof = 0;
  346. AVPacket pkt = { 0 };
  347. /*
  348. * MediaCodec.flush() discards both input and output buffers, thus we
  349. * need to delay the call to this function until the user has released or
  350. * renderered the frames he retains.
  351. *
  352. * After we have buffered an input packet, check if the codec is in the
  353. * flushing state. If it is, we need to call ff_mediacodec_dec_flush.
  354. *
  355. * ff_mediacodec_dec_flush returns 0 if the flush cannot be performed on
  356. * the codec (because the user retains frames). The codec stays in the
  357. * flushing state.
  358. *
  359. * ff_mediacodec_dec_flush returns 1 if the flush can actually be
  360. * performed on the codec. The codec leaves the flushing state and can
  361. * process again packets.
  362. *
  363. * ff_mediacodec_dec_flush returns a negative value if an error has
  364. * occurred.
  365. *
  366. */
  367. if (ff_mediacodec_dec_is_flushing(avctx, s->ctx)) {
  368. if (!ff_mediacodec_dec_flush(avctx, s->ctx)) {
  369. return AVERROR(EAGAIN);
  370. }
  371. }
  372. ret = ff_decode_get_packet(avctx, &pkt);
  373. if (ret == AVERROR_EOF)
  374. is_eof = 1;
  375. else if (ret == AVERROR(EAGAIN))
  376. ; /* no input packet, but fallthrough to check for pending frames */
  377. else if (ret < 0)
  378. return ret;
  379. /* buffer the input packet */
  380. if (pkt.size) {
  381. if (av_fifo_space(s->fifo) < sizeof(pkt)) {
  382. ret = av_fifo_realloc2(s->fifo,
  383. av_fifo_size(s->fifo) + sizeof(pkt));
  384. if (ret < 0) {
  385. av_packet_unref(&pkt);
  386. return ret;
  387. }
  388. }
  389. av_fifo_generic_write(s->fifo, &pkt, sizeof(pkt), NULL);
  390. }
  391. /* process buffered data */
  392. while (!got_frame) {
  393. /* prepare the input data */
  394. if (s->buffered_pkt.size <= 0) {
  395. av_packet_unref(&s->buffered_pkt);
  396. /* no more data */
  397. if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
  398. AVPacket null_pkt = { 0 };
  399. if (is_eof) {
  400. ret = ff_mediacodec_dec_decode(avctx, s->ctx, frame,
  401. &got_frame, &null_pkt);
  402. if (ret < 0)
  403. return ret;
  404. else if (got_frame)
  405. return 0;
  406. else
  407. return AVERROR_EOF;
  408. }
  409. return AVERROR(EAGAIN);
  410. }
  411. av_fifo_generic_read(s->fifo, &s->buffered_pkt, sizeof(s->buffered_pkt), NULL);
  412. }
  413. ret = ff_mediacodec_dec_decode(avctx, s->ctx, frame, &got_frame, &s->buffered_pkt);
  414. if (ret < 0)
  415. return ret;
  416. s->buffered_pkt.size -= ret;
  417. s->buffered_pkt.data += ret;
  418. }
  419. return 0;
  420. }
  421. static void mediacodec_decode_flush(AVCodecContext *avctx)
  422. {
  423. MediaCodecH264DecContext *s = avctx->priv_data;
  424. while (av_fifo_size(s->fifo)) {
  425. AVPacket pkt;
  426. av_fifo_generic_read(s->fifo, &pkt, sizeof(pkt), NULL);
  427. av_packet_unref(&pkt);
  428. }
  429. av_fifo_reset(s->fifo);
  430. av_packet_unref(&s->buffered_pkt);
  431. ff_mediacodec_dec_flush(avctx, s->ctx);
  432. }
  433. static const AVCodecHWConfigInternal *mediacodec_hw_configs[] = {
  434. &(const AVCodecHWConfigInternal) {
  435. .public = {
  436. .pix_fmt = AV_PIX_FMT_MEDIACODEC,
  437. .methods = AV_CODEC_HW_CONFIG_METHOD_AD_HOC |
  438. AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX,
  439. .device_type = AV_HWDEVICE_TYPE_MEDIACODEC,
  440. },
  441. .hwaccel = NULL,
  442. },
  443. NULL
  444. };
  445. #if CONFIG_H264_MEDIACODEC_DECODER
  446. AVCodec ff_h264_mediacodec_decoder = {
  447. .name = "h264_mediacodec",
  448. .long_name = NULL_IF_CONFIG_SMALL("H.264 Android MediaCodec decoder"),
  449. .type = AVMEDIA_TYPE_VIDEO,
  450. .id = AV_CODEC_ID_H264,
  451. .priv_data_size = sizeof(MediaCodecH264DecContext),
  452. .init = mediacodec_decode_init,
  453. .receive_frame = mediacodec_receive_frame,
  454. .flush = mediacodec_decode_flush,
  455. .close = mediacodec_decode_close,
  456. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE,
  457. .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
  458. .bsfs = "h264_mp4toannexb",
  459. .hw_configs = mediacodec_hw_configs,
  460. .wrapper_name = "mediacodec",
  461. };
  462. #endif
  463. #if CONFIG_HEVC_MEDIACODEC_DECODER
  464. AVCodec ff_hevc_mediacodec_decoder = {
  465. .name = "hevc_mediacodec",
  466. .long_name = NULL_IF_CONFIG_SMALL("H.265 Android MediaCodec decoder"),
  467. .type = AVMEDIA_TYPE_VIDEO,
  468. .id = AV_CODEC_ID_HEVC,
  469. .priv_data_size = sizeof(MediaCodecH264DecContext),
  470. .init = mediacodec_decode_init,
  471. .receive_frame = mediacodec_receive_frame,
  472. .flush = mediacodec_decode_flush,
  473. .close = mediacodec_decode_close,
  474. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE,
  475. .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
  476. .bsfs = "hevc_mp4toannexb",
  477. .hw_configs = mediacodec_hw_configs,
  478. .wrapper_name = "mediacodec",
  479. };
  480. #endif
  481. #if CONFIG_MPEG2_MEDIACODEC_DECODER
  482. AVCodec ff_mpeg2_mediacodec_decoder = {
  483. .name = "mpeg2_mediacodec",
  484. .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Android MediaCodec decoder"),
  485. .type = AVMEDIA_TYPE_VIDEO,
  486. .id = AV_CODEC_ID_MPEG2VIDEO,
  487. .priv_data_size = sizeof(MediaCodecH264DecContext),
  488. .init = mediacodec_decode_init,
  489. .receive_frame = mediacodec_receive_frame,
  490. .flush = mediacodec_decode_flush,
  491. .close = mediacodec_decode_close,
  492. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE,
  493. .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
  494. .hw_configs = mediacodec_hw_configs,
  495. .wrapper_name = "mediacodec",
  496. };
  497. #endif
  498. #if CONFIG_MPEG4_MEDIACODEC_DECODER
  499. AVCodec ff_mpeg4_mediacodec_decoder = {
  500. .name = "mpeg4_mediacodec",
  501. .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Android MediaCodec decoder"),
  502. .type = AVMEDIA_TYPE_VIDEO,
  503. .id = AV_CODEC_ID_MPEG4,
  504. .priv_data_size = sizeof(MediaCodecH264DecContext),
  505. .init = mediacodec_decode_init,
  506. .receive_frame = mediacodec_receive_frame,
  507. .flush = mediacodec_decode_flush,
  508. .close = mediacodec_decode_close,
  509. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE,
  510. .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
  511. .hw_configs = mediacodec_hw_configs,
  512. .wrapper_name = "mediacodec",
  513. };
  514. #endif
  515. #if CONFIG_VP8_MEDIACODEC_DECODER
  516. AVCodec ff_vp8_mediacodec_decoder = {
  517. .name = "vp8_mediacodec",
  518. .long_name = NULL_IF_CONFIG_SMALL("VP8 Android MediaCodec decoder"),
  519. .type = AVMEDIA_TYPE_VIDEO,
  520. .id = AV_CODEC_ID_VP8,
  521. .priv_data_size = sizeof(MediaCodecH264DecContext),
  522. .init = mediacodec_decode_init,
  523. .receive_frame = mediacodec_receive_frame,
  524. .flush = mediacodec_decode_flush,
  525. .close = mediacodec_decode_close,
  526. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE,
  527. .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
  528. .hw_configs = mediacodec_hw_configs,
  529. .wrapper_name = "mediacodec",
  530. };
  531. #endif
  532. #if CONFIG_VP9_MEDIACODEC_DECODER
  533. AVCodec ff_vp9_mediacodec_decoder = {
  534. .name = "vp9_mediacodec",
  535. .long_name = NULL_IF_CONFIG_SMALL("VP9 Android MediaCodec decoder"),
  536. .type = AVMEDIA_TYPE_VIDEO,
  537. .id = AV_CODEC_ID_VP9,
  538. .priv_data_size = sizeof(MediaCodecH264DecContext),
  539. .init = mediacodec_decode_init,
  540. .receive_frame = mediacodec_receive_frame,
  541. .flush = mediacodec_decode_flush,
  542. .close = mediacodec_decode_close,
  543. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE,
  544. .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS,
  545. .hw_configs = mediacodec_hw_configs,
  546. .wrapper_name = "mediacodec",
  547. };
  548. #endif