├── README.md ├── configure └── libavcodec ├── allcodecs.c ├── codec_list.c ├── mediacodec.c ├── mediacodec.h ├── mediacodec_surface.c ├── mediacodec_surface.h ├── mediacodec_sw_buffer.c ├── mediacodec_sw_buffer.h ├── mediacodec_wrapper.c ├── mediacodec_wrapper.h ├── mediacodecdec.c ├── mediacodecdec_common.c ├── mediacodecdec_common.h └── mediacodecenc.c /README.md: -------------------------------------------------------------------------------- 1 | # ffmpeg_mediacodec_encoder 2 | -------------------------------------------------------------------------------- /libavcodec/allcodecs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Provide registration of all codecs, parsers and bitstream filters for libavcodec. 3 | * Copyright (c) 2002 Fabrice Bellard 4 | * 5 | * This file is part of FFmpeg. 6 | * 7 | * FFmpeg 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 | * FFmpeg 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 FFmpeg; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /** 23 | * @file 24 | * Provide registration of all codecs, parsers and bitstream filters for libavcodec. 25 | */ 26 | 27 | #include "config.h" 28 | #include "libavutil/thread.h" 29 | #include "avcodec.h" 30 | #include "version.h" 31 | 32 | extern AVCodec ff_a64multi_encoder; 33 | extern AVCodec ff_a64multi5_encoder; 34 | extern AVCodec ff_aasc_decoder; 35 | extern AVCodec ff_aic_decoder; 36 | extern AVCodec ff_alias_pix_encoder; 37 | extern AVCodec ff_alias_pix_decoder; 38 | extern AVCodec ff_agm_decoder; 39 | extern AVCodec ff_amv_encoder; 40 | extern AVCodec ff_amv_decoder; 41 | extern AVCodec ff_anm_decoder; 42 | extern AVCodec ff_ansi_decoder; 43 | extern AVCodec ff_apng_encoder; 44 | extern AVCodec ff_apng_decoder; 45 | extern AVCodec ff_arbc_decoder; 46 | extern AVCodec ff_asv1_encoder; 47 | extern AVCodec ff_asv1_decoder; 48 | extern AVCodec ff_asv2_encoder; 49 | extern AVCodec ff_asv2_decoder; 50 | extern AVCodec ff_aura_decoder; 51 | extern AVCodec ff_aura2_decoder; 52 | extern AVCodec ff_avrp_encoder; 53 | extern AVCodec ff_avrp_decoder; 54 | extern AVCodec ff_avrn_decoder; 55 | extern AVCodec ff_avs_decoder; 56 | extern AVCodec ff_avui_encoder; 57 | extern AVCodec ff_avui_decoder; 58 | extern AVCodec ff_ayuv_encoder; 59 | extern AVCodec ff_ayuv_decoder; 60 | extern AVCodec ff_bethsoftvid_decoder; 61 | extern AVCodec ff_bfi_decoder; 62 | extern AVCodec ff_bink_decoder; 63 | extern AVCodec ff_bitpacked_decoder; 64 | extern AVCodec ff_bmp_encoder; 65 | extern AVCodec ff_bmp_decoder; 66 | extern AVCodec ff_bmv_video_decoder; 67 | extern AVCodec ff_brender_pix_decoder; 68 | extern AVCodec ff_c93_decoder; 69 | extern AVCodec ff_cavs_decoder; 70 | extern AVCodec ff_cdgraphics_decoder; 71 | extern AVCodec ff_cdxl_decoder; 72 | extern AVCodec ff_cfhd_decoder; 73 | extern AVCodec ff_cinepak_encoder; 74 | extern AVCodec ff_cinepak_decoder; 75 | extern AVCodec ff_clearvideo_decoder; 76 | extern AVCodec ff_cljr_encoder; 77 | extern AVCodec ff_cljr_decoder; 78 | extern AVCodec ff_cllc_decoder; 79 | extern AVCodec ff_comfortnoise_encoder; 80 | extern AVCodec ff_comfortnoise_decoder; 81 | extern AVCodec ff_cpia_decoder; 82 | extern AVCodec ff_cscd_decoder; 83 | extern AVCodec ff_cyuv_decoder; 84 | extern AVCodec ff_dds_decoder; 85 | extern AVCodec ff_dfa_decoder; 86 | extern AVCodec ff_dirac_decoder; 87 | extern AVCodec ff_dnxhd_encoder; 88 | extern AVCodec ff_dnxhd_decoder; 89 | extern AVCodec ff_dpx_encoder; 90 | extern AVCodec ff_dpx_decoder; 91 | extern AVCodec ff_dsicinvideo_decoder; 92 | extern AVCodec ff_dvaudio_decoder; 93 | extern AVCodec ff_dvvideo_encoder; 94 | extern AVCodec ff_dvvideo_decoder; 95 | extern AVCodec ff_dxa_decoder; 96 | extern AVCodec ff_dxtory_decoder; 97 | extern AVCodec ff_dxv_decoder; 98 | extern AVCodec ff_eacmv_decoder; 99 | extern AVCodec ff_eamad_decoder; 100 | extern AVCodec ff_eatgq_decoder; 101 | extern AVCodec ff_eatgv_decoder; 102 | extern AVCodec ff_eatqi_decoder; 103 | extern AVCodec ff_eightbps_decoder; 104 | extern AVCodec ff_eightsvx_exp_decoder; 105 | extern AVCodec ff_eightsvx_fib_decoder; 106 | extern AVCodec ff_escape124_decoder; 107 | extern AVCodec ff_escape130_decoder; 108 | extern AVCodec ff_exr_decoder; 109 | extern AVCodec ff_ffv1_encoder; 110 | extern AVCodec ff_ffv1_decoder; 111 | extern AVCodec ff_ffvhuff_encoder; 112 | extern AVCodec ff_ffvhuff_decoder; 113 | extern AVCodec ff_fic_decoder; 114 | extern AVCodec ff_fits_encoder; 115 | extern AVCodec ff_fits_decoder; 116 | extern AVCodec ff_flashsv_encoder; 117 | extern AVCodec ff_flashsv_decoder; 118 | extern AVCodec ff_flashsv2_encoder; 119 | extern AVCodec ff_flashsv2_decoder; 120 | extern AVCodec ff_flic_decoder; 121 | extern AVCodec ff_flv_encoder; 122 | extern AVCodec ff_flv_decoder; 123 | extern AVCodec ff_fmvc_decoder; 124 | extern AVCodec ff_fourxm_decoder; 125 | extern AVCodec ff_fraps_decoder; 126 | extern AVCodec ff_frwu_decoder; 127 | extern AVCodec ff_g2m_decoder; 128 | extern AVCodec ff_gdv_decoder; 129 | extern AVCodec ff_gif_encoder; 130 | extern AVCodec ff_gif_decoder; 131 | extern AVCodec ff_h261_encoder; 132 | extern AVCodec ff_h261_decoder; 133 | extern AVCodec ff_h263_encoder; 134 | extern AVCodec ff_h263_decoder; 135 | extern AVCodec ff_h263i_decoder; 136 | extern AVCodec ff_h263p_encoder; 137 | extern AVCodec ff_h263p_decoder; 138 | extern AVCodec ff_h263_v4l2m2m_decoder; 139 | extern AVCodec ff_h264_decoder; 140 | extern AVCodec ff_h264_crystalhd_decoder; 141 | extern AVCodec ff_h264_v4l2m2m_decoder; 142 | extern AVCodec ff_h264_mediacodec_decoder; 143 | extern AVCodec ff_h264_mmal_decoder; 144 | extern AVCodec ff_h264_qsv_decoder; 145 | extern AVCodec ff_h264_rkmpp_decoder; 146 | extern AVCodec ff_hap_encoder; 147 | extern AVCodec ff_hap_decoder; 148 | extern AVCodec ff_hevc_decoder; 149 | extern AVCodec ff_hevc_qsv_decoder; 150 | extern AVCodec ff_hevc_rkmpp_decoder; 151 | extern AVCodec ff_hevc_v4l2m2m_decoder; 152 | extern AVCodec ff_hnm4_video_decoder; 153 | extern AVCodec ff_hq_hqa_decoder; 154 | extern AVCodec ff_hqx_decoder; 155 | extern AVCodec ff_huffyuv_encoder; 156 | extern AVCodec ff_huffyuv_decoder; 157 | extern AVCodec ff_hymt_decoder; 158 | extern AVCodec ff_idcin_decoder; 159 | extern AVCodec ff_iff_ilbm_decoder; 160 | extern AVCodec ff_imm4_decoder; 161 | extern AVCodec ff_indeo2_decoder; 162 | extern AVCodec ff_indeo3_decoder; 163 | extern AVCodec ff_indeo4_decoder; 164 | extern AVCodec ff_indeo5_decoder; 165 | extern AVCodec ff_interplay_video_decoder; 166 | extern AVCodec ff_jpeg2000_encoder; 167 | extern AVCodec ff_jpeg2000_decoder; 168 | extern AVCodec ff_jpegls_encoder; 169 | extern AVCodec ff_jpegls_decoder; 170 | extern AVCodec ff_jv_decoder; 171 | extern AVCodec ff_kgv1_decoder; 172 | extern AVCodec ff_kmvc_decoder; 173 | extern AVCodec ff_lagarith_decoder; 174 | extern AVCodec ff_ljpeg_encoder; 175 | extern AVCodec ff_loco_decoder; 176 | extern AVCodec ff_lscr_decoder; 177 | extern AVCodec ff_m101_decoder; 178 | extern AVCodec ff_magicyuv_encoder; 179 | extern AVCodec ff_magicyuv_decoder; 180 | extern AVCodec ff_mdec_decoder; 181 | extern AVCodec ff_mimic_decoder; 182 | extern AVCodec ff_mjpeg_encoder; 183 | extern AVCodec ff_mjpeg_decoder; 184 | extern AVCodec ff_mjpegb_decoder; 185 | extern AVCodec ff_mmvideo_decoder; 186 | extern AVCodec ff_motionpixels_decoder; 187 | extern AVCodec ff_mpeg1video_encoder; 188 | extern AVCodec ff_mpeg1video_decoder; 189 | extern AVCodec ff_mpeg2video_encoder; 190 | extern AVCodec ff_mpeg2video_decoder; 191 | extern AVCodec ff_mpeg4_encoder; 192 | extern AVCodec ff_mpeg4_decoder; 193 | extern AVCodec ff_mpeg4_crystalhd_decoder; 194 | extern AVCodec ff_mpeg4_v4l2m2m_decoder; 195 | extern AVCodec ff_mpeg4_mmal_decoder; 196 | extern AVCodec ff_mpegvideo_decoder; 197 | extern AVCodec ff_mpeg1_v4l2m2m_decoder; 198 | extern AVCodec ff_mpeg2_mmal_decoder; 199 | extern AVCodec ff_mpeg2_crystalhd_decoder; 200 | extern AVCodec ff_mpeg2_v4l2m2m_decoder; 201 | extern AVCodec ff_mpeg2_qsv_decoder; 202 | extern AVCodec ff_mpeg2_mediacodec_decoder; 203 | extern AVCodec ff_msa1_decoder; 204 | extern AVCodec ff_mscc_decoder; 205 | extern AVCodec ff_msmpeg4v1_decoder; 206 | extern AVCodec ff_msmpeg4v2_encoder; 207 | extern AVCodec ff_msmpeg4v2_decoder; 208 | extern AVCodec ff_msmpeg4v3_encoder; 209 | extern AVCodec ff_msmpeg4v3_decoder; 210 | extern AVCodec ff_msmpeg4_crystalhd_decoder; 211 | extern AVCodec ff_msrle_decoder; 212 | extern AVCodec ff_mss1_decoder; 213 | extern AVCodec ff_mss2_decoder; 214 | extern AVCodec ff_msvideo1_encoder; 215 | extern AVCodec ff_msvideo1_decoder; 216 | extern AVCodec ff_mszh_decoder; 217 | extern AVCodec ff_mts2_decoder; 218 | extern AVCodec ff_mvc1_decoder; 219 | extern AVCodec ff_mvc2_decoder; 220 | extern AVCodec ff_mwsc_decoder; 221 | extern AVCodec ff_mxpeg_decoder; 222 | extern AVCodec ff_nuv_decoder; 223 | extern AVCodec ff_paf_video_decoder; 224 | extern AVCodec ff_pam_encoder; 225 | extern AVCodec ff_pam_decoder; 226 | extern AVCodec ff_pbm_encoder; 227 | extern AVCodec ff_pbm_decoder; 228 | extern AVCodec ff_pcx_encoder; 229 | extern AVCodec ff_pcx_decoder; 230 | extern AVCodec ff_pgm_encoder; 231 | extern AVCodec ff_pgm_decoder; 232 | extern AVCodec ff_pgmyuv_encoder; 233 | extern AVCodec ff_pgmyuv_decoder; 234 | extern AVCodec ff_pictor_decoder; 235 | extern AVCodec ff_pixlet_decoder; 236 | extern AVCodec ff_png_encoder; 237 | extern AVCodec ff_png_decoder; 238 | extern AVCodec ff_ppm_encoder; 239 | extern AVCodec ff_ppm_decoder; 240 | extern AVCodec ff_prores_encoder; 241 | extern AVCodec ff_prores_decoder; 242 | extern AVCodec ff_prores_aw_encoder; 243 | extern AVCodec ff_prores_ks_encoder; 244 | extern AVCodec ff_prosumer_decoder; 245 | extern AVCodec ff_psd_decoder; 246 | extern AVCodec ff_ptx_decoder; 247 | extern AVCodec ff_qdraw_decoder; 248 | extern AVCodec ff_qpeg_decoder; 249 | extern AVCodec ff_qtrle_encoder; 250 | extern AVCodec ff_qtrle_decoder; 251 | extern AVCodec ff_r10k_encoder; 252 | extern AVCodec ff_r10k_decoder; 253 | extern AVCodec ff_r210_encoder; 254 | extern AVCodec ff_r210_decoder; 255 | extern AVCodec ff_rasc_decoder; 256 | extern AVCodec ff_rawvideo_encoder; 257 | extern AVCodec ff_rawvideo_decoder; 258 | extern AVCodec ff_rl2_decoder; 259 | extern AVCodec ff_roq_encoder; 260 | extern AVCodec ff_roq_decoder; 261 | extern AVCodec ff_rpza_decoder; 262 | extern AVCodec ff_rscc_decoder; 263 | extern AVCodec ff_rv10_encoder; 264 | extern AVCodec ff_rv10_decoder; 265 | extern AVCodec ff_rv20_encoder; 266 | extern AVCodec ff_rv20_decoder; 267 | extern AVCodec ff_rv30_decoder; 268 | extern AVCodec ff_rv40_decoder; 269 | extern AVCodec ff_s302m_encoder; 270 | extern AVCodec ff_s302m_decoder; 271 | extern AVCodec ff_sanm_decoder; 272 | extern AVCodec ff_scpr_decoder; 273 | extern AVCodec ff_screenpresso_decoder; 274 | extern AVCodec ff_sdx2_dpcm_decoder; 275 | extern AVCodec ff_sgi_encoder; 276 | extern AVCodec ff_sgi_decoder; 277 | extern AVCodec ff_sgirle_decoder; 278 | extern AVCodec ff_sheervideo_decoder; 279 | extern AVCodec ff_smacker_decoder; 280 | extern AVCodec ff_smc_decoder; 281 | extern AVCodec ff_smvjpeg_decoder; 282 | extern AVCodec ff_snow_encoder; 283 | extern AVCodec ff_snow_decoder; 284 | extern AVCodec ff_sp5x_decoder; 285 | extern AVCodec ff_speedhq_decoder; 286 | extern AVCodec ff_srgc_decoder; 287 | extern AVCodec ff_sunrast_encoder; 288 | extern AVCodec ff_sunrast_decoder; 289 | extern AVCodec ff_svq1_encoder; 290 | extern AVCodec ff_svq1_decoder; 291 | extern AVCodec ff_svq3_decoder; 292 | extern AVCodec ff_targa_encoder; 293 | extern AVCodec ff_targa_decoder; 294 | extern AVCodec ff_targa_y216_decoder; 295 | extern AVCodec ff_tdsc_decoder; 296 | extern AVCodec ff_theora_decoder; 297 | extern AVCodec ff_thp_decoder; 298 | extern AVCodec ff_tiertexseqvideo_decoder; 299 | extern AVCodec ff_tiff_encoder; 300 | extern AVCodec ff_tiff_decoder; 301 | extern AVCodec ff_tmv_decoder; 302 | extern AVCodec ff_truemotion1_decoder; 303 | extern AVCodec ff_truemotion2_decoder; 304 | extern AVCodec ff_truemotion2rt_decoder; 305 | extern AVCodec ff_tscc_decoder; 306 | extern AVCodec ff_tscc2_decoder; 307 | extern AVCodec ff_txd_decoder; 308 | extern AVCodec ff_ulti_decoder; 309 | extern AVCodec ff_utvideo_encoder; 310 | extern AVCodec ff_utvideo_decoder; 311 | extern AVCodec ff_v210_encoder; 312 | extern AVCodec ff_v210_decoder; 313 | extern AVCodec ff_v210x_decoder; 314 | extern AVCodec ff_v308_encoder; 315 | extern AVCodec ff_v308_decoder; 316 | extern AVCodec ff_v408_encoder; 317 | extern AVCodec ff_v408_decoder; 318 | extern AVCodec ff_v410_encoder; 319 | extern AVCodec ff_v410_decoder; 320 | extern AVCodec ff_vb_decoder; 321 | extern AVCodec ff_vble_decoder; 322 | extern AVCodec ff_vc1_decoder; 323 | extern AVCodec ff_vc1_crystalhd_decoder; 324 | extern AVCodec ff_vc1image_decoder; 325 | extern AVCodec ff_vc1_mmal_decoder; 326 | extern AVCodec ff_vc1_qsv_decoder; 327 | extern AVCodec ff_vc1_v4l2m2m_decoder; 328 | extern AVCodec ff_vc2_encoder; 329 | extern AVCodec ff_vcr1_decoder; 330 | extern AVCodec ff_vmdvideo_decoder; 331 | extern AVCodec ff_vmnc_decoder; 332 | extern AVCodec ff_vp3_decoder; 333 | extern AVCodec ff_vp4_decoder; 334 | extern AVCodec ff_vp5_decoder; 335 | extern AVCodec ff_vp6_decoder; 336 | extern AVCodec ff_vp6a_decoder; 337 | extern AVCodec ff_vp6f_decoder; 338 | extern AVCodec ff_vp7_decoder; 339 | extern AVCodec ff_vp8_decoder; 340 | extern AVCodec ff_vp8_rkmpp_decoder; 341 | extern AVCodec ff_vp8_v4l2m2m_decoder; 342 | extern AVCodec ff_vp9_decoder; 343 | extern AVCodec ff_vp9_rkmpp_decoder; 344 | extern AVCodec ff_vp9_v4l2m2m_decoder; 345 | extern AVCodec ff_vqa_decoder; 346 | extern AVCodec ff_webp_decoder; 347 | extern AVCodec ff_wcmv_decoder; 348 | extern AVCodec ff_wrapped_avframe_encoder; 349 | extern AVCodec ff_wrapped_avframe_decoder; 350 | extern AVCodec ff_wmv1_encoder; 351 | extern AVCodec ff_wmv1_decoder; 352 | extern AVCodec ff_wmv2_encoder; 353 | extern AVCodec ff_wmv2_decoder; 354 | extern AVCodec ff_wmv3_decoder; 355 | extern AVCodec ff_wmv3_crystalhd_decoder; 356 | extern AVCodec ff_wmv3image_decoder; 357 | extern AVCodec ff_wnv1_decoder; 358 | extern AVCodec ff_xan_wc3_decoder; 359 | extern AVCodec ff_xan_wc4_decoder; 360 | extern AVCodec ff_xbm_encoder; 361 | extern AVCodec ff_xbm_decoder; 362 | extern AVCodec ff_xface_encoder; 363 | extern AVCodec ff_xface_decoder; 364 | extern AVCodec ff_xl_decoder; 365 | extern AVCodec ff_xpm_decoder; 366 | extern AVCodec ff_xwd_encoder; 367 | extern AVCodec ff_xwd_decoder; 368 | extern AVCodec ff_y41p_encoder; 369 | extern AVCodec ff_y41p_decoder; 370 | extern AVCodec ff_ylc_decoder; 371 | extern AVCodec ff_yop_decoder; 372 | extern AVCodec ff_yuv4_encoder; 373 | extern AVCodec ff_yuv4_decoder; 374 | extern AVCodec ff_zero12v_decoder; 375 | extern AVCodec ff_zerocodec_decoder; 376 | extern AVCodec ff_zlib_encoder; 377 | extern AVCodec ff_zlib_decoder; 378 | extern AVCodec ff_zmbv_encoder; 379 | extern AVCodec ff_zmbv_decoder; 380 | 381 | /* audio codecs */ 382 | extern AVCodec ff_aac_encoder; 383 | extern AVCodec ff_aac_decoder; 384 | extern AVCodec ff_aac_fixed_decoder; 385 | extern AVCodec ff_aac_latm_decoder; 386 | extern AVCodec ff_ac3_encoder; 387 | extern AVCodec ff_ac3_decoder; 388 | extern AVCodec ff_ac3_fixed_encoder; 389 | extern AVCodec ff_ac3_fixed_decoder; 390 | extern AVCodec ff_alac_encoder; 391 | extern AVCodec ff_alac_decoder; 392 | extern AVCodec ff_als_decoder; 393 | extern AVCodec ff_amrnb_decoder; 394 | extern AVCodec ff_amrwb_decoder; 395 | extern AVCodec ff_ape_decoder; 396 | extern AVCodec ff_aptx_encoder; 397 | extern AVCodec ff_aptx_decoder; 398 | extern AVCodec ff_aptx_hd_encoder; 399 | extern AVCodec ff_aptx_hd_decoder; 400 | extern AVCodec ff_atrac1_decoder; 401 | extern AVCodec ff_atrac3_decoder; 402 | extern AVCodec ff_atrac3al_decoder; 403 | extern AVCodec ff_atrac3p_decoder; 404 | extern AVCodec ff_atrac3pal_decoder; 405 | extern AVCodec ff_atrac9_decoder; 406 | extern AVCodec ff_binkaudio_dct_decoder; 407 | extern AVCodec ff_binkaudio_rdft_decoder; 408 | extern AVCodec ff_bmv_audio_decoder; 409 | extern AVCodec ff_cook_decoder; 410 | extern AVCodec ff_dca_encoder; 411 | extern AVCodec ff_dca_decoder; 412 | extern AVCodec ff_dolby_e_decoder; 413 | extern AVCodec ff_dsd_lsbf_decoder; 414 | extern AVCodec ff_dsd_msbf_decoder; 415 | extern AVCodec ff_dsd_lsbf_planar_decoder; 416 | extern AVCodec ff_dsd_msbf_planar_decoder; 417 | extern AVCodec ff_dsicinaudio_decoder; 418 | extern AVCodec ff_dss_sp_decoder; 419 | extern AVCodec ff_dst_decoder; 420 | extern AVCodec ff_eac3_encoder; 421 | extern AVCodec ff_eac3_decoder; 422 | extern AVCodec ff_evrc_decoder; 423 | extern AVCodec ff_ffwavesynth_decoder; 424 | extern AVCodec ff_flac_encoder; 425 | extern AVCodec ff_flac_decoder; 426 | extern AVCodec ff_g723_1_encoder; 427 | extern AVCodec ff_g723_1_decoder; 428 | extern AVCodec ff_g729_decoder; 429 | extern AVCodec ff_gsm_decoder; 430 | extern AVCodec ff_gsm_ms_decoder; 431 | extern AVCodec ff_hcom_decoder; 432 | extern AVCodec ff_iac_decoder; 433 | extern AVCodec ff_ilbc_decoder; 434 | extern AVCodec ff_imc_decoder; 435 | extern AVCodec ff_interplay_acm_decoder; 436 | extern AVCodec ff_mace3_decoder; 437 | extern AVCodec ff_mace6_decoder; 438 | extern AVCodec ff_metasound_decoder; 439 | extern AVCodec ff_mlp_encoder; 440 | extern AVCodec ff_mlp_decoder; 441 | extern AVCodec ff_mp1_decoder; 442 | extern AVCodec ff_mp1float_decoder; 443 | extern AVCodec ff_mp2_encoder; 444 | extern AVCodec ff_mp2_decoder; 445 | extern AVCodec ff_mp2float_decoder; 446 | extern AVCodec ff_mp2fixed_encoder; 447 | extern AVCodec ff_mp3float_decoder; 448 | extern AVCodec ff_mp3_decoder; 449 | extern AVCodec ff_mp3adufloat_decoder; 450 | extern AVCodec ff_mp3adu_decoder; 451 | extern AVCodec ff_mp3on4float_decoder; 452 | extern AVCodec ff_mp3on4_decoder; 453 | extern AVCodec ff_mpc7_decoder; 454 | extern AVCodec ff_mpc8_decoder; 455 | extern AVCodec ff_nellymoser_encoder; 456 | extern AVCodec ff_nellymoser_decoder; 457 | extern AVCodec ff_on2avc_decoder; 458 | extern AVCodec ff_opus_encoder; 459 | extern AVCodec ff_opus_decoder; 460 | extern AVCodec ff_paf_audio_decoder; 461 | extern AVCodec ff_qcelp_decoder; 462 | extern AVCodec ff_qdm2_decoder; 463 | extern AVCodec ff_qdmc_decoder; 464 | extern AVCodec ff_ra_144_encoder; 465 | extern AVCodec ff_ra_144_decoder; 466 | extern AVCodec ff_ra_288_decoder; 467 | extern AVCodec ff_ralf_decoder; 468 | extern AVCodec ff_sbc_encoder; 469 | extern AVCodec ff_sbc_decoder; 470 | extern AVCodec ff_shorten_decoder; 471 | extern AVCodec ff_sipr_decoder; 472 | extern AVCodec ff_smackaud_decoder; 473 | extern AVCodec ff_sonic_encoder; 474 | extern AVCodec ff_sonic_decoder; 475 | extern AVCodec ff_sonic_ls_encoder; 476 | extern AVCodec ff_tak_decoder; 477 | extern AVCodec ff_truehd_encoder; 478 | extern AVCodec ff_truehd_decoder; 479 | extern AVCodec ff_truespeech_decoder; 480 | extern AVCodec ff_tta_encoder; 481 | extern AVCodec ff_tta_decoder; 482 | extern AVCodec ff_twinvq_decoder; 483 | extern AVCodec ff_vmdaudio_decoder; 484 | extern AVCodec ff_vorbis_encoder; 485 | extern AVCodec ff_vorbis_decoder; 486 | extern AVCodec ff_wavpack_encoder; 487 | extern AVCodec ff_wavpack_decoder; 488 | extern AVCodec ff_wmalossless_decoder; 489 | extern AVCodec ff_wmapro_decoder; 490 | extern AVCodec ff_wmav1_encoder; 491 | extern AVCodec ff_wmav1_decoder; 492 | extern AVCodec ff_wmav2_encoder; 493 | extern AVCodec ff_wmav2_decoder; 494 | extern AVCodec ff_wmavoice_decoder; 495 | extern AVCodec ff_ws_snd1_decoder; 496 | extern AVCodec ff_xma1_decoder; 497 | extern AVCodec ff_xma2_decoder; 498 | 499 | /* PCM codecs */ 500 | extern AVCodec ff_pcm_alaw_encoder; 501 | extern AVCodec ff_pcm_alaw_decoder; 502 | extern AVCodec ff_pcm_bluray_decoder; 503 | extern AVCodec ff_pcm_dvd_encoder; 504 | extern AVCodec ff_pcm_dvd_decoder; 505 | extern AVCodec ff_pcm_f16le_decoder; 506 | extern AVCodec ff_pcm_f24le_decoder; 507 | extern AVCodec ff_pcm_f32be_encoder; 508 | extern AVCodec ff_pcm_f32be_decoder; 509 | extern AVCodec ff_pcm_f32le_encoder; 510 | extern AVCodec ff_pcm_f32le_decoder; 511 | extern AVCodec ff_pcm_f64be_encoder; 512 | extern AVCodec ff_pcm_f64be_decoder; 513 | extern AVCodec ff_pcm_f64le_encoder; 514 | extern AVCodec ff_pcm_f64le_decoder; 515 | extern AVCodec ff_pcm_lxf_decoder; 516 | extern AVCodec ff_pcm_mulaw_encoder; 517 | extern AVCodec ff_pcm_mulaw_decoder; 518 | extern AVCodec ff_pcm_s8_encoder; 519 | extern AVCodec ff_pcm_s8_decoder; 520 | extern AVCodec ff_pcm_s8_planar_encoder; 521 | extern AVCodec ff_pcm_s8_planar_decoder; 522 | extern AVCodec ff_pcm_s16be_encoder; 523 | extern AVCodec ff_pcm_s16be_decoder; 524 | extern AVCodec ff_pcm_s16be_planar_encoder; 525 | extern AVCodec ff_pcm_s16be_planar_decoder; 526 | extern AVCodec ff_pcm_s16le_encoder; 527 | extern AVCodec ff_pcm_s16le_decoder; 528 | extern AVCodec ff_pcm_s16le_planar_encoder; 529 | extern AVCodec ff_pcm_s16le_planar_decoder; 530 | extern AVCodec ff_pcm_s24be_encoder; 531 | extern AVCodec ff_pcm_s24be_decoder; 532 | extern AVCodec ff_pcm_s24daud_encoder; 533 | extern AVCodec ff_pcm_s24daud_decoder; 534 | extern AVCodec ff_pcm_s24le_encoder; 535 | extern AVCodec ff_pcm_s24le_decoder; 536 | extern AVCodec ff_pcm_s24le_planar_encoder; 537 | extern AVCodec ff_pcm_s24le_planar_decoder; 538 | extern AVCodec ff_pcm_s32be_encoder; 539 | extern AVCodec ff_pcm_s32be_decoder; 540 | extern AVCodec ff_pcm_s32le_encoder; 541 | extern AVCodec ff_pcm_s32le_decoder; 542 | extern AVCodec ff_pcm_s32le_planar_encoder; 543 | extern AVCodec ff_pcm_s32le_planar_decoder; 544 | extern AVCodec ff_pcm_s64be_encoder; 545 | extern AVCodec ff_pcm_s64be_decoder; 546 | extern AVCodec ff_pcm_s64le_encoder; 547 | extern AVCodec ff_pcm_s64le_decoder; 548 | extern AVCodec ff_pcm_u8_encoder; 549 | extern AVCodec ff_pcm_u8_decoder; 550 | extern AVCodec ff_pcm_u16be_encoder; 551 | extern AVCodec ff_pcm_u16be_decoder; 552 | extern AVCodec ff_pcm_u16le_encoder; 553 | extern AVCodec ff_pcm_u16le_decoder; 554 | extern AVCodec ff_pcm_u24be_encoder; 555 | extern AVCodec ff_pcm_u24be_decoder; 556 | extern AVCodec ff_pcm_u24le_encoder; 557 | extern AVCodec ff_pcm_u24le_decoder; 558 | extern AVCodec ff_pcm_u32be_encoder; 559 | extern AVCodec ff_pcm_u32be_decoder; 560 | extern AVCodec ff_pcm_u32le_encoder; 561 | extern AVCodec ff_pcm_u32le_decoder; 562 | extern AVCodec ff_pcm_vidc_encoder; 563 | extern AVCodec ff_pcm_vidc_decoder; 564 | extern AVCodec ff_pcm_zork_decoder; 565 | 566 | /* DPCM codecs */ 567 | extern AVCodec ff_gremlin_dpcm_decoder; 568 | extern AVCodec ff_interplay_dpcm_decoder; 569 | extern AVCodec ff_roq_dpcm_encoder; 570 | extern AVCodec ff_roq_dpcm_decoder; 571 | extern AVCodec ff_sol_dpcm_decoder; 572 | extern AVCodec ff_xan_dpcm_decoder; 573 | 574 | /* ADPCM codecs */ 575 | extern AVCodec ff_adpcm_4xm_decoder; 576 | extern AVCodec ff_adpcm_adx_encoder; 577 | extern AVCodec ff_adpcm_adx_decoder; 578 | extern AVCodec ff_adpcm_afc_decoder; 579 | extern AVCodec ff_adpcm_agm_decoder; 580 | extern AVCodec ff_adpcm_aica_decoder; 581 | extern AVCodec ff_adpcm_ct_decoder; 582 | extern AVCodec ff_adpcm_dtk_decoder; 583 | extern AVCodec ff_adpcm_ea_decoder; 584 | extern AVCodec ff_adpcm_ea_maxis_xa_decoder; 585 | extern AVCodec ff_adpcm_ea_r1_decoder; 586 | extern AVCodec ff_adpcm_ea_r2_decoder; 587 | extern AVCodec ff_adpcm_ea_r3_decoder; 588 | extern AVCodec ff_adpcm_ea_xas_decoder; 589 | extern AVCodec ff_adpcm_g722_encoder; 590 | extern AVCodec ff_adpcm_g722_decoder; 591 | extern AVCodec ff_adpcm_g726_encoder; 592 | extern AVCodec ff_adpcm_g726_decoder; 593 | extern AVCodec ff_adpcm_g726le_encoder; 594 | extern AVCodec ff_adpcm_g726le_decoder; 595 | extern AVCodec ff_adpcm_ima_amv_decoder; 596 | extern AVCodec ff_adpcm_ima_apc_decoder; 597 | extern AVCodec ff_adpcm_ima_dat4_decoder; 598 | extern AVCodec ff_adpcm_ima_dk3_decoder; 599 | extern AVCodec ff_adpcm_ima_dk4_decoder; 600 | extern AVCodec ff_adpcm_ima_ea_eacs_decoder; 601 | extern AVCodec ff_adpcm_ima_ea_sead_decoder; 602 | extern AVCodec ff_adpcm_ima_iss_decoder; 603 | extern AVCodec ff_adpcm_ima_oki_decoder; 604 | extern AVCodec ff_adpcm_ima_qt_encoder; 605 | extern AVCodec ff_adpcm_ima_qt_decoder; 606 | extern AVCodec ff_adpcm_ima_rad_decoder; 607 | extern AVCodec ff_adpcm_ima_smjpeg_decoder; 608 | extern AVCodec ff_adpcm_ima_wav_encoder; 609 | extern AVCodec ff_adpcm_ima_wav_decoder; 610 | extern AVCodec ff_adpcm_ima_ws_decoder; 611 | extern AVCodec ff_adpcm_ms_encoder; 612 | extern AVCodec ff_adpcm_ms_decoder; 613 | extern AVCodec ff_adpcm_mtaf_decoder; 614 | extern AVCodec ff_adpcm_psx_decoder; 615 | extern AVCodec ff_adpcm_sbpro_2_decoder; 616 | extern AVCodec ff_adpcm_sbpro_3_decoder; 617 | extern AVCodec ff_adpcm_sbpro_4_decoder; 618 | extern AVCodec ff_adpcm_swf_encoder; 619 | extern AVCodec ff_adpcm_swf_decoder; 620 | extern AVCodec ff_adpcm_thp_decoder; 621 | extern AVCodec ff_adpcm_thp_le_decoder; 622 | extern AVCodec ff_adpcm_vima_decoder; 623 | extern AVCodec ff_adpcm_xa_decoder; 624 | extern AVCodec ff_adpcm_yamaha_encoder; 625 | extern AVCodec ff_adpcm_yamaha_decoder; 626 | 627 | /* subtitles */ 628 | extern AVCodec ff_ssa_encoder; 629 | extern AVCodec ff_ssa_decoder; 630 | extern AVCodec ff_ass_encoder; 631 | extern AVCodec ff_ass_decoder; 632 | extern AVCodec ff_ccaption_decoder; 633 | extern AVCodec ff_dvbsub_encoder; 634 | extern AVCodec ff_dvbsub_decoder; 635 | extern AVCodec ff_dvdsub_encoder; 636 | extern AVCodec ff_dvdsub_decoder; 637 | extern AVCodec ff_jacosub_decoder; 638 | extern AVCodec ff_microdvd_decoder; 639 | extern AVCodec ff_movtext_encoder; 640 | extern AVCodec ff_movtext_decoder; 641 | extern AVCodec ff_mpl2_decoder; 642 | extern AVCodec ff_pgssub_decoder; 643 | extern AVCodec ff_pjs_decoder; 644 | extern AVCodec ff_realtext_decoder; 645 | extern AVCodec ff_sami_decoder; 646 | extern AVCodec ff_srt_encoder; 647 | extern AVCodec ff_srt_decoder; 648 | extern AVCodec ff_stl_decoder; 649 | extern AVCodec ff_subrip_encoder; 650 | extern AVCodec ff_subrip_decoder; 651 | extern AVCodec ff_subviewer_decoder; 652 | extern AVCodec ff_subviewer1_decoder; 653 | extern AVCodec ff_text_encoder; 654 | extern AVCodec ff_text_decoder; 655 | extern AVCodec ff_vplayer_decoder; 656 | extern AVCodec ff_webvtt_encoder; 657 | extern AVCodec ff_webvtt_decoder; 658 | extern AVCodec ff_xsub_encoder; 659 | extern AVCodec ff_xsub_decoder; 660 | 661 | /* external libraries */ 662 | extern AVCodec ff_aac_at_encoder; 663 | extern AVCodec ff_aac_at_decoder; 664 | extern AVCodec ff_ac3_at_decoder; 665 | extern AVCodec ff_adpcm_ima_qt_at_decoder; 666 | extern AVCodec ff_alac_at_encoder; 667 | extern AVCodec ff_alac_at_decoder; 668 | extern AVCodec ff_amr_nb_at_decoder; 669 | extern AVCodec ff_eac3_at_decoder; 670 | extern AVCodec ff_gsm_ms_at_decoder; 671 | extern AVCodec ff_ilbc_at_encoder; 672 | extern AVCodec ff_ilbc_at_decoder; 673 | extern AVCodec ff_mp1_at_decoder; 674 | extern AVCodec ff_mp2_at_decoder; 675 | extern AVCodec ff_mp3_at_decoder; 676 | extern AVCodec ff_pcm_alaw_at_encoder; 677 | extern AVCodec ff_pcm_alaw_at_decoder; 678 | extern AVCodec ff_pcm_mulaw_at_encoder; 679 | extern AVCodec ff_pcm_mulaw_at_decoder; 680 | extern AVCodec ff_qdmc_at_decoder; 681 | extern AVCodec ff_qdm2_at_decoder; 682 | extern AVCodec ff_libaom_av1_decoder; 683 | extern AVCodec ff_libaom_av1_encoder; 684 | extern AVCodec ff_libaribb24_decoder; 685 | extern AVCodec ff_libcelt_decoder; 686 | extern AVCodec ff_libcodec2_encoder; 687 | extern AVCodec ff_libcodec2_decoder; 688 | extern AVCodec ff_libdav1d_decoder; 689 | extern AVCodec ff_libdavs2_decoder; 690 | extern AVCodec ff_libfdk_aac_encoder; 691 | extern AVCodec ff_libfdk_aac_decoder; 692 | extern AVCodec ff_libgsm_encoder; 693 | extern AVCodec ff_libgsm_decoder; 694 | extern AVCodec ff_libgsm_ms_encoder; 695 | extern AVCodec ff_libgsm_ms_decoder; 696 | extern AVCodec ff_libilbc_encoder; 697 | extern AVCodec ff_libilbc_decoder; 698 | extern AVCodec ff_libmp3lame_encoder; 699 | extern AVCodec ff_libopencore_amrnb_encoder; 700 | extern AVCodec ff_libopencore_amrnb_decoder; 701 | extern AVCodec ff_libopencore_amrwb_decoder; 702 | extern AVCodec ff_libopenjpeg_encoder; 703 | extern AVCodec ff_libopenjpeg_decoder; 704 | extern AVCodec ff_libopus_encoder; 705 | extern AVCodec ff_libopus_decoder; 706 | extern AVCodec ff_librsvg_decoder; 707 | extern AVCodec ff_libshine_encoder; 708 | extern AVCodec ff_libspeex_encoder; 709 | extern AVCodec ff_libspeex_decoder; 710 | extern AVCodec ff_libtheora_encoder; 711 | extern AVCodec ff_libtwolame_encoder; 712 | extern AVCodec ff_libvo_amrwbenc_encoder; 713 | extern AVCodec ff_libvorbis_encoder; 714 | extern AVCodec ff_libvorbis_decoder; 715 | extern AVCodec ff_libvpx_vp8_encoder; 716 | extern AVCodec ff_libvpx_vp8_decoder; 717 | extern AVCodec ff_libvpx_vp9_encoder; 718 | extern AVCodec ff_libvpx_vp9_decoder; 719 | extern AVCodec ff_libwavpack_encoder; 720 | /* preferred over libwebp */ 721 | extern AVCodec ff_libwebp_anim_encoder; 722 | extern AVCodec ff_libwebp_encoder; 723 | extern AVCodec ff_libx262_encoder; 724 | extern AVCodec ff_libx264_encoder; 725 | extern AVCodec ff_libx264rgb_encoder; 726 | extern AVCodec ff_libx265_encoder; 727 | extern AVCodec ff_libxavs_encoder; 728 | extern AVCodec ff_libxavs2_encoder; 729 | extern AVCodec ff_libxvid_encoder; 730 | extern AVCodec ff_libzvbi_teletext_decoder; 731 | 732 | /* text */ 733 | extern AVCodec ff_bintext_decoder; 734 | extern AVCodec ff_xbin_decoder; 735 | extern AVCodec ff_idf_decoder; 736 | 737 | /* external libraries, that shouldn't be used by default if one of the 738 | * above is available */ 739 | extern AVCodec ff_h263_v4l2m2m_encoder; 740 | extern AVCodec ff_libopenh264_encoder; 741 | extern AVCodec ff_libopenh264_decoder; 742 | extern AVCodec ff_h264_amf_encoder; 743 | extern AVCodec ff_h264_cuvid_decoder; 744 | extern AVCodec ff_h264_nvenc_encoder; 745 | extern AVCodec ff_h264_omx_encoder; 746 | extern AVCodec ff_h264_qsv_encoder; 747 | extern AVCodec ff_h264_v4l2m2m_encoder; 748 | extern AVCodec ff_h264_vaapi_encoder; 749 | extern AVCodec ff_h264_videotoolbox_encoder; 750 | #if FF_API_NVENC_OLD_NAME 751 | extern AVCodec ff_nvenc_encoder; 752 | extern AVCodec ff_nvenc_h264_encoder; 753 | extern AVCodec ff_nvenc_hevc_encoder; 754 | #endif 755 | extern AVCodec ff_hevc_amf_encoder; 756 | extern AVCodec ff_hevc_cuvid_decoder; 757 | extern AVCodec ff_hevc_mediacodec_decoder; 758 | extern AVCodec ff_hevc_mediacodec_encoder; 759 | extern AVCodec ff_hevc_nvenc_encoder; 760 | extern AVCodec ff_hevc_qsv_encoder; 761 | extern AVCodec ff_hevc_v4l2m2m_encoder; 762 | extern AVCodec ff_hevc_vaapi_encoder; 763 | extern AVCodec ff_hevc_videotoolbox_encoder; 764 | extern AVCodec ff_libkvazaar_encoder; 765 | extern AVCodec ff_mjpeg_cuvid_decoder; 766 | extern AVCodec ff_mjpeg_qsv_encoder; 767 | extern AVCodec ff_mjpeg_vaapi_encoder; 768 | extern AVCodec ff_mpeg1_cuvid_decoder; 769 | extern AVCodec ff_mpeg2_cuvid_decoder; 770 | extern AVCodec ff_mpeg2_qsv_encoder; 771 | extern AVCodec ff_mpeg2_vaapi_encoder; 772 | extern AVCodec ff_mpeg4_cuvid_decoder; 773 | extern AVCodec ff_mpeg4_mediacodec_decoder; 774 | extern AVCodec ff_mpeg4_v4l2m2m_encoder; 775 | extern AVCodec ff_vc1_cuvid_decoder; 776 | extern AVCodec ff_vp8_cuvid_decoder; 777 | extern AVCodec ff_vp8_mediacodec_decoder; 778 | extern AVCodec ff_vp8_qsv_decoder; 779 | extern AVCodec ff_vp8_v4l2m2m_encoder; 780 | extern AVCodec ff_vp8_vaapi_encoder; 781 | extern AVCodec ff_vp9_cuvid_decoder; 782 | extern AVCodec ff_vp9_mediacodec_decoder; 783 | extern AVCodec ff_vp9_vaapi_encoder; 784 | 785 | // The iterate API is not usable with ossfuzz due to the excessive size of binaries created 786 | #if CONFIG_OSSFUZZ 787 | AVCodec * codec_list[] = { 788 | NULL, 789 | NULL 790 | }; 791 | #else 792 | #include "libavcodec/codec_list.c" 793 | #endif 794 | 795 | static AVOnce av_codec_static_init = AV_ONCE_INIT; 796 | static void av_codec_init_static(void) 797 | { 798 | for (int i = 0; codec_list[i]; i++) { 799 | if (codec_list[i]->init_static_data) 800 | codec_list[i]->init_static_data((AVCodec*)codec_list[i]); 801 | } 802 | } 803 | 804 | const AVCodec *av_codec_iterate(void **opaque) 805 | { 806 | uintptr_t i = (uintptr_t)*opaque; 807 | const AVCodec *c = codec_list[i]; 808 | 809 | ff_thread_once(&av_codec_static_init, av_codec_init_static); 810 | 811 | if (c) 812 | *opaque = (void*)(i + 1); 813 | 814 | return c; 815 | } 816 | 817 | #if FF_API_NEXT 818 | FF_DISABLE_DEPRECATION_WARNINGS 819 | static AVOnce av_codec_next_init = AV_ONCE_INIT; 820 | 821 | static void av_codec_init_next(void) 822 | { 823 | AVCodec *prev = NULL, *p; 824 | void *i = 0; 825 | while ((p = (AVCodec*)av_codec_iterate(&i))) { 826 | if (prev) 827 | prev->next = p; 828 | prev = p; 829 | } 830 | } 831 | 832 | 833 | 834 | av_cold void avcodec_register(AVCodec *codec) 835 | { 836 | ff_thread_once(&av_codec_next_init, av_codec_init_next); 837 | } 838 | 839 | AVCodec *av_codec_next(const AVCodec *c) 840 | { 841 | ff_thread_once(&av_codec_next_init, av_codec_init_next); 842 | 843 | if (c) 844 | return c->next; 845 | else 846 | return (AVCodec*)codec_list[0]; 847 | } 848 | 849 | void avcodec_register_all(void) 850 | { 851 | ff_thread_once(&av_codec_next_init, av_codec_init_next); 852 | } 853 | FF_ENABLE_DEPRECATION_WARNINGS 854 | #endif 855 | 856 | static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id) 857 | { 858 | switch(id){ 859 | //This is for future deprecatec codec ids, its empty since 860 | //last major bump but will fill up again over time, please don't remove it 861 | default : return id; 862 | } 863 | } 864 | 865 | static AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *)) 866 | { 867 | const AVCodec *p, *experimental = NULL; 868 | void *i = 0; 869 | 870 | id = remap_deprecated_codec_id(id); 871 | 872 | while ((p = av_codec_iterate(&i))) { 873 | if (!x(p)) 874 | continue; 875 | if (p->id == id) { 876 | if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) { 877 | experimental = p; 878 | } else 879 | return (AVCodec*)p; 880 | } 881 | } 882 | 883 | return (AVCodec*)experimental; 884 | } 885 | 886 | AVCodec *avcodec_find_encoder(enum AVCodecID id) 887 | { 888 | return find_codec(id, av_codec_is_encoder); 889 | } 890 | 891 | AVCodec *avcodec_find_decoder(enum AVCodecID id) 892 | { 893 | return find_codec(id, av_codec_is_decoder); 894 | } 895 | 896 | static AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCodec *)) 897 | { 898 | void *i = 0; 899 | const AVCodec *p; 900 | 901 | if (!name) 902 | return NULL; 903 | 904 | while ((p = av_codec_iterate(&i))) { 905 | if (!x(p)) 906 | continue; 907 | if (strcmp(name, p->name) == 0) 908 | return (AVCodec*)p; 909 | } 910 | 911 | return NULL; 912 | } 913 | 914 | AVCodec *avcodec_find_encoder_by_name(const char *name) 915 | { 916 | return find_codec_by_name(name, av_codec_is_encoder); 917 | } 918 | 919 | AVCodec *avcodec_find_decoder_by_name(const char *name) 920 | { 921 | return find_codec_by_name(name, av_codec_is_decoder); 922 | } 923 | -------------------------------------------------------------------------------- /libavcodec/codec_list.c: -------------------------------------------------------------------------------- 1 | static const AVCodec * const codec_list[] = { 2 | &ff_a64multi_encoder, 3 | &ff_a64multi5_encoder, 4 | &ff_alias_pix_encoder, 5 | &ff_amv_encoder, 6 | &ff_apng_encoder, 7 | &ff_asv1_encoder, 8 | &ff_asv2_encoder, 9 | &ff_avrp_encoder, 10 | &ff_avui_encoder, 11 | &ff_ayuv_encoder, 12 | &ff_bmp_encoder, 13 | &ff_cinepak_encoder, 14 | &ff_cljr_encoder, 15 | &ff_comfortnoise_encoder, 16 | &ff_dnxhd_encoder, 17 | &ff_dpx_encoder, 18 | &ff_dvvideo_encoder, 19 | &ff_ffv1_encoder, 20 | &ff_ffvhuff_encoder, 21 | &ff_fits_encoder, 22 | &ff_flashsv_encoder, 23 | &ff_flashsv2_encoder, 24 | &ff_flv_encoder, 25 | &ff_gif_encoder, 26 | &ff_h261_encoder, 27 | &ff_h263_encoder, 28 | &ff_h263p_encoder, 29 | &ff_huffyuv_encoder, 30 | &ff_jpeg2000_encoder, 31 | &ff_jpegls_encoder, 32 | &ff_ljpeg_encoder, 33 | &ff_magicyuv_encoder, 34 | &ff_mjpeg_encoder, 35 | &ff_mpeg1video_encoder, 36 | &ff_mpeg2video_encoder, 37 | &ff_mpeg4_encoder, 38 | &ff_msmpeg4v2_encoder, 39 | &ff_msmpeg4v3_encoder, 40 | &ff_msvideo1_encoder, 41 | &ff_pam_encoder, 42 | &ff_pbm_encoder, 43 | &ff_pcx_encoder, 44 | &ff_pgm_encoder, 45 | &ff_pgmyuv_encoder, 46 | &ff_png_encoder, 47 | &ff_ppm_encoder, 48 | &ff_prores_encoder, 49 | &ff_prores_aw_encoder, 50 | &ff_prores_ks_encoder, 51 | &ff_qtrle_encoder, 52 | &ff_r10k_encoder, 53 | &ff_r210_encoder, 54 | &ff_rawvideo_encoder, 55 | &ff_roq_encoder, 56 | &ff_rv10_encoder, 57 | &ff_rv20_encoder, 58 | &ff_s302m_encoder, 59 | &ff_sgi_encoder, 60 | &ff_snow_encoder, 61 | &ff_sunrast_encoder, 62 | &ff_svq1_encoder, 63 | &ff_targa_encoder, 64 | &ff_tiff_encoder, 65 | &ff_utvideo_encoder, 66 | &ff_v210_encoder, 67 | &ff_v308_encoder, 68 | &ff_v408_encoder, 69 | &ff_v410_encoder, 70 | &ff_vc2_encoder, 71 | &ff_wrapped_avframe_encoder, 72 | &ff_wmv1_encoder, 73 | &ff_wmv2_encoder, 74 | &ff_xbm_encoder, 75 | &ff_xface_encoder, 76 | &ff_xwd_encoder, 77 | &ff_y41p_encoder, 78 | &ff_yuv4_encoder, 79 | &ff_zlib_encoder, 80 | &ff_zmbv_encoder, 81 | &ff_aac_encoder, 82 | &ff_ac3_encoder, 83 | &ff_ac3_fixed_encoder, 84 | &ff_alac_encoder, 85 | &ff_aptx_encoder, 86 | &ff_aptx_hd_encoder, 87 | &ff_dca_encoder, 88 | &ff_eac3_encoder, 89 | &ff_flac_encoder, 90 | &ff_g723_1_encoder, 91 | &ff_mlp_encoder, 92 | &ff_mp2_encoder, 93 | &ff_mp2fixed_encoder, 94 | &ff_nellymoser_encoder, 95 | &ff_opus_encoder, 96 | &ff_ra_144_encoder, 97 | &ff_sbc_encoder, 98 | &ff_sonic_encoder, 99 | &ff_sonic_ls_encoder, 100 | &ff_truehd_encoder, 101 | &ff_tta_encoder, 102 | &ff_vorbis_encoder, 103 | &ff_wavpack_encoder, 104 | &ff_wmav1_encoder, 105 | &ff_wmav2_encoder, 106 | &ff_pcm_alaw_encoder, 107 | &ff_pcm_dvd_encoder, 108 | &ff_pcm_f32be_encoder, 109 | &ff_pcm_f32le_encoder, 110 | &ff_pcm_f64be_encoder, 111 | &ff_pcm_f64le_encoder, 112 | &ff_pcm_mulaw_encoder, 113 | &ff_pcm_s8_encoder, 114 | &ff_pcm_s8_planar_encoder, 115 | &ff_pcm_s16be_encoder, 116 | &ff_pcm_s16be_planar_encoder, 117 | &ff_pcm_s16le_encoder, 118 | &ff_pcm_s16le_planar_encoder, 119 | &ff_pcm_s24be_encoder, 120 | &ff_pcm_s24daud_encoder, 121 | &ff_pcm_s24le_encoder, 122 | &ff_pcm_s24le_planar_encoder, 123 | &ff_pcm_s32be_encoder, 124 | &ff_pcm_s32le_encoder, 125 | &ff_pcm_s32le_planar_encoder, 126 | &ff_pcm_s64be_encoder, 127 | &ff_pcm_s64le_encoder, 128 | &ff_pcm_u8_encoder, 129 | &ff_pcm_u16be_encoder, 130 | &ff_pcm_u16le_encoder, 131 | &ff_pcm_u24be_encoder, 132 | &ff_pcm_u24le_encoder, 133 | &ff_pcm_u32be_encoder, 134 | &ff_pcm_u32le_encoder, 135 | &ff_pcm_vidc_encoder, 136 | &ff_roq_dpcm_encoder, 137 | &ff_adpcm_adx_encoder, 138 | &ff_adpcm_g722_encoder, 139 | &ff_adpcm_g726_encoder, 140 | &ff_adpcm_g726le_encoder, 141 | &ff_adpcm_ima_qt_encoder, 142 | &ff_adpcm_ima_wav_encoder, 143 | &ff_adpcm_ms_encoder, 144 | &ff_adpcm_swf_encoder, 145 | &ff_adpcm_yamaha_encoder, 146 | &ff_ssa_encoder, 147 | &ff_ass_encoder, 148 | &ff_dvbsub_encoder, 149 | &ff_dvdsub_encoder, 150 | &ff_movtext_encoder, 151 | &ff_srt_encoder, 152 | &ff_subrip_encoder, 153 | &ff_text_encoder, 154 | &ff_webvtt_encoder, 155 | &ff_xsub_encoder, 156 | &ff_hevc_mediacodec_encoder, 157 | &ff_flv_decoder, 158 | &ff_h263_decoder, 159 | &ff_h263i_decoder, 160 | &ff_h263p_decoder, 161 | &ff_h264_decoder, 162 | &ff_h264_mediacodec_decoder, 163 | &ff_hevc_decoder, 164 | &ff_vp6_decoder, 165 | &ff_vp6a_decoder, 166 | &ff_vp6f_decoder, 167 | &ff_vp8_decoder, 168 | &ff_vp9_decoder, 169 | &ff_aac_decoder, 170 | &ff_aac_latm_decoder, 171 | &ff_flac_decoder, 172 | &ff_mp3float_decoder, 173 | &ff_mp3_decoder, 174 | &ff_mp3adufloat_decoder, 175 | &ff_mp3adu_decoder, 176 | &ff_mp3on4float_decoder, 177 | &ff_mp3on4_decoder, 178 | &ff_hevc_mediacodec_decoder, 179 | NULL }; 180 | -------------------------------------------------------------------------------- /libavcodec/mediacodec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec public API functions 3 | * 4 | * Copyright (c) 2016 Matthieu Bouron 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 | 23 | #include "config.h" 24 | 25 | #include "libavutil/error.h" 26 | 27 | #include "mediacodec.h" 28 | 29 | #if CONFIG_MEDIACODEC 30 | 31 | #include 32 | 33 | #include "libavcodec/avcodec.h" 34 | #include "libavutil/mem.h" 35 | 36 | #include "ffjni.h" 37 | #include "mediacodecdec_common.h" 38 | #include "version.h" 39 | 40 | AVMediaCodecContext *av_mediacodec_alloc_context(void) 41 | { 42 | return av_mallocz(sizeof(AVMediaCodecContext)); 43 | } 44 | 45 | int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface) 46 | { 47 | int ret = 0; 48 | JNIEnv *env = NULL; 49 | 50 | env = ff_jni_get_env(avctx); 51 | if (!env) { 52 | return AVERROR_EXTERNAL; 53 | } 54 | 55 | ctx->surface = (*env)->NewGlobalRef(env, surface); 56 | if (ctx->surface) { 57 | avctx->hwaccel_context = ctx; 58 | } else { 59 | av_log(avctx, AV_LOG_ERROR, "Could not create new global reference\n"); 60 | ret = AVERROR_EXTERNAL; 61 | } 62 | 63 | return ret; 64 | } 65 | 66 | void av_mediacodec_default_free(AVCodecContext *avctx) 67 | { 68 | JNIEnv *env = NULL; 69 | 70 | AVMediaCodecContext *ctx = avctx->hwaccel_context; 71 | 72 | if (!ctx) { 73 | return; 74 | } 75 | 76 | env = ff_jni_get_env(avctx); 77 | if (!env) { 78 | return; 79 | } 80 | 81 | if (ctx->surface) { 82 | (*env)->DeleteGlobalRef(env, ctx->surface); 83 | ctx->surface = NULL; 84 | } 85 | 86 | av_freep(&avctx->hwaccel_context); 87 | } 88 | 89 | int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) 90 | { 91 | MediaCodecDecContext *ctx = buffer->ctx; 92 | int released = atomic_fetch_add(&buffer->released, 1); 93 | 94 | if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { 95 | atomic_fetch_sub(&ctx->hw_buffer_count, 1); 96 | av_log(ctx->avctx, AV_LOG_DEBUG, 97 | "Releasing output buffer %zd (%p) ts=%"PRId64" with render=%d [%d pending]\n", 98 | buffer->index, buffer, buffer->pts, render, atomic_load(&ctx->hw_buffer_count)); 99 | return ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, render); 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time) 106 | { 107 | MediaCodecDecContext *ctx = buffer->ctx; 108 | int released = atomic_fetch_add(&buffer->released, 1); 109 | 110 | if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { 111 | atomic_fetch_sub(&ctx->hw_buffer_count, 1); 112 | av_log(ctx->avctx, AV_LOG_DEBUG, 113 | "Rendering output buffer %zd (%p) ts=%"PRId64" with time=%"PRId64" [%d pending]\n", 114 | buffer->index, buffer, buffer->pts, time, atomic_load(&ctx->hw_buffer_count)); 115 | return ff_AMediaCodec_releaseOutputBufferAtTime(ctx->codec, buffer->index, time); 116 | } 117 | 118 | return 0; 119 | } 120 | 121 | #else 122 | 123 | #include 124 | 125 | AVMediaCodecContext *av_mediacodec_alloc_context(void) 126 | { 127 | return NULL; 128 | } 129 | 130 | int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface) 131 | { 132 | return AVERROR(ENOSYS); 133 | } 134 | 135 | void av_mediacodec_default_free(AVCodecContext *avctx) 136 | { 137 | } 138 | 139 | int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render) 140 | { 141 | return AVERROR(ENOSYS); 142 | } 143 | 144 | int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time) 145 | { 146 | return AVERROR(ENOSYS); 147 | } 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /libavcodec/mediacodec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec public API 3 | * 4 | * Copyright (c) 2016 Matthieu Bouron 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 | 23 | #ifndef AVCODEC_MEDIACODEC_H 24 | #define AVCODEC_MEDIACODEC_H 25 | 26 | #include "libavcodec/avcodec.h" 27 | 28 | /** 29 | * This structure holds a reference to a android/view/Surface object that will 30 | * be used as output by the decoder. 31 | * 32 | */ 33 | typedef struct AVMediaCodecContext { 34 | 35 | /** 36 | * android/view/Surface object reference. 37 | */ 38 | void *surface; 39 | 40 | } AVMediaCodecContext; 41 | 42 | /** 43 | * Allocate and initialize a MediaCodec context. 44 | * 45 | * When decoding with MediaCodec is finished, the caller must free the 46 | * MediaCodec context with av_mediacodec_default_free. 47 | * 48 | * @return a pointer to a newly allocated AVMediaCodecContext on success, NULL otherwise 49 | */ 50 | AVMediaCodecContext *av_mediacodec_alloc_context(void); 51 | 52 | /** 53 | * Convenience function that sets up the MediaCodec context. 54 | * 55 | * @param avctx codec context 56 | * @param ctx MediaCodec context to initialize 57 | * @param surface reference to an android/view/Surface 58 | * @return 0 on success, < 0 otherwise 59 | */ 60 | int av_mediacodec_default_init(AVCodecContext *avctx, AVMediaCodecContext *ctx, void *surface); 61 | 62 | /** 63 | * This function must be called to free the MediaCodec context initialized with 64 | * av_mediacodec_default_init(). 65 | * 66 | * @param avctx codec context 67 | */ 68 | void av_mediacodec_default_free(AVCodecContext *avctx); 69 | 70 | /** 71 | * Opaque structure representing a MediaCodec buffer to render. 72 | */ 73 | typedef struct MediaCodecBuffer AVMediaCodecBuffer; 74 | 75 | /** 76 | * Release a MediaCodec buffer and render it to the surface that is associated 77 | * with the decoder. This function should only be called once on a given 78 | * buffer, once released the underlying buffer returns to the codec, thus 79 | * subsequent calls to this function will have no effect. 80 | * 81 | * @param buffer the buffer to render 82 | * @param render 1 to release and render the buffer to the surface or 0 to 83 | * discard the buffer 84 | * @return 0 on success, < 0 otherwise 85 | */ 86 | int av_mediacodec_release_buffer(AVMediaCodecBuffer *buffer, int render); 87 | 88 | /** 89 | * Release a MediaCodec buffer and render it at the given time to the surface 90 | * that is associated with the decoder. The timestamp must be within one second 91 | * of the current java/lang/System#nanoTime() (which is implemented using 92 | * CLOCK_MONOTONIC on Android). See the Android MediaCodec documentation 93 | * of android/media/MediaCodec#releaseOutputBuffer(int,long) for more details. 94 | * 95 | * @param buffer the buffer to render 96 | * @param time timestamp in nanoseconds of when to render the buffer 97 | * @return 0 on success, < 0 otherwise 98 | */ 99 | int av_mediacodec_render_buffer_at_time(AVMediaCodecBuffer *buffer, int64_t time); 100 | 101 | #endif /* AVCODEC_MEDIACODEC_H */ 102 | -------------------------------------------------------------------------------- /libavcodec/mediacodec_surface.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec Surface functions 3 | * 4 | * Copyright (c) 2016 Matthieu Bouron 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 | 23 | #include 24 | 25 | #include "ffjni.h" 26 | #include "mediacodec_surface.h" 27 | 28 | void *ff_mediacodec_surface_ref(void *surface, void *log_ctx) 29 | { 30 | JNIEnv *env = NULL; 31 | 32 | void *reference = NULL; 33 | 34 | env = ff_jni_get_env(log_ctx); 35 | if (!env) { 36 | return NULL; 37 | } 38 | 39 | reference = (*env)->NewGlobalRef(env, surface); 40 | 41 | return reference; 42 | } 43 | 44 | int ff_mediacodec_surface_unref(void *surface, void *log_ctx) 45 | { 46 | JNIEnv *env = NULL; 47 | 48 | env = ff_jni_get_env(log_ctx); 49 | if (!env) { 50 | return AVERROR_EXTERNAL; 51 | } 52 | 53 | (*env)->DeleteGlobalRef(env, surface); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /libavcodec/mediacodec_surface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec Surface functions 3 | * 4 | * Copyright (c) 2016 Matthieu Bouron 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 | 23 | #ifndef AVCODEC_MEDIACODEC_SURFACE_H 24 | #define AVCODEC_MEDIACODEC_SURFACE_H 25 | 26 | #include "libavcodec/avcodec.h" 27 | 28 | void *ff_mediacodec_surface_ref(void *surface, void *log_ctx); 29 | int ff_mediacodec_surface_unref(void *surface, void *log_ctx); 30 | 31 | #endif /* AVCODEC_MEDIACODEC_SURFACE_H */ 32 | -------------------------------------------------------------------------------- /libavcodec/mediacodec_sw_buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec software buffer copy functions 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #include 24 | #include 25 | 26 | #include "libavutil/frame.h" 27 | #include "libavutil/mem.h" 28 | 29 | #include "avcodec.h" 30 | #include "mediacodec_wrapper.h" 31 | #include "mediacodec_sw_buffer.h" 32 | #include "mediacodecdec_common.h" 33 | #include "../build/output-armv7a/include/libavutil/frame.h" 34 | 35 | #define QCOM_TILE_WIDTH 64 36 | #define QCOM_TILE_HEIGHT 32 37 | #define QCOM_TILE_SIZE (QCOM_TILE_WIDTH * QCOM_TILE_HEIGHT) 38 | #define QCOM_TILE_GROUP_SIZE (4 * QCOM_TILE_SIZE) 39 | 40 | /** 41 | * The code handling the various YUV color formats is taken from the 42 | * GStreamer project. 43 | * 44 | * Gstreamer reference: 45 | * https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/androidmedia/ 46 | * 47 | * Copyright (C) 2012, Collabora Ltd. 48 | * Author: Sebastian Dröge 49 | * 50 | * Copyright (C) 2012, Rafaël Carré 51 | * 52 | * Copyright (C) 2015, Sebastian Dröge 53 | * 54 | * Copyright (C) 2014-2015, Collabora Ltd. 55 | * Author: Matthieu Bouron 56 | * 57 | * Copyright (C) 2015, Edward Hervey 58 | * Author: Edward Hervey 59 | * 60 | * Copyright (C) 2015, Matthew Waters 61 | * 62 | * This library is free software; you can redistribute it and/or 63 | * modify it under the terms of the GNU Lesser General Public 64 | * License as published by the Free Software Foundation 65 | * version 2.1 of the License. 66 | * 67 | * This library is distributed in the hope that it will be useful, 68 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 69 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 70 | * Lesser General Public License for more details. 71 | * 72 | * You should have received a copy of the GNU Lesser General Public 73 | * License along with this library; if not, write to the Free Software 74 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 75 | * 76 | */ 77 | void ff_mediacodec_sw_buffer_copy_yuv420_planar(AVCodecContext *avctx, 78 | MediaCodecDecContext *s, 79 | uint8_t *data, 80 | size_t size, 81 | FFAMediaCodecBufferInfo *info, 82 | AVFrame *frame) 83 | { 84 | int i; 85 | uint8_t *src = NULL; 86 | 87 | for (i = 0; i < 3; i++) { 88 | int stride = s->stride; 89 | int height; 90 | 91 | src = data + info->offset; 92 | if (i == 0) { 93 | height = avctx->height; 94 | 95 | src += s->crop_top * s->stride; 96 | src += s->crop_left; 97 | } else { 98 | height = avctx->height / 2; 99 | stride = (s->stride + 1) / 2; 100 | 101 | src += s->slice_height * s->stride; 102 | 103 | if (i == 2) { 104 | src += ((s->slice_height + 1) / 2) * stride; 105 | } 106 | 107 | src += s->crop_top * stride; 108 | src += (s->crop_left / 2); 109 | } 110 | 111 | if (frame->linesize[i] == stride) { 112 | memcpy(frame->data[i], src, height * stride); 113 | } else { 114 | int j, width; 115 | uint8_t *dst = frame->data[i]; 116 | 117 | if (i == 0) { 118 | width = avctx->width; 119 | } else if (i >= 1) { 120 | width = FFMIN(frame->linesize[i], FFALIGN(avctx->width, 2) / 2); 121 | } 122 | 123 | for (j = 0; j < height; j++) { 124 | memcpy(dst, src, width); 125 | src += stride; 126 | dst += frame->linesize[i]; 127 | } 128 | } 129 | } 130 | } 131 | 132 | void ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(AVCodecContext *avctx, 133 | MediaCodecDecContext *s, 134 | uint8_t *data, 135 | size_t size, 136 | FFAMediaCodecBufferInfo *info, 137 | AVFrame *frame) 138 | { 139 | int i; 140 | uint8_t *src = NULL; 141 | 142 | for (i = 0; i < 2; i++) { 143 | int height; 144 | 145 | src = data + info->offset; 146 | if (i == 0) { 147 | height = avctx->height; 148 | 149 | src += s->crop_top * s->stride; 150 | src += s->crop_left; 151 | } else if (i == 1) { 152 | height = avctx->height / 2; 153 | 154 | src += s->slice_height * s->stride; 155 | src += s->crop_top * s->stride; 156 | src += s->crop_left; 157 | } 158 | 159 | if (frame->linesize[i] == s->stride) { 160 | memcpy(frame->data[i], src, height * s->stride); 161 | } else { 162 | int j, k, width; 163 | uint8_t *dst = frame->data[i]; 164 | uint8_t tmp = 0; 165 | 166 | if (i == 0) { 167 | width = avctx->width; 168 | } else if (i == 1) { 169 | width = FFMIN(frame->linesize[i], FFALIGN(avctx->width, 2)); 170 | } 171 | 172 | for (j = 0; j < height; j++) { 173 | memcpy(dst, src, width); 174 | src += s->stride; 175 | dst += frame->linesize[i]; 176 | } 177 | 178 | /*if (i == 1) { 179 | // convert nv12 to nv21 180 | dst = frame->data[1]; 181 | for(j = 0; j < height; j++) { 182 | for(k = 0; k < width; k+=2) { 183 | tmp = dst[k]; 184 | dst[k] = dst[k+1]; 185 | dst[k+1] = tmp; 186 | } 187 | dst += frame->linesize[1]; 188 | } 189 | }*/ 190 | } 191 | } 192 | } 193 | 194 | 195 | 196 | void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar(AVCodecContext *avctx, 197 | MediaCodecDecContext *s, 198 | uint8_t *data, 199 | size_t size, 200 | FFAMediaCodecBufferInfo *info, 201 | AVFrame *frame) 202 | { 203 | int i; 204 | uint8_t *src = NULL; 205 | 206 | for (i = 0; i < 2; i++) { 207 | int height; 208 | 209 | src = data + info->offset; 210 | if (i == 0) { 211 | height = avctx->height; 212 | } else if (i == 1) { 213 | height = avctx->height / 2; 214 | 215 | src += (s->slice_height - s->crop_top / 2) * s->stride; 216 | 217 | src += s->crop_top * s->stride; 218 | src += s->crop_left; 219 | } 220 | 221 | if (frame->linesize[i] == s->stride) { 222 | memcpy(frame->data[i], src, height * s->stride); 223 | } else { 224 | int j, width; 225 | uint8_t *dst = frame->data[i]; 226 | 227 | if (i == 0) { 228 | width = avctx->width; 229 | } else if (i == 1) { 230 | width = FFMIN(frame->linesize[i], FFALIGN(avctx->width, 2)); 231 | } 232 | 233 | for (j = 0; j < height; j++) { 234 | memcpy(dst, src, width); 235 | src += s->stride; 236 | dst += frame->linesize[i]; 237 | } 238 | } 239 | } 240 | } 241 | 242 | /** 243 | * The code handling the QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka 244 | * color format is taken from the VLC project. 245 | * 246 | * VLC reference: 247 | * http://git.videolan.org/?p=vlc.git;a=blob;f=modules/codec/omxil/qcom.c;hb=HEAD 248 | * 249 | * VLC copyright notice: 250 | * 251 | ***************************************************************************** 252 | * qcom.c : pixel format translation for Qualcomm tiled nv12 253 | ***************************************************************************** 254 | * Copyright © 2012 Rafaël Carré 255 | * 256 | * Authors: Rafaël Carré 257 | * 258 | * This program is free software; you can redistribute it and/or modify it 259 | * under the terms of the GNU Lesser General Public License as published by 260 | * the Free Software Foundation; either version 2.1 of the License, or 261 | * (at your option) any later version. 262 | * 263 | * This program is distributed in the hope that it will be useful, 264 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 265 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 266 | * GNU Lesser General Public License for more details. 267 | * 268 | * You should have received a copy of the GNU Lesser General Public License 269 | * along with this program; if not, write to the Free Software Foundation, 270 | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 271 | * 272 | */ 273 | 274 | static size_t qcom_tile_pos(size_t x, size_t y, size_t w, size_t h) 275 | { 276 | size_t flim = x + (y & ~1) * w; 277 | 278 | if (y & 1) { 279 | flim += (x & ~3) + 2; 280 | } else if ((h & 1) == 0 || y != (h - 1)) { 281 | flim += (x + 2) & ~3; 282 | } 283 | 284 | return flim; 285 | } 286 | 287 | void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar_64x32Tile2m8ka(AVCodecContext *avctx, 288 | MediaCodecDecContext *s, 289 | uint8_t *data, 290 | size_t size, 291 | FFAMediaCodecBufferInfo *info, 292 | AVFrame *frame) 293 | { 294 | size_t width = frame->width; 295 | size_t linesize = frame->linesize[0]; 296 | size_t height = frame->height; 297 | 298 | const size_t tile_w = (width - 1) / QCOM_TILE_WIDTH + 1; 299 | const size_t tile_w_align = (tile_w + 1) & ~1; 300 | const size_t tile_h_luma = (height - 1) / QCOM_TILE_HEIGHT + 1; 301 | const size_t tile_h_chroma = (height / 2 - 1) / QCOM_TILE_HEIGHT + 1; 302 | 303 | size_t luma_size = tile_w_align * tile_h_luma * QCOM_TILE_SIZE; 304 | if((luma_size % QCOM_TILE_GROUP_SIZE) != 0) 305 | luma_size = (((luma_size - 1) / QCOM_TILE_GROUP_SIZE) + 1) * QCOM_TILE_GROUP_SIZE; 306 | 307 | for(size_t y = 0; y < tile_h_luma; y++) { 308 | size_t row_width = width; 309 | for(size_t x = 0; x < tile_w; x++) { 310 | size_t tile_width = row_width; 311 | size_t tile_height = height; 312 | /* dest luma memory index for this tile */ 313 | size_t luma_idx = y * QCOM_TILE_HEIGHT * linesize + x * QCOM_TILE_WIDTH; 314 | /* dest chroma memory index for this tile */ 315 | /* XXX: remove divisions */ 316 | size_t chroma_idx = (luma_idx / linesize) * linesize / 2 + (luma_idx % linesize); 317 | 318 | /* luma source pointer for this tile */ 319 | const uint8_t *src_luma = data 320 | + qcom_tile_pos(x, y,tile_w_align, tile_h_luma) * QCOM_TILE_SIZE; 321 | 322 | /* chroma source pointer for this tile */ 323 | const uint8_t *src_chroma = data + luma_size 324 | + qcom_tile_pos(x, y/2, tile_w_align, tile_h_chroma) * QCOM_TILE_SIZE; 325 | if (y & 1) 326 | src_chroma += QCOM_TILE_SIZE/2; 327 | 328 | /* account for right columns */ 329 | if (tile_width > QCOM_TILE_WIDTH) 330 | tile_width = QCOM_TILE_WIDTH; 331 | 332 | /* account for bottom rows */ 333 | if (tile_height > QCOM_TILE_HEIGHT) 334 | tile_height = QCOM_TILE_HEIGHT; 335 | 336 | tile_height /= 2; 337 | while (tile_height--) { 338 | memcpy(frame->data[0] + luma_idx, src_luma, tile_width); 339 | src_luma += QCOM_TILE_WIDTH; 340 | luma_idx += linesize; 341 | 342 | memcpy(frame->data[0] + luma_idx, src_luma, tile_width); 343 | src_luma += QCOM_TILE_WIDTH; 344 | luma_idx += linesize; 345 | 346 | memcpy(frame->data[1] + chroma_idx, src_chroma, tile_width); 347 | src_chroma += QCOM_TILE_WIDTH; 348 | chroma_idx += linesize; 349 | } 350 | row_width -= QCOM_TILE_WIDTH; 351 | } 352 | height -= QCOM_TILE_HEIGHT; 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /libavcodec/mediacodec_sw_buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec software buffer copy functions 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #ifndef AVCODEC_MEDIACODEC_SW_BUFFER_H 24 | #define AVCODEC_MEDIACODEC_SW_BUFFER_H 25 | 26 | #include 27 | 28 | #include "libavutil/frame.h" 29 | 30 | #include "avcodec.h" 31 | #include "mediacodec_wrapper.h" 32 | #include "mediacodecdec_common.h" 33 | 34 | void ff_mediacodec_sw_buffer_copy_yuv420_planar(AVCodecContext *avctx, 35 | MediaCodecDecContext *s, 36 | uint8_t *data, 37 | size_t size, 38 | FFAMediaCodecBufferInfo *info, 39 | AVFrame *frame); 40 | 41 | void ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(AVCodecContext *avctx, 42 | MediaCodecDecContext *s, 43 | uint8_t *data, 44 | size_t size, 45 | FFAMediaCodecBufferInfo *info, 46 | AVFrame *frame); 47 | 48 | void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar(AVCodecContext *avctx, 49 | MediaCodecDecContext *s, 50 | uint8_t *data, 51 | size_t size, 52 | FFAMediaCodecBufferInfo *info, 53 | AVFrame *frame); 54 | 55 | void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar_64x32Tile2m8ka(AVCodecContext *avctx, 56 | MediaCodecDecContext *s, 57 | uint8_t *data, 58 | size_t size, 59 | FFAMediaCodecBufferInfo *info, 60 | AVFrame *frame); 61 | 62 | #endif /* AVCODEC_MEDIACODEC_SW_BUFFER_H */ 63 | -------------------------------------------------------------------------------- /libavcodec/mediacodec_wrapper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec Wrapper 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #include 24 | 25 | #include "libavutil/avassert.h" 26 | #include "libavutil/mem.h" 27 | #include "libavutil/avstring.h" 28 | 29 | #include "avcodec.h" 30 | #include "ffjni.h" 31 | #include "version.h" 32 | #include "mediacodec_wrapper.h" 33 | 34 | struct JNIAMediaCodecListFields { 35 | 36 | jclass mediacodec_list_class; 37 | jmethodID init_id; 38 | jmethodID find_decoder_for_format_id; 39 | 40 | jmethodID get_codec_count_id; 41 | jmethodID get_codec_info_at_id; 42 | 43 | jclass mediacodec_info_class; 44 | jmethodID get_name_id; 45 | jmethodID get_codec_capabilities_id; 46 | jmethodID get_supported_types_id; 47 | jmethodID is_encoder_id; 48 | 49 | jclass codec_capabilities_class; 50 | jfieldID color_formats_id; 51 | jfieldID profile_levels_id; 52 | 53 | jclass codec_profile_level_class; 54 | jfieldID profile_id; 55 | jfieldID level_id; 56 | 57 | jfieldID avc_profile_baseline_id; 58 | jfieldID avc_profile_main_id; 59 | jfieldID avc_profile_extended_id; 60 | jfieldID avc_profile_high_id; 61 | jfieldID avc_profile_high10_id; 62 | jfieldID avc_profile_high422_id; 63 | jfieldID avc_profile_high444_id; 64 | 65 | jfieldID hevc_profile_main_id; 66 | jfieldID hevc_profile_main10_id; 67 | jfieldID hevc_profile_main10_hdr10_id; 68 | 69 | }; 70 | 71 | static const struct FFJniField jni_amediacodeclist_mapping[] = { 72 | { "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 }, 73 | { "android/media/MediaCodecList", "", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 }, 74 | { "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 }, 75 | 76 | { "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 }, 77 | { "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 }, 78 | 79 | { "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 }, 80 | { "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 }, 81 | { "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 }, 82 | { "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 }, 83 | { "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 }, 84 | 85 | { "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 }, 86 | { "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 }, 87 | { "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 }, 88 | 89 | { "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 }, 90 | { "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 }, 91 | { "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 }, 92 | 93 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileBaseline", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_baseline_id), 1 }, 94 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileMain", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_main_id), 1 }, 95 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileExtended", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_extended_id), 1 }, 96 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high_id), 1 }, 97 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high10_id), 1 }, 98 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh422", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high422_id), 1 }, 99 | { "android/media/MediaCodecInfo$CodecProfileLevel", "AVCProfileHigh444", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, avc_profile_high444_id), 1 }, 100 | 101 | { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main_id), 0 }, 102 | { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main10_id), 0 }, 103 | { "android/media/MediaCodecInfo$CodecProfileLevel", "HEVCProfileMain10HDR10", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecListFields, hevc_profile_main10_hdr10_id), 0 }, 104 | 105 | { NULL } 106 | }; 107 | 108 | struct JNIAMediaFormatFields { 109 | 110 | jclass mediaformat_class; 111 | 112 | jmethodID init_id; 113 | 114 | jmethodID contains_key_id; 115 | 116 | jmethodID get_integer_id; 117 | jmethodID get_long_id; 118 | jmethodID get_float_id; 119 | jmethodID get_bytebuffer_id; 120 | jmethodID get_string_id; 121 | 122 | jmethodID set_integer_id; 123 | jmethodID set_long_id; 124 | jmethodID set_float_id; 125 | jmethodID set_bytebuffer_id; 126 | jmethodID set_string_id; 127 | 128 | jmethodID to_string_id; 129 | 130 | }; 131 | 132 | static const struct FFJniField jni_amediaformat_mapping[] = { 133 | { "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 }, 134 | 135 | { "android/media/MediaFormat", "", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 }, 136 | 137 | { "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, contains_key_id), 1 }, 138 | 139 | { "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 }, 140 | { "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 }, 141 | { "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 }, 142 | { "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 }, 143 | { "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 }, 144 | 145 | { "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 }, 146 | { "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 }, 147 | { "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 }, 148 | { "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 }, 149 | { "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 }, 150 | 151 | { "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 }, 152 | 153 | { NULL } 154 | }; 155 | 156 | static const AVClass amediaformat_class = { 157 | .class_name = "amediaformat", 158 | .item_name = av_default_item_name, 159 | .version = LIBAVUTIL_VERSION_INT, 160 | }; 161 | 162 | struct FFAMediaFormat { 163 | 164 | const AVClass *class; 165 | struct JNIAMediaFormatFields jfields; 166 | jobject object; 167 | }; 168 | 169 | struct JNIAMediaCodecFields { 170 | 171 | jclass mediacodec_class; 172 | 173 | jfieldID info_try_again_later_id; 174 | jfieldID info_output_buffers_changed_id; 175 | jfieldID info_output_format_changed_id; 176 | 177 | jfieldID buffer_flag_codec_config_id; 178 | jfieldID buffer_flag_end_of_stream_id; 179 | jfieldID buffer_flag_key_frame_id; 180 | jfieldID buffer_flag_partial_frame_id; 181 | jfieldID buffer_flag_muxer_data_id; 182 | 183 | jfieldID configure_flag_encode_id; 184 | 185 | jmethodID create_by_codec_name_id; 186 | jmethodID create_decoder_by_type_id; 187 | jmethodID create_encoder_by_type_id; 188 | 189 | jmethodID get_name_id; 190 | 191 | jmethodID configure_id; 192 | jmethodID start_id; 193 | jmethodID flush_id; 194 | jmethodID stop_id; 195 | jmethodID release_id; 196 | 197 | jmethodID get_output_format_id; 198 | 199 | jmethodID dequeue_input_buffer_id; 200 | jmethodID queue_input_buffer_id; 201 | jmethodID get_input_buffer_id; 202 | jmethodID get_input_buffers_id; 203 | 204 | jmethodID dequeue_output_buffer_id; 205 | jmethodID get_output_buffer_id; 206 | jmethodID get_output_buffers_id; 207 | jmethodID release_output_buffer_id; 208 | jmethodID release_output_buffer_at_time_id; 209 | 210 | jclass mediainfo_class; 211 | 212 | jmethodID init_id; 213 | 214 | jfieldID flags_id; 215 | jfieldID offset_id; 216 | jfieldID presentation_time_us_id; 217 | jfieldID size_id; 218 | 219 | }; 220 | 221 | static const struct FFJniField jni_amediacodec_mapping[] = { 222 | { "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 }, 223 | 224 | { "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 }, 225 | { "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 }, 226 | { "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 }, 227 | 228 | { "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 }, 229 | { "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 }, 230 | { "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 }, 231 | { "android/media/MediaCodec", "BUFFER_FLAG_PARTIAL_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_partial_frame_id), 0 }, 232 | { "android/media/MediaCodec", "BUFFER_FLAG_MUXER_DATA", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_muxer_data_id), 0 }, 233 | 234 | { "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 }, 235 | 236 | { "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 }, 237 | { "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 }, 238 | { "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 }, 239 | 240 | { "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 }, 241 | 242 | { "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 }, 243 | { "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 }, 244 | { "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 }, 245 | { "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 }, 246 | { "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 }, 247 | 248 | { "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 }, 249 | 250 | { "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 }, 251 | { "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 }, 252 | { "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 }, 253 | { "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 }, 254 | 255 | { "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 }, 256 | { "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 }, 257 | { "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 }, 258 | { "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 }, 259 | { "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 }, 260 | 261 | { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 }, 262 | 263 | { "android/media/MediaCodec.BufferInfo", "", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 }, 264 | { "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 }, 265 | { "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 }, 266 | { "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 }, 267 | { "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 }, 268 | 269 | { NULL } 270 | }; 271 | 272 | static const AVClass amediacodec_class = { 273 | .class_name = "amediacodec", 274 | .item_name = av_default_item_name, 275 | .version = LIBAVUTIL_VERSION_INT, 276 | }; 277 | 278 | struct FFAMediaCodec { 279 | 280 | const AVClass *class; 281 | 282 | struct JNIAMediaCodecFields jfields; 283 | 284 | jobject object; 285 | jobject buffer_info; 286 | 287 | jobject input_buffers; 288 | jobject output_buffers; 289 | 290 | int INFO_TRY_AGAIN_LATER; 291 | int INFO_OUTPUT_BUFFERS_CHANGED; 292 | int INFO_OUTPUT_FORMAT_CHANGED; 293 | 294 | int BUFFER_FLAG_CODEC_CONFIG; 295 | int BUFFER_FLAG_END_OF_STREAM; 296 | int BUFFER_FLAG_KEY_FRAME; 297 | int BUFFER_FLAG_PARTIAL_FRAME; 298 | int BUFFER_FLAG_MUXER_DATA; 299 | 300 | int CONFIGURE_FLAG_ENCODE; 301 | 302 | int has_get_i_o_buffer; 303 | }; 304 | 305 | #define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret) do { \ 306 | (env) = ff_jni_get_env(log_ctx); \ 307 | if (!(env)) { \ 308 | return ret; \ 309 | } \ 310 | } while (0) 311 | 312 | #define JNI_GET_ENV_OR_RETURN_VOID(env, log_ctx) do { \ 313 | (env) = ff_jni_get_env(log_ctx); \ 314 | if (!(env)) { \ 315 | return; \ 316 | } \ 317 | } while (0) 318 | 319 | int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx) 320 | { 321 | int ret = -1; 322 | 323 | JNIEnv *env = NULL; 324 | struct JNIAMediaCodecListFields jfields = { 0 }; 325 | jfieldID field_id = 0; 326 | 327 | JNI_GET_ENV_OR_RETURN(env, avctx, -1); 328 | 329 | if (ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, avctx) < 0) { 330 | goto done; 331 | } 332 | 333 | if (avctx->codec_id == AV_CODEC_ID_H264) { 334 | switch(avctx->profile) { 335 | case FF_PROFILE_H264_BASELINE: 336 | case FF_PROFILE_H264_CONSTRAINED_BASELINE: 337 | field_id = jfields.avc_profile_baseline_id; 338 | break; 339 | case FF_PROFILE_H264_MAIN: 340 | field_id = jfields.avc_profile_main_id; 341 | break; 342 | case FF_PROFILE_H264_EXTENDED: 343 | field_id = jfields.avc_profile_extended_id; 344 | break; 345 | case FF_PROFILE_H264_HIGH: 346 | field_id = jfields.avc_profile_high_id; 347 | break; 348 | case FF_PROFILE_H264_HIGH_10: 349 | case FF_PROFILE_H264_HIGH_10_INTRA: 350 | field_id = jfields.avc_profile_high10_id; 351 | break; 352 | case FF_PROFILE_H264_HIGH_422: 353 | case FF_PROFILE_H264_HIGH_422_INTRA: 354 | field_id = jfields.avc_profile_high422_id; 355 | break; 356 | case FF_PROFILE_H264_HIGH_444: 357 | case FF_PROFILE_H264_HIGH_444_INTRA: 358 | case FF_PROFILE_H264_HIGH_444_PREDICTIVE: 359 | field_id = jfields.avc_profile_high444_id; 360 | break; 361 | } 362 | } else if (avctx->codec_id == AV_CODEC_ID_HEVC) { 363 | switch (avctx->profile) { 364 | case FF_PROFILE_HEVC_MAIN: 365 | case FF_PROFILE_HEVC_MAIN_STILL_PICTURE: 366 | field_id = jfields.hevc_profile_main_id; 367 | break; 368 | case FF_PROFILE_HEVC_MAIN_10: 369 | field_id = jfields.hevc_profile_main10_id; 370 | break; 371 | } 372 | } 373 | 374 | if (field_id) { 375 | ret = (*env)->GetStaticIntField(env, jfields.codec_profile_level_class, field_id); 376 | if (ff_jni_exception_check(env, 1, avctx) < 0) { 377 | ret = -1; 378 | goto done; 379 | } 380 | } 381 | 382 | done: 383 | ff_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, avctx); 384 | 385 | return ret; 386 | } 387 | 388 | char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx) 389 | { 390 | int ret; 391 | int i; 392 | int codec_count; 393 | int found_codec = 0; 394 | char *name = NULL; 395 | char *supported_type = NULL; 396 | 397 | JNIEnv *env = NULL; 398 | struct JNIAMediaCodecListFields jfields = { 0 }; 399 | struct JNIAMediaFormatFields mediaformat_jfields = { 0 }; 400 | 401 | jobject codec_name = NULL; 402 | 403 | jobject info = NULL; 404 | jobject type = NULL; 405 | jobjectArray types = NULL; 406 | 407 | jobject capabilities = NULL; 408 | jobject profile_level = NULL; 409 | jobjectArray profile_levels = NULL; 410 | 411 | JNI_GET_ENV_OR_RETURN(env, log_ctx, NULL); 412 | 413 | if ((ret = ff_jni_init_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx)) < 0) { 414 | goto done; 415 | } 416 | 417 | if ((ret = ff_jni_init_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx)) < 0) { 418 | goto done; 419 | } 420 | 421 | codec_count = (*env)->CallStaticIntMethod(env, jfields.mediacodec_list_class, jfields.get_codec_count_id); 422 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 423 | goto done; 424 | } 425 | 426 | for(i = 0; i < codec_count; i++) { 427 | int j; 428 | int type_count; 429 | int is_encoder; 430 | 431 | info = (*env)->CallStaticObjectMethod(env, jfields.mediacodec_list_class, jfields.get_codec_info_at_id, i); 432 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 433 | goto done; 434 | } 435 | 436 | types = (*env)->CallObjectMethod(env, info, jfields.get_supported_types_id); 437 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 438 | goto done; 439 | } 440 | 441 | is_encoder = (*env)->CallBooleanMethod(env, info, jfields.is_encoder_id); 442 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 443 | goto done; 444 | } 445 | 446 | if (is_encoder != encoder) { 447 | goto done_with_info; 448 | } 449 | 450 | type_count = (*env)->GetArrayLength(env, types); 451 | for (j = 0; j < type_count; j++) { 452 | int k; 453 | int profile_count; 454 | 455 | type = (*env)->GetObjectArrayElement(env, types, j); 456 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 457 | goto done; 458 | } 459 | 460 | supported_type = ff_jni_jstring_to_utf_chars(env, type, log_ctx); 461 | if (!supported_type) { 462 | goto done; 463 | } 464 | 465 | if (!av_strcasecmp(supported_type, mime)) { 466 | codec_name = (*env)->CallObjectMethod(env, info, jfields.get_name_id); 467 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 468 | goto done; 469 | } 470 | 471 | name = ff_jni_jstring_to_utf_chars(env, codec_name, log_ctx); 472 | if (!name) { 473 | goto done; 474 | } 475 | 476 | if (codec_name) { 477 | (*env)->DeleteLocalRef(env, codec_name); 478 | codec_name = NULL; 479 | } 480 | 481 | /* Skip software decoders */ 482 | if ( 483 | strstr(name, "OMX.google") || 484 | strstr(name, "OMX.ffmpeg") || 485 | (strstr(name, "OMX.SEC") && strstr(name, ".sw.")) || 486 | !strcmp(name, "OMX.qcom.video.decoder.hevcswvdec")) { 487 | av_freep(&name); 488 | goto done_with_type; 489 | } 490 | 491 | capabilities = (*env)->CallObjectMethod(env, info, jfields.get_codec_capabilities_id, type); 492 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 493 | goto done; 494 | } 495 | 496 | profile_levels = (*env)->GetObjectField(env, capabilities, jfields.profile_levels_id); 497 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 498 | goto done; 499 | } 500 | 501 | profile_count = (*env)->GetArrayLength(env, profile_levels); 502 | if (!profile_count) { 503 | found_codec = 1; 504 | } 505 | for (k = 0; k < profile_count; k++) { 506 | int supported_profile = 0; 507 | 508 | if (profile < 0) { 509 | found_codec = 1; 510 | break; 511 | } 512 | 513 | profile_level = (*env)->GetObjectArrayElement(env, profile_levels, k); 514 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 515 | goto done; 516 | } 517 | 518 | supported_profile = (*env)->GetIntField(env, profile_level, jfields.profile_id); 519 | if (ff_jni_exception_check(env, 1, log_ctx) < 0) { 520 | goto done; 521 | } 522 | 523 | found_codec = profile == supported_profile; 524 | 525 | if (profile_level) { 526 | (*env)->DeleteLocalRef(env, profile_level); 527 | profile_level = NULL; 528 | } 529 | 530 | if (found_codec) { 531 | break; 532 | } 533 | } 534 | } 535 | 536 | done_with_type: 537 | if (profile_levels) { 538 | (*env)->DeleteLocalRef(env, profile_levels); 539 | profile_levels = NULL; 540 | } 541 | 542 | if (capabilities) { 543 | (*env)->DeleteLocalRef(env, capabilities); 544 | capabilities = NULL; 545 | } 546 | 547 | if (type) { 548 | (*env)->DeleteLocalRef(env, type); 549 | type = NULL; 550 | } 551 | 552 | av_freep(&supported_type); 553 | 554 | if (found_codec) { 555 | break; 556 | } 557 | 558 | av_freep(&name); 559 | } 560 | 561 | done_with_info: 562 | if (info) { 563 | (*env)->DeleteLocalRef(env, info); 564 | info = NULL; 565 | } 566 | 567 | if (types) { 568 | (*env)->DeleteLocalRef(env, types); 569 | types = NULL; 570 | } 571 | 572 | if (found_codec) { 573 | break; 574 | } 575 | } 576 | 577 | done: 578 | if (codec_name) { 579 | (*env)->DeleteLocalRef(env, codec_name); 580 | } 581 | 582 | if (info) { 583 | (*env)->DeleteLocalRef(env, info); 584 | } 585 | 586 | if (type) { 587 | (*env)->DeleteLocalRef(env, type); 588 | } 589 | 590 | if (types) { 591 | (*env)->DeleteLocalRef(env, types); 592 | } 593 | 594 | if (capabilities) { 595 | (*env)->DeleteLocalRef(env, capabilities); 596 | } 597 | 598 | if (profile_level) { 599 | (*env)->DeleteLocalRef(env, profile_level); 600 | } 601 | 602 | if (profile_levels) { 603 | (*env)->DeleteLocalRef(env, profile_levels); 604 | } 605 | 606 | av_freep(&supported_type); 607 | 608 | ff_jni_reset_jfields(env, &jfields, jni_amediacodeclist_mapping, 0, log_ctx); 609 | ff_jni_reset_jfields(env, &mediaformat_jfields, jni_amediaformat_mapping, 0, log_ctx); 610 | 611 | if (!found_codec) { 612 | av_freep(&name); 613 | } 614 | 615 | return name; 616 | } 617 | 618 | FFAMediaFormat *ff_AMediaFormat_new(void) 619 | { 620 | JNIEnv *env = NULL; 621 | FFAMediaFormat *format = NULL; 622 | jobject object = NULL; 623 | 624 | format = av_mallocz(sizeof(FFAMediaFormat)); 625 | if (!format) { 626 | return NULL; 627 | } 628 | format->class = &amediaformat_class; 629 | 630 | env = ff_jni_get_env(format); 631 | if (!env) { 632 | av_freep(&format); 633 | return NULL; 634 | } 635 | 636 | if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) { 637 | goto fail; 638 | } 639 | 640 | object = (*env)->NewObject(env, format->jfields.mediaformat_class, format->jfields.init_id); 641 | if (!object) { 642 | goto fail; 643 | } 644 | 645 | format->object = (*env)->NewGlobalRef(env, object); 646 | if (!format->object) { 647 | goto fail; 648 | } 649 | 650 | fail: 651 | if (object) { 652 | (*env)->DeleteLocalRef(env, object); 653 | } 654 | 655 | if (!format->object) { 656 | ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format); 657 | av_freep(&format); 658 | } 659 | 660 | return format; 661 | } 662 | 663 | static FFAMediaFormat *ff_AMediaFormat_newFromObject(void *object) 664 | { 665 | JNIEnv *env = NULL; 666 | FFAMediaFormat *format = NULL; 667 | 668 | format = av_mallocz(sizeof(FFAMediaFormat)); 669 | if (!format) { 670 | return NULL; 671 | } 672 | format->class = &amediaformat_class; 673 | 674 | env = ff_jni_get_env(format); 675 | if (!env) { 676 | av_freep(&format); 677 | return NULL; 678 | } 679 | 680 | if (ff_jni_init_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format) < 0) { 681 | goto fail; 682 | } 683 | 684 | format->object = (*env)->NewGlobalRef(env, object); 685 | if (!format->object) { 686 | goto fail; 687 | } 688 | 689 | return format; 690 | fail: 691 | ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format); 692 | 693 | av_freep(&format); 694 | 695 | return NULL; 696 | } 697 | 698 | int ff_AMediaFormat_delete(FFAMediaFormat* format) 699 | { 700 | int ret = 0; 701 | 702 | JNIEnv *env = NULL; 703 | 704 | if (!format) { 705 | return 0; 706 | } 707 | 708 | JNI_GET_ENV_OR_RETURN(env, format, AVERROR_EXTERNAL); 709 | 710 | (*env)->DeleteGlobalRef(env, format->object); 711 | format->object = NULL; 712 | 713 | ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format); 714 | 715 | av_freep(&format); 716 | 717 | return ret; 718 | } 719 | 720 | char* ff_AMediaFormat_toString(FFAMediaFormat* format) 721 | { 722 | char *ret = NULL; 723 | 724 | JNIEnv *env = NULL; 725 | jstring description = NULL; 726 | 727 | av_assert0(format != NULL); 728 | 729 | JNI_GET_ENV_OR_RETURN(env, format, NULL); 730 | 731 | description = (*env)->CallObjectMethod(env, format->object, format->jfields.to_string_id); 732 | if (ff_jni_exception_check(env, 1, NULL) < 0) { 733 | goto fail; 734 | } 735 | 736 | ret = ff_jni_jstring_to_utf_chars(env, description, format); 737 | fail: 738 | if (description) { 739 | (*env)->DeleteLocalRef(env, description); 740 | } 741 | 742 | return ret; 743 | } 744 | 745 | int ff_AMediaFormat_getInt32(FFAMediaFormat* format, const char *name, int32_t *out) 746 | { 747 | int ret = 1; 748 | 749 | JNIEnv *env = NULL; 750 | jstring key = NULL; 751 | jboolean contains_key; 752 | 753 | av_assert0(format != NULL); 754 | 755 | JNI_GET_ENV_OR_RETURN(env, format, 0); 756 | 757 | key = ff_jni_utf_chars_to_jstring(env, name, format); 758 | if (!key) { 759 | ret = 0; 760 | goto fail; 761 | } 762 | 763 | contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key); 764 | if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) { 765 | ret = 0; 766 | goto fail; 767 | } 768 | 769 | *out = (*env)->CallIntMethod(env, format->object, format->jfields.get_integer_id, key); 770 | if ((ret = ff_jni_exception_check(env, 1, format)) < 0) { 771 | ret = 0; 772 | goto fail; 773 | } 774 | 775 | ret = 1; 776 | fail: 777 | if (key) { 778 | (*env)->DeleteLocalRef(env, key); 779 | } 780 | 781 | return ret; 782 | } 783 | 784 | int ff_AMediaFormat_getInt64(FFAMediaFormat* format, const char *name, int64_t *out) 785 | { 786 | int ret = 1; 787 | 788 | JNIEnv *env = NULL; 789 | jstring key = NULL; 790 | jboolean contains_key; 791 | 792 | av_assert0(format != NULL); 793 | 794 | JNI_GET_ENV_OR_RETURN(env, format, 0); 795 | 796 | key = ff_jni_utf_chars_to_jstring(env, name, format); 797 | if (!key) { 798 | ret = 0; 799 | goto fail; 800 | } 801 | 802 | contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key); 803 | if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) { 804 | ret = 0; 805 | goto fail; 806 | } 807 | 808 | *out = (*env)->CallLongMethod(env, format->object, format->jfields.get_long_id, key); 809 | if ((ret = ff_jni_exception_check(env, 1, format)) < 0) { 810 | ret = 0; 811 | goto fail; 812 | } 813 | 814 | ret = 1; 815 | fail: 816 | if (key) { 817 | (*env)->DeleteLocalRef(env, key); 818 | } 819 | 820 | return ret; 821 | } 822 | 823 | int ff_AMediaFormat_getFloat(FFAMediaFormat* format, const char *name, float *out) 824 | { 825 | int ret = 1; 826 | 827 | JNIEnv *env = NULL; 828 | jstring key = NULL; 829 | jboolean contains_key; 830 | 831 | av_assert0(format != NULL); 832 | 833 | JNI_GET_ENV_OR_RETURN(env, format, 0); 834 | 835 | key = ff_jni_utf_chars_to_jstring(env, name, format); 836 | if (!key) { 837 | ret = 0; 838 | goto fail; 839 | } 840 | 841 | contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key); 842 | if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) { 843 | ret = 0; 844 | goto fail; 845 | } 846 | 847 | *out = (*env)->CallFloatMethod(env, format->object, format->jfields.get_float_id, key); 848 | if ((ret = ff_jni_exception_check(env, 1, format)) < 0) { 849 | ret = 0; 850 | goto fail; 851 | } 852 | 853 | ret = 1; 854 | fail: 855 | if (key) { 856 | (*env)->DeleteLocalRef(env, key); 857 | } 858 | 859 | return ret; 860 | } 861 | 862 | int ff_AMediaFormat_getBuffer(FFAMediaFormat* format, const char *name, void** data, size_t *size) 863 | { 864 | int ret = 1; 865 | 866 | JNIEnv *env = NULL; 867 | jstring key = NULL; 868 | jboolean contains_key; 869 | jobject result = NULL; 870 | 871 | av_assert0(format != NULL); 872 | 873 | JNI_GET_ENV_OR_RETURN(env, format, 0); 874 | 875 | key = ff_jni_utf_chars_to_jstring(env, name, format); 876 | if (!key) { 877 | ret = 0; 878 | goto fail; 879 | } 880 | 881 | contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key); 882 | if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) { 883 | ret = 0; 884 | goto fail; 885 | } 886 | 887 | result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_bytebuffer_id, key); 888 | if ((ret = ff_jni_exception_check(env, 1, format)) < 0) { 889 | ret = 0; 890 | goto fail; 891 | } 892 | 893 | *data = (*env)->GetDirectBufferAddress(env, result); 894 | *size = (*env)->GetDirectBufferCapacity(env, result); 895 | 896 | if (*data && *size) { 897 | void *src = *data; 898 | *data = av_malloc(*size); 899 | if (!*data) { 900 | ret = 0; 901 | goto fail; 902 | } 903 | 904 | memcpy(*data, src, *size); 905 | } 906 | 907 | ret = 1; 908 | fail: 909 | if (key) { 910 | (*env)->DeleteLocalRef(env, key); 911 | } 912 | 913 | if (result) { 914 | (*env)->DeleteLocalRef(env, result); 915 | } 916 | 917 | return ret; 918 | } 919 | 920 | int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *name, const char **out) 921 | { 922 | int ret = 1; 923 | 924 | JNIEnv *env = NULL; 925 | jstring key = NULL; 926 | jboolean contains_key; 927 | jstring result = NULL; 928 | 929 | av_assert0(format != NULL); 930 | 931 | JNI_GET_ENV_OR_RETURN(env, format, 0); 932 | 933 | key = ff_jni_utf_chars_to_jstring(env, name, format); 934 | if (!key) { 935 | ret = 0; 936 | goto fail; 937 | } 938 | 939 | contains_key = (*env)->CallBooleanMethod(env, format->object, format->jfields.contains_key_id, key); 940 | if (!contains_key || (ret = ff_jni_exception_check(env, 1, format)) < 0) { 941 | ret = 0; 942 | goto fail; 943 | } 944 | 945 | result = (*env)->CallObjectMethod(env, format->object, format->jfields.get_string_id, key); 946 | if ((ret = ff_jni_exception_check(env, 1, format)) < 0) { 947 | ret = 0; 948 | goto fail; 949 | } 950 | 951 | *out = ff_jni_jstring_to_utf_chars(env, result, format); 952 | if (!*out) { 953 | ret = 0; 954 | goto fail; 955 | } 956 | 957 | ret = 1; 958 | fail: 959 | if (key) { 960 | (*env)->DeleteLocalRef(env, key); 961 | } 962 | 963 | if (result) { 964 | (*env)->DeleteLocalRef(env, result); 965 | } 966 | 967 | return ret; 968 | } 969 | 970 | void ff_AMediaFormat_setInt32(FFAMediaFormat* format, const char* name, int32_t value) 971 | { 972 | JNIEnv *env = NULL; 973 | jstring key = NULL; 974 | 975 | av_assert0(format != NULL); 976 | 977 | JNI_GET_ENV_OR_RETURN_VOID(env, format); 978 | 979 | key = ff_jni_utf_chars_to_jstring(env, name, format); 980 | if (!key) { 981 | goto fail; 982 | } 983 | 984 | (*env)->CallVoidMethod(env, format->object, format->jfields.set_integer_id, key, value); 985 | if (ff_jni_exception_check(env, 1, format) < 0) { 986 | goto fail; 987 | } 988 | 989 | fail: 990 | if (key) { 991 | (*env)->DeleteLocalRef(env, key); 992 | } 993 | } 994 | 995 | void ff_AMediaFormat_setInt64(FFAMediaFormat* format, const char* name, int64_t value) 996 | { 997 | JNIEnv *env = NULL; 998 | jstring key = NULL; 999 | 1000 | av_assert0(format != NULL); 1001 | 1002 | JNI_GET_ENV_OR_RETURN_VOID(env, format); 1003 | 1004 | key = ff_jni_utf_chars_to_jstring(env, name, format); 1005 | if (!key) { 1006 | goto fail; 1007 | } 1008 | 1009 | (*env)->CallVoidMethod(env, format->object, format->jfields.set_long_id, key, value); 1010 | if (ff_jni_exception_check(env, 1, format) < 0) { 1011 | goto fail; 1012 | } 1013 | 1014 | fail: 1015 | if (key) { 1016 | (*env)->DeleteLocalRef(env, key); 1017 | } 1018 | } 1019 | 1020 | void ff_AMediaFormat_setFloat(FFAMediaFormat* format, const char* name, float value) 1021 | { 1022 | JNIEnv *env = NULL; 1023 | jstring key = NULL; 1024 | 1025 | av_assert0(format != NULL); 1026 | 1027 | JNI_GET_ENV_OR_RETURN_VOID(env, format); 1028 | 1029 | key = ff_jni_utf_chars_to_jstring(env, name, format); 1030 | if (!key) { 1031 | goto fail; 1032 | } 1033 | 1034 | (*env)->CallVoidMethod(env, format->object, format->jfields.set_float_id, key, value); 1035 | if (ff_jni_exception_check(env, 1, format) < 0) { 1036 | goto fail; 1037 | } 1038 | 1039 | fail: 1040 | if (key) { 1041 | (*env)->DeleteLocalRef(env, key); 1042 | } 1043 | } 1044 | 1045 | void ff_AMediaFormat_setString(FFAMediaFormat* format, const char* name, const char* value) 1046 | { 1047 | JNIEnv *env = NULL; 1048 | jstring key = NULL; 1049 | jstring string = NULL; 1050 | 1051 | av_assert0(format != NULL); 1052 | 1053 | JNI_GET_ENV_OR_RETURN_VOID(env, format); 1054 | 1055 | key = ff_jni_utf_chars_to_jstring(env, name, format); 1056 | if (!key) { 1057 | goto fail; 1058 | } 1059 | 1060 | string = ff_jni_utf_chars_to_jstring(env, value, format); 1061 | if (!string) { 1062 | goto fail; 1063 | } 1064 | 1065 | (*env)->CallVoidMethod(env, format->object, format->jfields.set_string_id, key, string); 1066 | if (ff_jni_exception_check(env, 1, format) < 0) { 1067 | goto fail; 1068 | } 1069 | 1070 | fail: 1071 | if (key) { 1072 | (*env)->DeleteLocalRef(env, key); 1073 | } 1074 | 1075 | if (string) { 1076 | (*env)->DeleteLocalRef(env, string); 1077 | } 1078 | } 1079 | 1080 | void ff_AMediaFormat_setBuffer(FFAMediaFormat* format, const char* name, void* data, size_t size) 1081 | { 1082 | JNIEnv *env = NULL; 1083 | jstring key = NULL; 1084 | jobject buffer = NULL; 1085 | void *buffer_data = NULL; 1086 | 1087 | av_assert0(format != NULL); 1088 | 1089 | JNI_GET_ENV_OR_RETURN_VOID(env, format); 1090 | 1091 | key = ff_jni_utf_chars_to_jstring(env, name, format); 1092 | if (!key) { 1093 | goto fail; 1094 | } 1095 | 1096 | if (!data || !size) { 1097 | goto fail; 1098 | } 1099 | 1100 | buffer_data = av_malloc(size); 1101 | if (!buffer_data) { 1102 | goto fail; 1103 | } 1104 | 1105 | memcpy(buffer_data, data, size); 1106 | 1107 | buffer = (*env)->NewDirectByteBuffer(env, buffer_data, size); 1108 | if (!buffer) { 1109 | goto fail; 1110 | } 1111 | 1112 | (*env)->CallVoidMethod(env, format->object, format->jfields.set_bytebuffer_id, key, buffer); 1113 | if (ff_jni_exception_check(env, 1, format) < 0) { 1114 | goto fail; 1115 | } 1116 | 1117 | fail: 1118 | if (key) { 1119 | (*env)->DeleteLocalRef(env, key); 1120 | } 1121 | 1122 | if (buffer) { 1123 | (*env)->DeleteLocalRef(env, buffer); 1124 | } 1125 | } 1126 | 1127 | static int codec_init_static_fields(FFAMediaCodec *codec) 1128 | { 1129 | int ret = 0; 1130 | JNIEnv *env = NULL; 1131 | 1132 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1133 | 1134 | codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id); 1135 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1136 | goto fail; 1137 | } 1138 | 1139 | codec->BUFFER_FLAG_CODEC_CONFIG = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_codec_config_id); 1140 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1141 | goto fail; 1142 | } 1143 | 1144 | codec->BUFFER_FLAG_END_OF_STREAM = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_end_of_stream_id); 1145 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1146 | goto fail; 1147 | } 1148 | 1149 | if (codec->jfields.buffer_flag_key_frame_id) { 1150 | codec->BUFFER_FLAG_KEY_FRAME = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_key_frame_id); 1151 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1152 | goto fail; 1153 | } 1154 | } 1155 | 1156 | if (codec->jfields.buffer_flag_partial_frame_id) { 1157 | codec->BUFFER_FLAG_PARTIAL_FRAME = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_partial_frame_id); 1158 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1159 | goto fail; 1160 | } 1161 | } 1162 | 1163 | if (codec->jfields.buffer_flag_muxer_data_id) { 1164 | codec->BUFFER_FLAG_MUXER_DATA = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.buffer_flag_muxer_data_id); 1165 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1166 | goto fail; 1167 | } 1168 | } 1169 | 1170 | codec->CONFIGURE_FLAG_ENCODE = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.configure_flag_encode_id); 1171 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1172 | goto fail; 1173 | } 1174 | 1175 | codec->INFO_TRY_AGAIN_LATER = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_try_again_later_id); 1176 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1177 | goto fail; 1178 | } 1179 | 1180 | codec->INFO_OUTPUT_BUFFERS_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_buffers_changed_id); 1181 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1182 | goto fail; 1183 | } 1184 | 1185 | codec->INFO_OUTPUT_FORMAT_CHANGED = (*env)->GetStaticIntField(env, codec->jfields.mediacodec_class, codec->jfields.info_output_format_changed_id); 1186 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1187 | goto fail; 1188 | } 1189 | 1190 | fail: 1191 | 1192 | return ret; 1193 | } 1194 | 1195 | #define CREATE_CODEC_BY_NAME 0 1196 | #define CREATE_DECODER_BY_TYPE 1 1197 | #define CREATE_ENCODER_BY_TYPE 2 1198 | 1199 | static inline FFAMediaCodec *codec_create(int method, const char *arg) 1200 | { 1201 | int ret = -1; 1202 | JNIEnv *env = NULL; 1203 | FFAMediaCodec *codec = NULL; 1204 | jstring jarg = NULL; 1205 | jobject object = NULL; 1206 | jobject buffer_info = NULL; 1207 | jmethodID create_id = NULL; 1208 | 1209 | codec = av_mallocz(sizeof(FFAMediaCodec)); 1210 | if (!codec) { 1211 | return NULL; 1212 | } 1213 | codec->class = &amediacodec_class; 1214 | 1215 | env = ff_jni_get_env(codec); 1216 | if (!env) { 1217 | av_freep(&codec); 1218 | return NULL; 1219 | } 1220 | 1221 | if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) { 1222 | goto fail; 1223 | } 1224 | 1225 | jarg = ff_jni_utf_chars_to_jstring(env, arg, codec); 1226 | if (!jarg) { 1227 | goto fail; 1228 | } 1229 | 1230 | switch (method) { 1231 | case CREATE_CODEC_BY_NAME: create_id = codec->jfields.create_by_codec_name_id; break; 1232 | case CREATE_DECODER_BY_TYPE: create_id = codec->jfields.create_decoder_by_type_id; break; 1233 | case CREATE_ENCODER_BY_TYPE: create_id = codec->jfields.create_encoder_by_type_id; break; 1234 | default: 1235 | av_assert0(0); 1236 | } 1237 | 1238 | object = (*env)->CallStaticObjectMethod(env, 1239 | codec->jfields.mediacodec_class, 1240 | create_id, 1241 | jarg); 1242 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1243 | goto fail; 1244 | } 1245 | 1246 | codec->object = (*env)->NewGlobalRef(env, object); 1247 | if (!codec->object) { 1248 | goto fail; 1249 | } 1250 | 1251 | if (codec_init_static_fields(codec) < 0) { 1252 | goto fail; 1253 | } 1254 | 1255 | if (codec->jfields.get_input_buffer_id && codec->jfields.get_output_buffer_id) { 1256 | codec->has_get_i_o_buffer = 1; 1257 | } 1258 | 1259 | buffer_info = (*env)->NewObject(env, codec->jfields.mediainfo_class, codec->jfields.init_id); 1260 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1261 | goto fail; 1262 | } 1263 | 1264 | codec->buffer_info = (*env)->NewGlobalRef(env, buffer_info); 1265 | if (!codec->buffer_info) { 1266 | goto fail; 1267 | } 1268 | 1269 | ret = 0; 1270 | fail: 1271 | if (jarg) { 1272 | (*env)->DeleteLocalRef(env, jarg); 1273 | } 1274 | 1275 | if (object) { 1276 | (*env)->DeleteLocalRef(env, object); 1277 | } 1278 | 1279 | if (buffer_info) { 1280 | (*env)->DeleteLocalRef(env, buffer_info); 1281 | } 1282 | 1283 | if (ret < 0) { 1284 | if (codec->object) { 1285 | (*env)->DeleteGlobalRef(env, codec->object); 1286 | } 1287 | 1288 | if (codec->buffer_info) { 1289 | (*env)->DeleteGlobalRef(env, codec->buffer_info); 1290 | } 1291 | 1292 | ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec); 1293 | av_freep(&codec); 1294 | } 1295 | 1296 | return codec; 1297 | } 1298 | 1299 | #define DECLARE_FF_AMEDIACODEC_CREATE_FUNC(name, method) \ 1300 | FFAMediaCodec *ff_AMediaCodec_##name(const char *arg) \ 1301 | { \ 1302 | return codec_create(method, arg); \ 1303 | } \ 1304 | 1305 | DECLARE_FF_AMEDIACODEC_CREATE_FUNC(createCodecByName, CREATE_CODEC_BY_NAME) 1306 | DECLARE_FF_AMEDIACODEC_CREATE_FUNC(createDecoderByType, CREATE_DECODER_BY_TYPE) 1307 | DECLARE_FF_AMEDIACODEC_CREATE_FUNC(createEncoderByType, CREATE_ENCODER_BY_TYPE) 1308 | 1309 | int ff_AMediaCodec_delete(FFAMediaCodec* codec) 1310 | { 1311 | int ret = 0; 1312 | 1313 | JNIEnv *env = NULL; 1314 | 1315 | if (!codec) { 1316 | return 0; 1317 | } 1318 | 1319 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1320 | 1321 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_id); 1322 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1323 | ret = AVERROR_EXTERNAL; 1324 | } 1325 | 1326 | (*env)->DeleteGlobalRef(env, codec->object); 1327 | codec->object = NULL; 1328 | 1329 | (*env)->DeleteGlobalRef(env, codec->buffer_info); 1330 | codec->buffer_info = NULL; 1331 | 1332 | ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec); 1333 | 1334 | av_freep(&codec); 1335 | 1336 | return ret; 1337 | } 1338 | 1339 | char *ff_AMediaCodec_getName(FFAMediaCodec *codec) 1340 | { 1341 | char *ret = NULL; 1342 | JNIEnv *env = NULL; 1343 | jobject *name = NULL; 1344 | 1345 | JNI_GET_ENV_OR_RETURN(env, codec, NULL); 1346 | 1347 | name = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_name_id); 1348 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1349 | goto fail; 1350 | } 1351 | 1352 | ret = ff_jni_jstring_to_utf_chars(env, name, codec); 1353 | 1354 | fail: 1355 | if (name) { 1356 | (*env)->DeleteLocalRef(env, name); 1357 | } 1358 | 1359 | return ret; 1360 | } 1361 | 1362 | int ff_AMediaCodec_configure(FFAMediaCodec* codec, const FFAMediaFormat* format, void* surface, void *crypto, uint32_t flags) 1363 | { 1364 | int ret = 0; 1365 | JNIEnv *env = NULL; 1366 | 1367 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1368 | 1369 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.configure_id, format->object, surface, NULL, flags); 1370 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1371 | ret = AVERROR_EXTERNAL; 1372 | goto fail; 1373 | } 1374 | 1375 | fail: 1376 | return ret; 1377 | } 1378 | 1379 | int ff_AMediaCodec_start(FFAMediaCodec* codec) 1380 | { 1381 | int ret = 0; 1382 | JNIEnv *env = NULL; 1383 | 1384 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1385 | 1386 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.start_id); 1387 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1388 | ret = AVERROR_EXTERNAL; 1389 | goto fail; 1390 | } 1391 | 1392 | fail: 1393 | return ret; 1394 | } 1395 | 1396 | int ff_AMediaCodec_stop(FFAMediaCodec* codec) 1397 | { 1398 | int ret = 0; 1399 | JNIEnv *env = NULL; 1400 | 1401 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1402 | 1403 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.stop_id); 1404 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1405 | ret = AVERROR_EXTERNAL; 1406 | goto fail; 1407 | } 1408 | 1409 | fail: 1410 | return ret; 1411 | } 1412 | 1413 | int ff_AMediaCodec_flush(FFAMediaCodec* codec) 1414 | { 1415 | int ret = 0; 1416 | JNIEnv *env = NULL; 1417 | 1418 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1419 | 1420 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.flush_id); 1421 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1422 | ret = AVERROR_EXTERNAL; 1423 | goto fail; 1424 | } 1425 | 1426 | fail: 1427 | return ret; 1428 | } 1429 | 1430 | int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec* codec, size_t idx, int render) 1431 | { 1432 | int ret = 0; 1433 | JNIEnv *env = NULL; 1434 | 1435 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1436 | 1437 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_id, (jint)idx, (jboolean)render); 1438 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1439 | ret = AVERROR_EXTERNAL; 1440 | goto fail; 1441 | } 1442 | 1443 | fail: 1444 | return ret; 1445 | } 1446 | 1447 | int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, int64_t timestampNs) 1448 | { 1449 | int ret = 0; 1450 | JNIEnv *env = NULL; 1451 | 1452 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1453 | 1454 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.release_output_buffer_at_time_id, (jint)idx, (jlong)timestampNs); 1455 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1456 | ret = AVERROR_EXTERNAL; 1457 | goto fail; 1458 | } 1459 | 1460 | fail: 1461 | return ret; 1462 | } 1463 | 1464 | ssize_t ff_AMediaCodec_dequeueInputBuffer(FFAMediaCodec* codec, int64_t timeoutUs) 1465 | { 1466 | int ret = 0; 1467 | JNIEnv *env = NULL; 1468 | 1469 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1470 | 1471 | ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_input_buffer_id, timeoutUs); 1472 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1473 | ret = AVERROR_EXTERNAL; 1474 | goto fail; 1475 | } 1476 | 1477 | fail: 1478 | return ret; 1479 | } 1480 | 1481 | int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec* codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags) 1482 | { 1483 | int ret = 0; 1484 | JNIEnv *env = NULL; 1485 | 1486 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1487 | 1488 | (*env)->CallVoidMethod(env, codec->object, codec->jfields.queue_input_buffer_id, (jint)idx, (jint)offset, (jint)size, time, flags); 1489 | if ((ret = ff_jni_exception_check(env, 1, codec)) < 0) { 1490 | ret = AVERROR_EXTERNAL; 1491 | goto fail; 1492 | } 1493 | 1494 | fail: 1495 | return ret; 1496 | } 1497 | 1498 | ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs) 1499 | { 1500 | int ret = 0; 1501 | JNIEnv *env = NULL; 1502 | 1503 | JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL); 1504 | 1505 | ret = (*env)->CallIntMethod(env, codec->object, codec->jfields.dequeue_output_buffer_id, codec->buffer_info, timeoutUs); 1506 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1507 | return AVERROR_EXTERNAL; 1508 | } 1509 | 1510 | info->flags = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.flags_id); 1511 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1512 | return AVERROR_EXTERNAL; 1513 | } 1514 | 1515 | info->offset = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.offset_id); 1516 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1517 | return AVERROR_EXTERNAL; 1518 | } 1519 | 1520 | info->presentationTimeUs = (*env)->GetLongField(env, codec->buffer_info, codec->jfields.presentation_time_us_id); 1521 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1522 | return AVERROR_EXTERNAL; 1523 | } 1524 | 1525 | info->size = (*env)->GetIntField(env, codec->buffer_info, codec->jfields.size_id); 1526 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1527 | return AVERROR_EXTERNAL; 1528 | } 1529 | 1530 | return ret; 1531 | } 1532 | 1533 | uint8_t* ff_AMediaCodec_getInputBuffer(FFAMediaCodec* codec, size_t idx, size_t *out_size) 1534 | { 1535 | uint8_t *ret = NULL; 1536 | JNIEnv *env = NULL; 1537 | 1538 | jobject buffer = NULL; 1539 | jobject input_buffers = NULL; 1540 | 1541 | JNI_GET_ENV_OR_RETURN(env, codec, NULL); 1542 | 1543 | if (codec->has_get_i_o_buffer) { 1544 | buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffer_id, (jint)idx); 1545 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1546 | goto fail; 1547 | } 1548 | } else { 1549 | if (!codec->input_buffers) { 1550 | input_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_input_buffers_id); 1551 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1552 | goto fail; 1553 | } 1554 | 1555 | codec->input_buffers = (*env)->NewGlobalRef(env, input_buffers); 1556 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1557 | goto fail; 1558 | } 1559 | } 1560 | 1561 | buffer = (*env)->GetObjectArrayElement(env, codec->input_buffers, idx); 1562 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1563 | goto fail; 1564 | } 1565 | } 1566 | 1567 | ret = (*env)->GetDirectBufferAddress(env, buffer); 1568 | *out_size = (*env)->GetDirectBufferCapacity(env, buffer); 1569 | fail: 1570 | if (buffer) { 1571 | (*env)->DeleteLocalRef(env, buffer); 1572 | } 1573 | 1574 | if (input_buffers) { 1575 | (*env)->DeleteLocalRef(env, input_buffers); 1576 | } 1577 | 1578 | return ret; 1579 | } 1580 | 1581 | uint8_t* ff_AMediaCodec_getOutputBuffer(FFAMediaCodec* codec, size_t idx, size_t *out_size) 1582 | { 1583 | uint8_t *ret = NULL; 1584 | JNIEnv *env = NULL; 1585 | 1586 | jobject buffer = NULL; 1587 | jobject output_buffers = NULL; 1588 | 1589 | JNI_GET_ENV_OR_RETURN(env, codec, NULL); 1590 | 1591 | if (codec->has_get_i_o_buffer) { 1592 | buffer = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffer_id, (jint)idx); 1593 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1594 | goto fail; 1595 | } 1596 | } else { 1597 | if (!codec->output_buffers) { 1598 | output_buffers = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_buffers_id); 1599 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1600 | goto fail; 1601 | } 1602 | 1603 | codec->output_buffers = (*env)->NewGlobalRef(env, output_buffers); 1604 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1605 | goto fail; 1606 | } 1607 | } 1608 | 1609 | buffer = (*env)->GetObjectArrayElement(env, codec->output_buffers, idx); 1610 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1611 | goto fail; 1612 | } 1613 | } 1614 | 1615 | ret = (*env)->GetDirectBufferAddress(env, buffer); 1616 | *out_size = (*env)->GetDirectBufferCapacity(env, buffer); 1617 | fail: 1618 | if (buffer) { 1619 | (*env)->DeleteLocalRef(env, buffer); 1620 | } 1621 | 1622 | if (output_buffers) { 1623 | (*env)->DeleteLocalRef(env, output_buffers); 1624 | } 1625 | 1626 | return ret; 1627 | } 1628 | 1629 | FFAMediaFormat* ff_AMediaCodec_getOutputFormat(FFAMediaCodec* codec) 1630 | { 1631 | FFAMediaFormat *ret = NULL; 1632 | JNIEnv *env = NULL; 1633 | 1634 | jobject mediaformat = NULL; 1635 | 1636 | JNI_GET_ENV_OR_RETURN(env, codec, NULL); 1637 | 1638 | mediaformat = (*env)->CallObjectMethod(env, codec->object, codec->jfields.get_output_format_id); 1639 | if (ff_jni_exception_check(env, 1, codec) < 0) { 1640 | goto fail; 1641 | } 1642 | 1643 | ret = ff_AMediaFormat_newFromObject(mediaformat); 1644 | fail: 1645 | if (mediaformat) { 1646 | (*env)->DeleteLocalRef(env, mediaformat); 1647 | } 1648 | 1649 | return ret; 1650 | } 1651 | 1652 | int ff_AMediaCodec_infoTryAgainLater(FFAMediaCodec *codec, ssize_t idx) 1653 | { 1654 | return idx == codec->INFO_TRY_AGAIN_LATER; 1655 | } 1656 | 1657 | int ff_AMediaCodec_infoOutputBuffersChanged(FFAMediaCodec *codec, ssize_t idx) 1658 | { 1659 | return idx == codec->INFO_OUTPUT_BUFFERS_CHANGED; 1660 | } 1661 | 1662 | int ff_AMediaCodec_infoOutputFormatChanged(FFAMediaCodec *codec, ssize_t idx) 1663 | { 1664 | return idx == codec->INFO_OUTPUT_FORMAT_CHANGED; 1665 | } 1666 | 1667 | int ff_AMediaCodec_getBufferFlagCodecConfig(FFAMediaCodec *codec) 1668 | { 1669 | return codec->BUFFER_FLAG_CODEC_CONFIG; 1670 | } 1671 | 1672 | int ff_AMediaCodec_getBufferFlagEndOfStream(FFAMediaCodec *codec) 1673 | { 1674 | return codec->BUFFER_FLAG_END_OF_STREAM; 1675 | } 1676 | 1677 | int ff_AMediaCodec_getBufferFlagKeyFrame(FFAMediaCodec *codec) 1678 | { 1679 | return codec->BUFFER_FLAG_KEY_FRAME; 1680 | } 1681 | 1682 | int ff_AMediaCodec_getBufferFlagPartialFrame(FFAMediaCodec *codec) 1683 | { 1684 | return codec->BUFFER_FLAG_PARTIAL_FRAME; 1685 | } 1686 | 1687 | int ff_AMediaCodec_getBufferFlagMuxerData(FFAMediaCodec *codec) 1688 | { 1689 | return codec->BUFFER_FLAG_MUXER_DATA; 1690 | } 1691 | 1692 | int ff_AMediaCodec_getConfigureFlagEncode(FFAMediaCodec *codec) 1693 | { 1694 | return codec->CONFIGURE_FLAG_ENCODE; 1695 | } 1696 | 1697 | int ff_AMediaCodec_cleanOutputBuffers(FFAMediaCodec *codec) 1698 | { 1699 | int ret = 0; 1700 | 1701 | if (!codec->has_get_i_o_buffer) { 1702 | if (codec->output_buffers) { 1703 | JNIEnv *env = NULL; 1704 | 1705 | env = ff_jni_get_env(codec); 1706 | if (!env) { 1707 | ret = AVERROR_EXTERNAL; 1708 | goto fail; 1709 | } 1710 | 1711 | (*env)->DeleteGlobalRef(env, codec->output_buffers); 1712 | codec->output_buffers = NULL; 1713 | } 1714 | } 1715 | 1716 | fail: 1717 | return ret; 1718 | } 1719 | 1720 | int ff_Build_SDK_INT(AVCodecContext *avctx) 1721 | { 1722 | int ret = -1; 1723 | JNIEnv *env = NULL; 1724 | jclass versionClass; 1725 | jfieldID sdkIntFieldID; 1726 | JNI_GET_ENV_OR_RETURN(env, avctx, -1); 1727 | 1728 | versionClass = (*env)->FindClass(env, "android/os/Build$VERSION"); 1729 | sdkIntFieldID = (*env)->GetStaticFieldID(env, versionClass, "SDK_INT", "I"); 1730 | ret = (*env)->GetStaticIntField(env, versionClass, sdkIntFieldID); 1731 | (*env)->DeleteLocalRef(env, versionClass); 1732 | return ret; 1733 | } 1734 | -------------------------------------------------------------------------------- /libavcodec/mediacodec_wrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec Wrapper 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #ifndef AVCODEC_MEDIACODEC_WRAPPER_H 24 | #define AVCODEC_MEDIACODEC_WRAPPER_H 25 | 26 | #include 27 | #include 28 | 29 | #include "avcodec.h" 30 | 31 | /** 32 | * The following API around MediaCodec and MediaFormat is based on the 33 | * NDK one provided by Google since Android 5.0. 34 | * 35 | * Differences from the NDK API: 36 | * 37 | * Buffers returned by ff_AMediaFormat_toString and ff_AMediaFormat_getString 38 | * are newly allocated buffer and must be freed by the user after use. 39 | * 40 | * The MediaCrypto API is not implemented. 41 | * 42 | * ff_AMediaCodec_infoTryAgainLater, ff_AMediaCodec_infoOutputBuffersChanged, 43 | * ff_AMediaCodec_infoOutputFormatChanged, ff_AMediaCodec_cleanOutputBuffers 44 | * ff_AMediaCodec_getName and ff_AMediaCodec_getBufferFlagEndOfStream are not 45 | * part of the original NDK API and are convenience functions to hide JNI 46 | * implementation. 47 | * 48 | * The API around MediaCodecList is not part of the NDK (and is lacking as 49 | * we still need to retrieve the codec name to work around faulty decoders 50 | * and encoders). 51 | * 52 | * For documentation, please refers to NdkMediaCodec.h NdkMediaFormat.h and 53 | * http://developer.android.com/reference/android/media/MediaCodec.html. 54 | * 55 | */ 56 | 57 | int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx); 58 | 59 | char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx); 60 | 61 | struct FFAMediaFormat; 62 | typedef struct FFAMediaFormat FFAMediaFormat; 63 | 64 | FFAMediaFormat *ff_AMediaFormat_new(void); 65 | int ff_AMediaFormat_delete(FFAMediaFormat* format); 66 | 67 | char* ff_AMediaFormat_toString(FFAMediaFormat* format); 68 | 69 | int ff_AMediaFormat_getInt32(FFAMediaFormat* format, const char *name, int32_t *out); 70 | int ff_AMediaFormat_getInt64(FFAMediaFormat* format, const char *name, int64_t *out); 71 | int ff_AMediaFormat_getFloat(FFAMediaFormat* format, const char *name, float *out); 72 | int ff_AMediaFormat_getBuffer(FFAMediaFormat* format, const char *name, void** data, size_t *size); 73 | int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *name, const char **out); 74 | 75 | void ff_AMediaFormat_setInt32(FFAMediaFormat* format, const char* name, int32_t value); 76 | void ff_AMediaFormat_setInt64(FFAMediaFormat* format, const char* name, int64_t value); 77 | void ff_AMediaFormat_setFloat(FFAMediaFormat* format, const char* name, float value); 78 | void ff_AMediaFormat_setString(FFAMediaFormat* format, const char* name, const char* value); 79 | void ff_AMediaFormat_setBuffer(FFAMediaFormat* format, const char* name, void* data, size_t size); 80 | 81 | struct FFAMediaCodec; 82 | typedef struct FFAMediaCodec FFAMediaCodec; 83 | typedef struct FFAMediaCodecCryptoInfo FFAMediaCodecCryptoInfo; 84 | 85 | struct FFAMediaCodecBufferInfo { 86 | int32_t offset; 87 | int32_t size; 88 | int64_t presentationTimeUs; 89 | uint32_t flags; 90 | }; 91 | typedef struct FFAMediaCodecBufferInfo FFAMediaCodecBufferInfo; 92 | 93 | char *ff_AMediaCodec_getName(FFAMediaCodec *codec); 94 | 95 | FFAMediaCodec* ff_AMediaCodec_createCodecByName(const char *name); 96 | FFAMediaCodec* ff_AMediaCodec_createDecoderByType(const char *mime_type); 97 | FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime_type); 98 | 99 | int ff_AMediaCodec_configure(FFAMediaCodec* codec, const FFAMediaFormat* format, void* surface, void *crypto, uint32_t flags); 100 | int ff_AMediaCodec_start(FFAMediaCodec* codec); 101 | int ff_AMediaCodec_stop(FFAMediaCodec* codec); 102 | int ff_AMediaCodec_flush(FFAMediaCodec* codec); 103 | int ff_AMediaCodec_delete(FFAMediaCodec* codec); 104 | 105 | uint8_t* ff_AMediaCodec_getInputBuffer(FFAMediaCodec* codec, size_t idx, size_t *out_size); 106 | uint8_t* ff_AMediaCodec_getOutputBuffer(FFAMediaCodec* codec, size_t idx, size_t *out_size); 107 | 108 | ssize_t ff_AMediaCodec_dequeueInputBuffer(FFAMediaCodec* codec, int64_t timeoutUs); 109 | int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec* codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags); 110 | 111 | ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec* codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs); 112 | FFAMediaFormat* ff_AMediaCodec_getOutputFormat(FFAMediaCodec* codec); 113 | 114 | int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec* codec, size_t idx, int render); 115 | int ff_AMediaCodec_releaseOutputBufferAtTime(FFAMediaCodec *codec, size_t idx, int64_t timestampNs); 116 | 117 | int ff_AMediaCodec_infoTryAgainLater(FFAMediaCodec *codec, ssize_t idx); 118 | int ff_AMediaCodec_infoOutputBuffersChanged(FFAMediaCodec *codec, ssize_t idx); 119 | int ff_AMediaCodec_infoOutputFormatChanged(FFAMediaCodec *codec, ssize_t indx); 120 | 121 | int ff_AMediaCodec_getBufferFlagCodecConfig (FFAMediaCodec *codec); 122 | int ff_AMediaCodec_getBufferFlagEndOfStream(FFAMediaCodec *codec); 123 | int ff_AMediaCodec_getBufferFlagKeyFrame(FFAMediaCodec *codec); 124 | int ff_AMediaCodec_getBufferFlagPartialFrame(FFAMediaCodec *codec); 125 | int ff_AMediaCodec_getBufferFlagMuxerData(FFAMediaCodec *codec); 126 | 127 | int ff_AMediaCodec_getConfigureFlagEncode(FFAMediaCodec *codec); 128 | 129 | int ff_AMediaCodec_cleanOutputBuffers(FFAMediaCodec *codec); 130 | 131 | int ff_Build_SDK_INT(AVCodecContext *avctx); 132 | 133 | #endif /* AVCODEC_MEDIACODEC_WRAPPER_H */ 134 | -------------------------------------------------------------------------------- /libavcodec/mediacodecdec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #include 24 | #include 25 | 26 | #include "libavutil/avassert.h" 27 | #include "libavutil/common.h" 28 | #include "libavutil/opt.h" 29 | #include "libavutil/intreadwrite.h" 30 | #include "libavutil/pixfmt.h" 31 | #include "libavutil/internal.h" 32 | 33 | #include "avcodec.h" 34 | #include "decode.h" 35 | #include "h264_parse.h" 36 | #include "hevc_parse.h" 37 | #include "hwaccel.h" 38 | #include "internal.h" 39 | #include "mediacodec_wrapper.h" 40 | #include "mediacodecdec_common.h" 41 | 42 | typedef struct MediaCodecH264DecContext { 43 | 44 | AVClass *avclass; 45 | 46 | MediaCodecDecContext *ctx; 47 | 48 | AVPacket buffered_pkt; 49 | 50 | int delay_flush; 51 | int amlogic_mpeg2_api23_workaround; 52 | 53 | } MediaCodecH264DecContext; 54 | 55 | static av_cold int mediacodec_decode_close(AVCodecContext *avctx) 56 | { 57 | MediaCodecH264DecContext *s = avctx->priv_data; 58 | 59 | ff_mediacodec_dec_close(avctx, s->ctx); 60 | s->ctx = NULL; 61 | 62 | av_packet_unref(&s->buffered_pkt); 63 | 64 | return 0; 65 | } 66 | 67 | #if CONFIG_H264_MEDIACODEC_DECODER || CONFIG_HEVC_MEDIACODEC_DECODER 68 | static int h2645_ps_to_nalu(const uint8_t *src, int src_size, uint8_t **out, int *out_size) 69 | { 70 | int i; 71 | int ret = 0; 72 | uint8_t *p = NULL; 73 | static const uint8_t nalu_header[] = { 0x00, 0x00, 0x00, 0x01 }; 74 | 75 | if (!out || !out_size) { 76 | return AVERROR(EINVAL); 77 | } 78 | 79 | p = av_malloc(sizeof(nalu_header) + src_size); 80 | if (!p) { 81 | return AVERROR(ENOMEM); 82 | } 83 | 84 | *out = p; 85 | *out_size = sizeof(nalu_header) + src_size; 86 | 87 | memcpy(p, nalu_header, sizeof(nalu_header)); 88 | memcpy(p + sizeof(nalu_header), src, src_size); 89 | 90 | /* Escape 0x00, 0x00, 0x0{0-3} pattern */ 91 | for (i = 4; i < *out_size; i++) { 92 | if (i < *out_size - 3 && 93 | p[i + 0] == 0 && 94 | p[i + 1] == 0 && 95 | p[i + 2] <= 3) { 96 | uint8_t *new; 97 | 98 | *out_size += 1; 99 | new = av_realloc(*out, *out_size); 100 | if (!new) { 101 | ret = AVERROR(ENOMEM); 102 | goto done; 103 | } 104 | *out = p = new; 105 | 106 | i = i + 2; 107 | memmove(p + i + 1, p + i, *out_size - (i + 1)); 108 | p[i] = 0x03; 109 | } 110 | } 111 | done: 112 | if (ret < 0) { 113 | av_freep(out); 114 | *out_size = 0; 115 | } 116 | 117 | return ret; 118 | } 119 | #endif 120 | 121 | #if CONFIG_H264_MEDIACODEC_DECODER 122 | static int h264_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) 123 | { 124 | int i; 125 | int ret; 126 | 127 | H264ParamSets ps; 128 | const PPS *pps = NULL; 129 | const SPS *sps = NULL; 130 | int is_avc = 0; 131 | int nal_length_size = 0; 132 | 133 | memset(&ps, 0, sizeof(ps)); 134 | 135 | ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, 136 | &ps, &is_avc, &nal_length_size, 0, avctx); 137 | if (ret < 0) { 138 | goto done; 139 | } 140 | 141 | for (i = 0; i < MAX_PPS_COUNT; i++) { 142 | if (ps.pps_list[i]) { 143 | pps = (const PPS*)ps.pps_list[i]->data; 144 | break; 145 | } 146 | } 147 | 148 | if (pps) { 149 | if (ps.sps_list[pps->sps_id]) { 150 | sps = (const SPS*)ps.sps_list[pps->sps_id]->data; 151 | } 152 | } 153 | 154 | if (pps && sps) { 155 | uint8_t *data = NULL; 156 | int data_size = 0; 157 | 158 | if ((ret = h2645_ps_to_nalu(sps->data, sps->data_size, &data, &data_size)) < 0) { 159 | goto done; 160 | } 161 | ff_AMediaFormat_setBuffer(format, "csd-0", (void*)data, data_size); 162 | av_freep(&data); 163 | 164 | if ((ret = h2645_ps_to_nalu(pps->data, pps->data_size, &data, &data_size)) < 0) { 165 | goto done; 166 | } 167 | ff_AMediaFormat_setBuffer(format, "csd-1", (void*)data, data_size); 168 | av_freep(&data); 169 | } else { 170 | av_log(avctx, AV_LOG_ERROR, "Could not extract PPS/SPS from extradata"); 171 | ret = AVERROR_INVALIDDATA; 172 | } 173 | 174 | done: 175 | ff_h264_ps_uninit(&ps); 176 | 177 | return ret; 178 | } 179 | #endif 180 | 181 | #if CONFIG_HEVC_MEDIACODEC_DECODER 182 | static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) 183 | { 184 | int i; 185 | int ret; 186 | 187 | HEVCParamSets ps; 188 | HEVCSEI sei; 189 | 190 | const HEVCVPS *vps = NULL; 191 | const HEVCPPS *pps = NULL; 192 | const HEVCSPS *sps = NULL; 193 | int is_nalff = 0; 194 | int nal_length_size = 0; 195 | 196 | uint8_t *vps_data = NULL; 197 | uint8_t *sps_data = NULL; 198 | uint8_t *pps_data = NULL; 199 | int vps_data_size = 0; 200 | int sps_data_size = 0; 201 | int pps_data_size = 0; 202 | 203 | memset(&ps, 0, sizeof(ps)); 204 | memset(&sei, 0, sizeof(sei)); 205 | 206 | ret = ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size, 207 | &ps, &sei, &is_nalff, &nal_length_size, 0, 1, avctx); 208 | if (ret < 0) { 209 | goto done; 210 | } 211 | 212 | for (i = 0; i < HEVC_MAX_VPS_COUNT; i++) { 213 | if (ps.vps_list[i]) { 214 | vps = (const HEVCVPS*)ps.vps_list[i]->data; 215 | break; 216 | } 217 | } 218 | 219 | for (i = 0; i < HEVC_MAX_PPS_COUNT; i++) { 220 | if (ps.pps_list[i]) { 221 | pps = (const HEVCPPS*)ps.pps_list[i]->data; 222 | break; 223 | } 224 | } 225 | 226 | if (pps) { 227 | if (ps.sps_list[pps->sps_id]) { 228 | sps = (const HEVCSPS*)ps.sps_list[pps->sps_id]->data; 229 | } 230 | } 231 | 232 | if (vps && pps && sps) { 233 | uint8_t *data; 234 | int data_size; 235 | 236 | if ((ret = h2645_ps_to_nalu(vps->data, vps->data_size, &vps_data, &vps_data_size)) < 0 || 237 | (ret = h2645_ps_to_nalu(sps->data, sps->data_size, &sps_data, &sps_data_size)) < 0 || 238 | (ret = h2645_ps_to_nalu(pps->data, pps->data_size, &pps_data, &pps_data_size)) < 0) { 239 | goto done; 240 | } 241 | 242 | data_size = vps_data_size + sps_data_size + pps_data_size; 243 | data = av_mallocz(data_size); 244 | if (!data) { 245 | ret = AVERROR(ENOMEM); 246 | goto done; 247 | } 248 | 249 | memcpy(data , vps_data, vps_data_size); 250 | memcpy(data + vps_data_size , sps_data, sps_data_size); 251 | memcpy(data + vps_data_size + sps_data_size, pps_data, pps_data_size); 252 | 253 | ff_AMediaFormat_setBuffer(format, "csd-0", data, data_size); 254 | 255 | av_freep(&data); 256 | } else { 257 | av_log(avctx, AV_LOG_ERROR, "Could not extract VPS/PPS/SPS from extradata"); 258 | ret = AVERROR_INVALIDDATA; 259 | } 260 | 261 | done: 262 | ff_hevc_ps_uninit(&ps); 263 | 264 | av_freep(&vps_data); 265 | av_freep(&sps_data); 266 | av_freep(&pps_data); 267 | 268 | return ret; 269 | } 270 | #endif 271 | 272 | #if CONFIG_MPEG2_MEDIACODEC_DECODER || \ 273 | CONFIG_MPEG4_MEDIACODEC_DECODER || \ 274 | CONFIG_VP8_MEDIACODEC_DECODER || \ 275 | CONFIG_VP9_MEDIACODEC_DECODER 276 | static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) 277 | { 278 | int ret = 0; 279 | 280 | if (avctx->extradata) { 281 | ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size); 282 | } 283 | 284 | return ret; 285 | } 286 | #endif 287 | 288 | static av_cold int mediacodec_decode_init(AVCodecContext *avctx) 289 | { 290 | int ret; 291 | int sdk_int; 292 | 293 | const char *codec_mime = NULL; 294 | 295 | FFAMediaFormat *format = NULL; 296 | MediaCodecH264DecContext *s = avctx->priv_data; 297 | 298 | format = ff_AMediaFormat_new(); 299 | if (!format) { 300 | av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n"); 301 | ret = AVERROR_EXTERNAL; 302 | goto done; 303 | } 304 | 305 | switch (avctx->codec_id) { 306 | #if CONFIG_H264_MEDIACODEC_DECODER 307 | case AV_CODEC_ID_H264: 308 | codec_mime = "video/avc"; 309 | 310 | ret = h264_set_extradata(avctx, format); 311 | if (ret < 0) 312 | goto done; 313 | break; 314 | #endif 315 | #if CONFIG_HEVC_MEDIACODEC_DECODER 316 | case AV_CODEC_ID_HEVC: 317 | codec_mime = "video/hevc"; 318 | 319 | ret = hevc_set_extradata(avctx, format); 320 | if (ret < 0) 321 | goto done; 322 | break; 323 | #endif 324 | #if CONFIG_MPEG2_MEDIACODEC_DECODER 325 | case AV_CODEC_ID_MPEG2VIDEO: 326 | codec_mime = "video/mpeg2"; 327 | 328 | ret = common_set_extradata(avctx, format); 329 | if (ret < 0) 330 | goto done; 331 | break; 332 | #endif 333 | #if CONFIG_MPEG4_MEDIACODEC_DECODER 334 | case AV_CODEC_ID_MPEG4: 335 | codec_mime = "video/mp4v-es", 336 | 337 | ret = common_set_extradata(avctx, format); 338 | if (ret < 0) 339 | goto done; 340 | break; 341 | #endif 342 | #if CONFIG_VP8_MEDIACODEC_DECODER 343 | case AV_CODEC_ID_VP8: 344 | codec_mime = "video/x-vnd.on2.vp8"; 345 | 346 | ret = common_set_extradata(avctx, format); 347 | if (ret < 0) 348 | goto done; 349 | break; 350 | #endif 351 | #if CONFIG_VP9_MEDIACODEC_DECODER 352 | case AV_CODEC_ID_VP9: 353 | codec_mime = "video/x-vnd.on2.vp9"; 354 | 355 | ret = common_set_extradata(avctx, format); 356 | if (ret < 0) 357 | goto done; 358 | break; 359 | #endif 360 | default: 361 | av_assert0(0); 362 | } 363 | 364 | ff_AMediaFormat_setString(format, "mime", codec_mime); 365 | ff_AMediaFormat_setInt32(format, "width", avctx->width); 366 | ff_AMediaFormat_setInt32(format, "height", avctx->height); 367 | 368 | s->ctx = av_mallocz(sizeof(*s->ctx)); 369 | if (!s->ctx) { 370 | av_log(avctx, AV_LOG_ERROR, "Failed to allocate MediaCodecDecContext\n"); 371 | ret = AVERROR(ENOMEM); 372 | goto done; 373 | } 374 | 375 | s->ctx->delay_flush = s->delay_flush; 376 | 377 | if ((ret = ff_mediacodec_dec_init(avctx, s->ctx, codec_mime, format)) < 0) { 378 | s->ctx = NULL; 379 | goto done; 380 | } 381 | 382 | av_log(avctx, AV_LOG_INFO, 383 | "MediaCodec started successfully: codec = %s, ret = %d\n", 384 | s->ctx->codec_name, ret); 385 | 386 | sdk_int = ff_Build_SDK_INT(avctx); 387 | if (sdk_int <= 23 && 388 | strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) { 389 | av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n", 390 | s->ctx->codec_name, sdk_int); 391 | s->amlogic_mpeg2_api23_workaround = 1; 392 | } 393 | 394 | done: 395 | if (format) { 396 | ff_AMediaFormat_delete(format); 397 | } 398 | 399 | if (ret < 0) { 400 | mediacodec_decode_close(avctx); 401 | } 402 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_decode_init finish! %d", ret); 403 | return ret; 404 | } 405 | 406 | static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) 407 | { 408 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame start"); 409 | MediaCodecH264DecContext *s = avctx->priv_data; 410 | int ret; 411 | ssize_t index; 412 | 413 | /* In delay_flush mode, wait until the user has released or rendered 414 | all retained frames. */ 415 | if (s->delay_flush && ff_mediacodec_dec_is_flushing(avctx, s->ctx)) { 416 | if (!ff_mediacodec_dec_flush(avctx, s->ctx)) { 417 | return AVERROR(EAGAIN); 418 | } 419 | } 420 | 421 | /* poll for new frame */ 422 | ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); 423 | if (ret != AVERROR(EAGAIN)) 424 | return ret; 425 | 426 | /* feed decoder */ 427 | int get_input_buffer_retry = 0; 428 | while (1) { 429 | if (s->ctx->current_input_buffer < 0) { 430 | /* poll for input space */ 431 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame try to get input buffer"); 432 | index = ff_AMediaCodec_dequeueInputBuffer(s->ctx->codec, 10000); 433 | if (index < 0) { 434 | get_input_buffer_retry++; 435 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame can't get input buffer %d,retry: %d", index, get_input_buffer_retry); 436 | /* no space, block for an output frame to appear */ 437 | if (get_input_buffer_retry < 3) { 438 | continue; 439 | } else { 440 | return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); 441 | } 442 | } 443 | s->ctx->current_input_buffer = index; 444 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame got input buffer %d", index); 445 | } 446 | 447 | /* try to flush any buffered packet data */ 448 | if (s->buffered_pkt.size > 0) { 449 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame current packet is not empty, try to send to decoder"); 450 | ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt, false); 451 | if (ret >= 0) { 452 | s->buffered_pkt.size -= ret; 453 | s->buffered_pkt.data += ret; 454 | if (s->buffered_pkt.size <= 0) 455 | av_packet_unref(&s->buffered_pkt); 456 | } else if (ret < 0 && ret != AVERROR(EAGAIN)) { 457 | return ret; 458 | } 459 | 460 | if (s->amlogic_mpeg2_api23_workaround && s->buffered_pkt.size <= 0) { 461 | /* fallthrough to fetch next packet regardless of input buffer space */ 462 | } else { 463 | /* poll for space again */ 464 | continue; 465 | } 466 | } 467 | 468 | /* fetch new packet or eof */ 469 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame try to get packet AVCodecContext"); 470 | ret = ff_decode_get_packet(avctx, &s->buffered_pkt); 471 | if (ret == AVERROR_EOF) { 472 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame try to get packet got AVERROR_EOF"); 473 | AVPacket null_pkt = { 0 }; 474 | ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, true); 475 | if (ret < 0) 476 | return ret; 477 | return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); 478 | } else if (ret == AVERROR(EAGAIN) && s->ctx->current_input_buffer < 0) { 479 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame try to get packet got EAGAIN and current input buffer:%d", s->ctx->current_input_buffer); 480 | return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); 481 | } else if (ret < 0) { 482 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame try to get packet got RET: %d", ret); 483 | return ret; 484 | } else { 485 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX mediacodec_receive_frame got AVPacket %p", &s->buffered_pkt); 486 | } 487 | } 488 | 489 | return AVERROR(EAGAIN); 490 | } 491 | 492 | static void mediacodec_decode_flush(AVCodecContext *avctx) 493 | { 494 | MediaCodecH264DecContext *s = avctx->priv_data; 495 | 496 | av_packet_unref(&s->buffered_pkt); 497 | 498 | ff_mediacodec_dec_flush(avctx, s->ctx); 499 | } 500 | 501 | static const AVCodecHWConfigInternal *mediacodec_hw_configs[] = { 502 | &(const AVCodecHWConfigInternal) { 503 | .public = { 504 | .pix_fmt = AV_PIX_FMT_MEDIACODEC, 505 | .methods = AV_CODEC_HW_CONFIG_METHOD_AD_HOC | 506 | AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX, 507 | .device_type = AV_HWDEVICE_TYPE_MEDIACODEC, 508 | }, 509 | .hwaccel = NULL, 510 | }, 511 | NULL 512 | }; 513 | 514 | #define OFFSET(x) offsetof(MediaCodecH264DecContext, x) 515 | #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM 516 | static const AVOption ff_mediacodec_vdec_options[] = { 517 | { "delay_flush", "Delay flush until hw output buffers are returned to the decoder", 518 | OFFSET(delay_flush), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VD }, 519 | { NULL } 520 | }; 521 | 522 | #define DECLARE_MEDIACODEC_VCLASS(short_name) \ 523 | static const AVClass ff_##short_name##_mediacodec_dec_class = { \ 524 | .class_name = #short_name "_mediacodec", \ 525 | .item_name = av_default_item_name, \ 526 | .option = ff_mediacodec_vdec_options, \ 527 | .version = LIBAVUTIL_VERSION_INT, \ 528 | }; 529 | 530 | #define DECLARE_MEDIACODEC_VDEC(short_name, full_name, codec_id, bsf) \ 531 | DECLARE_MEDIACODEC_VCLASS(short_name) \ 532 | AVCodec ff_##short_name##_mediacodec_decoder = { \ 533 | .name = #short_name "_mediacodec", \ 534 | .long_name = NULL_IF_CONFIG_SMALL(full_name " Android MediaCodec decoder"), \ 535 | .type = AVMEDIA_TYPE_VIDEO, \ 536 | .id = codec_id, \ 537 | .priv_class = &ff_##short_name##_mediacodec_dec_class, \ 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 | .bsfs = bsf, \ 546 | .hw_configs = mediacodec_hw_configs, \ 547 | .wrapper_name = "mediacodec", \ 548 | }; \ 549 | 550 | #if CONFIG_H264_MEDIACODEC_DECODER 551 | DECLARE_MEDIACODEC_VDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb") 552 | #endif 553 | 554 | #if CONFIG_HEVC_MEDIACODEC_DECODER 555 | DECLARE_MEDIACODEC_VDEC(hevc, "H.265", AV_CODEC_ID_HEVC, "hevc_mp4toannexb") 556 | #endif 557 | 558 | #if CONFIG_MPEG2_MEDIACODEC_DECODER 559 | DECLARE_MEDIACODEC_VDEC(mpeg2, "MPEG-2", AV_CODEC_ID_MPEG2VIDEO, NULL) 560 | #endif 561 | 562 | #if CONFIG_MPEG4_MEDIACODEC_DECODER 563 | DECLARE_MEDIACODEC_VDEC(mpeg4, "MPEG-4", AV_CODEC_ID_MPEG4, NULL) 564 | #endif 565 | 566 | #if CONFIG_VP8_MEDIACODEC_DECODER 567 | DECLARE_MEDIACODEC_VDEC(vp8, "VP8", AV_CODEC_ID_VP8, NULL) 568 | #endif 569 | 570 | #if CONFIG_VP9_MEDIACODEC_DECODER 571 | DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL) 572 | #endif 573 | -------------------------------------------------------------------------------- /libavcodec/mediacodecdec_common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec decoder 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #include 24 | #include 25 | 26 | #include "libavutil/common.h" 27 | #include "libavutil/hwcontext_mediacodec.h" 28 | #include "libavutil/mem.h" 29 | #include "libavutil/log.h" 30 | #include "libavutil/pixfmt.h" 31 | #include "libavutil/time.h" 32 | #include "libavutil/timestamp.h" 33 | 34 | #include "avcodec.h" 35 | #include "internal.h" 36 | 37 | #include "mediacodec.h" 38 | #include "mediacodec_surface.h" 39 | #include "mediacodec_sw_buffer.h" 40 | #include "mediacodec_wrapper.h" 41 | #include "mediacodecdec_common.h" 42 | #include "libavutil/frame.h" 43 | #include "unistd.h" 44 | #include "stdio.h" 45 | #include "../build/output-armv7a/include/libavutil/frame.h" 46 | 47 | /** 48 | * OMX.k3.video.decoder.avc, OMX.NVIDIA.* OMX.SEC.avc.dec and OMX.google 49 | * codec workarounds used in various place are taken from the Gstreamer 50 | * project. 51 | * 52 | * Gstreamer references: 53 | * https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/androidmedia/ 54 | * 55 | * Gstreamer copyright notice: 56 | * 57 | * Copyright (C) 2012, Collabora Ltd. 58 | * Author: Sebastian Dröge 59 | * 60 | * Copyright (C) 2012, Rafaël Carré 61 | * 62 | * Copyright (C) 2015, Sebastian Dröge 63 | * 64 | * Copyright (C) 2014-2015, Collabora Ltd. 65 | * Author: Matthieu Bouron 66 | * 67 | * Copyright (C) 2015, Edward Hervey 68 | * Author: Edward Hervey 69 | * 70 | * Copyright (C) 2015, Matthew Waters 71 | * 72 | * This library is free software; you can redistribute it and/or 73 | * modify it under the terms of the GNU Lesser General Public 74 | * License as published by the Free Software Foundation 75 | * version 2.1 of the License. 76 | * 77 | * This library is distributed in the hope that it will be useful, 78 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 79 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 80 | * Lesser General Public License for more details. 81 | * 82 | * You should have received a copy of the GNU Lesser General Public 83 | * License along with this library; if not, write to the Free Software 84 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 85 | * 86 | */ 87 | 88 | #define INPUT_DEQUEUE_TIMEOUT_US 8000 89 | #define OUTPUT_DEQUEUE_TIMEOUT_US 8000 90 | #define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US 1000000 91 | 92 | enum { 93 | COLOR_FormatYUV420Planar = 0x13, 94 | COLOR_FormatYUV420SemiPlanar = 0x15, 95 | COLOR_FormatYUV422PackedPlanar = 0x17, 96 | COLOR_FormatYCbYCr = 0x19, 97 | COLOR_FormatAndroidOpaque = 0x7F000789, 98 | COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00, 99 | COLOR_QCOM_FormatYUV420SemiPlanar32m = 0x7fa30c04, 100 | COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7fa30c03, 101 | COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100, 102 | COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced = 0x7f000001, 103 | }; 104 | 105 | static const struct { 106 | 107 | int color_format; 108 | enum AVPixelFormat pix_fmt; 109 | 110 | } color_formats[] = { 111 | 112 | { COLOR_FormatYUV420Planar, AV_PIX_FMT_YUV420P }, 113 | { COLOR_FormatYUV420SemiPlanar, AV_PIX_FMT_NV12 }, 114 | { COLOR_QCOM_FormatYUV420SemiPlanar, AV_PIX_FMT_NV12 }, 115 | { COLOR_FormatYUV422PackedPlanar, AV_PIX_FMT_NV12 }, 116 | { COLOR_QCOM_FormatYUV420SemiPlanar32m, AV_PIX_FMT_NV12 }, 117 | { COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, AV_PIX_FMT_NV12 }, 118 | { COLOR_TI_FormatYUV420PackedSemiPlanar, AV_PIX_FMT_NV12 }, 119 | { COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced, AV_PIX_FMT_NV12 }, 120 | { 0 } 121 | }; 122 | 123 | static enum AVPixelFormat mcdec_map_color_format(AVCodecContext *avctx, 124 | MediaCodecDecContext *s, 125 | int color_format) 126 | { 127 | int i; 128 | enum AVPixelFormat ret = AV_PIX_FMT_NONE; 129 | 130 | if (s->surface) { 131 | return AV_PIX_FMT_MEDIACODEC; 132 | } 133 | 134 | if (!strcmp(s->codec_name, "OMX.k3.video.decoder.avc") && color_format == COLOR_FormatYCbYCr) { 135 | s->color_format = color_format = COLOR_TI_FormatYUV420PackedSemiPlanar; 136 | } 137 | 138 | for (i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { 139 | if (color_formats[i].color_format == color_format) { 140 | return color_formats[i].pix_fmt; 141 | } 142 | } 143 | 144 | av_log(avctx, AV_LOG_ERROR, "Output color format 0x%x (value=%d) is not supported\n", 145 | color_format, color_format); 146 | 147 | return ret; 148 | } 149 | 150 | static void ff_mediacodec_dec_ref(MediaCodecDecContext *s) 151 | { 152 | atomic_fetch_add(&s->refcount, 1); 153 | } 154 | 155 | static void ff_mediacodec_dec_unref(MediaCodecDecContext *s) 156 | { 157 | if (!s) 158 | return; 159 | 160 | if (atomic_fetch_sub(&s->refcount, 1) == 1) { 161 | if (s->codec) { 162 | ff_AMediaCodec_delete(s->codec); 163 | s->codec = NULL; 164 | } 165 | 166 | if (s->format) { 167 | ff_AMediaFormat_delete(s->format); 168 | s->format = NULL; 169 | } 170 | 171 | if (s->surface) { 172 | ff_mediacodec_surface_unref(s->surface, NULL); 173 | s->surface = NULL; 174 | } 175 | 176 | av_freep(&s->codec_name); 177 | av_freep(&s); 178 | } 179 | } 180 | 181 | static void mediacodec_buffer_release(void *opaque, uint8_t *data) 182 | { 183 | AVMediaCodecBuffer *buffer = opaque; 184 | MediaCodecDecContext *ctx = buffer->ctx; 185 | int released = atomic_load(&buffer->released); 186 | 187 | if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { 188 | atomic_fetch_sub(&ctx->hw_buffer_count, 1); 189 | av_log(ctx->avctx, AV_LOG_DEBUG, 190 | "Releasing output buffer %zd (%p) ts=%"PRId64" on free() [%d pending]\n", 191 | buffer->index, buffer, buffer->pts, atomic_load(&ctx->hw_buffer_count)); 192 | ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, 0); 193 | } 194 | 195 | if (ctx->delay_flush) 196 | ff_mediacodec_dec_unref(ctx); 197 | av_freep(&buffer); 198 | } 199 | 200 | static int mediacodec_wrap_hw_buffer(AVCodecContext *avctx, 201 | MediaCodecDecContext *s, 202 | ssize_t index, 203 | FFAMediaCodecBufferInfo *info, 204 | AVFrame *frame) 205 | { 206 | int ret = 0; 207 | int status = 0; 208 | AVMediaCodecBuffer *buffer = NULL; 209 | 210 | frame->buf[0] = NULL; 211 | frame->width = avctx->width; 212 | frame->height = avctx->height; 213 | frame->format = avctx->pix_fmt; 214 | frame->sample_aspect_ratio = avctx->sample_aspect_ratio; 215 | 216 | if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) { 217 | frame->pts = av_rescale_q(info->presentationTimeUs, 218 | AV_TIME_BASE_Q, 219 | avctx->pkt_timebase); 220 | } else { 221 | frame->pts = info->presentationTimeUs; 222 | } 223 | #if FF_API_PKT_PTS 224 | FF_DISABLE_DEPRECATION_WARNINGS 225 | frame->pkt_pts = frame->pts; 226 | FF_ENABLE_DEPRECATION_WARNINGS 227 | #endif 228 | frame->pkt_dts = AV_NOPTS_VALUE; 229 | 230 | buffer = av_mallocz(sizeof(AVMediaCodecBuffer)); 231 | if (!buffer) { 232 | ret = AVERROR(ENOMEM); 233 | goto fail; 234 | } 235 | 236 | atomic_init(&buffer->released, 0); 237 | 238 | frame->buf[0] = av_buffer_create(NULL, 239 | 0, 240 | mediacodec_buffer_release, 241 | buffer, 242 | AV_BUFFER_FLAG_READONLY); 243 | 244 | if (!frame->buf[0]) { 245 | ret = AVERROR(ENOMEM); 246 | goto fail; 247 | 248 | } 249 | 250 | buffer->ctx = s; 251 | buffer->serial = atomic_load(&s->serial); 252 | if (s->delay_flush) 253 | ff_mediacodec_dec_ref(s); 254 | 255 | buffer->index = index; 256 | buffer->pts = info->presentationTimeUs; 257 | 258 | frame->data[3] = (uint8_t *)buffer; 259 | 260 | atomic_fetch_add(&s->hw_buffer_count, 1); 261 | av_log(avctx, AV_LOG_DEBUG, 262 | "Wrapping output buffer %zd (%p) ts=%"PRId64" [%d pending]\n", 263 | buffer->index, buffer, buffer->pts, atomic_load(&s->hw_buffer_count)); 264 | 265 | return 0; 266 | fail: 267 | av_freep(buffer); 268 | av_buffer_unref(&frame->buf[0]); 269 | status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0); 270 | if (status < 0) { 271 | av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n"); 272 | ret = AVERROR_EXTERNAL; 273 | } 274 | 275 | return ret; 276 | } 277 | 278 | static int mediacodec_wrap_sw_buffer(AVCodecContext *avctx, 279 | MediaCodecDecContext *s, 280 | uint8_t *data, 281 | size_t size, 282 | ssize_t index, 283 | FFAMediaCodecBufferInfo *info, 284 | AVFrame *frame) 285 | { 286 | int ret = 0; 287 | int status = 0; 288 | 289 | frame->width = avctx->width; 290 | frame->height = avctx->height; 291 | frame->format = avctx->pix_fmt; 292 | 293 | /* MediaCodec buffers needs to be copied to our own refcounted buffers 294 | * because the flush command invalidates all input and output buffers. 295 | */ 296 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { 297 | av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer\n"); 298 | goto done; 299 | } 300 | 301 | /* Override frame->pkt_pts as ff_get_buffer will override its value based 302 | * on the last avpacket received which is not in sync with the frame: 303 | * * N avpackets can be pushed before 1 frame is actually returned 304 | * * 0-sized avpackets are pushed to flush remaining frames at EOS */ 305 | if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) { 306 | frame->pts = av_rescale_q(info->presentationTimeUs, 307 | AV_TIME_BASE_Q, 308 | avctx->pkt_timebase); 309 | } else { 310 | frame->pts = info->presentationTimeUs; 311 | } 312 | #if FF_API_PKT_PTS 313 | FF_DISABLE_DEPRECATION_WARNINGS 314 | frame->pkt_pts = frame->pts; 315 | FF_ENABLE_DEPRECATION_WARNINGS 316 | #endif 317 | frame->pkt_dts = AV_NOPTS_VALUE; 318 | 319 | av_log(avctx, AV_LOG_TRACE, 320 | "Frame: width=%d stride=%d height=%d slice-height=%d " 321 | "crop-top=%d crop-bottom=%d crop-left=%d crop-right=%d encoder=%s " 322 | "destination linesizes=%d,%d,%d\n" , 323 | avctx->width, s->stride, avctx->height, s->slice_height, 324 | s->crop_top, s->crop_bottom, s->crop_left, s->crop_right, s->codec_name, 325 | frame->linesize[0], frame->linesize[1], frame->linesize[2]); 326 | 327 | switch (s->color_format) { 328 | case COLOR_FormatYUV420Planar: 329 | ff_mediacodec_sw_buffer_copy_yuv420_planar(avctx, s, data, size, info, frame); 330 | break; 331 | case COLOR_FormatYUV420SemiPlanar: 332 | case COLOR_QCOM_FormatYUV420SemiPlanar: 333 | case COLOR_QCOM_FormatYUV420SemiPlanar32m: 334 | ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(avctx, s, data, size, info, frame); 335 | break; 336 | case COLOR_TI_FormatYUV420PackedSemiPlanar: 337 | case COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced: 338 | ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar(avctx, s, data, size, info, frame); 339 | break; 340 | case COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: 341 | ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar_64x32Tile2m8ka(avctx, s, data, size, info, frame); 342 | break; 343 | default: 344 | av_log(avctx, AV_LOG_ERROR, "Unsupported color format 0x%x (value=%d)\n", 345 | s->color_format, s->color_format); 346 | ret = AVERROR(EINVAL); 347 | goto done; 348 | } 349 | 350 | ret = 0; 351 | done: 352 | status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0); 353 | if (status < 0) { 354 | av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n"); 355 | ret = AVERROR_EXTERNAL; 356 | } 357 | 358 | return ret; 359 | } 360 | 361 | #define AMEDIAFORMAT_GET_INT32(name, key, mandatory) do { \ 362 | int32_t value = 0; \ 363 | if (ff_AMediaFormat_getInt32(s->format, key, &value)) { \ 364 | (name) = value; \ 365 | } else if (mandatory) { \ 366 | av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", key, format); \ 367 | ret = AVERROR_EXTERNAL; \ 368 | goto fail; \ 369 | } \ 370 | } while (0) \ 371 | 372 | static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s) 373 | { 374 | int ret = 0; 375 | int width = 0; 376 | int height = 0; 377 | char *format = NULL; 378 | 379 | if (!s->format) { 380 | av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n"); 381 | return AVERROR(EINVAL); 382 | } 383 | 384 | format = ff_AMediaFormat_toString(s->format); 385 | if (!format) { 386 | return AVERROR_EXTERNAL; 387 | } 388 | av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format); 389 | 390 | /* Mandatory fields */ 391 | AMEDIAFORMAT_GET_INT32(s->width, "width", 1); 392 | AMEDIAFORMAT_GET_INT32(s->height, "height", 1); 393 | 394 | AMEDIAFORMAT_GET_INT32(s->stride, "stride", 0); 395 | s->stride = s->stride > 0 ? s->stride : s->width; 396 | 397 | AMEDIAFORMAT_GET_INT32(s->slice_height, "slice-height", 0); 398 | 399 | if (strstr(s->codec_name, "OMX.Nvidia.") && s->slice_height == 0) { 400 | s->slice_height = FFALIGN(s->height, 16); 401 | } else if (strstr(s->codec_name, "OMX.SEC.avc.dec")) { 402 | s->slice_height = avctx->height; 403 | s->stride = avctx->width; 404 | } else if (s->slice_height == 0) { 405 | s->slice_height = s->height; 406 | } 407 | 408 | AMEDIAFORMAT_GET_INT32(s->color_format, "color-format", 1); 409 | avctx->pix_fmt = mcdec_map_color_format(avctx, s, s->color_format); 410 | if (avctx->pix_fmt == AV_PIX_FMT_NONE) { 411 | av_log(avctx, AV_LOG_ERROR, "Output color format is not supported\n"); 412 | ret = AVERROR(EINVAL); 413 | goto fail; 414 | } 415 | 416 | /* Optional fields */ 417 | AMEDIAFORMAT_GET_INT32(s->crop_top, "crop-top", 0); 418 | AMEDIAFORMAT_GET_INT32(s->crop_bottom, "crop-bottom", 0); 419 | AMEDIAFORMAT_GET_INT32(s->crop_left, "crop-left", 0); 420 | AMEDIAFORMAT_GET_INT32(s->crop_right, "crop-right", 0); 421 | 422 | width = s->crop_right + 1 - s->crop_left; 423 | height = s->crop_bottom + 1 - s->crop_top; 424 | 425 | AMEDIAFORMAT_GET_INT32(s->display_width, "display-width", 0); 426 | AMEDIAFORMAT_GET_INT32(s->display_height, "display-height", 0); 427 | 428 | if (s->display_width && s->display_height) { 429 | AVRational sar = av_div_q( 430 | (AVRational){ s->display_width, s->display_height }, 431 | (AVRational){ width, height }); 432 | ff_set_sar(avctx, sar); 433 | } 434 | 435 | av_log(avctx, AV_LOG_INFO, 436 | "Output crop parameters top=%d bottom=%d left=%d right=%d, " 437 | "resulting dimensions width=%d height=%d\n", 438 | s->crop_top, s->crop_bottom, s->crop_left, s->crop_right, 439 | width, height); 440 | 441 | av_freep(&format); 442 | return ff_set_dimensions(avctx, width, height); 443 | fail: 444 | av_freep(&format); 445 | return ret; 446 | } 447 | 448 | static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s) 449 | { 450 | FFAMediaCodec *codec = s->codec; 451 | int status; 452 | 453 | s->output_buffer_count = 0; 454 | 455 | s->draining = 0; 456 | s->flushing = 0; 457 | s->eos = 0; 458 | atomic_fetch_add(&s->serial, 1); 459 | atomic_init(&s->hw_buffer_count, 0); 460 | s->current_input_buffer = -1; 461 | 462 | status = ff_AMediaCodec_flush(codec); 463 | if (status < 0) { 464 | av_log(avctx, AV_LOG_ERROR, "Failed to flush codec\n"); 465 | return AVERROR_EXTERNAL; 466 | } 467 | 468 | return 0; 469 | } 470 | 471 | int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, 472 | const char *mime, FFAMediaFormat *format) 473 | { 474 | int ret = 0; 475 | int status; 476 | int profile; 477 | 478 | enum AVPixelFormat pix_fmt; 479 | static const enum AVPixelFormat pix_fmts[] = { 480 | AV_PIX_FMT_MEDIACODEC, 481 | AV_PIX_FMT_NONE, 482 | }; 483 | 484 | s->avctx = avctx; 485 | atomic_init(&s->refcount, 1); 486 | atomic_init(&s->hw_buffer_count, 0); 487 | atomic_init(&s->serial, 1); 488 | s->current_input_buffer = -1; 489 | s->out_yuv_seq = 0; 490 | 491 | pix_fmt = ff_get_format(avctx, pix_fmts); 492 | if (pix_fmt == AV_PIX_FMT_MEDIACODEC) { 493 | AVMediaCodecContext *user_ctx = avctx->hwaccel_context; 494 | 495 | if (avctx->hw_device_ctx) { 496 | AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)(avctx->hw_device_ctx->data); 497 | if (device_ctx->type == AV_HWDEVICE_TYPE_MEDIACODEC) { 498 | if (device_ctx->hwctx) { 499 | AVMediaCodecDeviceContext *mediacodec_ctx = (AVMediaCodecDeviceContext *)device_ctx->hwctx; 500 | s->surface = ff_mediacodec_surface_ref(mediacodec_ctx->surface, avctx); 501 | av_log(avctx, AV_LOG_INFO, "Using surface %p\n", s->surface); 502 | } 503 | } 504 | } 505 | 506 | if (!s->surface && user_ctx && user_ctx->surface) { 507 | s->surface = ff_mediacodec_surface_ref(user_ctx->surface, avctx); 508 | av_log(avctx, AV_LOG_INFO, "Using surface %p\n", s->surface); 509 | } 510 | } 511 | 512 | profile = ff_AMediaCodecProfile_getProfileFromAVCodecContext(avctx); 513 | if (profile < 0) { 514 | av_log(avctx, AV_LOG_WARNING, "Unsupported or unknown profile\n"); 515 | } 516 | 517 | s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, profile, 0, avctx); 518 | if (!s->codec_name) { 519 | ret = AVERROR_EXTERNAL; 520 | goto fail; 521 | } 522 | 523 | av_log(avctx, AV_LOG_DEBUG, "Found decoder %s\n", s->codec_name); 524 | s->codec = ff_AMediaCodec_createCodecByName(s->codec_name); 525 | if (!s->codec) { 526 | av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for type %s and name %s\n", mime, s->codec_name); 527 | ret = AVERROR_EXTERNAL; 528 | goto fail; 529 | } 530 | 531 | status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0); 532 | if (status < 0) { 533 | char *desc = ff_AMediaFormat_toString(format); 534 | av_log(avctx, AV_LOG_ERROR, 535 | "Failed to configure codec (status = %d) with format %s\n", 536 | status, desc); 537 | av_freep(&desc); 538 | 539 | ret = AVERROR_EXTERNAL; 540 | goto fail; 541 | } 542 | 543 | status = ff_AMediaCodec_start(s->codec); 544 | if (status < 0) { 545 | char *desc = ff_AMediaFormat_toString(format); 546 | av_log(avctx, AV_LOG_ERROR, 547 | "Failed to start codec (status = %d) with format %s\n", 548 | status, desc); 549 | av_freep(&desc); 550 | ret = AVERROR_EXTERNAL; 551 | goto fail; 552 | } 553 | 554 | s->format = ff_AMediaCodec_getOutputFormat(s->codec); 555 | if (s->format) { 556 | if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) { 557 | av_log(avctx, AV_LOG_ERROR, 558 | "Failed to configure context\n"); 559 | goto fail; 560 | } 561 | } 562 | 563 | av_log(avctx, AV_LOG_DEBUG, "MediaCodec %p started successfully\n", s->codec); 564 | 565 | return 0; 566 | 567 | fail: 568 | av_log(avctx, AV_LOG_ERROR, "MediaCodec %p failed to start\n", s->codec); 569 | ff_mediacodec_dec_close(avctx, s); 570 | return ret; 571 | } 572 | 573 | int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s, 574 | AVPacket *pkt, bool wait) 575 | { 576 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_send start"); 577 | int offset = 0; 578 | int need_draining = 0; 579 | uint8_t *data; 580 | ssize_t index = s->current_input_buffer; 581 | size_t size; 582 | FFAMediaCodec *codec = s->codec; 583 | int status; 584 | int64_t input_dequeue_timeout_us = wait ? INPUT_DEQUEUE_TIMEOUT_US : 0; 585 | int64_t pts; 586 | 587 | if (s->flushing) { 588 | av_log(avctx, AV_LOG_ERROR, "Decoder is flushing and cannot accept new buffer " 589 | "until all output buffers have been released\n"); 590 | return AVERROR_EXTERNAL; 591 | } 592 | 593 | if (pkt->size == 0) { 594 | need_draining = 1; 595 | } 596 | 597 | if (s->draining && s->eos) { 598 | return AVERROR_EOF; 599 | } 600 | 601 | int get_input_buffer_retry = 0; 602 | while (offset < pkt->size || (need_draining && !s->draining)) { 603 | if (index < 0) { 604 | index = ff_AMediaCodec_dequeueInputBuffer(codec, input_dequeue_timeout_us); 605 | if (ff_AMediaCodec_infoTryAgainLater(codec, index)) { 606 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_send No input buffer available, try again later\n"); 607 | break; 608 | } 609 | 610 | if (index < 0) { 611 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_send Failed to dequeue input buffer (status=%zd) retry:%d\n", index, get_input_buffer_retry); 612 | get_input_buffer_retry++; 613 | if(get_input_buffer_retry < 3) { 614 | continue; 615 | } else { 616 | return AVERROR_EXTERNAL; 617 | } 618 | } 619 | } 620 | get_input_buffer_retry = 0; 621 | s->current_input_buffer = -1; 622 | 623 | data = ff_AMediaCodec_getInputBuffer(codec, index, &size); 624 | if (!data) { 625 | av_log(avctx, AV_LOG_ERROR, "Failed to get input buffer\n"); 626 | return AVERROR_EXTERNAL; 627 | } 628 | 629 | pts = pkt->pts; 630 | if (pts != AV_NOPTS_VALUE && avctx->pkt_timebase.num && avctx->pkt_timebase.den) { 631 | pts = av_rescale_q(pts, avctx->pkt_timebase, AV_TIME_BASE_Q); 632 | } 633 | 634 | if (need_draining) { 635 | uint32_t flags = ff_AMediaCodec_getBufferFlagEndOfStream(codec); 636 | 637 | av_log(avctx, AV_LOG_DEBUG, "Sending End Of Stream signal\n"); 638 | 639 | status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags); 640 | if (status < 0) { 641 | av_log(avctx, AV_LOG_ERROR, "Failed to queue input empty buffer (status = %d)\n", status); 642 | return AVERROR_EXTERNAL; 643 | } 644 | 645 | av_log(avctx, AV_LOG_TRACE, 646 | "Queued input buffer %zd size=%zd ts=%"PRIi64"\n", index, size, pts); 647 | 648 | s->draining = 1; 649 | return 0; 650 | } 651 | 652 | size = FFMIN(pkt->size - offset, size); 653 | memcpy(data, pkt->data + offset, size); 654 | offset += size; 655 | 656 | status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0); 657 | if (status < 0) { 658 | av_log(avctx, AV_LOG_ERROR, "Failed to queue input buffer (status = %d)\n", status); 659 | return AVERROR_EXTERNAL; 660 | } 661 | 662 | av_log(avctx, AV_LOG_ERROR, 663 | "XXXXXXXXXX Queued input buffer %zd size=%zd ts=%"PRIi64"\n", index, size, pts); 664 | } 665 | 666 | if (offset == 0) 667 | return AVERROR(EAGAIN); 668 | return offset; 669 | } 670 | 671 | int save_frame(char *filename, AVFrame *frame) { 672 | FILE *yuvf; 673 | int i,j,w; 674 | uint8_t *pos; 675 | 676 | yuvf = fopen(filename, "wb+"); 677 | if (!yuvf) { 678 | return -1; 679 | } 680 | pos = frame->data[0]; 681 | w = frame->width; 682 | for(i = 0; i < frame->height; i++) { 683 | fwrite(pos, sizeof(uint8_t), w, yuvf); 684 | pos += frame->linesize[0]; 685 | } 686 | w = FFMIN(frame->linesize[1], FFALIGN(w, 2)); 687 | pos = frame->data[1]; 688 | for(i = 0; i < frame->height / 2; i++) { 689 | fwrite(pos, sizeof(uint8_t), w, yuvf); 690 | pos += frame->linesize[1]; 691 | } 692 | fclose(yuvf); 693 | return 0; 694 | } 695 | 696 | int ff_mediacodec_dec_receive(AVCodecContext *avctx, MediaCodecDecContext *s, 697 | AVFrame *frame, bool wait) 698 | { 699 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive start"); 700 | 701 | int ret; 702 | uint8_t *data; 703 | ssize_t index; 704 | size_t size; 705 | FFAMediaCodec *codec = s->codec; 706 | FFAMediaCodecBufferInfo info = { 0 }; 707 | int status; 708 | int64_t output_dequeue_timeout_us = OUTPUT_DEQUEUE_TIMEOUT_US; 709 | 710 | // for out put the yuv to file 711 | char filename[100]; 712 | FILE *yuvf; 713 | int i,j,w; 714 | uint8_t *pos; 715 | 716 | if (s->draining && s->eos) { 717 | return AVERROR_EOF; 718 | } 719 | 720 | if (s->draining) { 721 | /* If the codec is flushing or need to be flushed, block for a fair 722 | * amount of time to ensure we got a frame */ 723 | output_dequeue_timeout_us = OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US; 724 | } else if (s->output_buffer_count == 0 || !wait) { 725 | /* If the codec hasn't produced any frames, do not block so we 726 | * can push data to it as fast as possible, and get the first 727 | * frame */ 728 | output_dequeue_timeout_us = 0; 729 | } 730 | 731 | index = ff_AMediaCodec_dequeueOutputBuffer(codec, &info, output_dequeue_timeout_us); 732 | if (index >= 0) { 733 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Got output buffer %zd" 734 | " offset=%" PRIi32 " size=%" PRIi32 " ts=%" PRIi64 735 | " flags=%" PRIu32 "\n", index, info.offset, info.size, 736 | info.presentationTimeUs, info.flags); 737 | 738 | if (info.flags & ff_AMediaCodec_getBufferFlagPartialFrame(codec)) { 739 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive got hahaha BufferFlagPartialFrame"); 740 | } 741 | 742 | if (info.flags & ff_AMediaCodec_getBufferFlagMuxerData(codec)) { 743 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive got hahaha BufferFlagMuxerData"); 744 | } 745 | 746 | if (info.flags & ff_AMediaCodec_getBufferFlagEndOfStream(codec)) { 747 | s->eos = 1; 748 | } 749 | 750 | if (info.size) { 751 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive got data"); 752 | if (s->surface) { 753 | if ((ret = mediacodec_wrap_hw_buffer(avctx, s, index, &info, frame)) < 0) { 754 | av_log(avctx, AV_LOG_ERROR, "Failed to wrap MediaCodec buffer\n"); 755 | return ret; 756 | } 757 | } else { 758 | data = ff_AMediaCodec_getOutputBuffer(codec, index, &size); 759 | if (!data) { 760 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Failed to get output buffer\n"); 761 | return AVERROR_EXTERNAL; 762 | } 763 | 764 | if ((ret = mediacodec_wrap_sw_buffer(avctx, s, data, size, index, &info, frame)) < 0) { 765 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Failed to wrap MediaCodec buffer\n"); 766 | return ret; 767 | } 768 | 769 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive got new frame: %d\n", s->output_buffer_count); 770 | /*if(s->out_yuv_seq < 2) { 771 | sprintf(filename, "/data/local/tmp/test/%s%d.yuv","mdec", s->out_yuv_seq); 772 | yuvf = fopen(filename, "wb+"); 773 | if(!yuvf) { 774 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Failed to create file\n"); 775 | } 776 | fwrite(data, sizeof(uint8_t), info.size, yuvf); 777 | fclose(yuvf); 778 | 779 | sprintf(filename, "/data/local/tmp/test/%s%d.yuv","frame", s->out_yuv_seq); 780 | save_frame(filename, frame); 781 | s->out_yuv_seq++; 782 | }*/ 783 | } 784 | 785 | s->output_buffer_count++; 786 | return 0; 787 | } else { 788 | status = ff_AMediaCodec_releaseOutputBuffer(codec, index, 0); 789 | if (status < 0) { 790 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Failed to release output buffer\n"); 791 | } 792 | } 793 | 794 | } else if (ff_AMediaCodec_infoOutputFormatChanged(codec, index)) { 795 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Got OutputFormatChanged"); 796 | char *format = NULL; 797 | 798 | if (s->format) { 799 | status = ff_AMediaFormat_delete(s->format); 800 | if (status < 0) { 801 | av_log(avctx, AV_LOG_ERROR, "Failed to delete MediaFormat %p\n", s->format); 802 | } 803 | } 804 | 805 | s->format = ff_AMediaCodec_getOutputFormat(codec); 806 | if (!s->format) { 807 | av_log(avctx, AV_LOG_ERROR, "Failed to get output format\n"); 808 | return AVERROR_EXTERNAL; 809 | } 810 | 811 | format = ff_AMediaFormat_toString(s->format); 812 | if (!format) { 813 | return AVERROR_EXTERNAL; 814 | } 815 | av_log(avctx, AV_LOG_INFO, "Output MediaFormat changed to %s\n", format); 816 | av_freep(&format); 817 | 818 | if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) { 819 | return ret; 820 | } 821 | 822 | } else if (ff_AMediaCodec_infoOutputBuffersChanged(codec, index)) { 823 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Got OutputBuffersChanged"); 824 | ff_AMediaCodec_cleanOutputBuffers(codec); 825 | } else if (ff_AMediaCodec_infoTryAgainLater(codec, index)) { 826 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Got TryAgainLater"); 827 | if (s->draining) { 828 | av_log(avctx, AV_LOG_ERROR, "Failed to dequeue output buffer within %" PRIi64 "ms " 829 | "while draining remaining frames, output will probably lack frames\n", 830 | output_dequeue_timeout_us / 1000); 831 | } else { 832 | av_log(avctx, AV_LOG_TRACE, "No output buffer available, try again later\n"); 833 | } 834 | } else { 835 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive Failed to dequeue output buffer (status=%zd)\n", index); 836 | return AVERROR_EXTERNAL; 837 | } 838 | 839 | av_log(avctx, AV_LOG_ERROR, "XXXXXXXXXX ff_mediacodec_dec_receive EAGAIN"); 840 | return AVERROR(EAGAIN); 841 | } 842 | 843 | /* 844 | * ff_mediacodec_dec_flush returns 0 if the flush cannot be performed on 845 | * the codec (because the user retains frames). The codec stays in the 846 | * flushing state. 847 | * 848 | * ff_mediacodec_dec_flush returns 1 if the flush can actually be 849 | * performed on the codec. The codec leaves the flushing state and can 850 | * process again packets. 851 | * 852 | * ff_mediacodec_dec_flush returns a negative value if an error has 853 | * occurred. 854 | */ 855 | int ff_mediacodec_dec_flush(AVCodecContext *avctx, MediaCodecDecContext *s) 856 | { 857 | if (!s->surface || atomic_load(&s->refcount) == 1) { 858 | int ret; 859 | 860 | /* No frames (holding a reference to the codec) are retained by the 861 | * user, thus we can flush the codec and returns accordingly */ 862 | if ((ret = mediacodec_dec_flush_codec(avctx, s)) < 0) { 863 | return ret; 864 | } 865 | 866 | return 1; 867 | } 868 | 869 | s->flushing = 1; 870 | return 0; 871 | } 872 | 873 | int ff_mediacodec_dec_close(AVCodecContext *avctx, MediaCodecDecContext *s) 874 | { 875 | ff_mediacodec_dec_unref(s); 876 | 877 | return 0; 878 | } 879 | 880 | int ff_mediacodec_dec_is_flushing(AVCodecContext *avctx, MediaCodecDecContext *s) 881 | { 882 | return s->flushing; 883 | } 884 | 885 | //-----------------------------------encoder spliter------------------------------------- 886 | static int mediacodec_enc_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s) 887 | { 888 | int ret = 0; 889 | int width = 0; 890 | int height = 0; 891 | char *format = NULL; 892 | 893 | if (!s->format) { 894 | av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n"); 895 | return AVERROR(EINVAL); 896 | } 897 | 898 | format = ff_AMediaFormat_toString(s->format); 899 | if (!format) { 900 | return AVERROR_EXTERNAL; 901 | } 902 | av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format); 903 | 904 | /* Mandatory fields */ 905 | AMEDIAFORMAT_GET_INT32(s->width, "width", 1); 906 | AMEDIAFORMAT_GET_INT32(s->height, "height", 1); 907 | 908 | AMEDIAFORMAT_GET_INT32(s->stride, "stride", 0); 909 | s->stride = s->stride > 0 ? s->stride : s->width; 910 | 911 | AMEDIAFORMAT_GET_INT32(s->slice_height, "slice-height", 0); 912 | 913 | if (strstr(s->codec_name, "OMX.Nvidia.") && s->slice_height == 0) { 914 | s->slice_height = FFALIGN(s->height, 16); 915 | } else if (strstr(s->codec_name, "OMX.SEC.avc.dec")) { 916 | s->slice_height = avctx->height; 917 | s->stride = avctx->width; 918 | } else if (s->slice_height == 0) { 919 | s->slice_height = s->height; 920 | } 921 | 922 | /*AMEDIAFORMAT_GET_INT32(s->color_format, "color-format", 1); 923 | avctx->pix_fmt = mcdec_map_color_format(avctx, s, s->color_format); 924 | if (avctx->pix_fmt == AV_PIX_FMT_NONE) { 925 | av_log(avctx, AV_LOG_ERROR, "Output color format is not supported\n"); 926 | ret = AVERROR(EINVAL); 927 | goto fail; 928 | }*/ 929 | 930 | /* Optional fields */ 931 | AMEDIAFORMAT_GET_INT32(s->crop_top, "crop-top", 0); 932 | AMEDIAFORMAT_GET_INT32(s->crop_bottom, "crop-bottom", 0); 933 | AMEDIAFORMAT_GET_INT32(s->crop_left, "crop-left", 0); 934 | AMEDIAFORMAT_GET_INT32(s->crop_right, "crop-right", 0); 935 | 936 | width = s->crop_right + 1 - s->crop_left; 937 | height = s->crop_bottom + 1 - s->crop_top; 938 | 939 | AMEDIAFORMAT_GET_INT32(s->display_width, "display-width", 0); 940 | AMEDIAFORMAT_GET_INT32(s->display_height, "display-height", 0); 941 | 942 | if (s->display_width && s->display_height) { 943 | AVRational sar = av_div_q( 944 | (AVRational){ s->display_width, s->display_height }, 945 | (AVRational){ width, height }); 946 | ff_set_sar(avctx, sar); 947 | } 948 | 949 | av_log(avctx, AV_LOG_INFO, 950 | "Output crop parameters top=%d bottom=%d left=%d right=%d, " 951 | "resulting dimensions width=%d height=%d\n", 952 | s->crop_top, s->crop_bottom, s->crop_left, s->crop_right, 953 | width, height); 954 | 955 | av_freep(&format); 956 | return ff_set_dimensions(avctx, width, height); 957 | fail: 958 | av_freep(&format); 959 | return ret; 960 | } 961 | 962 | 963 | int ff_mediacodec_enc_init(AVCodecContext *avctx, MediaCodecDecContext *s, 964 | const char *mime, FFAMediaFormat *format, int profile) 965 | { 966 | int ret = 0; 967 | int status; 968 | 969 | enum AVPixelFormat pix_fmt; 970 | static const enum AVPixelFormat pix_fmts[] = { 971 | AV_PIX_FMT_MEDIACODEC, 972 | AV_PIX_FMT_NONE, 973 | }; 974 | 975 | s->avctx = avctx; 976 | s->draining = 0; 977 | atomic_init(&s->refcount, 1); 978 | atomic_init(&s->hw_buffer_count, 0); 979 | atomic_init(&s->serial, 1); 980 | s->current_input_buffer = -1; 981 | 982 | if(profile < 0) { 983 | profile = 1; 984 | } 985 | 986 | s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, profile, 1, avctx); 987 | if (!s->codec_name) { 988 | ret = AVERROR_EXTERNAL; 989 | goto fail; 990 | } 991 | 992 | av_log(avctx, AV_LOG_DEBUG, "Found encoder %s\n", s->codec_name); 993 | s->codec = ff_AMediaCodec_createCodecByName(s->codec_name); 994 | if (!s->codec) { 995 | av_log(avctx, AV_LOG_ERROR, "Failed to create media encoder for type %s and name %s\n", mime, s->codec_name); 996 | ret = AVERROR_EXTERNAL; 997 | goto fail; 998 | } 999 | 1000 | status = ff_AMediaCodec_configure(s->codec, format, NULL, NULL, 1); 1001 | if (status < 0) { 1002 | char *desc = ff_AMediaFormat_toString(format); 1003 | av_log(avctx, AV_LOG_ERROR, 1004 | "Failed to configure codec (status = %d) with format %s\n", 1005 | status, desc); 1006 | av_freep(&desc); 1007 | 1008 | ret = AVERROR_EXTERNAL; 1009 | goto fail; 1010 | } 1011 | 1012 | status = ff_AMediaCodec_start(s->codec); 1013 | if (status < 0) { 1014 | char *desc = ff_AMediaFormat_toString(format); 1015 | av_log(avctx, AV_LOG_ERROR, 1016 | "Failed to start codec (status = %d) with format %s\n", 1017 | status, desc); 1018 | av_freep(&desc); 1019 | ret = AVERROR_EXTERNAL; 1020 | goto fail; 1021 | } 1022 | 1023 | s->format = ff_AMediaCodec_getOutputFormat(s->codec); 1024 | if (s->format) { 1025 | if ((ret = mediacodec_enc_parse_format(avctx, s)) < 0) { 1026 | av_log(avctx, AV_LOG_ERROR, 1027 | "Failed to configure context\n"); 1028 | goto fail; 1029 | } 1030 | } 1031 | 1032 | av_log(avctx, AV_LOG_DEBUG, "MediaCodec %p started successfully\n", s->codec); 1033 | 1034 | return 0; 1035 | 1036 | fail: 1037 | av_log(avctx, AV_LOG_ERROR, "MediaCodec %p failed to start\n", s->codec); 1038 | ff_mediacodec_dec_close(avctx, s); 1039 | return ret; 1040 | } 1041 | 1042 | 1043 | int ff_mediacodec_enc_send(AVCodecContext *avctx, MediaCodecDecContext *s, AVFrame *frame, AVPacket *pkt) 1044 | { 1045 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send start"); 1046 | int offset = 0; 1047 | int need_draining = 0; 1048 | uint8_t *data; 1049 | ssize_t index = s->current_input_buffer; 1050 | size_t size; 1051 | FFAMediaCodec *codec = s->codec; 1052 | int status; 1053 | int64_t input_dequeue_timeout_us = INPUT_DEQUEUE_TIMEOUT_US; 1054 | int64_t pts; 1055 | size_t frame_size; 1056 | int w, h, w2, i, j, linesize; 1057 | uint8_t *frame_data; 1058 | uint8_t tmp; 1059 | int ret; 1060 | 1061 | if (s->draining && s->eos) { 1062 | return AVERROR_EOF; 1063 | } 1064 | 1065 | if (s->flushing) { 1066 | av_log(avctx, AV_LOG_ERROR, "Encoder is flushing and cannot accept new buffer " 1067 | "until all output buffers have been released\n"); 1068 | return AVERROR_EXTERNAL; 1069 | } 1070 | 1071 | if (!frame) { 1072 | need_draining = 1; 1073 | frame_size = 0; 1074 | } else { 1075 | switch (frame->format) { 1076 | case COLOR_FormatYUV420SemiPlanar: 1077 | case COLOR_QCOM_FormatYUV420SemiPlanar: 1078 | case COLOR_FormatYUV422PackedPlanar: 1079 | case COLOR_QCOM_FormatYUV420SemiPlanar32m: 1080 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send color format OK: %d", frame->format); 1081 | break; 1082 | default: 1083 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send color format not supported: %d", frame->format); 1084 | return AVERROR_EXTERNAL; 1085 | } 1086 | 1087 | pts = frame->pts; 1088 | w = s->crop_right - s->crop_left; 1089 | h = s->crop_bottom - s->crop_top; 1090 | if(!w) { 1091 | w = s->width; 1092 | } 1093 | if(!h) { 1094 | h = s->height; 1095 | } 1096 | w2 = FFALIGN(w, 2); 1097 | // get data from AVFrame 1098 | frame_size = h * w + h / 2 * w2; 1099 | // frame_data = av_mallocz(frame_size); 1100 | frame_data = malloc(frame_size); 1101 | if(!frame_data) { 1102 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send alloc frame data error"); 1103 | return AVERROR(EINVAL); 1104 | } 1105 | 1106 | linesize = frame->linesize[0]; 1107 | offset = 0; 1108 | for(i = 0; i< h; i++) 1109 | { 1110 | memcpy(frame_data + offset, frame->data[0] + i * linesize, w); 1111 | offset += w; 1112 | } 1113 | linesize = frame->linesize[1]; 1114 | for(i = 0; i < h / 2; i++) 1115 | { 1116 | memcpy(frame_data + offset, frame->data[1] + i * linesize, w2); 1117 | // convert nv12 to nv21 1118 | for(j = 0; j < w2; j+=2) { 1119 | tmp = frame_data[offset + j]; 1120 | frame_data[offset + j] = frame_data[offset + j + 1]; 1121 | frame_data[offset + j + 1] = tmp; 1122 | } 1123 | offset += w2; 1124 | } 1125 | } 1126 | 1127 | offset = 0; 1128 | 1129 | int get_input_buffer_retry = 0; 1130 | 1131 | while (offset < frame_size || (need_draining && !s->draining)) { 1132 | index = ff_AMediaCodec_dequeueInputBuffer(codec, input_dequeue_timeout_us); 1133 | if (ff_AMediaCodec_infoTryAgainLater(codec, index)) { 1134 | get_input_buffer_retry++; 1135 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send No input buffer available, try again later: %d\n", get_input_buffer_retry); 1136 | if(get_input_buffer_retry > 3) { 1137 | ff_mediacodec_enc_receive(avctx, s, pkt); 1138 | get_input_buffer_retry = 0; 1139 | continue; 1140 | } else { 1141 | sleep(10); 1142 | continue; 1143 | } 1144 | } 1145 | get_input_buffer_retry = 0; 1146 | if (index < 0) { 1147 | // here we need try to get output to free new input buffer 1148 | if(pkt->size > 0) { 1149 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send Failed to dequeue input buffer (status=%zd)\n", index); 1150 | break; 1151 | } else { 1152 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send Failed to dequeue input buffer (status=%zd), try to get output to free input buffer\n", index); 1153 | ff_mediacodec_enc_receive(avctx, s, pkt); 1154 | continue; 1155 | } 1156 | } 1157 | s->current_input_buffer = -1; // reset current input buffer index 1158 | 1159 | data = ff_AMediaCodec_getInputBuffer(codec, index, &size); 1160 | if (!data) { 1161 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send Failed to get input buffer\n"); 1162 | ret = AVERROR_EXTERNAL; 1163 | goto done; 1164 | } 1165 | 1166 | if (need_draining) { 1167 | uint32_t flags = ff_AMediaCodec_getBufferFlagEndOfStream(codec); 1168 | 1169 | av_log(avctx, AV_LOG_DEBUG, "YYYYYYYYYY ff_mediacodec_enc_send Sending End Of Stream signal\n"); 1170 | 1171 | status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags); 1172 | if (status < 0) { 1173 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send Failed to queue input empty buffer (status = %d)\n", status); 1174 | ret = AVERROR_EXTERNAL; 1175 | goto done; 1176 | } 1177 | 1178 | av_log(avctx, AV_LOG_ERROR, 1179 | "YYYYYYYYYY ff_mediacodec_enc_send Queued empty EOS input buffer %zd with flags=%d\n", index, flags); 1180 | 1181 | s->draining = 1; 1182 | ret = 0; 1183 | goto done; 1184 | } 1185 | 1186 | size = FFMIN(frame_size - offset, size); 1187 | memcpy(data, frame_data + offset, size); 1188 | offset += size; 1189 | 1190 | status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0); 1191 | if (status < 0) { 1192 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send Failed to queue input buffer (status = %d)\n", status); 1193 | ret = AVERROR_EXTERNAL; 1194 | goto done; 1195 | } 1196 | 1197 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_send Queued input buffer %zd size=%zd ts=%"PRIi64"\n", index, size, pts); 1198 | } 1199 | 1200 | if (offset == 0) { 1201 | ret = AVERROR(EAGAIN); 1202 | goto done; 1203 | } 1204 | 1205 | done: 1206 | if (frame_data) { 1207 | av_free(frame_data); 1208 | } 1209 | return ret; 1210 | } 1211 | 1212 | int ff_mediacodec_enc_receive(AVCodecContext *avctx, 1213 | MediaCodecDecContext *s, 1214 | AVPacket *pkt) 1215 | { 1216 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive start"); 1217 | 1218 | int ret; 1219 | uint8_t *data; 1220 | ssize_t index; 1221 | size_t size; 1222 | FFAMediaCodec *codec = s->codec; 1223 | FFAMediaCodecBufferInfo info = { 0 }; 1224 | int status; 1225 | int64_t output_dequeue_timeout_us = OUTPUT_DEQUEUE_TIMEOUT_US; 1226 | int key_frame = 0; 1227 | int is_config_data = 0; 1228 | 1229 | if (s->draining && s->eos) { 1230 | return AVERROR_EOF; 1231 | } 1232 | 1233 | if (s->draining) { 1234 | /* If the codec is flushing or need to be flushed, block for a fair 1235 | * amount of time to ensure we got a packet */ 1236 | // output_dequeue_timeout_us = OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US; 1237 | output_dequeue_timeout_us = OUTPUT_DEQUEUE_TIMEOUT_US; 1238 | } 1239 | index = ff_AMediaCodec_dequeueOutputBuffer(codec, &info, output_dequeue_timeout_us); 1240 | if (index >= 0) { 1241 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY Got output buffer %zd" 1242 | " offset=%" PRIi32 " size=%" PRIi32 " ts=%" PRIi64 1243 | " flags=%" PRIu32 "\n", index, info.offset, info.size, 1244 | info.presentationTimeUs, info.flags); 1245 | 1246 | if (info.flags & ff_AMediaCodec_getBufferFlagEndOfStream(codec)) { 1247 | s->eos = 1; 1248 | } 1249 | 1250 | if (info.flags & ff_AMediaCodec_getBufferFlagKeyFrame(codec)) { 1251 | key_frame = 1; 1252 | } else { 1253 | key_frame = 0; 1254 | } 1255 | 1256 | if (info.flags & ff_AMediaCodec_getBufferFlagCodecConfig(codec)) { 1257 | is_config_data = 1; 1258 | } else { 1259 | is_config_data = 0; 1260 | } 1261 | 1262 | if (info.flags & ff_AMediaCodec_getBufferFlagPartialFrame(codec)) { 1263 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive got hahaha BufferFlagPartialFrame"); 1264 | } 1265 | 1266 | if (info.flags & ff_AMediaCodec_getBufferFlagMuxerData(codec)) { 1267 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive got hahaha BufferFlagMuxerData"); 1268 | } 1269 | 1270 | if (info.size) { 1271 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive got data"); 1272 | data = ff_AMediaCodec_getOutputBuffer(codec, index, &size); 1273 | if (!data) { 1274 | av_log(avctx, AV_LOG_ERROR, "Failed to get output buffer\n"); 1275 | return AVERROR_EXTERNAL; 1276 | } 1277 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY buffer info size:%d byte buffer size:%d\n", info.size, size); 1278 | 1279 | if (is_config_data) { 1280 | avctx->extradata_size = info.size; 1281 | avctx->extradata = av_mallocz(info.size + AV_INPUT_BUFFER_PADDING_SIZE); 1282 | if (!avctx->extradata) { 1283 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive alloc memory for extradata error\n"); 1284 | return AVERROR(ENOMEM); 1285 | } 1286 | memcpy(avctx->extradata, data, info.size); 1287 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive got config data: %d - %d\n", info.size, size); 1288 | } 1289 | if (key_frame) { 1290 | ret = av_new_packet(pkt, info.size + avctx->extradata_size); 1291 | if (ret < 0) { 1292 | return AVERROR(ENOMEM); 1293 | } 1294 | pkt->pts = info.presentationTimeUs; 1295 | pkt->flags |= AV_PKT_FLAG_KEY; 1296 | memcpy(pkt->data, avctx->extradata, avctx->extradata_size); 1297 | memcpy(pkt->data + avctx->extradata_size, data, info.size); 1298 | } else { 1299 | ret = av_new_packet(pkt, info.size); 1300 | if (ret < 0) { 1301 | return AVERROR(ENOMEM); 1302 | } 1303 | pkt->pts = info.presentationTimeUs; 1304 | memcpy(pkt->data, data, info.size); 1305 | } 1306 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive got packet: size:%d, key_frame:%d,pts:%ld", pkt->size, key_frame, pkt->pts); 1307 | ret = 0; 1308 | s->output_buffer_count++; 1309 | 1310 | status = ff_AMediaCodec_releaseOutputBuffer(codec, index, 0); 1311 | if (status < 0) { 1312 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive Failed to release output buffer\n"); 1313 | } 1314 | return ret; 1315 | } else { 1316 | status = ff_AMediaCodec_releaseOutputBuffer(codec, index, 0); 1317 | if (status < 0) { 1318 | av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n"); 1319 | } 1320 | } 1321 | 1322 | } else if (ff_AMediaCodec_infoOutputFormatChanged(codec, index)) { 1323 | char *format = NULL; 1324 | 1325 | if (s->format) { 1326 | status = ff_AMediaFormat_delete(s->format); 1327 | if (status < 0) { 1328 | av_log(avctx, AV_LOG_ERROR, "Failed to delete MediaFormat %p\n", s->format); 1329 | } 1330 | } 1331 | 1332 | s->format = ff_AMediaCodec_getOutputFormat(codec); 1333 | if (!s->format) { 1334 | av_log(avctx, AV_LOG_ERROR, "Failed to get output format\n"); 1335 | return AVERROR_EXTERNAL; 1336 | } 1337 | 1338 | format = ff_AMediaFormat_toString(s->format); 1339 | if (!format) { 1340 | return AVERROR_EXTERNAL; 1341 | } 1342 | av_log(avctx, AV_LOG_INFO, "Output MediaFormat changed to %s\n", format); 1343 | av_freep(&format); 1344 | 1345 | if ((ret = mediacodec_enc_parse_format(avctx, s)) < 0) { 1346 | return ret; 1347 | } 1348 | 1349 | } else if (ff_AMediaCodec_infoOutputBuffersChanged(codec, index)) { 1350 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive output buffer changed"); 1351 | ff_AMediaCodec_cleanOutputBuffers(codec); 1352 | } else if (ff_AMediaCodec_infoTryAgainLater(codec, index)) { 1353 | if (s->draining) { 1354 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive Failed to dequeue output buffer within %" PRIi64 "ms " 1355 | "while draining remaining frames, output will probably lack frames\n", 1356 | output_dequeue_timeout_us / 1000); 1357 | } else { 1358 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive No output buffer available, try again later\n"); 1359 | } 1360 | } else { 1361 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive Failed to dequeue output buffer (status=%zd)\n", index); 1362 | return AVERROR_EXTERNAL; 1363 | } 1364 | 1365 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY ff_mediacodec_enc_receive EAGAIN"); 1366 | return AVERROR(EAGAIN); 1367 | } 1368 | -------------------------------------------------------------------------------- /libavcodec/mediacodecdec_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Android MediaCodec decoder 3 | * 4 | * Copyright (c) 2015-2016 Matthieu Bouron 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 | 23 | #ifndef AVCODEC_MEDIACODECDEC_COMMON_H 24 | #define AVCODEC_MEDIACODECDEC_COMMON_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "libavutil/frame.h" 32 | #include "libavutil/pixfmt.h" 33 | 34 | #include "avcodec.h" 35 | #include "mediacodec_wrapper.h" 36 | 37 | typedef struct MediaCodecDecContext { 38 | 39 | AVCodecContext *avctx; 40 | atomic_int refcount; 41 | atomic_int hw_buffer_count; 42 | 43 | char *codec_name; 44 | 45 | FFAMediaCodec *codec; 46 | FFAMediaFormat *format; 47 | 48 | void *surface; 49 | 50 | int started; 51 | int draining; 52 | int flushing; 53 | int eos; 54 | 55 | int width; 56 | int height; 57 | int stride; 58 | int slice_height; 59 | int color_format; 60 | int crop_top; 61 | int crop_bottom; 62 | int crop_left; 63 | int crop_right; 64 | int display_width; 65 | int display_height; 66 | 67 | uint64_t output_buffer_count; 68 | ssize_t current_input_buffer; 69 | 70 | bool delay_flush; 71 | atomic_int serial; 72 | int out_yuv_seq; 73 | 74 | } MediaCodecDecContext; 75 | 76 | int ff_mediacodec_dec_init(AVCodecContext *avctx, 77 | MediaCodecDecContext *s, 78 | const char *mime, 79 | FFAMediaFormat *format); 80 | 81 | int ff_mediacodec_dec_send(AVCodecContext *avctx, 82 | MediaCodecDecContext *s, 83 | AVPacket *pkt, 84 | bool wait); 85 | 86 | int ff_mediacodec_dec_receive(AVCodecContext *avctx, 87 | MediaCodecDecContext *s, 88 | AVFrame *frame, 89 | bool wait); 90 | 91 | int ff_mediacodec_dec_flush(AVCodecContext *avctx, 92 | MediaCodecDecContext *s); 93 | 94 | int ff_mediacodec_dec_close(AVCodecContext *avctx, 95 | MediaCodecDecContext *s); 96 | 97 | int ff_mediacodec_dec_is_flushing(AVCodecContext *avctx, 98 | MediaCodecDecContext *s); 99 | 100 | int ff_mediacodec_enc_init(AVCodecContext *avctx, MediaCodecDecContext *s, 101 | const char *mime, FFAMediaFormat *format, int profile); 102 | 103 | int ff_mediacodec_enc_send(AVCodecContext *avctx, MediaCodecDecContext *s, AVFrame *frame, AVPacket *pkt); 104 | 105 | int ff_mediacodec_enc_receive(AVCodecContext *avctx, MediaCodecDecContext *s, AVPacket *pkt); 106 | 107 | int save_frame(char *filename, AVFrame *frame); 108 | 109 | typedef struct MediaCodecBuffer { 110 | 111 | MediaCodecDecContext *ctx; 112 | ssize_t index; 113 | int64_t pts; 114 | atomic_int released; 115 | int serial; 116 | 117 | } MediaCodecBuffer; 118 | 119 | #endif /* AVCODEC_MEDIACODECDEC_COMMON_H */ 120 | -------------------------------------------------------------------------------- /libavcodec/mediacodecenc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "libavutil/avassert.h" 5 | #include "libavutil/common.h" 6 | #include "libavutil/opt.h" 7 | #include "libavutil/intreadwrite.h" 8 | #include "libavutil/pixfmt.h" 9 | #include "libavutil/internal.h" 10 | 11 | #include "internal.h" 12 | #include "avcodec.h" 13 | #include "decode.h" 14 | #include "mediacodec_wrapper.h" 15 | #include "mediacodecdec_common.h" 16 | #include "../build/output-armv7a/include/libavutil/frame.h" 17 | 18 | typedef struct MediaCodecEncContext { 19 | AVClass *avclass; 20 | 21 | MediaCodecDecContext *ctx; 22 | 23 | int delay_flush; 24 | int fr; 25 | int i_frame_interval; 26 | int bit_rate; 27 | int profile; 28 | int level; 29 | 30 | int bitrate_mode; 31 | #define BITRATE_MODE_CQ 0 32 | #define BITRATE_MODE_VBR 1 33 | #define BITRATE_MODE_CBR 2 34 | 35 | int draining; 36 | AVPacket buffered_pkt; 37 | } MediaCodecEncContext; 38 | 39 | static av_cold int mediacodec_encode_close(AVCodecContext *avctx) { 40 | return 0; 41 | } 42 | 43 | static av_cold int mediacodec_encode_init(AVCodecContext *avctx) { 44 | int ret; 45 | 46 | const char *codec_mime = NULL; 47 | 48 | FFAMediaFormat *format = NULL; 49 | MediaCodecEncContext *s = avctx->priv_data; 50 | 51 | if (avctx->bit_rate <= 0) { 52 | av_log(avctx, AV_LOG_ERROR, "bit rate is not set\n"); 53 | /*ret = AVERROR_EXIT; 54 | goto done;*/ 55 | avctx->bit_rate = 1 * 1000 * 1000; 56 | } 57 | s->bit_rate = avctx->bit_rate; 58 | 59 | format = ff_AMediaFormat_new(); 60 | if (!format) { 61 | av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n"); 62 | ret = AVERROR_EXTERNAL; 63 | goto done; 64 | } 65 | 66 | codec_mime = "video/hevc"; 67 | 68 | // todo proccess extradata 69 | /*ret = set_extradata(avctx, format); 70 | if (ret < 0) 71 | goto done;*/ 72 | 73 | ff_AMediaFormat_setString(format, "mime", codec_mime); 74 | ff_AMediaFormat_setInt32(format, "width", avctx->width); 75 | ff_AMediaFormat_setInt32(format, "height", avctx->height); 76 | if (s->fr <= 0) { 77 | s->fr = 30; 78 | } 79 | ff_AMediaFormat_setInt32(format, "frame-rate", s->fr); 80 | ff_AMediaFormat_setInt32(format, "i-frame-interval", s->i_frame_interval); 81 | ff_AMediaFormat_setInt32(format, "bitrate-mode", s->bitrate_mode); 82 | ff_AMediaFormat_setInt32(format, "bitrate", s->bit_rate); 83 | // ff_AMediaFormat_setInt32(format, "profile", s->profile); 84 | ff_AMediaFormat_setInt32(format, "max-input-size", 1920 * 1080 * 4); 85 | ff_AMediaFormat_setInt32(format, "color-format", 0x7F420888); // COLOR_FormatYUV420Flexible 86 | 87 | 88 | s->ctx = av_mallocz(sizeof(*s->ctx)); 89 | if (!s->ctx) { 90 | av_log(avctx, AV_LOG_ERROR, "Failed to allocate MediaCodecDecContext\n"); 91 | ret = AVERROR(ENOMEM); 92 | goto done; 93 | } 94 | 95 | s->ctx->delay_flush = s->delay_flush; 96 | av_init_packet(&s->buffered_pkt); 97 | s->buffered_pkt.data = NULL; 98 | s->buffered_pkt.size = 0; 99 | 100 | if ((ret = ff_mediacodec_enc_init(avctx, s->ctx, codec_mime, format, s->profile)) < 0) { 101 | s->ctx = NULL; 102 | goto done; 103 | } 104 | 105 | av_log(avctx, AV_LOG_INFO, 106 | "MediaCodec started successfully: codec = %s, ret = %d\n", 107 | s->ctx->codec_name, ret); 108 | done: 109 | if (format) { 110 | ff_AMediaFormat_delete(format); 111 | } 112 | 113 | if (ret < 0) { 114 | mediacodec_encode_close(avctx); 115 | } 116 | 117 | return ret; 118 | } 119 | 120 | static av_cold int mediacodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) { 121 | MediaCodecEncContext *s = avctx->priv_data; 122 | int ret; 123 | /* In delay_flush mode, wait until the user has released or rendered 124 | all retained frames. */ 125 | if (s->delay_flush && ff_mediacodec_dec_is_flushing(avctx, s->ctx)) { 126 | if (!ff_mediacodec_dec_flush(avctx, s->ctx)) { 127 | return AVERROR(EAGAIN); 128 | } 129 | } 130 | ret = ff_mediacodec_enc_send(avctx, s->ctx, frame, &s->buffered_pkt); 131 | av_log(avctx, AV_LOG_ERROR, "YYYYYYYYYY mediacodec_send_frame return: %d", ret); 132 | return ret; 133 | } 134 | 135 | static av_cold int mediacodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { 136 | MediaCodecEncContext *s = avctx->priv_data; 137 | if (s->buffered_pkt.size > 0) { 138 | av_packet_move_ref(avpkt, &s->buffered_pkt); 139 | return 0; 140 | } 141 | return ff_mediacodec_enc_receive(avctx, s->ctx, avpkt); 142 | } 143 | 144 | static void mediacodec_encode_flush(AVCodecContext *avctx) { 145 | MediaCodecEncContext *s = avctx->priv_data; 146 | 147 | // av_packet_unref(&s->buffered_pkt); 148 | 149 | ff_mediacodec_dec_flush(avctx, s->ctx); 150 | } 151 | 152 | #define OFFSET(x) offsetof(MediaCodecEncContext, x) 153 | #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 154 | static const AVOption ff_mediacodec_venc_options[] = { 155 | {"delay_flush", "Delay flush until hw output buffers are returned to the encoder", 156 | OFFSET(delay_flush), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 157 | VE}, 158 | {"fr", "set frame rate", OFFSET(fr), AV_OPT_TYPE_INT, {.i64 = 30}, INT_MIN, INT_MAX, 159 | VE}, 160 | {"i_frame_interval", "set I frame interval", 161 | OFFSET(i_frame_interval), AV_OPT_TYPE_INT, {.i64 = 1}, INT_MIN, INT_MAX, 162 | VE}, 163 | {"bitrate_mode", "set bit rate mode cq/cbr/vbr", OFFSET(bitrate_mode), AV_OPT_TYPE_FLAGS, {.i64 = BITRATE_MODE_CBR}, INT_MIN, INT_MAX, 164 | VE, "bitrate_mode"}, 165 | {"cq", "do not control", 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CQ}, INT_MIN, INT_MAX, 166 | VE, "bitrate_mode"}, 167 | {"vbr", "depends on the picture", 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_VBR}, INT_MIN, INT_MAX, 168 | VE, "bitrate_mode"}, 169 | {"cbr", "try best to keep bitrate as set bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR}, INT_MIN, INT_MAX, 170 | VE, "bitrate_mode"}, 171 | {"profile", "set mediacodec profile", 172 | OFFSET(profile), AV_OPT_TYPE_INT, {.i64 = 1}, INT_MIN, INT_MAX, 173 | VE}, 174 | {NULL} 175 | }; 176 | 177 | 178 | static const AVClass ff_hevc_mediacodec_enc_class = {\ 179 | .class_name = "hevc_mediacodec_enc", \ 180 | .item_name = av_default_item_name, \ 181 | .option = ff_mediacodec_venc_options, \ 182 | .version = LIBAVUTIL_VERSION_INT, \ 183 | }; 184 | 185 | AVCodec ff_hevc_mediacodec_encoder = { 186 | .name = "hevc_mediacodec_enc", 187 | .long_name = NULL_IF_CONFIG_SMALL("MediaCodec HEVC Encoder"), 188 | .type = AVMEDIA_TYPE_VIDEO, 189 | .id = AV_CODEC_ID_HEVC, 190 | .init = mediacodec_encode_init, 191 | // .encode2 = mediacodec_encode_frame, 192 | .send_frame = mediacodec_send_frame, 193 | .receive_packet = mediacodec_receive_packet, 194 | .close = mediacodec_encode_close, 195 | .flush = mediacodec_encode_flush, 196 | .priv_data_size = sizeof(MediaCodecEncContext), 197 | .priv_class = &ff_hevc_mediacodec_enc_class, 198 | .capabilities = AV_CODEC_CAP_DELAY, 199 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 200 | .wrapper_name = "mediacodec", 201 | }; 202 | --------------------------------------------------------------------------------