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.

641 lines
18KB

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