History

avcodec: add Mediacodec audio decoders support

Matthieu Bouron committed 2 years ago

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

Unified · Split

6 files
  1. Changelog +1 −0
  2. configure +8 −0
  3. libavcodec/Makefile +4 −0
  4. libavcodec/allcodecs.c +4 −0
  5. libavcodec/mediacodecdec.c +99 −3
  6. libavcodec/mediacodecdec_common.c +305 −28
Changelog+1−0
@@ -18,6 +18,7 @@ version <next>: · 17 unmodified lines
1818 - D3D12VA HEVC encoder
1919 - Cropping metadata parsing and writing in Matroska and MP4/MOV de/muxers
2020 - Intel QSV-accelerated VVC decoding
21+- MediaCodec AAC/AMR-NB/AMR-WB/MP3 decoding
2122
2223
2324 version 7.0:
configure+8−0
@@ -3324,8 +3324,14 @@ amf_deps_any="libdl LoadLibrary" · 3323 unmodified lines
33243324 nvenc_deps="ffnvcodec"
33253325 nvenc_deps_any="libdl LoadLibrary"
33263326
3327+aac_mediacodec_decoder_deps="mediacodec"
3328+aac_mediacodec_decoder_select="aac_adtstoasc_bsf aac_parser"
33273329 aac_mf_encoder_deps="mediafoundation"
33283330 ac3_mf_encoder_deps="mediafoundation"
3331+amrnb_mediacodec_decoder_deps="mediacodec"
3332+amrnb_mediacodec_decoder_select="amr_parser"
3333+amrwb_mediacodec_decoder_deps="mediacodec"
3334+amrwb_mediacodec_decoder_select="amr_parser"
33293335 av1_amf_encoder_deps="amf"
33303336 av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS"
33313337 av1_mediacodec_decoder_deps="mediacodec"
@@ -3387,6 +3393,8 @@ mjpeg_qsv_encoder_select="qsvenc" · 55 unmodified lines
33873393 mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
33883394 mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode"
33893395 mp3_mf_encoder_deps="mediafoundation"
3396+mp3_mediacodec_decoder_deps="mediacodec"
3397+mp3_mediacodec_decoder_select="mpegaudioheader"
33903398 mpeg1_cuvid_decoder_deps="cuvid"
33913399 mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m"
33923400 mpeg2_cuvid_decoder_deps="cuvid"
libavcodec/Makefile+4−0
@@ -197,6 +197,7 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \ · 196 unmodified lines
197197 aacenc_pred.o \
198198 psymodel.o kbdwin.o \
199199 mpeg4audio_sample_rates.o
200+OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o
200201 OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o
201202 OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
202203 OBJS-$(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
223224 celp_math.o acelp_filters.o \
224225 acelp_vectors.o \
225226 acelp_pitch_delay.o
227+OBJS-$(CONFIG_AMRNB_MEDIACODEC_DECODER) += mediacodecdec.o
228+OBJS-$(CONFIG_AMRWB_MEDIACODEC_DECODER) += mediacodecdec.o
226229 OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o
227230 OBJS-$(CONFIG_ANM_DECODER) += anm.o
228231 OBJS-$(CONFIG_ANULL_DECODER) += null.o
@@ -521,6 +524,7 @@ OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \ · 292 unmodified lines
521524 mpegaudiotabs.o
522525 OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
523526 OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
527+OBJS-$(CONFIG_MP3_MEDIACODEC_DECODER) += mediacodecdec.o
524528 OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o
525529 OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
526530 OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
libavcodec/allcodecs.c+4−0
@@ -822,8 +822,11 @@ extern const FFCodec ff_idf_decoder; · 821 unmodified lines
822822
823823 /* external libraries, that shouldn't be used by default if one of the
824824 * above is available */
825+extern const FFCodec ff_aac_mediacodec_decoder;
825826 extern const FFCodec ff_aac_mf_encoder;
826827 extern const FFCodec ff_ac3_mf_encoder;
828+extern const FFCodec ff_amrnb_mediacodec_decoder;
829+extern const FFCodec ff_amrwb_mediacodec_decoder;
827830 extern const FFCodec ff_h263_v4l2m2m_encoder;
828831 extern const FFCodec ff_libaom_av1_decoder;
829832 /* hwaccel hooks only, so prefer external decoders */
@@ -863,6 +866,7 @@ extern const FFCodec ff_mjpeg_cuvid_decoder; · 33 unmodified lines
863866 extern const FFCodec ff_mjpeg_qsv_encoder;
864867 extern const FFCodec ff_mjpeg_qsv_decoder;
865868 extern const FFCodec ff_mjpeg_vaapi_encoder;
869+extern const FFCodec ff_mp3_mediacodec_decoder;
866870 extern const FFCodec ff_mp3_mf_encoder;
867871 extern const FFCodec ff_mpeg1_cuvid_decoder;
868872 extern const FFCodec ff_mpeg2_cuvid_decoder;
libavcodec/mediacodecdec.c+99−3
@@ -291,7 +291,11 @@ done: · 290 unmodified lines
291291 CONFIG_MPEG4_MEDIACODEC_DECODER || \
292292 CONFIG_VP8_MEDIACODEC_DECODER || \
293293 CONFIG_VP9_MEDIACODEC_DECODER || \
294− CONFIG_AV1_MEDIACODEC_DECODER
294+ CONFIG_AV1_MEDIACODEC_DECODER || \
295+ CONFIG_AAC_MEDIACODEC_DECODER || \
296+ CONFIG_AMRNB_MEDIACODEC_DECODER || \
297+ CONFIG_AMRWB_MEDIACODEC_DECODER || \
298+ CONFIG_MP3_MEDIACODEC_DECODER
295299 static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
296300 {
297301 int ret = 0;
@@ -388,13 +392,55 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx) · 90 unmodified lines
388392 goto done;
389393 break;
390394 #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
391431 default:
392432 av_assert0(0);
393433 }
394434
395435 ff_AMediaFormat_setString(format, "mime", codec_mime);
396− ff_AMediaFormat_setInt32(format, "width", avctx->width);
397− ff_AMediaFormat_setInt32(format, "height", avctx->height);
436+
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+ }
398444
399445 s->ctx = av_mallocz(sizeof(*s->ctx));
400446 if (!s->ctx) {
@@ -611,3 +657,53 @@ DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL) · 210 unmodified lines
611657 #if CONFIG_AV1_MEDIACODEC_DECODER
612658 DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL)
613659 #endif
660+
661+#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
662+static 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) \
669+static 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) \
677+DECLARE_MEDIACODEC_VCLASS(short_name) \
678+const 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
696+DECLARE_MEDIACODEC_ADEC(aac, "AAC", AV_CODEC_ID_AAC, "aac_adtstoasc")
697+#endif
698+
699+#if CONFIG_AMRNB_MEDIACODEC_DECODER
700+DECLARE_MEDIACODEC_ADEC(amrnb, "AMR-NB", AV_CODEC_ID_AMR_NB, NULL)
701+#endif
702+
703+#if CONFIG_AMRWB_MEDIACODEC_DECODER
704+DECLARE_MEDIACODEC_ADEC(amrwb, "AMR-WB", AV_CODEC_ID_AMR_WB, NULL)
705+#endif
706+
707+#if CONFIG_MP3_MEDIACODEC_DECODER
708+DECLARE_MEDIACODEC_ADEC(mp3, "MP3", AV_CODEC_ID_MP3, NULL)
709+#endif
libavcodec/mediacodecdec_common.c+305−28
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #include <string.h>
2424 #include <sys/types.h>
2525
26+#include "libavutil/avassert.h"
2627 #include "libavutil/common.h"
2728 #include "libavutil/hwcontext_mediacodec.h"
2829 #include "libavutil/mem.h"
@@ -30,6 +31,7 @@ · 1 unmodified line
3031 #include "libavutil/pixfmt.h"
3132 #include "libavutil/time.h"
3233 #include "libavutil/timestamp.h"
34+#include "libavutil/channel_layout.h"
3335
3436 #include "avcodec.h"
3537 #include "decode.h"
@@ -85,6 +87,107 @@ · 49 unmodified lines
8587 #define OUTPUT_DEQUEUE_TIMEOUT_US 8000
8688 #define OUTPUT_DEQUEUE_BLOCK_TIMEOUT_US 1000000
8789
90+enum {
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+
98+static 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+
112+static 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+
130+enum
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+
152+static 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+
178+static 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+
88191 enum {
89192 COLOR_FormatYUV420Planar = 0x13,
90193 COLOR_FormatYUV420SemiPlanar = 0x15,
@@ -265,13 +368,79 @@ fail: · 174 unmodified lines
265368 return ret;
266369 }
267370
268−static int mediacodec_wrap_sw_buffer(AVCodecContext *avctx,
269− MediaCodecDecContext *s,
270− uint8_t *data,
271− size_t size,
272− ssize_t index,
273− FFAMediaCodecBufferInfo *info,
274− AVFrame *frame)
371+static int mediacodec_wrap_sw_audio_buffer(AVCodecContext *avctx,
372+ MediaCodecDecContext *s,
373+ uint8_t *data,
374+ size_t size,
375+ ssize_t index,
376+ FFAMediaCodecBufferInfo *info,
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;
427+done:
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+
437+static 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)
275444 {
276445 int ret = 0;
277446 int status = 0;
@@ -343,6 +512,22 @@ done: · 65 unmodified lines
343512 return ret;
344513 }
345514
515+static 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+
346531 #define AMEDIAFORMAT_GET_INT32(name, key, mandatory) do { \
347532 int32_t value = 0; \
348533 if (ff_AMediaFormat_getInt32(s->format, key, &value)) { \
@@ -354,7 +539,7 @@ done: · 5 unmodified lines
354539 } \
355540 } while (0) \
356541
357−static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecContext *s)
542+static int mediacodec_dec_parse_video_format(AVCodecContext *avctx, MediaCodecDecContext *s)
358543 {
359544 int ret = 0;
360545 int width = 0;
@@ -463,6 +648,63 @@ fail: · 102 unmodified lines
463648 return ret;
464649 }
465650
651+static 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+
693+fail:
694+ av_freep(&format);
695+ return ret;
696+}
697+
698+static 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+
466708 static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContext *s)
467709 {
468710 FFAMediaCodec *codec = s->codec;
@@ -486,11 +728,9 @@ static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContex · 17 unmodified lines
486728 return 0;
487729 }
488730
489−int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s,
490− const char *mime, FFAMediaFormat *format)
731+static int mediacodec_dec_get_video_codec(AVCodecContext *avctx, MediaCodecDecContext *s,
732+ const char *mime, FFAMediaFormat *format)
491733 {
492− int ret = 0;
493− int status;
494734 int profile;
495735
496736 enum AVPixelFormat pix_fmt;
@@ -499,12 +739,6 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 2 unmodified lines
499739 AV_PIX_FMT_NONE,
500740 };
501741
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−
508742 pix_fmt = ff_get_format(avctx, pix_fmts);
509743 if (pix_fmt == AV_PIX_FMT_MEDIACODEC) {
510744 AVMediaCodecContext *user_ctx = avctx->hwaccel_context;
@@ -536,8 +770,7 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 25 unmodified lines
536770 // getCodecNameByType() can fail due to missing JVM, while NDK
537771 // mediacodec can be used without JVM.
538772 if (!s->use_ndk_codec) {
539− ret = AVERROR_EXTERNAL;
540− goto fail;
773+ return AVERROR_EXTERNAL;
541774 }
542775 av_log(avctx, AV_LOG_INFO, "Failed to getCodecNameByType\n");
543776 } else {
@@ -556,10 +789,52 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 12 unmodified lines
556789 }
557790 if (!s->codec) {
558791 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;
560− goto fail;
792+ return AVERROR_EXTERNAL;
793+ }
794+
795+ return 0;
796+}
797+
798+static 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);
561812 }
562813
814+ return 0;
815+}
816+
817+int 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+
563838 status = ff_AMediaCodec_configure(s->codec, format, s->surface, NULL, 0);
564839 if (status < 0) {
565840 char *desc = ff_AMediaFormat_toString(format);
@@ -583,12 +858,14 @@ int ff_mediacodec_dec_init(AVCodecContext *avctx, MediaCodecDecContext *s, · 17 unmodified lines
583858 goto fail;
584859 }
585860
586− s->format = ff_AMediaCodec_getOutputFormat(s->codec);
587− if (s->format) {
588− if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) {
589− av_log(avctx, AV_LOG_ERROR,
590− "Failed to configure context\n");
591− goto fail;
861+ if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
862+ s->format = ff_AMediaCodec_getOutputFormat(s->codec);
863+ if (s->format) {
864+ if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) {
865+ av_log(avctx, AV_LOG_ERROR,
866+ "Failed to configure context\n");
867+ goto fail;
868+ }
592869 }
593870 }
594871

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