mediacodecdec.c (24261B)
1 /* 2 * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders 3 * 4 * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com> 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include "config_components.h" 24 25 #include <stdint.h> 26 #include <string.h> 27 28 #include "libavutil/avassert.h" 29 #include "libavutil/common.h" 30 #include "libavutil/mem.h" 31 #include "libavutil/opt.h" 32 #include "libavutil/intreadwrite.h" 33 #include "libavutil/pixfmt.h" 34 #include "libavutil/internal.h" 35 36 #include "avcodec.h" 37 #include "codec_internal.h" 38 #include "decode.h" 39 #if CONFIG_H264_MEDIACODEC_DECODER_EXTRADATA 40 #include "h264_parse.h" 41 #include "h264_ps.h" 42 #endif 43 #if CONFIG_HEVC_MEDIACODEC_DECODER_EXTRADATA 44 #include "hevc/parse.h" 45 #endif 46 #include "hwconfig.h" 47 #include "internal.h" 48 #include "fffjni.h" 49 #include "mediacodec_wrapper.h" 50 #include "mediacodecdec_common.h" 51 52 typedef struct MediaCodecH264DecContext { 53 54 AVClass *avclass; 55 56 MediaCodecDecContext *ctx; 57 58 AVPacket buffered_pkt; 59 60 int delay_flush; 61 int amlogic_mpeg2_api23_workaround; 62 63 int use_ndk_codec; 64 // Ref. MediaFormat KEY_OPERATING_RATE 65 int operating_rate; 66 } MediaCodecH264DecContext; 67 68 static av_cold int mediacodec_decode_close(AVCodecContext *avctx) 69 { 70 MediaCodecH264DecContext *s = avctx->priv_data; 71 72 ff_mediacodec_dec_close(avctx, s->ctx); 73 s->ctx = NULL; 74 75 av_packet_unref(&s->buffered_pkt); 76 77 return 0; 78 } 79 80 #if CONFIG_H264_MEDIACODEC_DECODER || CONFIG_HEVC_MEDIACODEC_DECODER 81 static int h2645_ps_to_nalu(const uint8_t *src, int src_size, uint8_t **out, int *out_size) 82 { 83 int i; 84 int ret = 0; 85 uint8_t *p = NULL; 86 static const uint8_t nalu_header[] = { 0x00, 0x00, 0x00, 0x01 }; 87 88 if (!out || !out_size) { 89 return AVERROR(EINVAL); 90 } 91 92 p = av_malloc(sizeof(nalu_header) + src_size); 93 if (!p) { 94 return AVERROR(ENOMEM); 95 } 96 97 *out = p; 98 *out_size = sizeof(nalu_header) + src_size; 99 100 memcpy(p, nalu_header, sizeof(nalu_header)); 101 memcpy(p + sizeof(nalu_header), src, src_size); 102 103 /* Escape 0x00, 0x00, 0x0{0-3} pattern */ 104 for (i = 4; i < *out_size; i++) { 105 if (i < *out_size - 3 && 106 p[i + 0] == 0 && 107 p[i + 1] == 0 && 108 p[i + 2] <= 3) { 109 uint8_t *new; 110 111 *out_size += 1; 112 new = av_realloc(*out, *out_size); 113 if (!new) { 114 ret = AVERROR(ENOMEM); 115 goto done; 116 } 117 *out = p = new; 118 119 i = i + 2; 120 memmove(p + i + 1, p + i, *out_size - (i + 1)); 121 p[i] = 0x03; 122 } 123 } 124 done: 125 if (ret < 0) { 126 av_freep(out); 127 *out_size = 0; 128 } 129 130 return ret; 131 } 132 #endif 133 134 #if CONFIG_H264_MEDIACODEC_DECODER_EXTRADATA 135 static int h264_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) 136 { 137 int i; 138 int ret; 139 140 H264ParamSets ps; 141 const PPS *pps = NULL; 142 const SPS *sps = NULL; 143 int is_avc = 0; 144 int nal_length_size = 0; 145 146 memset(&ps, 0, sizeof(ps)); 147 148 ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size, 149 &ps, &is_avc, &nal_length_size, 0, avctx); 150 if (ret < 0) { 151 goto done; 152 } 153 154 for (i = 0; i < MAX_PPS_COUNT; i++) { 155 if (ps.pps_list[i]) { 156 pps = ps.pps_list[i]; 157 break; 158 } 159 } 160 161 if (pps) { 162 if (ps.sps_list[pps->sps_id]) { 163 sps = ps.sps_list[pps->sps_id]; 164 } 165 } 166 167 if (pps && sps) { 168 uint8_t *data = NULL; 169 int data_size = 0; 170 171 avctx->profile = ff_h264_get_profile(sps); 172 avctx->level = sps->level_idc; 173 174 if ((ret = h2645_ps_to_nalu(sps->data, sps->data_size, &data, &data_size)) < 0) { 175 goto done; 176 } 177 ff_AMediaFormat_setBuffer(format, "csd-0", (void*)data, data_size); 178 av_freep(&data); 179 180 if ((ret = h2645_ps_to_nalu(pps->data, pps->data_size, &data, &data_size)) < 0) { 181 goto done; 182 } 183 ff_AMediaFormat_setBuffer(format, "csd-1", (void*)data, data_size); 184 av_freep(&data); 185 } else { 186 const int warn = is_avc && (avctx->codec_tag == MKTAG('a','v','c','1') || 187 avctx->codec_tag == MKTAG('a','v','c','2')); 188 av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG, 189 "Could not extract PPS/SPS from extradata\n"); 190 ret = 0; 191 } 192 193 done: 194 ff_h264_ps_uninit(&ps); 195 196 return ret; 197 } 198 #endif 199 200 #if CONFIG_HEVC_MEDIACODEC_DECODER_EXTRADATA 201 static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) 202 { 203 int i; 204 int ret; 205 206 HEVCParamSets ps; 207 HEVCSEI sei; 208 209 const HEVCVPS *vps = NULL; 210 const HEVCPPS *pps = NULL; 211 const HEVCSPS *sps = NULL; 212 int is_nalff = 0; 213 int nal_length_size = 0; 214 215 uint8_t *vps_data = NULL; 216 uint8_t *sps_data = NULL; 217 uint8_t *pps_data = NULL; 218 int vps_data_size = 0; 219 int sps_data_size = 0; 220 int pps_data_size = 0; 221 222 memset(&ps, 0, sizeof(ps)); 223 memset(&sei, 0, sizeof(sei)); 224 225 ret = ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size, 226 &ps, &sei, &is_nalff, &nal_length_size, 0, 1, avctx); 227 if (ret < 0) { 228 goto done; 229 } 230 231 for (i = 0; i < HEVC_MAX_VPS_COUNT; i++) { 232 if (ps.vps_list[i]) { 233 vps = ps.vps_list[i]; 234 break; 235 } 236 } 237 238 for (i = 0; i < HEVC_MAX_PPS_COUNT; i++) { 239 if (ps.pps_list[i]) { 240 pps = ps.pps_list[i]; 241 break; 242 } 243 } 244 245 if (pps) { 246 if (ps.sps_list[pps->sps_id]) { 247 sps = ps.sps_list[pps->sps_id]; 248 } 249 } 250 251 if (vps && pps && sps) { 252 uint8_t *data; 253 int data_size; 254 255 avctx->profile = sps->ptl.general_ptl.profile_idc; 256 avctx->level = sps->ptl.general_ptl.level_idc; 257 258 if ((ret = h2645_ps_to_nalu(vps->data, vps->data_size, &vps_data, &vps_data_size)) < 0 || 259 (ret = h2645_ps_to_nalu(sps->data, sps->data_size, &sps_data, &sps_data_size)) < 0 || 260 (ret = h2645_ps_to_nalu(pps->data, pps->data_size, &pps_data, &pps_data_size)) < 0) { 261 goto done; 262 } 263 264 data_size = vps_data_size + sps_data_size + pps_data_size; 265 data = av_mallocz(data_size); 266 if (!data) { 267 ret = AVERROR(ENOMEM); 268 goto done; 269 } 270 271 memcpy(data , vps_data, vps_data_size); 272 memcpy(data + vps_data_size , sps_data, sps_data_size); 273 memcpy(data + vps_data_size + sps_data_size, pps_data, pps_data_size); 274 275 ff_AMediaFormat_setBuffer(format, "csd-0", data, data_size); 276 277 av_freep(&data); 278 } else { 279 const int warn = is_nalff && avctx->codec_tag == MKTAG('h','v','c','1'); 280 av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG, 281 "Could not extract VPS/PPS/SPS from extradata\n"); 282 ret = 0; 283 } 284 285 done: 286 ff_hevc_ps_uninit(&ps); 287 288 av_freep(&vps_data); 289 av_freep(&sps_data); 290 av_freep(&pps_data); 291 292 return ret; 293 } 294 #endif 295 296 #if CONFIG_MPEG2_MEDIACODEC_DECODER || \ 297 CONFIG_MPEG4_MEDIACODEC_DECODER || \ 298 CONFIG_VP8_MEDIACODEC_DECODER || \ 299 CONFIG_VP9_MEDIACODEC_DECODER || \ 300 CONFIG_AV1_MEDIACODEC_DECODER || \ 301 CONFIG_AAC_MEDIACODEC_DECODER || \ 302 CONFIG_AMRNB_MEDIACODEC_DECODER || \ 303 CONFIG_AMRWB_MEDIACODEC_DECODER || \ 304 CONFIG_MP3_MEDIACODEC_DECODER 305 static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format) 306 { 307 int ret = 0; 308 309 if (avctx->extradata) { 310 ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size); 311 } 312 313 return ret; 314 } 315 #endif 316 317 static av_cold int mediacodec_decode_init(AVCodecContext *avctx) 318 { 319 int ret; 320 int sdk_int; 321 322 const char *codec_mime = NULL; 323 324 FFAMediaFormat *format = NULL; 325 MediaCodecH264DecContext *s = avctx->priv_data; 326 327 if (s->use_ndk_codec < 0) 328 s->use_ndk_codec = !av_jni_get_java_vm(avctx); 329 330 format = ff_AMediaFormat_new(s->use_ndk_codec); 331 if (!format) { 332 av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n"); 333 ret = AVERROR_EXTERNAL; 334 goto done; 335 } 336 337 switch (avctx->codec_id) { 338 #if CONFIG_AV1_MEDIACODEC_DECODER 339 case AV_CODEC_ID_AV1: 340 codec_mime = "video/av01"; 341 342 ret = common_set_extradata(avctx, format); 343 if (ret < 0) 344 goto done; 345 break; 346 #endif 347 #if CONFIG_H264_MEDIACODEC_DECODER 348 case AV_CODEC_ID_H264: 349 codec_mime = "video/avc"; 350 351 #if CONFIG_H264_MEDIACODEC_DECODER_EXTRADATA 352 ret = h264_set_extradata(avctx, format); 353 #else 354 ret = 0; 355 #endif 356 if (ret < 0) 357 goto done; 358 break; 359 #endif 360 #if CONFIG_HEVC_MEDIACODEC_DECODER 361 case AV_CODEC_ID_HEVC: 362 codec_mime = "video/hevc"; 363 364 #if CONFIG_HEVC_MEDIACODEC_DECODER_EXTRADATA 365 ret = hevc_set_extradata(avctx, format); 366 #else 367 ret = 0; 368 #endif 369 if (ret < 0) 370 goto done; 371 break; 372 #endif 373 #if CONFIG_MPEG2_MEDIACODEC_DECODER 374 case AV_CODEC_ID_MPEG2VIDEO: 375 codec_mime = "video/mpeg2"; 376 377 ret = common_set_extradata(avctx, format); 378 if (ret < 0) 379 goto done; 380 break; 381 #endif 382 #if CONFIG_MPEG4_MEDIACODEC_DECODER 383 case AV_CODEC_ID_MPEG4: 384 codec_mime = "video/mp4v-es", 385 386 ret = common_set_extradata(avctx, format); 387 if (ret < 0) 388 goto done; 389 break; 390 #endif 391 #if CONFIG_VP8_MEDIACODEC_DECODER 392 case AV_CODEC_ID_VP8: 393 codec_mime = "video/x-vnd.on2.vp8"; 394 395 ret = common_set_extradata(avctx, format); 396 if (ret < 0) 397 goto done; 398 break; 399 #endif 400 #if CONFIG_VP9_MEDIACODEC_DECODER 401 case AV_CODEC_ID_VP9: 402 codec_mime = "video/x-vnd.on2.vp9"; 403 404 ret = common_set_extradata(avctx, format); 405 if (ret < 0) 406 goto done; 407 break; 408 #endif 409 #if CONFIG_AAC_MEDIACODEC_DECODER 410 case AV_CODEC_ID_AAC: 411 codec_mime = "audio/mp4a-latm"; 412 413 ret = common_set_extradata(avctx, format); 414 if (ret < 0) 415 goto done; 416 break; 417 #endif 418 #if CONFIG_AMRNB_MEDIACODEC_DECODER 419 case AV_CODEC_ID_AMR_NB: 420 codec_mime = "audio/3gpp"; 421 422 ret = common_set_extradata(avctx, format); 423 if (ret < 0) 424 goto done; 425 break; 426 #endif 427 #if CONFIG_AMRWB_MEDIACODEC_DECODER 428 case AV_CODEC_ID_AMR_WB: 429 codec_mime = "audio/amr-wb"; 430 431 ret = common_set_extradata(avctx, format); 432 if (ret < 0) 433 goto done; 434 break; 435 #endif 436 #if CONFIG_MP3_MEDIACODEC_DECODER 437 case AV_CODEC_ID_MP3: 438 codec_mime = "audio/mpeg"; 439 440 ret = common_set_extradata(avctx, format); 441 if (ret < 0) 442 goto done; 443 break; 444 #endif 445 default: 446 av_assert0(0); 447 } 448 449 ff_AMediaFormat_setString(format, "mime", codec_mime); 450 451 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { 452 ff_AMediaFormat_setInt32(format, "width", avctx->width); 453 ff_AMediaFormat_setInt32(format, "height", avctx->height); 454 } else { 455 ff_AMediaFormat_setInt32(format, "channel-count", avctx->ch_layout.nb_channels); 456 ff_AMediaFormat_setInt32(format, "sample-rate", avctx->sample_rate); 457 } 458 if (s->operating_rate > 0) 459 ff_AMediaFormat_setInt32(format, "operating-rate", s->operating_rate); 460 461 s->ctx = av_mallocz(sizeof(*s->ctx)); 462 if (!s->ctx) { 463 av_log(avctx, AV_LOG_ERROR, "Failed to allocate MediaCodecDecContext\n"); 464 ret = AVERROR(ENOMEM); 465 goto done; 466 } 467 468 s->ctx->delay_flush = s->delay_flush; 469 s->ctx->use_ndk_codec = s->use_ndk_codec; 470 471 if ((ret = ff_mediacodec_dec_init(avctx, s->ctx, codec_mime, format)) < 0) { 472 s->ctx = NULL; 473 goto done; 474 } 475 476 av_log(avctx, AV_LOG_INFO, 477 "MediaCodec started successfully: codec = %s, ret = %d\n", 478 s->ctx->codec_name, ret); 479 480 sdk_int = ff_Build_SDK_INT(avctx); 481 /* ff_Build_SDK_INT can fail when target API < 24 and JVM isn't available. 482 * If we don't check sdk_int > 0, the workaround might be enabled by 483 * mistake. 484 * JVM is required to make the workaround works reliably. On the other hand, 485 * missing a workaround should not be a serious issue, we do as best we can. 486 */ 487 if (sdk_int > 0 && sdk_int <= 23 && 488 strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) { 489 av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n", 490 s->ctx->codec_name, sdk_int); 491 s->amlogic_mpeg2_api23_workaround = 1; 492 } 493 494 done: 495 if (format) { 496 ff_AMediaFormat_delete(format); 497 } 498 499 if (ret < 0) { 500 mediacodec_decode_close(avctx); 501 } 502 503 return ret; 504 } 505 506 static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) 507 { 508 MediaCodecH264DecContext *s = avctx->priv_data; 509 int ret; 510 ssize_t index; 511 512 /* In delay_flush mode, wait until the user has released or rendered 513 all retained frames. */ 514 if (s->delay_flush && ff_mediacodec_dec_is_flushing(avctx, s->ctx)) { 515 if (!ff_mediacodec_dec_flush(avctx, s->ctx)) { 516 return AVERROR(EAGAIN); 517 } 518 } 519 520 /* poll for new frame */ 521 ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); 522 if (ret != AVERROR(EAGAIN)) 523 return ret; 524 525 /* feed decoder */ 526 while (1) { 527 if (s->ctx->current_input_buffer < 0 && !s->ctx->draining) { 528 /* poll for input space */ 529 index = ff_AMediaCodec_dequeueInputBuffer(s->ctx->codec, 0); 530 if (index < 0) { 531 /* no space, block for an output frame to appear */ 532 ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); 533 /* Try again if both input port and output port return EAGAIN. 534 * If no data is consumed and no frame in output, it can make 535 * both avcodec_send_packet() and avcodec_receive_frame() 536 * return EAGAIN, which violate the design. 537 */ 538 if (ff_AMediaCodec_infoTryAgainLater(s->ctx->codec, index) && 539 ret == AVERROR(EAGAIN)) 540 continue; 541 return ret; 542 } 543 s->ctx->current_input_buffer = index; 544 } 545 546 /* try to flush any buffered packet data */ 547 if (s->buffered_pkt.size > 0) { 548 ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt, false); 549 if (ret >= 0) { 550 s->buffered_pkt.size -= ret; 551 s->buffered_pkt.data += ret; 552 if (s->buffered_pkt.size <= 0) { 553 av_packet_unref(&s->buffered_pkt); 554 } else { 555 av_log(avctx, AV_LOG_WARNING, 556 "could not send entire packet in single input buffer (%d < %d)\n", 557 ret, s->buffered_pkt.size+ret); 558 } 559 } else if (ret < 0 && ret != AVERROR(EAGAIN)) { 560 return ret; 561 } 562 563 if (s->amlogic_mpeg2_api23_workaround && s->buffered_pkt.size <= 0) { 564 /* fallthrough to fetch next packet regardless of input buffer space */ 565 } else { 566 /* poll for space again */ 567 continue; 568 } 569 } 570 571 /* fetch new packet or eof */ 572 ret = ff_decode_get_packet(avctx, &s->buffered_pkt); 573 if (ret == AVERROR_EOF) { 574 AVPacket null_pkt = { 0 }; 575 ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, true); 576 if (ret < 0) 577 return ret; 578 return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); 579 } else if (ret == AVERROR(EAGAIN) && s->ctx->current_input_buffer < 0) { 580 return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); 581 } else if (ret < 0) { 582 return ret; 583 } 584 } 585 586 return AVERROR(EAGAIN); 587 } 588 589 static void mediacodec_decode_flush(AVCodecContext *avctx) 590 { 591 MediaCodecH264DecContext *s = avctx->priv_data; 592 593 av_packet_unref(&s->buffered_pkt); 594 595 ff_mediacodec_dec_flush(avctx, s->ctx); 596 } 597 598 static const AVCodecHWConfigInternal *const mediacodec_hw_configs[] = { 599 &(const AVCodecHWConfigInternal) { 600 .public = { 601 .pix_fmt = AV_PIX_FMT_MEDIACODEC, 602 .methods = AV_CODEC_HW_CONFIG_METHOD_AD_HOC | 603 AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX, 604 .device_type = AV_HWDEVICE_TYPE_MEDIACODEC, 605 }, 606 .hwaccel = NULL, 607 }, 608 NULL 609 }; 610 611 #define OFFSET(x) offsetof(MediaCodecH264DecContext, x) 612 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM 613 static const AVOption ff_mediacodec_vdec_options[] = { 614 { "delay_flush", "Delay flush until hw output buffers are returned to the decoder", 615 OFFSET(delay_flush), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VD }, 616 { "ndk_codec", "Use MediaCodec from NDK", 617 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VD }, 618 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified", 619 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VD }, 620 { NULL } 621 }; 622 623 #define DECLARE_MEDIACODEC_VCLASS(short_name) \ 624 static const AVClass ff_##short_name##_mediacodec_dec_class = { \ 625 .class_name = #short_name "_mediacodec", \ 626 .item_name = av_default_item_name, \ 627 .option = ff_mediacodec_vdec_options, \ 628 .version = LIBAVUTIL_VERSION_INT, \ 629 }; 630 631 #define DECLARE_MEDIACODEC_VDEC(short_name, full_name, codec_id, bsf) \ 632 DECLARE_MEDIACODEC_VCLASS(short_name) \ 633 const FFCodec ff_ ## short_name ## _mediacodec_decoder = { \ 634 .p.name = #short_name "_mediacodec", \ 635 CODEC_LONG_NAME(full_name " Android MediaCodec decoder"), \ 636 .p.type = AVMEDIA_TYPE_VIDEO, \ 637 .p.id = codec_id, \ 638 .p.priv_class = &ff_##short_name##_mediacodec_dec_class, \ 639 .priv_data_size = sizeof(MediaCodecH264DecContext), \ 640 .init = mediacodec_decode_init, \ 641 FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame), \ 642 .flush = mediacodec_decode_flush, \ 643 .close = mediacodec_decode_close, \ 644 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \ 645 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \ 646 .bsfs = bsf, \ 647 .hw_configs = mediacodec_hw_configs, \ 648 .p.wrapper_name = "mediacodec", \ 649 }; \ 650 651 #if CONFIG_H264_MEDIACODEC_DECODER 652 DECLARE_MEDIACODEC_VDEC(h264, "H.264", AV_CODEC_ID_H264, NULL) 653 #endif 654 655 #if CONFIG_HEVC_MEDIACODEC_DECODER 656 DECLARE_MEDIACODEC_VDEC(hevc, "H.265", AV_CODEC_ID_HEVC, NULL) 657 #endif 658 659 #if CONFIG_MPEG2_MEDIACODEC_DECODER 660 DECLARE_MEDIACODEC_VDEC(mpeg2, "MPEG-2", AV_CODEC_ID_MPEG2VIDEO, NULL) 661 #endif 662 663 #if CONFIG_MPEG4_MEDIACODEC_DECODER 664 DECLARE_MEDIACODEC_VDEC(mpeg4, "MPEG-4", AV_CODEC_ID_MPEG4, NULL) 665 #endif 666 667 #if CONFIG_VP8_MEDIACODEC_DECODER 668 DECLARE_MEDIACODEC_VDEC(vp8, "VP8", AV_CODEC_ID_VP8, NULL) 669 #endif 670 671 #if CONFIG_VP9_MEDIACODEC_DECODER 672 DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL) 673 #endif 674 675 #if CONFIG_AV1_MEDIACODEC_DECODER 676 DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL) 677 #endif 678 679 #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM 680 static const AVOption ff_mediacodec_adec_options[] = { 681 { "ndk_codec", "Use MediaCodec from NDK", 682 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AD }, 683 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified", 684 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AD }, 685 { NULL } 686 }; 687 688 #define DECLARE_MEDIACODEC_ACLASS(short_name) \ 689 static const AVClass ff_##short_name##_mediacodec_dec_class = { \ 690 .class_name = #short_name "_mediacodec", \ 691 .item_name = av_default_item_name, \ 692 .option = ff_mediacodec_adec_options, \ 693 .version = LIBAVUTIL_VERSION_INT, \ 694 }; 695 696 #define DECLARE_MEDIACODEC_ADEC(short_name, full_name, codec_id, bsf) \ 697 DECLARE_MEDIACODEC_VCLASS(short_name) \ 698 const FFCodec ff_ ## short_name ## _mediacodec_decoder = { \ 699 .p.name = #short_name "_mediacodec", \ 700 CODEC_LONG_NAME(full_name " Android MediaCodec decoder"), \ 701 .p.type = AVMEDIA_TYPE_AUDIO, \ 702 .p.id = codec_id, \ 703 .p.priv_class = &ff_##short_name##_mediacodec_dec_class, \ 704 .priv_data_size = sizeof(MediaCodecH264DecContext), \ 705 .init = mediacodec_decode_init, \ 706 FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame), \ 707 .flush = mediacodec_decode_flush, \ 708 .close = mediacodec_decode_close, \ 709 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \ 710 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \ 711 .bsfs = bsf, \ 712 .p.wrapper_name = "mediacodec", \ 713 }; \ 714 715 #if CONFIG_AAC_MEDIACODEC_DECODER 716 DECLARE_MEDIACODEC_ADEC(aac, "AAC", AV_CODEC_ID_AAC, "aac_adtstoasc") 717 #endif 718 719 #if CONFIG_AMRNB_MEDIACODEC_DECODER 720 DECLARE_MEDIACODEC_ADEC(amrnb, "AMR-NB", AV_CODEC_ID_AMR_NB, NULL) 721 #endif 722 723 #if CONFIG_AMRWB_MEDIACODEC_DECODER 724 DECLARE_MEDIACODEC_ADEC(amrwb, "AMR-WB", AV_CODEC_ID_AMR_WB, NULL) 725 #endif 726 727 #if CONFIG_MP3_MEDIACODEC_DECODER 728 DECLARE_MEDIACODEC_ADEC(mp3, "MP3", AV_CODEC_ID_MP3, NULL) 729 #endif 730 731 int moz_avcodec_mediacodec_is_eos(AVCodecContext* avctx) { 732 // Note that MediaCodecH264DecContext is used by all codec types. 733 MediaCodecH264DecContext *s = avctx->priv_data; 734 return s->ctx->eos; 735 }