History

avcodec: add Mediacodec audio decoders support

Matthieu Bouron committed 2 years ago

Commit 0a780d31 parent 7d1dda46 files · +421 −31Browse files

Showing the changes to libavcodec (4 of 6 files). Show all

Unified · Split

4 files
  1. libavcodec/Makefile +4 −0
  2. libavcodec/allcodecs.c +4 −0
  3. libavcodec/mediacodecdec.c +99 −3
  4. libavcodec/mediacodecdec_common.c +305 −28
libavcodec/Makefile+4−0
@@ -197,6 +197,7 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ · 196 unmodified lines
197 aacenc_pred.o \197 aacenc_pred.o \
198 psymodel.o kbdwin.o \198 psymodel.o kbdwin.o \
199 mpeg4audio_sample_rates.o199 mpeg4audio_sample_rates.o
200OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o
200OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o201OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o
201OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o202OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
202OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o \203OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o \
@@ -223,6 +224,8 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \ · 20 unmodified lines
223 celp_math.o acelp_filters.o \224 celp_math.o acelp_filters.o \
224 acelp_vectors.o \225 acelp_vectors.o \
225 acelp_pitch_delay.o226 acelp_pitch_delay.o
227OBJS-$(CONFIG_AMRNB_MEDIACODEC_DECODER) += mediacodecdec.o
228OBJS-$(CONFIG_AMRWB_MEDIACODEC_DECODER) += mediacodecdec.o
226OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o229OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o
227OBJS-$(CONFIG_ANM_DECODER) += anm.o230OBJS-$(CONFIG_ANM_DECODER) += anm.o
228OBJS-$(CONFIG_ANULL_DECODER) += null.o231OBJS-$(CONFIG_ANULL_DECODER) += null.o
@@ -521,6 +524,7 @@ OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \ · 292 unmodified lines
521 mpegaudiotabs.o524 mpegaudiotabs.o
522OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o525OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
523OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o526OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
527OBJS-$(CONFIG_MP3_MEDIACODEC_DECODER) += mediacodecdec.o
524OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o528OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o
525OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o529OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
526OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o530OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
libavcodec/allcodecs.c+4−0
@@ -822,8 +822,11 @@ extern const FFCodec ff_idf_decoder; · 821 unmodified lines
822 822
823/* external libraries, that shouldn't be used by default if one of the823/* external libraries, that shouldn't be used by default if one of the
824 * above is available */824 * above is available */
825extern const FFCodec ff_aac_mediacodec_decoder;
825extern const FFCodec ff_aac_mf_encoder;826extern const FFCodec ff_aac_mf_encoder;
826extern const FFCodec ff_ac3_mf_encoder;827extern const FFCodec ff_ac3_mf_encoder;
828extern const FFCodec ff_amrnb_mediacodec_decoder;
829extern const FFCodec ff_amrwb_mediacodec_decoder;
827extern const FFCodec ff_h263_v4l2m2m_encoder;830extern const FFCodec ff_h263_v4l2m2m_encoder;
828extern const FFCodec ff_libaom_av1_decoder;831extern const FFCodec ff_libaom_av1_decoder;
829/* hwaccel hooks only, so prefer external decoders */832/* hwaccel hooks only, so prefer external decoders */
@@ -863,6 +866,7 @@ extern const FFCodec ff_mjpeg_cuvid_decoder; · 33 unmodified lines
863extern const FFCodec ff_mjpeg_qsv_encoder;866extern const FFCodec ff_mjpeg_qsv_encoder;
864extern const FFCodec ff_mjpeg_qsv_decoder;867extern const FFCodec ff_mjpeg_qsv_decoder;
865extern const FFCodec ff_mjpeg_vaapi_encoder;868extern const FFCodec ff_mjpeg_vaapi_encoder;
869extern const FFCodec ff_mp3_mediacodec_decoder;
866extern const FFCodec ff_mp3_mf_encoder;870extern const FFCodec ff_mp3_mf_encoder;
867extern const FFCodec ff_mpeg1_cuvid_decoder;871extern const FFCodec ff_mpeg1_cuvid_decoder;
868extern const FFCodec ff_mpeg2_cuvid_decoder;872extern const FFCodec ff_mpeg2_cuvid_decoder;
libavcodec/mediacodecdec.c+99−3
@@ -291,7 +291,11 @@ done: · 290 unmodified lines
291 CONFIG_MPEG4_MEDIACODEC_DECODER || \291 CONFIG_MPEG4_MEDIACODEC_DECODER || \
292 CONFIG_VP8_MEDIACODEC_DECODER || \292 CONFIG_VP8_MEDIACODEC_DECODER || \
293 CONFIG_VP9_MEDIACODEC_DECODER || \293 CONFIG_VP9_MEDIACODEC_DECODER || \
294 CONFIG_AV1_MEDIACODEC_DECODER294 CONFIG_AV1_MEDIACODEC_DECODER || \
295 CONFIG_AAC_MEDIACODEC_DECODER || \
296 CONFIG_AMRNB_MEDIACODEC_DECODER || \
297 CONFIG_AMRWB_MEDIACODEC_DECODER || \
298 CONFIG_MP3_MEDIACODEC_DECODER
295static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)299static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
296{300{
297 int ret = 0;301 int ret = 0;
@@ -388,13 +392,55 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx) · 90 unmodified lines
388 goto done;392 goto done;
389 break;393 break;
390#endif394#endif
395#if CONFIG_AAC_MEDIACODEC_DECODER
396 case AV_CODEC_ID_AAC:
397 codec_mime = "audio/mp4a-latm";
398
399 ret = common_set_extradata(avctx, format);
400 if (ret < 0)
401 goto done;
402 break;
403#endif
404#if CONFIG_AMRNB_MEDIACODEC_DECODER
405 case AV_CODEC_ID_AMR_NB:
406 codec_mime = "audio/3gpp";
407
408 ret = common_set_extradata(avctx, format);
409 if (ret < 0)
410 goto done;
411 break;
412#endif
413#if CONFIG_AMRWB_MEDIACODEC_DECODER
414 case AV_CODEC_ID_AMR_WB:
415 codec_mime = "audio/amr-wb";
416
417 ret = common_set_extradata(avctx, format);
418 if (ret < 0)
419 goto done;
420 break;
421#endif
422#if CONFIG_MP3_MEDIACODEC_DECODER
423 case AV_CODEC_ID_MP3:
424 codec_mime = "audio/mpeg";
425
426 ret = common_set_extradata(avctx, format);
427 if (ret < 0)
428 goto done;
429 break;
430#endif
391 default:431 default:
392 av_assert0(0);432 av_assert0(0);
393 }433 }
394 434
395 ff_AMediaFormat_setString(format, "mime", codec_mime);435 ff_AMediaFormat_setString(format, "mime", codec_mime);
396 ff_AMediaFormat_setInt32(format, "width", avctx->width);436
397 ff_AMediaFormat_setInt32(format, "height", avctx->height);437 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
438 ff_AMediaFormat_setInt32(format, "width", avctx->width);
439 ff_AMediaFormat_setInt32(format, "height", avctx->height);
440 } else {
441 ff_AMediaFormat_setInt32(format, "channel-count", avctx->ch_layout.nb_channels);
442 ff_AMediaFormat_setInt32(format, "sample-rate", avctx->sample_rate);
443 }
398 444
399 s->ctx = av_mallocz(sizeof(*s->ctx));445 s->ctx = av_mallocz(sizeof(*s->ctx));
400 if (!s->ctx) {446 if (!s->ctx) {
@@ -611,3 +657,53 @@ DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL) · 210 unmodified lines
611#if CONFIG_AV1_MEDIACODEC_DECODER657#if CONFIG_AV1_MEDIACODEC_DECODER
612DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL)658DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL)
613#endif659#endif
660
661#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
662static const AVOption ff_mediacodec_adec_options[] = {
663 { "ndk_codec", "Use MediaCodec from NDK",
664 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AD },
665 { NULL }
666};
667
668#define DECLARE_MEDIACODEC_ACLASS(short_name) \
669static const AVClass ff_##short_name##_mediacodec_dec_class = { \
670 .class_name = #short_name "_mediacodec", \
671 .item_name = av_default_item_name, \
672 .option = ff_mediacodec_adec_options, \
673 .version = LIBAVUTIL_VERSION_INT, \
674};
675
676#define DECLARE_MEDIACODEC_ADEC(short_name, full_name, codec_id, bsf) \
677DECLARE_MEDIACODEC_VCLASS(short_name) \
678const FFCodec ff_ ## short_name ## _mediacodec_decoder = { \
679 .p.name = #short_name "_mediacodec", \
680 CODEC_LONG_NAME(full_name " Android MediaCodec decoder"), \
681 .p.type = AVMEDIA_TYPE_AUDIO, \
682 .p.id = codec_id, \
683 .p.priv_class = &ff_##short_name##_mediacodec_dec_class, \
684 .priv_data_size = sizeof(MediaCodecH264DecContext), \
685 .init = mediacodec_decode_init, \
686 FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame), \
687 .flush = mediacodec_decode_flush, \
688 .close = mediacodec_decode_close, \
689 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
690 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
691 .bsfs = bsf, \
692 .p.wrapper_name = "mediacodec", \
693}; \
694
695#if CONFIG_AAC_MEDIACODEC_DECODER
696DECLARE_MEDIACODEC_ADEC(aac, "AAC", AV_CODEC_ID_AAC, "aac_adtstoasc")
697#endif
698
699#if CONFIG_AMRNB_MEDIACODEC_DECODER
700DECLARE_MEDIACODEC_ADEC(amrnb, "AMR-NB", AV_CODEC_ID_AMR_NB, NULL)
701#endif
702
703#if CONFIG_AMRWB_MEDIACODEC_DECODER
704DECLARE_MEDIACODEC_ADEC(amrwb, "AMR-WB", AV_CODEC_ID_AMR_WB, NULL)
705#endif
706
707#if CONFIG_MP3_MEDIACODEC_DECODER
708DECLARE_MEDIACODEC_ADEC(mp3, "MP3", AV_CODEC_ID_MP3, NULL)
709#endif
libavcodec/mediacodecdec_common.c+305−28
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include <string.h>23#include <string.h>
24#include <sys/types.h>24#include <sys/types.h>
25 25
26#include "libavutil/avassert.h"
26#include "libavutil/common.h"27#include "libavutil/common.h"
27#include "libavutil/hwcontext_mediacodec.h"28#include "libavutil/hwcontext_mediacodec.h"
28#include "libavutil/mem.h"29#include "libavutil/mem.h"
@@ -30,6 +31,7 @@ · 1 unmodified line
30#include "libavutil/pixfmt.h"31#include "libavutil/pixfmt.h"
31#include "libavutil/time.h"32#include "libavutil/time.h"
32#include "libavutil/timestamp.h"33#include "libavutil/timestamp.h"
34#include "libavutil/channel_layout.h"
33 35
34#include "avcodec.h"36#include "avcodec.h"
35#include "decode.h"37#include "decode.h"
@@ -85,6 +87,107 @@ · 49 unmodified lines
85#define OUTPUT_DEQUEUE_TIMEOUT_US 800087#define OUTPUT_DEQUEUE_TIMEOUT_US 8000
86#define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US 100000088#define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US 1000000
87 89
90enum {
91 ENCODING_PCM_16BIT = 0x00000002,
92 ENCODING_PCM_8BIT = 0x00000003,
93 ENCODING_PCM_FLOAT = 0x00000004,
94 ENCODING_PCM_24BIT_PACKED = 0x00000015,
95 ENCODING_PCM_32BIT = 0x00000016,
96};
97
98static const struct {
99
100 int pcm_format;
101 enum AVSampleFormat sample_format;
102
103} sample_formats[] = {
104
105 { ENCODING_PCM_16BIT, AV_SAMPLE_FMT_S16 },
106 { ENCODING_PCM_8BIT, AV_SAMPLE_FMT_U8 },
107 { ENCODING_PCM_FLOAT, AV_SAMPLE_FMT_FLT },
108 { ENCODING_PCM_32BIT, AV_SAMPLE_FMT_S32 },
109 { 0 }
110};
111
112static enum AVSampleFormat mcdec_map_pcm_format(AVCodecContext *avctx,
113 MediaCodecDecContext *s,
114 int pcm_format)
115{
116 enum AVSampleFormat ret = AV_SAMPLE_FMT_NONE;
117
118 for (int i = 0; i < FF_ARRAY_ELEMS(sample_formats); i++) {
119 if (sample_formats[i].pcm_format == pcm_format) {
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",
125 pcm_format, pcm_format);
126
127 return ret;
128}
129
130enum
131{
132 CHANNEL_OUT_FRONT_LEFT = 0x4,
133 CHANNEL_OUT_FRONT_RIGHT = 0x8,
134 CHANNEL_OUT_FRONT_CENTER = 0x10,
135 CHANNEL_OUT_LOW_FREQUENCY = 0x20,
136 CHANNEL_OUT_BACK_LEFT = 0x40,
137 CHANNEL_OUT_BACK_RIGHT = 0x80,
138 CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100,
139 CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200,
140 CHANNEL_OUT_BACK_CENTER = 0x400,
141 CHANNEL_OUT_SIDE_LEFT = 0x800,
142 CHANNEL_OUT_SIDE_RIGHT = 0x1000,
143 CHANNEL_OUT_TOP_CENTER = 0x2000,
144 CHANNEL_OUT_TOP_FRONT_LEFT = 0x4000,
145 CHANNEL_OUT_TOP_FRONT_CENTER = 0x8000,
146 CHANNEL_OUT_TOP_FRONT_RIGHT = 0x10000,
147 CHANNEL_OUT_TOP_BACK_LEFT = 0x20000,
148 CHANNEL_OUT_TOP_BACK_CENTER = 0x40000,
149 CHANNEL_OUT_TOP_BACK_RIGHT = 0x80000,
150};
151
152static const struct {
153
154 int mask;
155 uint64_t layout;
156
157} channel_masks[] = {
158 { CHANNEL_OUT_FRONT_LEFT, AV_CH_FRONT_LEFT },
159 { CHANNEL_OUT_FRONT_RIGHT, AV_CH_FRONT_RIGHT },
160 { CHANNEL_OUT_FRONT_CENTER, AV_CH_FRONT_CENTER },
161 { CHANNEL_OUT_LOW_FREQUENCY, AV_CH_LOW_FREQUENCY },
162 { CHANNEL_OUT_BACK_LEFT, AV_CH_BACK_LEFT },
163 { CHANNEL_OUT_BACK_RIGHT, AV_CH_BACK_RIGHT },
164 { CHANNEL_OUT_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_LEFT_OF_CENTER },
165 { CHANNEL_OUT_FRONT_RIGHT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER },
166 { CHANNEL_OUT_BACK_CENTER, AV_CH_BACK_CENTER },
167 { CHANNEL_OUT_SIDE_LEFT, AV_CH_SIDE_LEFT },
168 { CHANNEL_OUT_SIDE_RIGHT, AV_CH_SIDE_RIGHT },
169 { CHANNEL_OUT_TOP_CENTER, AV_CH_TOP_CENTER },
170 { CHANNEL_OUT_TOP_FRONT_LEFT, AV_CH_TOP_FRONT_LEFT },
171 { CHANNEL_OUT_TOP_FRONT_CENTER, AV_CH_TOP_FRONT_CENTER },
172 { CHANNEL_OUT_TOP_FRONT_RIGHT, AV_CH_TOP_FRONT_RIGHT },
173 { CHANNEL_OUT_TOP_BACK_LEFT, AV_CH_TOP_BACK_LEFT },
174 { CHANNEL_OUT_TOP_BACK_CENTER, AV_CH_TOP_BACK_CENTER },
175 { CHANNEL_OUT_TOP_BACK_RIGHT, AV_CH_TOP_BACK_RIGHT },
176};
177
178static uint64_t mcdec_map_channel_mask(AVCodecContext *avctx,
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
88enum {191enum {
89 COLOR_FormatYUV420Planar = 0x13,192 COLOR_FormatYUV420Planar = 0x13,
90 COLOR_FormatYUV420SemiPlanar = 0x15,193 COLOR_FormatYUV420SemiPlanar = 0x15,
@@ -265,13 +368,79 @@ fail: · 174 unmodified lines
265 return ret;368 return ret;
266}369}
267 370
268static int mediacodec_wrap_sw_buffer(AVCodecContext *avctx,371static int mediacodec_wrap_sw_audio_buffer(AVCodecContext *avctx,
269 MediaCodecDecContext *s,372 MediaCodecDecContext *s,
270 uint8_t *data,373 uint8_t *data,
271 size_t size,374 size_t size,
272 ssize_t index,375 ssize_t index,
273 FFAMediaCodecBufferInfo *info,376 FFAMediaCodecBufferInfo *info,
274 AVFrame *frame)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 frame->format = avctx->sample_fmt;
389 frame->sample_rate = avctx->sample_rate;
390 frame->nb_samples = info->size / (sample_size * avctx->ch_layout.nb_channels);
391
392 ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout);
393 if (ret < 0) {
394 av_log(avctx, AV_LOG_ERROR, "Could not copy channel layout\n");
395 goto done;
396 }
397
398 /* MediaCodec buffers needs to be copied to our own refcounted buffers
399 * because the flush command invalidates all input and output buffers.
400 */
401 ret = ff_get_buffer(avctx, frame, 0);
402 if (ret < 0) {
403 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer\n");
404 goto done;
405 }
406
407 /* Override frame->pts as ff_get_buffer will override its value based
408 * on the last avpacket received which is not in sync with the frame:
409 * * N avpackets can be pushed before 1 frame is actually returned
410 * * 0-sized avpackets are pushed to flush remaining frames at EOS */
411 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den) {
412 frame->pts = av_rescale_q(info->presentationTimeUs,
413 AV_TIME_BASE_Q,
414 avctx->pkt_timebase);
415 } else {
416 frame->pts = info->presentationTimeUs;
417 }
418 frame->pkt_dts = AV_NOPTS_VALUE;
419
420 av_log(avctx, AV_LOG_TRACE,
421 "Frame: format=%d channels=%d sample_rate=%d nb_samples=%d",
422 avctx->sample_fmt, avctx->ch_layout.nb_channels, avctx->sample_rate, frame->nb_samples);
423
424 memcpy(frame->data[0], data, info->size);
425
426 ret = 0;
427done:
428 status = ff_AMediaCodec_releaseOutputBuffer(s->codec, index, 0);
429 if (status < 0) {
430 av_log(avctx, AV_LOG_ERROR, "Failed to release output buffer\n");
431 ret = AVERROR_EXTERNAL;
432 }
433
434 return ret;
435}
436
437static int mediacodec_wrap_sw_video_buffer(AVCodecContext *avctx,
438 MediaCodecDecContext *s,
439 uint8_t *data,
440 size_t size,
441 ssize_t index,
442 FFAMediaCodecBufferInfo *info,
443 AVFrame *frame)
275{444{
276 int ret = 0;445 int ret = 0;
277 int status = 0;446 int status = 0;
@@ -343,6 +512,22 @@ done: · 65 unmodified lines
343 return ret;512 return ret;
344}513}
345 514
515static int mediacodec_wrap_sw_buffer(AVCodecContext *avctx,
516 MediaCodecDecContext *s,
517 uint8_t *data,
518 size_t size,
519 ssize_t index,
520 FFAMediaCodecBufferInfo *info,
521 AVFrame *frame)
522{
523 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO)
524 return mediacodec_wrap_sw_audio_buffer(avctx, s, data, size, index, info, frame);
525 else if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
526 return mediacodec_wrap_sw_video_buffer(avctx, s, data, size, index, info, frame);
527 else
528 av_assert0(0);
529}
530
346#define AMEDIAFORMAT_GET_INT32(name, key, mandatory) do { \531#define AMEDIAFORMAT_GET_INT32(name, key, mandatory) do { \
347 int32_t value = 0; \532 int32_t value = 0; \
348 if (ff_AMediaFormat_getInt32(s->format, key, &value)) { \533 if (ff_AMediaFormat_getInt32(s->format, key, &value)) { \
@@ -354,7 +539,7 @@ done: · 5 unmodified lines
354 } \539 } \
355} while (0) \540} while (0) \
356 541
357static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s)542static int mediacodec_dec_parse_video_format(AVCodecContext *avctx, MediaCodecDecContext *s)
358{543{
359 int ret = 0;544 int ret = 0;
360 int width = 0;545 int width = 0;
@@ -463,6 +648,63 @@ fail: · 102 unmodified lines
463 return ret;648 return ret;
464}649}
465 650
651static int mediacodec_dec_parse_audio_format(AVCodecContext *avctx, MediaCodecDecContext *s)
652{
653 int ret = 0;
654 int sample_rate = 0;
655 int channel_count = 0;
656 int channel_mask = 0;
657 int pcm_encoding = 0;
658 char *format = NULL;
659
660 if (!s->format) {
661 av_log(avctx, AV_LOG_ERROR, "Output MediaFormat is not set\n");
662 return AVERROR(EINVAL);
663 }
664
665 format = ff_AMediaFormat_toString(s->format);
666 if (!format) {
667 return AVERROR_EXTERNAL;
668 }
669 av_log(avctx, AV_LOG_DEBUG, "Parsing MediaFormat %s\n", format);
670
671 /* Mandatory fields */
672 AMEDIAFORMAT_GET_INT32(channel_count, "channel-count", 1);
673 AMEDIAFORMAT_GET_INT32(sample_rate, "sample-rate", 1);
674
675 AMEDIAFORMAT_GET_INT32(pcm_encoding, "pcm-encoding", 0);
676 if (pcm_encoding)
677 avctx->sample_fmt = mcdec_map_pcm_format(avctx, s, pcm_encoding);
678 else
679 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
680
681 avctx->sample_rate = sample_rate;
682
683 AMEDIAFORMAT_GET_INT32(channel_mask, "channel-mask", 0);
684 if (channel_mask)
685 av_channel_layout_from_mask(&avctx->ch_layout, mcdec_map_channel_mask(avctx, channel_mask));
686 else
687 av_channel_layout_default(&avctx->ch_layout, channel_count);
688
689 av_log(avctx, AV_LOG_INFO,
690 "Output parameters channel-count=%d channel-layout=%x sample-rate=%d\n",
691 channel_count, channel_mask, sample_rate);
692
693fail:
694 av_freep(&format);
695 return ret;
696}
697
698static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s)
699{
700 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO)
701 return mediacodec_dec_parse_audio_format(avctx, s);
702 else if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
703 return mediacodec_dec_parse_video_format(avctx, s);
704 else
705 av_assert0(0);
706}
707
466static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s)708static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s)
467{709{
468 FFAMediaCodec *codec = s->codec;710 FFAMediaCodec *codec = s->codec;
@@ -486,11 +728,9 @@ static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContex · 17 unmodified lines
486 return 0;728 return 0;
487}729}
488 730
489int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s,731static int mediacodec_dec_get_video_codec(AVCodecContext *avctx, MediaCodecDecContext *s,
490 const char *mime, FFAMediaFormat *format)732 const char *mime, FFAMediaFormat *format)
491{733{
492 int ret = 0;
493 int status;
494 int profile;734 int profile;
495 735
496 enum AVPixelFormat pix_fmt;736 enum AVPixelFormat pix_fmt;
@@ -499,12 +739,6 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 2 unmodified lines
499 AV_PIX_FMT_NONE,739 AV_PIX_FMT_NONE,
500 };740 };
501 741
502 s->avctx = avctx;
503 atomic_init(&s->refcount, 1);
504 atomic_init(&s->hw_buffer_count, 0);
505 atomic_init(&s->serial, 1);
506 s->current_input_buffer = -1;
507
508 pix_fmt = ff_get_format(avctx, pix_fmts);742 pix_fmt = ff_get_format(avctx, pix_fmts);
509 if (pix_fmt == AV_PIX_FMT_MEDIACODEC) {743 if (pix_fmt == AV_PIX_FMT_MEDIACODEC) {
510 AVMediaCodecContext *user_ctx = avctx->hwaccel_context;744 AVMediaCodecContext *user_ctx = avctx->hwaccel_context;
@@ -536,8 +770,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 25 unmodified lines
536 // getCodecNameByType() can fail due to missing JVM, while NDK770 // getCodecNameByType() can fail due to missing JVM, while NDK
537 // mediacodec can be used without JVM.771 // mediacodec can be used without JVM.
538 if (!s->use_ndk_codec) {772 if (!s->use_ndk_codec) {
539 ret = AVERROR_EXTERNAL;773 return AVERROR_EXTERNAL;
540 goto fail;
541 }774 }
542 av_log(avctx, AV_LOG_INFO, "Failed to getCodecNameByType\n");775 av_log(avctx, AV_LOG_INFO, "Failed to getCodecNameByType\n");
543 } else {776 } else {
@@ -556,10 +789,52 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 12 unmodified lines
556 }789 }
557 if (!s->codec) {790 if (!s->codec) {
558 av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for type %s and name %s\n", mime, s->codec_name);791 av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for type %s and name %s\n", mime, s->codec_name);
559 ret = AVERROR_EXTERNAL;792 return AVERROR_EXTERNAL;
560 goto fail;793 }
794
795 return 0;
796}
797
798static int mediacodec_dec_get_audio_codec(AVCodecContext *avctx, MediaCodecDecContext *s,
799 const char *mime, FFAMediaFormat *format)
800{
801 s->codec = ff_AMediaCodec_createDecoderByType(mime, s->use_ndk_codec);
802 if (!s->codec) {
803 av_log(avctx, AV_LOG_ERROR, "Failed to create media decoder for mime %s\n", mime);
804 return AVERROR_EXTERNAL;
805 }
806
807 s->codec_name = ff_AMediaCodec_getName(s->codec);
808 if (!s->codec_name) {
809 s->codec_name = av_strdup(mime);
810 if (!s->codec_name)
811 return AVERROR(ENOMEM);
561 }812 }
562 813
814 return 0;
815}
816
817int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s,
818 const char *mime, FFAMediaFormat *format)
819{
820 int ret;
821 int status;
822
823 s->avctx = avctx;
824 atomic_init(&s->refcount, 1);
825 atomic_init(&s->hw_buffer_count, 0);
826 atomic_init(&s->serial, 1);
827 s->current_input_buffer = -1;
828
829 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO)
830 ret = mediacodec_dec_get_audio_codec(avctx, s, mime, format);
831 else if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
832 ret = mediacodec_dec_get_video_codec(avctx, s, mime, format);
833 else
834 av_assert0(0);
835 if (ret < 0)
836 goto fail;
837
563 status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0);838 status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0);
564 if (status < 0) {839 if (status < 0) {
565 char *desc = ff_AMediaFormat_toString(format);840 char *desc = ff_AMediaFormat_toString(format);
@@ -583,12 +858,14 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 17 unmodified lines
583 goto fail;858 goto fail;
584 }859 }
585 860
586 s->format = ff_AMediaCodec_getOutputFormat(s->codec);861 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
587 if (s->format) {862 s->format = ff_AMediaCodec_getOutputFormat(s->codec);
588 if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) {863 if (s->format) {
589 av_log(avctx, AV_LOG_ERROR,864 if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) {
590 "Failed to configure context\n");865 av_log(avctx, AV_LOG_ERROR,
591 goto fail;866 "Failed to configure context\n");
867 goto fail;
868 }
592 }869 }
593 }870 }
594 871

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t