FFmpeg
Loading...
Searching...
No Matches
mediacodecdec_common.c
Go to the documentation of this file.
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/avassert.h"
27#include "libavutil/common.h"
29#include "libavutil/mem.h"
30#include "libavutil/log.h"
31#include "libavutil/pixfmt.h"
32#include "libavutil/time.h"
33#include "libavutil/timestamp.h"
35
36#include "avcodec.h"
37#include "decode.h"
38
39#include "mediacodec.h"
40#include "mediacodec_surface.h"
42#include "mediacodec_wrapper.h"
44
45/**
46 * OMX.k3.video.decoder.avc, OMX.NVIDIA.* OMX.SEC.avc.dec and OMX.google
47 * codec workarounds used in various place are taken from the Gstreamer
48 * project.
49 *
50 * Gstreamer references:
51 * https://cgit.freedesktop.org/gstreamer/gst-plugins-bad/tree/sys/androidmedia/
52 *
53 * Gstreamer copyright notice:
54 *
55 * Copyright (C) 2012, Collabora Ltd.
56 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
57 *
58 * Copyright (C) 2012, Rafaël Carré <funman@videolanorg>
59 *
60 * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com>
61 *
62 * Copyright (C) 2014-2015, Collabora Ltd.
63 * Author: Matthieu Bouron <matthieu.bouron@gcollabora.com>
64 *
65 * Copyright (C) 2015, Edward Hervey
66 * Author: Edward Hervey <bilboed@gmail.com>
67 *
68 * Copyright (C) 2015, Matthew Waters <matthew@centricular.com>
69 *
70 * This library is free software; you can redistribute it and/or
71 * modify it under the terms of the GNU Lesser General Public
72 * License as published by the Free Software Foundation
73 * version 2.1 of the License.
74 *
75 * This library is distributed in the hope that it will be useful,
76 * but WITHOUT ANY WARRANTY; without even the implied warranty of
77 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
78 * Lesser General Public License for more details.
79 *
80 * You should have received a copy of the GNU Lesser General Public
81 * License along with this library; if not, write to the Free Software
82 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
83 *
84 */
85
86#define INPUT_DEQUEUE_TIMEOUT_US 8000
87#define OUTPUT_DEQUEUE_TIMEOUT_US 8000
88#define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US 1000000
89
90enum {
91 ENCODING_PCM_16BIT = 0x00000002,
92 ENCODING_PCM_8BIT = 0x00000003,
93 ENCODING_PCM_FLOAT = 0x00000004,
95 ENCODING_PCM_32BIT = 0x00000016,
96};
97
98static const struct {
99
102
103} sample_formats[] = {
104
109 { 0 }
111
114 int pcm_format)
115{
117
118 for (int i = 0; i < FF_ARRAY_ELEMS(sample_formats); i++) {
120 return sample_formats[i].sample_format;
121 }
122 }
123
124 av_log(avctx, AV_LOG_ERROR, "Output sample format 0x%x (value=%d) is not supported\n",
126
127 return ret;
128}
129
130enum
131{
150};
151
152static const struct {
153
154 int mask;
155 uint64_t layout;
156
157} channel_masks[] = {
177
179 int channel_mask)
180{
181 uint64_t channel_layout = 0;
182
183 for (int i = 0; i < FF_ARRAY_ELEMS(channel_masks); i++) {
184 if (channel_mask & channel_masks[i].mask)
185 channel_layout |= channel_masks[i].layout;
186 }
187
188 return channel_layout;
189}
190
191enum {
201};
202
203static const struct {
204
207
208} color_formats[] = {
209
217 { 0 }
219
222 int color_format)
223{
224 int i;
226
227 if (s->surface) {
229 }
230
231 if (!strcmp(s->codec_name, "OMX.k3.video.decoder.avc") && color_format == COLOR_FormatYCbYCr) {
233 }
234
235 for (i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) {
237 return color_formats[i].pix_fmt;
238 }
239 }
240
241 av_log(avctx, AV_LOG_ERROR, "Output color format 0x%x (value=%d) is not supported\n",
243
244 return ret;
245}
246
248{
249 atomic_fetch_add(&s->refcount, 1);
250}
251
253{
254 if (!s)
255 return;
256
257 if (atomic_fetch_sub(&s->refcount, 1) == 1) {
258 if (s->codec) {
259 ff_AMediaCodec_delete(s->codec);
260 s->codec = NULL;
261 }
262
263 if (s->format) {
264 ff_AMediaFormat_delete(s->format);
265 s->format = NULL;
266 }
267
268 if (s->surface) {
270 s->surface = NULL;
271 }
272
273 av_freep(&s->codec_name);
274 av_freep(&s);
275 }
276}
277
278static void mediacodec_buffer_release(void *opaque, uint8_t *data)
279{
280 AVMediaCodecBuffer *buffer = opaque;
282 int released = atomic_load(&buffer->released);
283
284 if (!released && (ctx->delay_flush || buffer->serial == atomic_load(&ctx->serial))) {
285 atomic_fetch_sub(&ctx->hw_buffer_count, 1);
286 av_log(ctx->avctx, AV_LOG_DEBUG,
287 "Releasing output buffer %zd (%p) ts=%"PRId64" on free() [%d pending]\n",
288 buffer->index, buffer, buffer->pts, atomic_load(&ctx->hw_buffer_count));
290 }
291
294}
295
298 ssize_t index,
300 AVFrame *frame)
301{
302 int ret = 0;
303 int status = 0;
304 AVMediaCodecBuffer *buffer = NULL;
305
306 frame->buf[0] = NULL;
307 frame->width = avctx->width;
308 frame->height = avctx->height;
309 frame->format = avctx->pix_fmt;
310 frame->sample_aspect_ratio = avctx->sample_aspect_ratio;
311
312 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) {
315 avctx->pkt_timebase);
316 } else {
317 frame->pts = info->presentationTimeUs;
318 }
319 frame->pkt_dts = AV_NOPTS_VALUE;
320 frame->color_range = avctx->color_range;
321 frame->color_primaries = avctx->color_primaries;
322 frame->color_trc = avctx->color_trc;
323 frame->colorspace = avctx->colorspace;
324
325 buffer = av_mallocz(sizeof(AVMediaCodecBuffer));
326 if (!buffer) {
327 ret = AVERROR(ENOMEM);
328 goto fail;
329 }
330
331 atomic_init(&buffer->released, 0);
332
333 frame->buf[0] = av_buffer_create(NULL,
334 0,
336 buffer,
338
339 if (!frame->buf[0]) {
340 ret = AVERROR(ENOMEM);
341 goto fail;
342
343 }
344
345 buffer->ctx = s;
346 buffer->serial = atomic_load(&s->serial);
348
349 buffer->index = index;
350 buffer->pts = info->presentationTimeUs;
351
352 frame->data[3] = (uint8_t *)buffer;
353
354 atomic_fetch_add(&s->hw_buffer_count, 1);
355 av_log(avctx, AV_LOG_DEBUG,
356 "Wrapping output buffer %zd (%p) ts=%"PRId64" [%d pending]\n",
357 buffer->index, buffer, buffer->pts, atomic_load(&s->hw_buffer_count));
358
359 return 0;
360fail:
362 status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0);
363 if (status < 0) {
364 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n");
365 ret = AVERROR_EXTERNAL;
366 }
367
368 return ret;
369}
370
373 uint8_t *data,
374 size_t size,
375 ssize_t index,
377 AVFrame *frame)
378{
379 int ret = 0;
380 int status = 0;
381 const int sample_size = av_get_bytes_per_sample(avctx->sample_fmt);
382 if (!sample_size) {
383 av_log(avctx, AV_LOG_ERROR, "Could not get bytes per sample\n");
384 ret = AVERROR(ENOSYS);
385 goto done;
386 }
387
388 if (info->size % (sample_size * avctx->ch_layout.nb_channels)) {
389 av_log(avctx, AV_LOG_ERROR, "input is not a multiple of channels * sample_size\n");
390 ret = AVERROR(EINVAL);
391 goto done;
392 }
393
394 frame->format = avctx->sample_fmt;
395 frame->sample_rate = avctx->sample_rate;
396 frame->nb_samples = info->size / (sample_size * avctx->ch_layout.nb_channels);
397
398 ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout);
399 if (ret < 0) {
400 av_log(avctx, AV_LOG_ERROR, "Could not copy channel layout\n");
401 goto done;
402 }
403
404 /* MediaCodec buffers needs to be copied to our own refcounted buffers
405 * because the flush command invalidates all input and output buffers.
406 */
407 ret = ff_get_buffer(avctx, frame, 0);
408 if (ret < 0) {
409 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer\n");
410 goto done;
411 }
412
413 /* Override frame->pts as ff_get_buffer will override its value based
414 * on the last avpacket received which is not in sync with the frame:
415 * * N avpackets can be pushed before 1 frame is actually returned
416 * * 0-sized avpackets are pushed to flush remaining frames at EOS */
417 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) {
420 avctx->pkt_timebase);
421 } else {
422 frame->pts = info->presentationTimeUs;
423 }
424 frame->pkt_dts = AV_NOPTS_VALUE;
425 frame->flags |= AV_FRAME_FLAG_KEY;
426
427 av_log(avctx, AV_LOG_TRACE,
428 "Frame: format=%d channels=%d sample_rate=%d nb_samples=%d",
429 avctx->sample_fmt, avctx->ch_layout.nb_channels, avctx->sample_rate, frame->nb_samples);
430
431 memcpy(frame->data[0], data, info->size);
432
433 ret = 0;
434done:
435 status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0);
436 if (status < 0) {
437 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n");
438 ret = AVERROR_EXTERNAL;
439 }
440
441 return ret;
442}
443
446 uint8_t *data,
447 size_t size,
448 ssize_t index,
450 AVFrame *frame)
451{
452 int ret = 0;
453 int status = 0;
454
455 frame->width = avctx->width;
456 frame->height = avctx->height;
457 frame->format = avctx->pix_fmt;
458
459 /* MediaCodec buffers needs to be copied to our own refcounted buffers
460 * because the flush command invalidates all input and output buffers.
461 */
462 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
463 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer\n");
464 goto done;
465 }
466
467 /* Override frame->pkt_pts as ff_get_buffer will override its value based
468 * on the last avpacket received which is not in sync with the frame:
469 * * N avpackets can be pushed before 1 frame is actually returned
470 * * 0-sized avpackets are pushed to flush remaining frames at EOS */
471 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) {
474 avctx->pkt_timebase);
475 } else {
476 frame->pts = info->presentationTimeUs;
477 }
478 frame->pkt_dts = AV_NOPTS_VALUE;
479
480 av_log(avctx, AV_LOG_TRACE,
481 "Frame: width=%d stride=%d height=%d slice-height=%d "
482 "crop-top=%d crop-bottom=%d crop-left=%d crop-right=%d encoder=%s "
483 "destination linesizes=%d,%d,%d\n" ,
484 avctx->width, s->stride, avctx->height, s->slice_height,
485 s->crop_top, s->crop_bottom, s->crop_left, s->crop_right, s->codec_name,
486 frame->linesize[0], frame->linesize[1], frame->linesize[2]);
487
488 switch (s->color_format) {
491 break;
496 break;
500 break;
503 break;
504 default:
505 av_log(avctx, AV_LOG_ERROR, "Unsupported color format 0x%x (value=%d)\n",
506 s->color_format, s->color_format);
507 ret = AVERROR(EINVAL);
508 goto done;
509 }
510
511 ret = 0;
512done:
513 status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0);
514 if (status < 0) {
515 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n");
516 ret = AVERROR_EXTERNAL;
517 }
518
519 return ret;
520}
521
524 uint8_t *data,
525 size_t size,
526 ssize_t index,
528 AVFrame *frame)
529{
530 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO)
531 return mediacodec_wrap_sw_audio_buffer(avctx, s, data, size, index, info, frame);
532 else if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
533 return mediacodec_wrap_sw_video_buffer(avctx, s, data, size, index, info, frame);
534 else
535 av_assert0(0);
536}
537
538#define AMEDIAFORMAT_GET_INT32(name, key, mandatory) do { \
539 int32_t value = 0; \
540 if (ff_AMediaFormat_getInt32(s->format, key, &value)) { \
541 (name) = value; \
542 } else if (mandatory) { \
543 av_log(avctx, AV_LOG_ERROR, "Could not get %s from format %s\n", key, format); \
544 ret = AVERROR_EXTERNAL; \
545 goto fail; \
546 } else { \
547 (name) = 0; \
548 } \
549} while (0) \
550
552{
553 int ret = 0;
554 int width = 0;
555 int height = 0;
556 int color_range = 0;
557 int color_standard = 0;
558 int color_transfer = 0;
559 char *format = NULL;
560
561 if (!s->format) {
562 av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n");
563 return AVERROR(EINVAL);
564 }
565
567 if (!format) {
568 return AVERROR_EXTERNAL;
569 }
570 av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format);
571
572 /* Mandatory fields */
573 AMEDIAFORMAT_GET_INT32(s->width, "width", 1);
574 AMEDIAFORMAT_GET_INT32(s->height, "height", 1);
575
576 AMEDIAFORMAT_GET_INT32(s->stride, "stride", 0);
577 s->stride = s->stride > 0 ? s->stride : s->width;
578
579 AMEDIAFORMAT_GET_INT32(s->slice_height, "slice-height", 0);
580
581 if (strstr(s->codec_name, "OMX.Nvidia.") && s->slice_height == 0) {
582 s->slice_height = FFALIGN(s->height, 16);
583 } else if (strstr(s->codec_name, "OMX.SEC.avc.dec")) {
584 s->slice_height = avctx->height;
585 s->stride = avctx->width;
586 } else if (strstr(s->codec_name, "OMX.MTK.VIDEO.DECODER.MPEG2")) {
587 s->slice_height = s->height;
588 } else if (s->slice_height == 0) {
589 s->slice_height = s->height;
590 }
591
592 AMEDIAFORMAT_GET_INT32(s->color_format, "color-format", 1);
593 avctx->pix_fmt = mcdec_map_color_format(avctx, s, s->color_format);
594 if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
595 av_log(avctx, AV_LOG_ERROR, "Output color format is not supported\n");
596 ret = AVERROR(EINVAL);
597 goto fail;
598 }
599
600 /* Optional fields */
601 AMEDIAFORMAT_GET_INT32(s->crop_top, "crop-top", 0);
602 AMEDIAFORMAT_GET_INT32(s->crop_bottom, "crop-bottom", 0);
603 AMEDIAFORMAT_GET_INT32(s->crop_left, "crop-left", 0);
604 AMEDIAFORMAT_GET_INT32(s->crop_right, "crop-right", 0);
605
606 // Try "crop" for NDK
607 // MediaTek SOC return some default value like Rect(0, 0, 318, 238)
608 if (!(s->crop_right && s->crop_bottom) && s->use_ndk_codec && !strstr(s->codec_name, ".mtk."))
609 ff_AMediaFormat_getRect(s->format, "crop", &s->crop_left, &s->crop_top, &s->crop_right, &s->crop_bottom);
610
611 if (s->crop_right && s->crop_bottom) {
612 width = s->crop_right + 1 - s->crop_left;
613 height = s->crop_bottom + 1 - s->crop_top;
614 } else {
615 /* TODO: NDK MediaFormat should try getRect() first.
616 * Try crop-width/crop-height, it works on NVIDIA Shield.
617 */
618 AMEDIAFORMAT_GET_INT32(width, "crop-width", 0);
619 AMEDIAFORMAT_GET_INT32(height, "crop-height", 0);
620 }
621 if (!width || !height) {
622 width = s->width;
623 height = s->height;
624 }
625
626 AMEDIAFORMAT_GET_INT32(s->display_width, "display-width", 0);
627 AMEDIAFORMAT_GET_INT32(s->display_height, "display-height", 0);
628
629 if (s->display_width && s->display_height) {
630 AVRational sar = av_div_q(
631 (AVRational){ s->display_width, s->display_height },
632 (AVRational){ width, height });
633 ff_set_sar(avctx, sar);
634 }
635
636 AMEDIAFORMAT_GET_INT32(color_range, "color-range", 0);
637 if (color_range)
639
640 AMEDIAFORMAT_GET_INT32(color_standard, "color-standard", 0);
641 if (color_standard) {
644 }
645
646 AMEDIAFORMAT_GET_INT32(color_transfer, "color-transfer", 0);
647 if (color_transfer)
649
650 av_log(avctx, AV_LOG_INFO,
651 "Output crop parameters top=%d bottom=%d left=%d right=%d, "
652 "resulting dimensions width=%d height=%d\n",
653 s->crop_top, s->crop_bottom, s->crop_left, s->crop_right,
654 width, height);
655
657 return ff_set_dimensions(avctx, width, height);
658fail:
660 return ret;
661}
662
664{
665 int ret = 0;
666 int sample_rate = 0;
667 int channel_count = 0;
668 int channel_mask = 0;
669 int pcm_encoding = 0;
670 char *format = NULL;
671
672 if (!s->format) {
673 av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n");
674 return AVERROR(EINVAL);
675 }
676
678 if (!format) {
679 return AVERROR_EXTERNAL;
680 }
681 av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format);
682
683 /* Mandatory fields */
684 AMEDIAFORMAT_GET_INT32(channel_count, "channel-count", 1);
685 AMEDIAFORMAT_GET_INT32(sample_rate, "sample-rate", 1);
686
687 AMEDIAFORMAT_GET_INT32(pcm_encoding, "pcm-encoding", 0);
688 if (pcm_encoding)
689 avctx->sample_fmt = mcdec_map_pcm_format(avctx, s, pcm_encoding);
690 else
692
693 avctx->sample_rate = sample_rate;
694
695 AMEDIAFORMAT_GET_INT32(channel_mask, "channel-mask", 0);
696 if (channel_mask)
697 av_channel_layout_from_mask(&avctx->ch_layout, mcdec_map_channel_mask(avctx, channel_mask));
698 else
699 av_channel_layout_default(&avctx->ch_layout, channel_count);
700
701 av_log(avctx, AV_LOG_INFO,
702 "Output parameters channel-count=%d channel-layout=%x sample-rate=%d\n",
703 channel_count, channel_mask, sample_rate);
704
705fail:
707 return ret;
708}
709
711{
712 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO)
714 else if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
716 else
717 av_assert0(0);
718}
719
721{
722 FFAMediaCodec *codec = s->codec;
723 int status;
724
725 s->output_buffer_count = 0;
726
727 s->draining = 0;
728 s->flushing = 0;
729 s->eos = 0;
730 atomic_fetch_add(&s->serial, 1);
731 atomic_init(&s->hw_buffer_count, 0);
732 s->current_input_buffer = -1;
733
734 status = ff_AMediaCodec_flush(codec);
735 if (status < 0) {
736 av_log(avctx, AV_LOG_ERROR, "Failed to flush codec\n");
737 return AVERROR_EXTERNAL;
738 }
739
740 return 0;
741}
742
744 const char *mime, FFAMediaFormat *format)
745{
746 int profile;
747
749 static const enum AVPixelFormat pix_fmts[] = {
752 };
753
756 AVMediaCodecContext *user_ctx = avctx->hwaccel_context;
757
758 if (avctx->hw_device_ctx) {
759 AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)(avctx->hw_device_ctx->data);
760 if (device_ctx->type == AV_HWDEVICE_TYPE_MEDIACODEC) {
761 if (device_ctx->hwctx) {
762 AVMediaCodecDeviceContext *mediacodec_ctx = (AVMediaCodecDeviceContext *)device_ctx->hwctx;
763 s->surface = ff_mediacodec_surface_ref(mediacodec_ctx->surface, mediacodec_ctx->native_window, avctx);
764 av_log(avctx, AV_LOG_INFO, "Using surface %p\n", s->surface);
765 }
766 }
767 }
768
769 if (!s->surface && user_ctx && user_ctx->surface) {
770 s->surface = ff_mediacodec_surface_ref(user_ctx->surface, NULL, avctx);
771 av_log(avctx, AV_LOG_INFO, "Using surface %p\n", s->surface);
772 }
773 }
774
776 if (profile < 0) {
777 av_log(avctx, AV_LOG_WARNING, "Unsupported or unknown profile\n");
778 }
779
780 s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, profile, 0, avctx);
781 if (!s->codec_name && (avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH)) {
782 profile = -1;
783 s->codec_name = ff_AMediaCodecList_getCodecNameByType(mime, profile, 0, avctx);
784 }
785 if (!s->codec_name) {
786 av_log(avctx, AV_LOG_INFO, "Failed to getCodecNameByType(%s, %d)\n", mime, profile);
787 // getCodecNameByType() can fail due to missing JVM, while NDK
788 // mediacodec can be used without JVM.
789 if (!s->use_ndk_codec) {
790 return AVERROR_EXTERNAL;
791 }
792 } else {
793 av_log(avctx, AV_LOG_DEBUG, "Found decoder %s\n", s->codec_name);
794 }
795
796 if (s->codec_name)
797 s->codec = ff_AMediaCodec_createCodecByName(s->codec_name, s->use_ndk_codec);
798 else {
799 s->codec = ff_AMediaCodec_createDecoderByType(mime, s->use_ndk_codec);
800 if (s->codec) {
801 s->codec_name = ff_AMediaCodec_getName(s->codec);
802 if (!s->codec_name)
803 s->codec_name = av_strdup(mime);
804 }
805 }
806 if (!s->codec) {
807 av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for type %s and name %s\n", mime, s->codec_name);
808 return AVERROR_EXTERNAL;
809 }
810
811 return 0;
812}
813
815 const char *mime, FFAMediaFormat *format)
816{
817 s->codec = ff_AMediaCodec_createDecoderByType(mime, s->use_ndk_codec);
818 if (!s->codec) {
819 av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for mime %s\n", mime);
820 return AVERROR_EXTERNAL;
821 }
822
823 s->codec_name = ff_AMediaCodec_getName(s->codec);
824 if (!s->codec_name) {
825 s->codec_name = av_strdup(mime);
826 if (!s->codec_name)
827 return AVERROR(ENOMEM);
828 }
829
830 return 0;
831}
832
834 const char *mime, FFAMediaFormat *format)
835{
836 int ret;
837 int status;
838
839 s->avctx = avctx;
840 atomic_init(&s->refcount, 1);
841 atomic_init(&s->hw_buffer_count, 0);
842 atomic_init(&s->serial, 1);
843 s->current_input_buffer = -1;
844
845 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO)
846 ret = mediacodec_dec_get_audio_codec(avctx, s, mime, format);
847 else if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
848 ret = mediacodec_dec_get_video_codec(avctx, s, mime, format);
849 else
850 av_assert0(0);
851 if (ret < 0)
852 goto fail;
853
854 status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0);
855 if (status < 0) {
857 av_log(avctx, AV_LOG_ERROR,
858 "Failed to configure codec %s (status = %d) with format %s\n",
859 s->codec_name, status, desc);
860 av_freep(&desc);
861
862 ret = AVERROR_EXTERNAL;
863 goto fail;
864 }
865
866 status = ff_AMediaCodec_start(s->codec);
867 if (status < 0) {
869 av_log(avctx, AV_LOG_ERROR,
870 "Failed to start codec %s (status = %d) with format %s\n",
871 s->codec_name, status, desc);
872 av_freep(&desc);
873 ret = AVERROR_EXTERNAL;
874 goto fail;
875 }
876
877 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
878 s->format = ff_AMediaCodec_getOutputFormat(s->codec);
879 if (s->format) {
880 if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) {
881 av_log(avctx, AV_LOG_ERROR,
882 "Failed to configure context\n");
883 goto fail;
884 }
885 }
886 }
887
888 av_log(avctx, AV_LOG_DEBUG, "MediaCodec %p started successfully\n", s->codec);
889
890 return 0;
891
892fail:
893 av_log(avctx, AV_LOG_ERROR, "MediaCodec %p failed to start\n", s->codec);
895 return ret;
896}
897
899 AVPacket *pkt, bool wait)
900{
901 int offset = 0;
902 int need_draining = 0;
903 uint8_t *data;
904 size_t size;
905 FFAMediaCodec *codec = s->codec;
906 int status;
907 int64_t input_dequeue_timeout_us = wait ? INPUT_DEQUEUE_TIMEOUT_US : 0;
908 int64_t pts;
909
910 if (s->flushing) {
911 av_log(avctx, AV_LOG_ERROR, "Decoder is flushing and cannot accept new buffer "
912 "until all output buffers have been released\n");
913 return AVERROR_EXTERNAL;
914 }
915
916 if (pkt->size == 0) {
917 need_draining = 1;
918 }
919
920 if (s->draining && s->eos) {
921 return AVERROR_EOF;
922 }
923
924 while (offset < pkt->size || (need_draining && !s->draining)) {
925 ssize_t index = s->current_input_buffer;
926 if (index < 0) {
927 index = ff_AMediaCodec_dequeueInputBuffer(codec, input_dequeue_timeout_us);
929 av_log(avctx, AV_LOG_TRACE, "No input buffer available, try again later\n");
930 break;
931 }
932
933 if (index < 0) {
934 av_log(avctx, AV_LOG_ERROR, "Failed to dequeue input buffer (status=%zd)\n", index);
935 return AVERROR_EXTERNAL;
936 }
937 }
938 s->current_input_buffer = -1;
939
941 if (!data) {
942 av_log(avctx, AV_LOG_ERROR, "Failed to get input buffer\n");
943 return AVERROR_EXTERNAL;
944 }
945
946 pts = pkt->pts;
947 if (pts == AV_NOPTS_VALUE) {
948 av_log(avctx, AV_LOG_WARNING, "Input packet is missing PTS\n");
949 pts = 0;
950 }
951 if (pts && avctx->pkt_timebase.num && avctx->pkt_timebase.den) {
953 }
954
955 if (need_draining) {
957
958 av_log(avctx, AV_LOG_DEBUG, "Sending End Of Stream signal\n");
959
960 status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, 0, pts, flags);
961 if (status < 0) {
962 av_log(avctx, AV_LOG_ERROR, "Failed to queue input empty buffer (status = %d)\n", status);
963 return AVERROR_EXTERNAL;
964 }
965
966 av_log(avctx, AV_LOG_TRACE,
967 "Queued empty EOS input buffer %zd with flags=%d\n", index, flags);
968
969 s->draining = 1;
970 return 0;
971 }
972
973 size = FFMIN(pkt->size - offset, size);
974 memcpy(data, pkt->data + offset, size);
975 offset += size;
976
977 status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0);
978 if (status < 0) {
979 av_log(avctx, AV_LOG_ERROR, "Failed to queue input buffer (status = %d)\n", status);
980 return AVERROR_EXTERNAL;
981 }
982
983 av_log(avctx, AV_LOG_TRACE,
984 "Queued input buffer %zd size=%zd ts=%"PRIi64"\n", index, size, pts);
985 }
986
987 if (offset == 0)
988 return AVERROR(EAGAIN);
989 return offset;
990}
991
993 AVFrame *frame, bool wait)
994{
995 int ret;
996 uint8_t *data;
997 ssize_t index;
998 size_t size;
999 FFAMediaCodec *codec = s->codec;
1000 FFAMediaCodecBufferInfo info = { 0 };
1001 int status;
1002 int64_t output_dequeue_timeout_us = OUTPUT_DEQUEUE_TIMEOUT_US;
1003
1004 if (s->draining && s->eos) {
1005 return AVERROR_EOF;
1006 }
1007
1008 if (s->draining) {
1009 /* If the codec is flushing or need to be flushed, block for a fair
1010 * amount of time to ensure we got a frame */
1011 output_dequeue_timeout_us = OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US;
1012 } else if (s->output_buffer_count == 0 || !wait) {
1013 /* If the codec hasn't produced any frames, do not block so we
1014 * can push data to it as fast as possible, and get the first
1015 * frame */
1016 output_dequeue_timeout_us = 0;
1017 }
1018
1019 index = ff_AMediaCodec_dequeueOutputBuffer(codec, &info, output_dequeue_timeout_us);
1020 if (index >= 0) {
1021 av_log(avctx, AV_LOG_TRACE, "Got output buffer %zd"
1022 " offset=%" PRIi32 " size=%" PRIi32 " ts=%" PRIi64
1023 " flags=%" PRIu32 "\n", index, info.offset, info.size,
1024 info.presentationTimeUs, info.flags);
1025
1027 s->eos = 1;
1028 }
1029
1030 if (info.size) {
1031 if (s->surface) {
1032 if ((ret = mediacodec_wrap_hw_buffer(avctx, s, index, &info, frame)) < 0) {
1033 av_log(avctx, AV_LOG_ERROR, "Failed to wrap MediaCodec buffer\n");
1034 return ret;
1035 }
1036 } else {
1038 if (!data) {
1039 av_log(avctx, AV_LOG_ERROR, "Failed to get output buffer\n");
1040 return AVERROR_EXTERNAL;
1041 }
1042
1043 if ((ret = mediacodec_wrap_sw_buffer(avctx, s, data, size, index, &info, frame)) < 0) {
1044 av_log(avctx, AV_LOG_ERROR, "Failed to wrap MediaCodec buffer\n");
1045 return ret;
1046 }
1047 }
1048
1049 s->output_buffer_count++;
1050 return 0;
1051 } else {
1052 status = ff_AMediaCodec_releaseOutputBuffer(codec, index, 0);
1053 if (status < 0) {
1054 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n");
1055 }
1056 }
1057
1058 } else if (ff_AMediaCodec_infoOutputFormatChanged(codec, index)) {
1059 char *format = NULL;
1060
1061 if (s->format) {
1062 status = ff_AMediaFormat_delete(s->format);
1063 if (status < 0) {
1064 av_log(avctx, AV_LOG_ERROR, "Failed to delete MediaFormat %p\n", s->format);
1065 }
1066 }
1067
1068 s->format = ff_AMediaCodec_getOutputFormat(codec);
1069 if (!s->format) {
1070 av_log(avctx, AV_LOG_ERROR, "Failed to get output format\n");
1071 return AVERROR_EXTERNAL;
1072 }
1073
1075 if (!format) {
1076 return AVERROR_EXTERNAL;
1077 }
1078 av_log(avctx, AV_LOG_INFO, "Output MediaFormat changed to %s\n", format);
1079 av_freep(&format);
1080
1081 if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) {
1082 return ret;
1083 }
1084
1087 } else if (ff_AMediaCodec_infoTryAgainLater(codec, index)) {
1088 if (s->draining) {
1089 av_log(avctx, AV_LOG_ERROR, "Failed to dequeue output buffer within %" PRIi64 "ms "
1090 "while draining remaining frames, output will probably lack frames\n",
1091 output_dequeue_timeout_us / 1000);
1092 } else {
1093 av_log(avctx, AV_LOG_TRACE, "No output buffer available, try again later\n");
1094 }
1095 } else {
1096 av_log(avctx, AV_LOG_ERROR, "Failed to dequeue output buffer (status=%zd)\n", index);
1097 return AVERROR_EXTERNAL;
1098 }
1099
1100 if (s->draining && s->eos)
1101 return AVERROR_EOF;
1102 return AVERROR(EAGAIN);
1103}
1104
1105/*
1106* ff_mediacodec_dec_flush returns 0 if the flush cannot be performed on
1107* the codec (because the user retains frames). The codec stays in the
1108* flushing state.
1109*
1110* ff_mediacodec_dec_flush returns 1 if the flush can actually be
1111* performed on the codec. The codec leaves the flushing state and can
1112* process again packets.
1113*
1114* ff_mediacodec_dec_flush returns a negative value if an error has
1115* occurred.
1116*/
1118{
1119 if (!s->surface || !s->delay_flush || atomic_load(&s->refcount) == 1) {
1120 int ret;
1121
1122 /* No frames (holding a reference to the codec) are retained by the
1123 * user, thus we can flush the codec and returns accordingly */
1124 if ((ret = mediacodec_dec_flush_codec(avctx, s)) < 0) {
1125 return ret;
1126 }
1127
1128 return 1;
1129 }
1130
1131 s->flushing = 1;
1132 return 0;
1133}
1134
1136{
1137 if (!s)
1138 return 0;
1139
1140 if (s->codec) {
1141 if (atomic_load(&s->hw_buffer_count) == 0) {
1142 ff_AMediaCodec_stop(s->codec);
1143 av_log(avctx, AV_LOG_DEBUG, "MediaCodec %p stopped\n", s->codec);
1144 } else {
1145 av_log(avctx, AV_LOG_DEBUG, "Not stopping MediaCodec (there are buffers pending)\n");
1146 }
1147 }
1148
1150
1151 return 0;
1152}
1153
1155{
1156 return s->flushing;
1157}
static const char *const format[]
Definition af_aiir.c:444
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
common internal and external API header
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition decode.c:1229
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
Definition utils.c:106
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition utils.c:91
static AVPacket * pkt
static enum AVPixelFormat pix_fmt
static AVFrame * frame
#define atomic_load(object)
Definition stdatomic.h:93
#define atomic_init(obj, value)
Definition stdatomic.h:33
#define fail
Definition test.h:479
#define AV_CH_SIDE_LEFT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_BACK_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_FRONT_LEFT
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
Hardware acceleration should still be attempted for decoding when the codec profile does not match th...
Definition avcodec.h:2018
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition buffer.h:114
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition frame.h:687
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition rational.c:88
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition samplefmt.c:108
AVSampleFormat
Audio sample formats.
Definition samplefmt.h:55
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition samplefmt.h:59
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition samplefmt.h:57
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
int index
Definition gxfenc.c:90
@ AV_HWDEVICE_TYPE_MEDIACODEC
Definition hwcontext.h:38
unsigned offset
Definition libaomenc.c:763
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
const char * desc
Definition libsvtav1.c:83
static const uint16_t mask[17]
Definition lzw.c:38
#define FFMIN(a, b)
Definition macros.h:49
#define FFALIGN(x, a)
Definition macros.h:78
FFANativeWindow * ff_mediacodec_surface_ref(void *surface, void *native_window, void *log_ctx)
int ff_mediacodec_surface_unref(FFANativeWindow *window, void *log_ctx)
void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar_64x32Tile2m8ka(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, FFAMediaCodecBufferInfo *info, AVFrame *frame)
void ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, FFAMediaCodecBufferInfo *info, AVFrame *frame)
void ff_mediacodec_sw_buffer_copy_yuv420_planar(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, FFAMediaCodecBufferInfo *info, AVFrame *frame)
The code handling the various YUV color formats is taken from the GStreamer project.
void ff_mediacodec_sw_buffer_copy_yuv420_packed_semi_planar(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, FFAMediaCodecBufferInfo *info, AVFrame *frame)
FFAMediaCodec * ff_AMediaCodec_createDecoderByType(const char *mime_type, int ndk)
FFAMediaCodec * ff_AMediaCodec_createCodecByName(const char *name, int ndk)
char * ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int encoder, void *log_ctx)
enum AVColorPrimaries ff_AMediaFormatColorStandard_to_AVColorPrimaries(int color_standard)
Map MediaFormat color standard to AVColorPrimaries.
int ff_AMediaCodecProfile_getProfileFromAVCodecContext(AVCodecContext *avctx)
The following API around MediaCodec and MediaFormat is based on the NDK one provided by Google since ...
enum AVColorRange ff_AMediaFormatColorRange_to_AVColorRange(int color_range)
Map MediaFormat color range to AVColorRange.
enum AVColorTransferCharacteristic ff_AMediaFormatColorTransfer_to_AVColorTransfer(int color_transfer)
Map MediaFormat color transfer to AVColorTransferCharacteristic.
enum AVColorSpace ff_AMediaFormatColorStandard_to_AVColorSpace(int color_standard)
Map MediaFormat color standard to AVColorSpace.
static char * ff_AMediaFormat_toString(FFAMediaFormat *format)
static int ff_AMediaCodec_releaseOutputBuffer(FFAMediaCodec *codec, size_t idx, int render)
static FFAMediaFormat * ff_AMediaCodec_getOutputFormat(FFAMediaCodec *codec)
static int ff_AMediaCodec_flush(FFAMediaCodec *codec)
static int ff_AMediaFormat_getRect(FFAMediaFormat *format, const char *name, int32_t *left, int32_t *top, int32_t *right, int32_t *bottom)
static int ff_AMediaCodec_infoOutputBuffersChanged(FFAMediaCodec *codec, ssize_t idx)
static int ff_AMediaCodec_queueInputBuffer(FFAMediaCodec *codec, size_t idx, off_t offset, size_t size, uint64_t time, uint32_t flags)
static char * ff_AMediaCodec_getName(FFAMediaCodec *codec)
static int ff_AMediaCodec_getBufferFlagEndOfStream(FFAMediaCodec *codec)
static int ff_AMediaCodec_cleanOutputBuffers(FFAMediaCodec *codec)
static int ff_AMediaFormat_delete(FFAMediaFormat *format)
static int ff_AMediaCodec_configure(FFAMediaCodec *codec, const FFAMediaFormat *format, FFANativeWindow *surface, void *crypto, uint32_t flags)
static int ff_AMediaCodec_start(FFAMediaCodec *codec)
static uint8_t * ff_AMediaCodec_getOutputBuffer(FFAMediaCodec *codec, size_t idx, size_t *out_size)
static ssize_t ff_AMediaCodec_dequeueInputBuffer(FFAMediaCodec *codec, int64_t timeoutUs)
static int ff_AMediaCodec_infoOutputFormatChanged(FFAMediaCodec *codec, ssize_t idx)
static uint8_t * ff_AMediaCodec_getInputBuffer(FFAMediaCodec *codec, size_t idx, size_t *out_size)
static int ff_AMediaCodec_delete(FFAMediaCodec *codec)
static int ff_AMediaCodec_stop(FFAMediaCodec *codec)
static ssize_t ff_AMediaCodec_dequeueOutputBuffer(FFAMediaCodec *codec, FFAMediaCodecBufferInfo *info, int64_t timeoutUs)
static int ff_AMediaCodec_infoTryAgainLater(FFAMediaCodec *codec, ssize_t idx)
@ COLOR_TI_FormatYUV420PackedSemiPlanar
@ COLOR_QCOM_FormatYUV420SemiPlanar32m
@ COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced
@ COLOR_FormatYCbYCr
@ COLOR_FormatYUV420Planar
@ COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka
@ COLOR_FormatAndroidOpaque
@ COLOR_QCOM_FormatYUV420SemiPlanar
@ COLOR_FormatYUV420SemiPlanar
int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s, AVPacket *pkt, bool wait)
@ ENCODING_PCM_8BIT
@ ENCODING_PCM_24BIT_PACKED
@ ENCODING_PCM_32BIT
@ ENCODING_PCM_FLOAT
@ ENCODING_PCM_16BIT
static int mediacodec_wrap_sw_video_buffer(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, ssize_t index, FFAMediaCodecBufferInfo *info, AVFrame *frame)
static int mediacodec_wrap_hw_buffer(AVCodecContext *avctx, MediaCodecDecContext *s, ssize_t index, FFAMediaCodecBufferInfo *info, AVFrame *frame)
int ff_mediacodec_dec_flush(AVCodecContext *avctx, MediaCodecDecContext *s)
int ff_mediacodec_dec_receive(AVCodecContext *avctx, MediaCodecDecContext *s, AVFrame *frame, bool wait)
uint64_t layout
#define OUTPUT_DEQUEUE_TIMEOUT_US
static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s)
static int mediacodec_wrap_sw_buffer(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, ssize_t index, FFAMediaCodecBufferInfo *info, AVFrame *frame)
static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s)
int ff_mediacodec_dec_close(AVCodecContext *avctx, MediaCodecDecContext *s)
static int mediacodec_wrap_sw_audio_buffer(AVCodecContext *avctx, MediaCodecDecContext *s, uint8_t *data, size_t size, ssize_t index, FFAMediaCodecBufferInfo *info, AVFrame *frame)
#define INPUT_DEQUEUE_TIMEOUT_US
OMX.k3.video.decoder.avc, OMX.NVIDIA.
int pcm_format
static const struct @363176277014013144023233335312337360113163011307 channel_masks[]
static int mediacodec_dec_parse_audio_format(AVCodecContext *avctx, MediaCodecDecContext *s)
static const struct @000316305124326106314053112007167062251150035262 color_formats[]
static const struct @161106304217160064156176027033213377304043230355 sample_formats[]
#define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US
static int mediacodec_dec_get_video_codec(AVCodecContext *avctx, MediaCodecDecContext *s, const char *mime, FFAMediaFormat *format)
int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, const char *mime, FFAMediaFormat *format)
static void ff_mediacodec_dec_ref(MediaCodecDecContext *s)
@ CHANNEL_OUT_LOW_FREQUENCY
@ CHANNEL_OUT_TOP_BACK_LEFT
@ CHANNEL_OUT_TOP_FRONT_LEFT
@ CHANNEL_OUT_TOP_FRONT_RIGHT
@ CHANNEL_OUT_TOP_FRONT_CENTER
@ CHANNEL_OUT_FRONT_CENTER
@ CHANNEL_OUT_TOP_BACK_CENTER
@ CHANNEL_OUT_FRONT_RIGHT_OF_CENTER
@ CHANNEL_OUT_SIDE_RIGHT
@ CHANNEL_OUT_FRONT_RIGHT
@ CHANNEL_OUT_FRONT_LEFT
@ CHANNEL_OUT_SIDE_LEFT
@ CHANNEL_OUT_TOP_BACK_RIGHT
@ CHANNEL_OUT_BACK_CENTER
@ CHANNEL_OUT_TOP_CENTER
@ CHANNEL_OUT_BACK_LEFT
@ CHANNEL_OUT_BACK_RIGHT
@ CHANNEL_OUT_FRONT_LEFT_OF_CENTER
int ff_mediacodec_dec_is_flushing(AVCodecContext *avctx, MediaCodecDecContext *s)
enum AVSampleFormat sample_format
int color_format
static enum AVSampleFormat mcdec_map_pcm_format(AVCodecContext *avctx, MediaCodecDecContext *s, int pcm_format)
static uint64_t mcdec_map_channel_mask(AVCodecContext *avctx, int channel_mask)
static void ff_mediacodec_dec_unref(MediaCodecDecContext *s)
static int mediacodec_dec_get_audio_codec(AVCodecContext *avctx, MediaCodecDecContext *s, const char *mime, FFAMediaFormat *format)
static int mediacodec_dec_parse_video_format(AVCodecContext *avctx, MediaCodecDecContext *s)
#define AMEDIAFORMAT_GET_INT32(name, key, mandatory)
static enum AVPixelFormat mcdec_map_color_format(AVCodecContext *avctx, MediaCodecDecContext *s, int color_format)
static void mediacodec_buffer_release(void *opaque, uint8_t *data)
Memory handling functions.
const char data[16]
Definition mxf.c:149
int profile
Definition mxfenc.c:2299
#define av_strdup(s)
Definition ops_static.c:55
pixel format definitions
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_MEDIACODEC
hardware decoding through MediaCodec
Definition pixfmt.h:316
#define FF_ARRAY_ELEMS(a)
uint8_t * data
The data buffer.
Definition buffer.h:90
int nb_channels
Number of channels in this layout.
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition avcodec.h:1502
int width
picture width / height.
Definition avcodec.h:604
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition avcodec.h:554
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
enum AVMediaType codec_type
Definition avcodec.h:451
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition avcodec.h:628
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
int sample_rate
samples per second
Definition avcodec.h:1040
void * hwaccel_context
Legacy hardware accelerator context.
Definition avcodec.h:1447
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition avcodec.h:664
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition avcodec.h:1493
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition hwcontext.h:75
This structure holds a reference to a android/view/Surface object that will be used as output by the ...
Definition mediacodec.h:33
void * surface
android/view/Surface object reference.
Definition mediacodec.h:38
void * native_window
Pointer to ANativeWindow.
void * surface
android/view/Surface handle, to be filled by the user.
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
static char buffer[20]
Definition seek.c:32
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
timestamp utils, mostly useful for debugging/logging purposes
static int64_t pts
int size
color_range
#define atomic_fetch_sub(object, operand)
Definition stdatomic.h:140
#define atomic_fetch_add(object, operand)
Definition stdatomic.h:137