Skip to content

Commit

Permalink
avcodec: add Mediacodec audio decoders support
Browse files Browse the repository at this point in the history
Signed-off-by: Matthieu Bouron <matthieu.bouron@gmail.com>
  • Loading branch information
mbouron committed Sep 1, 2024
1 parent 7d1dda4 commit 0a780d3
Show file tree
Hide file tree
Showing 6 changed files with 421 additions and 31 deletions.
1 change: 1 addition & 0 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ version <next>:
- D3D12VA HEVC encoder
- Cropping metadata parsing and writing in Matroska and MP4/MOV de/muxers
- Intel QSV-accelerated VVC decoding
- MediaCodec AAC/AMR-NB/AMR-WB/MP3 decoding


version 7.0:
Expand Down
8 changes: 8 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -3324,8 +3324,14 @@ amf_deps_any="libdl LoadLibrary"
nvenc_deps="ffnvcodec"
nvenc_deps_any="libdl LoadLibrary"

aac_mediacodec_decoder_deps="mediacodec"
aac_mediacodec_decoder_select="aac_adtstoasc_bsf aac_parser"
aac_mf_encoder_deps="mediafoundation"
ac3_mf_encoder_deps="mediafoundation"
amrnb_mediacodec_decoder_deps="mediacodec"
amrnb_mediacodec_decoder_select="amr_parser"
amrwb_mediacodec_decoder_deps="mediacodec"
amrwb_mediacodec_decoder_select="amr_parser"
av1_amf_encoder_deps="amf"
av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS"
av1_mediacodec_decoder_deps="mediacodec"
Expand Down Expand Up @@ -3387,6 +3393,8 @@ mjpeg_qsv_encoder_select="qsvenc"
mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode"
mp3_mf_encoder_deps="mediafoundation"
mp3_mediacodec_decoder_deps="mediacodec"
mp3_mediacodec_decoder_select="mpegaudioheader"
mpeg1_cuvid_decoder_deps="cuvid"
mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m"
mpeg2_cuvid_decoder_deps="cuvid"
Expand Down
4 changes: 4 additions & 0 deletions libavcodec/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \
aacenc_pred.o \
psymodel.o kbdwin.o \
mpeg4audio_sample_rates.o
OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o \
Expand All @@ -223,6 +224,8 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \
celp_math.o acelp_filters.o \
acelp_vectors.o \
acelp_pitch_delay.o
OBJS-$(CONFIG_AMRNB_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_AMRWB_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o
OBJS-$(CONFIG_ANM_DECODER) += anm.o
OBJS-$(CONFIG_ANULL_DECODER) += null.o
Expand Down Expand Up @@ -521,6 +524,7 @@ OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
mpegaudiotabs.o
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
OBJS-$(CONFIG_MP3_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o
OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
Expand Down
4 changes: 4 additions & 0 deletions libavcodec/allcodecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,8 +822,11 @@ extern const FFCodec ff_idf_decoder;

/* external libraries, that shouldn't be used by default if one of the
* above is available */
extern const FFCodec ff_aac_mediacodec_decoder;
extern const FFCodec ff_aac_mf_encoder;
extern const FFCodec ff_ac3_mf_encoder;
extern const FFCodec ff_amrnb_mediacodec_decoder;
extern const FFCodec ff_amrwb_mediacodec_decoder;
extern const FFCodec ff_h263_v4l2m2m_encoder;
extern const FFCodec ff_libaom_av1_decoder;
/* hwaccel hooks only, so prefer external decoders */
Expand Down Expand Up @@ -863,6 +866,7 @@ extern const FFCodec ff_mjpeg_cuvid_decoder;
extern const FFCodec ff_mjpeg_qsv_encoder;
extern const FFCodec ff_mjpeg_qsv_decoder;
extern const FFCodec ff_mjpeg_vaapi_encoder;
extern const FFCodec ff_mp3_mediacodec_decoder;
extern const FFCodec ff_mp3_mf_encoder;
extern const FFCodec ff_mpeg1_cuvid_decoder;
extern const FFCodec ff_mpeg2_cuvid_decoder;
Expand Down
102 changes: 99 additions & 3 deletions libavcodec/mediacodecdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,11 @@ static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
CONFIG_MPEG4_MEDIACODEC_DECODER || \
CONFIG_VP8_MEDIACODEC_DECODER || \
CONFIG_VP9_MEDIACODEC_DECODER || \
CONFIG_AV1_MEDIACODEC_DECODER
CONFIG_AV1_MEDIACODEC_DECODER || \
CONFIG_AAC_MEDIACODEC_DECODER || \
CONFIG_AMRNB_MEDIACODEC_DECODER || \
CONFIG_AMRWB_MEDIACODEC_DECODER || \
CONFIG_MP3_MEDIACODEC_DECODER
static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
{
int ret = 0;
Expand Down Expand Up @@ -388,13 +392,55 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
goto done;
break;
#endif
#if CONFIG_AAC_MEDIACODEC_DECODER
case AV_CODEC_ID_AAC:
codec_mime = "audio/mp4a-latm";

ret = common_set_extradata(avctx, format);
if (ret < 0)
goto done;
break;
#endif
#if CONFIG_AMRNB_MEDIACODEC_DECODER
case AV_CODEC_ID_AMR_NB:
codec_mime = "audio/3gpp";

ret = common_set_extradata(avctx, format);
if (ret < 0)
goto done;
break;
#endif
#if CONFIG_AMRWB_MEDIACODEC_DECODER
case AV_CODEC_ID_AMR_WB:
codec_mime = "audio/amr-wb";

ret = common_set_extradata(avctx, format);
if (ret < 0)
goto done;
break;
#endif
#if CONFIG_MP3_MEDIACODEC_DECODER
case AV_CODEC_ID_MP3:
codec_mime = "audio/mpeg";

ret = common_set_extradata(avctx, format);
if (ret < 0)
goto done;
break;
#endif
default:
av_assert0(0);
}

ff_AMediaFormat_setString(format, "mime", codec_mime);
ff_AMediaFormat_setInt32(format, "width", avctx->width);
ff_AMediaFormat_setInt32(format, "height", avctx->height);

if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
ff_AMediaFormat_setInt32(format, "width", avctx->width);
ff_AMediaFormat_setInt32(format, "height", avctx->height);
} else {
ff_AMediaFormat_setInt32(format, "channel-count", avctx->ch_layout.nb_channels);
ff_AMediaFormat_setInt32(format, "sample-rate", avctx->sample_rate);
}

s->ctx = av_mallocz(sizeof(*s->ctx));
if (!s->ctx) {
Expand Down Expand Up @@ -611,3 +657,53 @@ DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL)
#if CONFIG_AV1_MEDIACODEC_DECODER
DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL)
#endif

#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption ff_mediacodec_adec_options[] = {
{ "ndk_codec", "Use MediaCodec from NDK",
OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AD },
{ NULL }
};

#define DECLARE_MEDIACODEC_ACLASS(short_name) \
static const AVClass ff_##short_name##_mediacodec_dec_class = { \
.class_name = #short_name "_mediacodec", \
.item_name = av_default_item_name, \
.option = ff_mediacodec_adec_options, \
.version = LIBAVUTIL_VERSION_INT, \
};

#define DECLARE_MEDIACODEC_ADEC(short_name, full_name, codec_id, bsf) \
DECLARE_MEDIACODEC_VCLASS(short_name) \
const FFCodec ff_ ## short_name ## _mediacodec_decoder = { \
.p.name = #short_name "_mediacodec", \
CODEC_LONG_NAME(full_name " Android MediaCodec decoder"), \
.p.type = AVMEDIA_TYPE_AUDIO, \
.p.id = codec_id, \
.p.priv_class = &ff_##short_name##_mediacodec_dec_class, \
.priv_data_size = sizeof(MediaCodecH264DecContext), \
.init = mediacodec_decode_init, \
FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame), \
.flush = mediacodec_decode_flush, \
.close = mediacodec_decode_close, \
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
.caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
.bsfs = bsf, \
.p.wrapper_name = "mediacodec", \
}; \

#if CONFIG_AAC_MEDIACODEC_DECODER
DECLARE_MEDIACODEC_ADEC(aac, "AAC", AV_CODEC_ID_AAC, "aac_adtstoasc")
#endif

#if CONFIG_AMRNB_MEDIACODEC_DECODER
DECLARE_MEDIACODEC_ADEC(amrnb, "AMR-NB", AV_CODEC_ID_AMR_NB, NULL)
#endif

#if CONFIG_AMRWB_MEDIACODEC_DECODER
DECLARE_MEDIACODEC_ADEC(amrwb, "AMR-WB", AV_CODEC_ID_AMR_WB, NULL)
#endif

#if CONFIG_MP3_MEDIACODEC_DECODER
DECLARE_MEDIACODEC_ADEC(mp3, "MP3", AV_CODEC_ID_MP3, NULL)
#endif
Loading

0 comments on commit 0a780d3

Please sign in to comment.