1/* 2 * Android MediaCodec decoder 3 * 4 * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com> 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23#include <string.h> 24#include <sys/types.h> 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 43/** 44 * OMX.k3.video.decoder.avc, OMX.NVIDIA.* OMX.SEC.avc.dec and OMX.google 45 * codec workarounds used in various place are taken from the Gstreamer 46 * project. 47 * 48 * Gstreamer references: 49 * https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/androidmedia/ 50 * 51 * Gstreamer copyright notice: 52 * 53 * Copyright (C) 2012, Collabora Ltd. 54 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> 55 * 56 * Copyright (C) 2012, Rafaël Carré <funman@videolanorg> 57 * 58 * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com> 59 * 60 * Copyright (C) 2014-2015, Collabora Ltd. 61 * Author: Matthieu Bouron <matthieu.bouron@gcollabora.com> 62 * 63 * Copyright (C) 2015, Edward Hervey 64 * Author: Edward Hervey <bilboed@gmail.com> 65 * 66 * Copyright (C) 2015, Matthew Waters <matthew@centricular.com> 67 * 68 * This library is free software; you can redistribute it and/or 69 * modify it under the terms of the GNU Lesser General Public 70 * License as published by the Free Software Foundation 71 * version 2.1 of the License. 72 * 73 * This library is distributed in the hope that it will be useful, 74 * but WITHOUT ANY WARRANTY; without even the implied warranty of 75 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 76 * Lesser General Public License for more details. 77 * 78 * You should have received a copy of the GNU Lesser General Public 79 * License along with this library; if not, write to the Free Software 80 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 81 * 82 */ 83 84#define INPUT_DEQUEUE_TIMEOUT_US 8000 85#define OUTPUT_DEQUEUE_TIMEOUT_US 8000 86#define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US 1000000 87 88enum { 89 COLOR_RANGE_FULL = 0x1, 90 COLOR_RANGE_LIMITED = 0x2, 91}; 92 93static enum AVColorRange mcdec_get_color_range(int color_range) 94{ 95 switch (color_range) { 96 case COLOR_RANGE_FULL: 97 return AVCOL_RANGE_JPEG; 98 case COLOR_RANGE_LIMITED: 99 return AVCOL_RANGE_MPEG; 100 default: 101 return AVCOL_RANGE_UNSPECIFIED; 102 } 103} 104 105enum { 106 COLOR_STANDARD_BT709 = 0x1, 107 COLOR_STANDARD_BT601_PAL = 0x2, 108 COLOR_STANDARD_BT601_NTSC = 0x4, 109 COLOR_STANDARD_BT2020 = 0x6, 110}; 111 112static enum AVColorSpace mcdec_get_color_space(int color_standard) 113{ 114 switch (color_standard) { 115 case COLOR_STANDARD_BT709: 116 return AVCOL_SPC_BT709; 117 case COLOR_STANDARD_BT601_PAL: 118 return AVCOL_SPC_BT470BG; 119 case COLOR_STANDARD_BT601_NTSC: 120 return AVCOL_SPC_SMPTE170M; 121 case COLOR_STANDARD_BT2020: 122 return AVCOL_SPC_BT2020_NCL; 123 default: 124 return AVCOL_SPC_UNSPECIFIED; 125 } 126} 127 128static enum AVColorPrimaries mcdec_get_color_pri(int color_standard) 129{ 130 switch (color_standard) { 131 case COLOR_STANDARD_BT709: 132 return AVCOL_PRI_BT709; 133 case COLOR_STANDARD_BT601_PAL: 134 return AVCOL_PRI_BT470BG; 135 case COLOR_STANDARD_BT601_NTSC: 136 return AVCOL_PRI_SMPTE170M; 137 case COLOR_STANDARD_BT2020: 138 return AVCOL_PRI_BT2020; 139 default: 140 return AVCOL_PRI_UNSPECIFIED; 141 } 142} 143 144enum { 145 COLOR_TRANSFER_LINEAR = 0x1, 146 COLOR_TRANSFER_SDR_VIDEO = 0x3, 147 COLOR_TRANSFER_ST2084 = 0x6, 148 COLOR_TRANSFER_HLG = 0x7, 149}; 150 151static enum AVColorTransferCharacteristic mcdec_get_color_trc(int color_transfer) 152{ 153 switch (color_transfer) { 154 case COLOR_TRANSFER_LINEAR: 155 return AVCOL_TRC_LINEAR; 156 case COLOR_TRANSFER_SDR_VIDEO: 157 return AVCOL_TRC_SMPTE170M; 158 case COLOR_TRANSFER_ST2084: 159 return AVCOL_TRC_SMPTEST2084; 160 case COLOR_TRANSFER_HLG: 161 return AVCOL_TRC_ARIB_STD_B67; 162 default: 163 return AVCOL_TRC_UNSPECIFIED; 164 } 165} 166 167enum { 168 COLOR_FormatYUV420Planar = 0x13, 169 COLOR_FormatYUV420SemiPlanar = 0x15, 170 COLOR_FormatYCbYCr = 0x19, 171 COLOR_FormatAndroidOpaque = 0x7F000789, 172 COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00, 173 COLOR_QCOM_FormatYUV420SemiPlanar32m = 0x7fa30c04, 174 COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7fa30c03, 175 COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100, 176 COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced = 0x7f000001, 177}; 178 179static const struct { 180 181 int color_format; 182 enum AVPixelFormat pix_fmt; 183 184} color_formats[] = { 185 186 { COLOR_FormatYUV420Planar, AV_PIX_FMT_YUV420P }, 187 { COLOR_FormatYUV420SemiPlanar, AV_PIX_FMT_NV12 }, 188 { COLOR_QCOM_FormatYUV420SemiPlanar, AV_PIX_FMT_NV12 }, 189 { COLOR_QCOM_FormatYUV420SemiPlanar32m, AV_PIX_FMT_NV12 }, 190 { COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, AV_PIX_FMT_NV12 }, 191 { COLOR_TI_FormatYUV420PackedSemiPlanar, AV_PIX_FMT_NV12 }, 192 { COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced, AV_PIX_FMT_NV12 }, 193 { 0 } 194}; 195 196static enum AVPixelFormat mcdec_map_color_format(AVCodecContext *avctx, 197 MediaCodecDecContext *s, 198 int color_format) 199{ 200 int i; 201 enum AVPixelFormat ret = AV_PIX_FMT_NONE; 202 203 if (s->surface) { 204 return AV_PIX_FMT_MEDIACODEC; 205 } 206 207 if (!strcmp(s->codec_name, "OMX.k3.video.decoder.avc") && color_format == COLOR_FormatYCbYCr) { 208 s->color_format = color_format = COLOR_TI_FormatYUV420PackedSemiPlanar; 209 } 210 211 for (i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) { 212 if (color_formats[i].color_format == color_format) { 213 return color_formats[i].pix_fmt; 214 } 215 } 216 217 av_log(avctx, AV_LOG_ERROR, "Output color format 0x%x (value=%d) is not supported\n", 218 color_format, color_format); 219 220 return ret; 221} 222 223static void ff_mediacodec_dec_ref(MediaCodecDecContext *s) 224{ 225 atomic_fetch_add(&s->refcount, 1); 226} 227 228static void ff_mediacodec_dec_unref(MediaCodecDecContext *s) 229{ 230 if (!s) 231 return; 232 233 if (atomic_fetch_sub(&s->refcount, 1) == 1) { 234 if (s->codec) { 235 ff_AMediaCodec_delete(s->codec); 236 s->codec = NULL; 237 } 238 239 if (s->format) { 240 ff_AMediaFormat_delete(s->format); 241 s->format = NULL; 242 } 243 244 if (s->surface) { 245 ff_mediacodec_surface_unref(s->surface, NULL); 246 s->surface = NULL; 247 } 248 249 av_freep(&s->codec_name); 250 av_freep(&s); 251 } 252} 253 254static void mediacodec_buffer_release(void *opaque, uint8_t *data) 255{ 256 AVMediaCodecBuffer *buffer = opaque; 257 MediaCodecDecContext *ctx = buffer->ctx; 258 int released = atomic_load(&buffer->released); 259 260 if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) { 261 atomic_fetch_sub(&ctx->hw_buffer_count, 1); 262 av_log(ctx->avctx, AV_LOG_DEBUG, 263 "Releasing output buffer %zd (%p) ts=%"PRId64" on free() [%d pending]\n", 264 buffer->index, buffer, buffer->pts, atomic_load(&ctx->hw_buffer_count)); 265 ff_AMediaCodec_releaseOutputBuffer(ctx->codec, buffer->index, 0); 266 } 267 268 if (ctx->delay_flush) 269 ff_mediacodec_dec_unref(ctx); 270 av_freep(&buffer); 271} 272 273static int mediacodec_wrap_hw_buffer(AVCodecContext *avctx, 274 MediaCodecDecContext *s, 275 ssize_t index, 276 FFAMediaCodecBufferInfo *info, 277 AVFrame *frame) 278{ 279 int ret = 0; 280 int status = 0; 281 AVMediaCodecBuffer *buffer = NULL; 282 283 frame->buf[0] = NULL; 284 frame->width = avctx->width; 285 frame->height = avctx->height; 286 frame->format = avctx->pix_fmt; 287 frame->sample_aspect_ratio = avctx->sample_aspect_ratio; 288 289 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) { 290 frame->pts = av_rescale_q(info->presentationTimeUs, 291 AV_TIME_BASE_Q, 292 avctx->pkt_timebase); 293 } else { 294 frame->pts = info->presentationTimeUs; 295 } 296 frame->pkt_dts = AV_NOPTS_VALUE; 297 frame->color_range = avctx->color_range; 298 frame->color_primaries = avctx->color_primaries; 299 frame->color_trc = avctx->color_trc; 300 frame->colorspace = avctx->colorspace; 301 302 buffer = av_mallocz(sizeof(AVMediaCodecBuffer)); 303 if (!buffer) { 304 ret = AVERROR(ENOMEM); 305 goto fail; 306 } 307 308 atomic_init(&buffer->released, 0); 309 310 frame->buf[0] = av_buffer_create(NULL, 311 0, 312 mediacodec_buffer_release, 313 buffer, 314 AV_BUFFER_FLAG_READONLY); 315 316 if (!frame->buf[0]) { 317 ret = AVERROR(ENOMEM); 318 goto fail; 319 320 } 321 322 buffer->ctx = s; 323 buffer->serial = atomic_load(&s->serial); 324 if (s->delay_flush) 325 ff_mediacodec_dec_ref(s); 326 327 buffer->index = index; 328 buffer->pts = info->presentationTimeUs; 329 330 frame->data[3] = (uint8_t *)buffer; 331 332 atomic_fetch_add(&s->hw_buffer_count, 1); 333 av_log(avctx, AV_LOG_DEBUG, 334 "Wrapping output buffer %zd (%p) ts=%"PRId64" [%d pending]\n", 335 buffer->index, buffer, buffer->pts, atomic_load(&s->hw_buffer_count)); 336 337 return 0; 338fail: 339 av_freep(buffer); 340 av_buffer_unref(&frame->buf[0]); 341 status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0); 342 if (status < 0) { 343 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n"); 344 ret = AVERROR_EXTERNAL; 345 } 346 347 return ret; 348} 349 350static int mediacodec_wrap_sw_buffer(AVCodecContext *avctx, 351 MediaCodecDecContext *s, 352 uint8_t *data, 353 size_t size, 354 ssize_t index, 355 FFAMediaCodecBufferInfo *info, 356 AVFrame *frame) 357{ 358 int ret = 0; 359 int status = 0; 360 361 frame->width = avctx->width; 362 frame->height = avctx->height; 363 frame->format = avctx->pix_fmt; 364 365 /* MediaCodec buffers needs to be copied to our own refcounted buffers 366 * because the flush command invalidates all input and output buffers. 367 */ 368 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { 369 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer\n"); 370 goto done; 371 } 372 373 /* Override frame->pkt_pts as ff_get_buffer will override its value based 374 * on the last avpacket received which is not in sync with the frame: 375 * * N avpackets can be pushed before 1 frame is actually returned 376 * * 0-sized avpackets are pushed to flush remaining frames at EOS */ 377 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) { 378 frame->pts = av_rescale_q(info->presentationTimeUs, 379 AV_TIME_BASE_Q, 380 avctx->pkt_timebase); 381 } else { 382 frame->pts = info->presentationTimeUs; 383 } 384 frame->pkt_dts = AV_NOPTS_VALUE; 385 386 av_log(avctx, AV_LOG_TRACE, 387 "Frame: width=%d stride=%d height=%d slice-height=%d " 388 "crop-top=%d crop-bottom=%d crop-left=%d crop-right=%d encoder=%s " 389 "destination linesizes=%d,%d,%d\n" , 390 avctx->width, s->stride, avctx->height, s->slice_height, 391 s->crop_top, s->crop_bottom, s->crop_left, s->crop_right, s->codec_name, 392 frame->linesize[0], frame->linesize[1], frame->linesize[2]); 393 394 switch (s->color_format) { 395 case COLOR_FormatYUV420Planar: 396 ff_mediacodec_sw_buffer_copy_yuv420_planar(avctx, s, data, size, info, frame); 397 break; 398 case COLOR_FormatYUV420SemiPlanar: 399 case COLOR_QCOM_FormatYUV420SemiPlanar: 400 case COLOR_QCOM_FormatYUV420SemiPlanar32m: 401 ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(avctx, s, data, size, info, frame); 402 break; 403 case COLOR_TI_FormatYUV420PackedSemiPlanar: 404 case COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced: 405 ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar(avctx, s, data, size, info, frame); 406 break; 407 case COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka: 408 ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar_64x32Tile2m8ka(avctx, s, data, size, info, frame); 409 break; 410 default: 411 av_log(avctx, AV_LOG_ERROR, "Unsupported color format 0x%x (value=%d)\n", 412 s->color_format, s->color_format); 413 ret = AVERROR(EINVAL); 414 goto done; 415 } 416 417 ret = 0; 418done: 419 status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0); 420 if (status < 0) { 421 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n"); 422 ret = AVERROR_EXTERNAL; 423 } 424 425 return ret; 426} 427 428#define AMEDIAFORMAT_GET_INT32(name, key, mandatory) do { \ 429 int32_t value = 0; \ 430 if (ff_AMediaFormat_getInt32(s->format, key, &value)) { \ 431 (name) = value; \ 432 } else if (mandatory) { \ 433 av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", key, format); \ 434 ret = AVERROR_EXTERNAL; \ 435 goto fail; \ 436 } \ 437} while (0) \ 438 439static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s) 440{ 441 int ret = 0; 442 int width = 0; 443 int height = 0; 444 int color_range = 0; 445 int color_standard = 0; 446 int color_transfer = 0; 447 char *format = NULL; 448 449 if (!s->format) { 450 av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n"); 451 return AVERROR(EINVAL); 452 } 453 454 format = ff_AMediaFormat_toString(s->format); 455 if (!format) { 456 return AVERROR_EXTERNAL; 457 } 458 av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format); 459 460 /* Mandatory fields */ 461 AMEDIAFORMAT_GET_INT32(s->width, "width", 1); 462 AMEDIAFORMAT_GET_INT32(s->height, "height", 1); 463 464 AMEDIAFORMAT_GET_INT32(s->stride, "stride", 0); 465 s->stride = s->stride > 0 ? s->stride : s->width; 466 467 AMEDIAFORMAT_GET_INT32(s->slice_height, "slice-height", 0); 468 469 if (strstr(s->codec_name, "OMX.Nvidia.") && s->slice_height == 0) { 470 s->slice_height = FFALIGN(s->height, 16); 471 } else if (strstr(s->codec_name, "OMX.SEC.avc.dec")) { 472 s->slice_height = avctx->height; 473 s->stride = avctx->width; 474 } else if (s->slice_height == 0) { 475 s->slice_height = s->height; 476 } 477 478 AMEDIAFORMAT_GET_INT32(s->color_format, "color-format", 1); 479 avctx->pix_fmt = mcdec_map_color_format(avctx, s, s->color_format); 480 if (avctx->pix_fmt == AV_PIX_FMT_NONE) { 481 av_log(avctx, AV_LOG_ERROR, "Output color format is not supported\n"); 482 ret = AVERROR(EINVAL); 483 goto fail; 484 } 485 486 /* Optional fields */ 487 AMEDIAFORMAT_GET_INT32(s->crop_top, "crop-top", 0); 488 AMEDIAFORMAT_GET_INT32(s->crop_bottom, "crop-bottom", 0); 489 AMEDIAFORMAT_GET_INT32(s->crop_left, "crop-left", 0); 490 AMEDIAFORMAT_GET_INT32(s->crop_right, "crop-right", 0); 491 492 width = s->crop_right + 1 - s->crop_left; 493 height = s->crop_bottom + 1 - s->crop_top; 494 495 AMEDIAFORMAT_GET_INT32(s->display_width, "display-width", 0); 496 AMEDIAFORMAT_GET_INT32(s->display_height, "display-height", 0); 497 498 if (s->display_width && s->display_height) { 499 AVRational sar = av_div_q( 500 (AVRational){ s->display_width, s->display_height }, 501 (AVRational){ width, height }); 502 ff_set_sar(avctx, sar); 503 } 504 505 AMEDIAFORMAT_GET_INT32(color_range, "color-range", 0); 506 if (color_range) 507 avctx->color_range = mcdec_get_color_range(color_range); 508 509 AMEDIAFORMAT_GET_INT32(color_standard, "color-standard", 0); 510 if (color_standard) { 511 avctx->colorspace = mcdec_get_color_space(color_standard); 512 avctx->color_primaries = mcdec_get_color_pri(color_standard); 513 } 514 515 AMEDIAFORMAT_GET_INT32(color_transfer, "color-transfer", 0); 516 if (color_transfer) 517 avctx->color_trc = mcdec_get_color_trc(color_transfer); 518 519 av_log(avctx, AV_LOG_INFO, 520 "Output crop parameters top=%d bottom=%d left=%d right=%d, " 521 "resulting dimensions width=%d height=%d\n", 522 s->crop_top, s->crop_bottom, s->crop_left, s->crop_right, 523 width, height); 524 525 av_freep(&format); 526 return ff_set_dimensions(avctx, width, height); 527fail: 528 av_freep(&format); 529 return ret; 530} 531 532static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s) 533{ 534 FFAMediaCodec *codec = s->codec; 535 int status; 536 537 s->output_buffer_count = 0; 538 539 s->draining = 0; 540 s->flushing = 0; 541 s->eos = 0; 542 atomic_fetch_add(&s->serial, 1); 543 atomic_init(&s->hw_buffer_count, 0); 544 s->current_input_buffer = -1; 545 546 status = ff_AMediaCodec_flush(codec); 547 if (status < 0) { 548 av_log(avctx, AV_LOG_ERROR, "Failed to flush codec\n"); 549 return AVERROR_EXTERNAL; 550 } 551 552 return 0; 553} 554 555int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, 556 const char *mime, FFAMediaFormat *format) 557{ 558 int ret = 0; 559 int status; 560 int profile; 561 562 enum AVPixelFormat pix_fmt; 563 static const enum AVPixelFormat pix_fmts[] = { 564 AV_PIX_FMT_MEDIACODEC, 565 AV_PIX_FMT_NONE, 566 }; 567 568 s->avctx = avctx; 569 atomic_init(&s->refcount, 1); 570 atomic_init(&s->hw_buffer_count, 0); 571 atomic_init(&s->serial, 1); 572 s->current_input_buffer = -1; 573 574 pix_fmt = ff_get_format(avctx, pix_fmts); 575 if (pix_fmt == AV_PIX_FMT_MEDIACODEC) { 576 AVMediaCodecContext *user_ctx = avctx->hwaccel_context; 577 578 if (avctx->hw_device_ctx) { 579 AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)(avctx->hw_device_ctx->data); 580 if (device_ctx->type == AV_HWDEVICE_TYPE_MEDIACODEC) { 581 if (device_ctx->hwctx) { 582 AVMediaCodecDeviceContext *mediacodec_ctx = (AVMediaCodecDeviceContext *)device_ctx->hwctx; 583 s->surface = ff_mediacodec_surface_ref(mediacodec_ctx->surface, avctx); 584 av_log(avctx, AV_LOG_INFO, "Using surface %p\n", s->surface); 585 } 586 } 587 } 588 589 if (!s->surface && user_ctx && user_ctx->surface) { 590 s->surface = ff_mediacodec_surface_ref(user_ctx->surface, avctx); 591 av_log(avctx, AV_LOG_INFO, "Using surface %p\n", s->surface); 592 } 593 } 594 595 profile = ff_AMediaCodecProfile_getProfileFromAVCodecContext(avctx); 596 if (profile < 0) { 597 av_log(avctx, AV_LOG_WARNING, "Unsupported or unknown profile\n"); 598 } 599 600 s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, profile, 0, avctx); 601 if (!s->codec_name) { 602 ret = AVERROR_EXTERNAL; 603 goto fail; 604 } 605 606 av_log(avctx, AV_LOG_DEBUG, "Found decoder %s\n", s->codec_name); 607 s->codec = ff_AMediaCodec_createCodecByName(s->codec_name); 608 if (!s->codec) { 609 av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for type %s and name %s\n", mime, s->codec_name); 610 ret = AVERROR_EXTERNAL; 611 goto fail; 612 } 613 614 status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0); 615 if (status < 0) { 616 char *desc = ff_AMediaFormat_toString(format); 617 av_log(avctx, AV_LOG_ERROR, 618 "Failed to configure codec %s (status = %d) with format %s\n", 619 s->codec_name, status, desc); 620 av_freep(&desc); 621 622 ret = AVERROR_EXTERNAL; 623 goto fail; 624 } 625 626 status = ff_AMediaCodec_start(s->codec); 627 if (status < 0) { 628 char *desc = ff_AMediaFormat_toString(format); 629 av_log(avctx, AV_LOG_ERROR, 630 "Failed to start codec %s (status = %d) with format %s\n", 631 s->codec_name, status, desc); 632 av_freep(&desc); 633 ret = AVERROR_EXTERNAL; 634 goto fail; 635 } 636 637 s->format = ff_AMediaCodec_getOutputFormat(s->codec); 638 if (s->format) { 639 if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) { 640 av_log(avctx, AV_LOG_ERROR, 641 "Failed to configure context\n"); 642 goto fail; 643 } 644 } 645 646 av_log(avctx, AV_LOG_DEBUG, "MediaCodec %p started successfully\n", s->codec); 647 648 return 0; 649 650fail: 651 av_log(avctx, AV_LOG_ERROR, "MediaCodec %p failed to start\n", s->codec); 652 ff_mediacodec_dec_close(avctx, s); 653 return ret; 654} 655 656int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s, 657 AVPacket *pkt, bool wait) 658{ 659 int offset = 0; 660 int need_draining = 0; 661 uint8_t *data; 662 size_t size; 663 FFAMediaCodec *codec = s->codec; 664 int status; 665 int64_t input_dequeue_timeout_us = wait ? INPUT_DEQUEUE_TIMEOUT_US : 0; 666 int64_t pts; 667 668 if (s->flushing) { 669 av_log(avctx, AV_LOG_ERROR, "Decoder is flushing and cannot accept new buffer " 670 "until all output buffers have been released\n"); 671 return AVERROR_EXTERNAL; 672 } 673 674 if (pkt->size == 0) { 675 need_draining = 1; 676 } 677 678 if (s->draining && s->eos) { 679 return AVERROR_EOF; 680 } 681 682 while (offset < pkt->size || (need_draining && !s->draining)) { 683 ssize_t index = s->current_input_buffer; 684 if (index < 0) { 685 index = ff_AMediaCodec_dequeueInputBuffer(codec, input_dequeue_timeout_us); 686 if (ff_AMediaCodec_infoTryAgainLater(codec, index)) { 687 av_log(avctx, AV_LOG_TRACE, "No input buffer available, try again later\n"); 688 break; 689 } 690 691 if (index < 0) { 692 av_log(avctx, AV_LOG_ERROR, "Failed to dequeue input buffer (status=%zd)\n", index); 693 return AVERROR_EXTERNAL; 694 } 695 } 696 s->current_input_buffer = -1; 697 698 data = ff_AMediaCodec_getInputBuffer(codec, index, &size); 699 if (!data) { 700 av_log(avctx, AV_LOG_ERROR, "Failed to get input buffer\n"); 701 return AVERROR_EXTERNAL; 702 } 703 704 pts = pkt->pts; 705 if (pts == AV_NOPTS_VALUE) { 706 av_log(avctx, AV_LOG_WARNING, "Input packet is missing PTS\n"); 707 pts = 0; 708 } 709 if (pts && avctx->pkt_timebase.num && avctx->pkt_timebase.den) { 710 pts = av_rescale_q(pts, avctx->pkt_timebase, AV_TIME_BASE_Q); 711 } 712 713 if (need_draining) { 714 uint32_t flags = ff_AMediaCodec_getBufferFlagEndOfStream(codec); 715 716 av_log(avctx, AV_LOG_DEBUG, "Sending End Of Stream signal\n"); 717 718 status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags); 719 if (status < 0) { 720 av_log(avctx, AV_LOG_ERROR, "Failed to queue input empty buffer (status = %d)\n", status); 721 return AVERROR_EXTERNAL; 722 } 723 724 av_log(avctx, AV_LOG_TRACE, 725 "Queued empty EOS input buffer %zd with flags=%d\n", index, flags); 726 727 s->draining = 1; 728 return 0; 729 } 730 731 size = FFMIN(pkt->size - offset, size); 732 memcpy(data, pkt->data + offset, size); 733 offset += size; 734 735 status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0); 736 if (status < 0) { 737 av_log(avctx, AV_LOG_ERROR, "Failed to queue input buffer (status = %d)\n", status); 738 return AVERROR_EXTERNAL; 739 } 740 741 av_log(avctx, AV_LOG_TRACE, 742 "Queued input buffer %zd size=%zd ts=%"PRIi64"\n", index, size, pts); 743 } 744 745 if (offset == 0) 746 return AVERROR(EAGAIN); 747 return offset; 748} 749 750int ff_mediacodec_dec_receive(AVCodecContext *avctx, MediaCodecDecContext *s, 751 AVFrame *frame, bool wait) 752{ 753 int ret; 754 uint8_t *data; 755 ssize_t index; 756 size_t size; 757 FFAMediaCodec *codec = s->codec; 758 FFAMediaCodecBufferInfo info = { 0 }; 759 int status; 760 int64_t output_dequeue_timeout_us = OUTPUT_DEQUEUE_TIMEOUT_US; 761 762 if (s->draining && s->eos) { 763 return AVERROR_EOF; 764 } 765 766 if (s->draining) { 767 /* If the codec is flushing or need to be flushed, block for a fair 768 * amount of time to ensure we got a frame */ 769 output_dequeue_timeout_us = OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US; 770 } else if (s->output_buffer_count == 0 || !wait) { 771 /* If the codec hasn't produced any frames, do not block so we 772 * can push data to it as fast as possible, and get the first 773 * frame */ 774 output_dequeue_timeout_us = 0; 775 } 776 777 index = ff_AMediaCodec_dequeueOutputBuffer(codec, &info, output_dequeue_timeout_us); 778 if (index >= 0) { 779 av_log(avctx, AV_LOG_TRACE, "Got output buffer %zd" 780 " offset=%" PRIi32 " size=%" PRIi32 " ts=%" PRIi64 781 " flags=%" PRIu32 "\n", index, info.offset, info.size, 782 info.presentationTimeUs, info.flags); 783 784 if (info.flags & ff_AMediaCodec_getBufferFlagEndOfStream(codec)) { 785 s->eos = 1; 786 } 787 788 if (info.size) { 789 if (s->surface) { 790 if ((ret = mediacodec_wrap_hw_buffer(avctx, s, index, &info, frame)) < 0) { 791 av_log(avctx, AV_LOG_ERROR, "Failed to wrap MediaCodec buffer\n"); 792 return ret; 793 } 794 } else { 795 data = ff_AMediaCodec_getOutputBuffer(codec, index, &size); 796 if (!data) { 797 av_log(avctx, AV_LOG_ERROR, "Failed to get output buffer\n"); 798 return AVERROR_EXTERNAL; 799 } 800 801 if ((ret = mediacodec_wrap_sw_buffer(avctx, s, data, size, index, &info, frame)) < 0) { 802 av_log(avctx, AV_LOG_ERROR, "Failed to wrap MediaCodec buffer\n"); 803 return ret; 804 } 805 } 806 807 s->output_buffer_count++; 808 return 0; 809 } else { 810 status = ff_AMediaCodec_releaseOutputBuffer(codec, index, 0); 811 if (status < 0) { 812 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n"); 813 } 814 } 815 816 } else if (ff_AMediaCodec_infoOutputFormatChanged(codec, index)) { 817 char *format = NULL; 818 819 if (s->format) { 820 status = ff_AMediaFormat_delete(s->format); 821 if (status < 0) { 822 av_log(avctx, AV_LOG_ERROR, "Failed to delete MediaFormat %p\n", s->format); 823 } 824 } 825 826 s->format = ff_AMediaCodec_getOutputFormat(codec); 827 if (!s->format) { 828 av_log(avctx, AV_LOG_ERROR, "Failed to get output format\n"); 829 return AVERROR_EXTERNAL; 830 } 831 832 format = ff_AMediaFormat_toString(s->format); 833 if (!format) { 834 return AVERROR_EXTERNAL; 835 } 836 av_log(avctx, AV_LOG_INFO, "Output MediaFormat changed to %s\n", format); 837 av_freep(&format); 838 839 if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) { 840 return ret; 841 } 842 843 } else if (ff_AMediaCodec_infoOutputBuffersChanged(codec, index)) { 844 ff_AMediaCodec_cleanOutputBuffers(codec); 845 } else if (ff_AMediaCodec_infoTryAgainLater(codec, index)) { 846 if (s->draining) { 847 av_log(avctx, AV_LOG_ERROR, "Failed to dequeue output buffer within %" PRIi64 "ms " 848 "while draining remaining frames, output will probably lack frames\n", 849 output_dequeue_timeout_us / 1000); 850 } else { 851 av_log(avctx, AV_LOG_TRACE, "No output buffer available, try again later\n"); 852 } 853 } else { 854 av_log(avctx, AV_LOG_ERROR, "Failed to dequeue output buffer (status=%zd)\n", index); 855 return AVERROR_EXTERNAL; 856 } 857 858 return AVERROR(EAGAIN); 859} 860 861/* 862* ff_mediacodec_dec_flush returns 0 if the flush cannot be performed on 863* the codec (because the user retains frames). The codec stays in the 864* flushing state. 865* 866* ff_mediacodec_dec_flush returns 1 if the flush can actually be 867* performed on the codec. The codec leaves the flushing state and can 868* process again packets. 869* 870* ff_mediacodec_dec_flush returns a negative value if an error has 871* occurred. 872*/ 873int ff_mediacodec_dec_flush(AVCodecContext *avctx, MediaCodecDecContext *s) 874{ 875 if (!s->surface || atomic_load(&s->refcount) == 1) { 876 int ret; 877 878 /* No frames (holding a reference to the codec) are retained by the 879 * user, thus we can flush the codec and returns accordingly */ 880 if ((ret = mediacodec_dec_flush_codec(avctx, s)) < 0) { 881 return ret; 882 } 883 884 return 1; 885 } 886 887 s->flushing = 1; 888 return 0; 889} 890 891int ff_mediacodec_dec_close(AVCodecContext *avctx, MediaCodecDecContext *s) 892{ 893 ff_mediacodec_dec_unref(s); 894 895 return 0; 896} 897 898int ff_mediacodec_dec_is_flushing(AVCodecContext *avctx, MediaCodecDecContext *s) 899{ 900 return s->flushing; 901} 902