avformat/mpeg: demux ivtv captions
[ffmpeg.git] / libavcodec / mediacodecdec.c
blob4937828f21753d5264eba13bb1c5503d60e12869
1 /*
2 * Android MediaCodec MPEG-2 / H.264 / H.265 / MPEG-4 / VP8 / VP9 decoders
4 * Copyright (c) 2015-2016 Matthieu Bouron <matthieu.bouron stupeflix.com>
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "config_components.h"
25 #include <stdint.h>
26 #include <string.h>
28 #include "libavutil/avassert.h"
29 #include "libavutil/common.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/pixfmt.h"
34 #include "libavutil/internal.h"
36 #include "avcodec.h"
37 #include "codec_internal.h"
38 #include "decode.h"
39 #include "h264_parse.h"
40 #include "h264_ps.h"
41 #include "hevc/parse.h"
42 #include "hwconfig.h"
43 #include "internal.h"
44 #include "jni.h"
45 #include "mediacodec_wrapper.h"
46 #include "mediacodecdec_common.h"
48 typedef struct MediaCodecH264DecContext {
50 AVClass *avclass;
52 MediaCodecDecContext *ctx;
54 AVPacket buffered_pkt;
56 int delay_flush;
57 int amlogic_mpeg2_api23_workaround;
59 int use_ndk_codec;
60 // Ref. MediaFormat KEY_OPERATING_RATE
61 int operating_rate;
62 } MediaCodecH264DecContext;
64 static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
66 MediaCodecH264DecContext *s = avctx->priv_data;
68 ff_mediacodec_dec_close(avctx, s->ctx);
69 s->ctx = NULL;
71 av_packet_unref(&s->buffered_pkt);
73 return 0;
76 #if CONFIG_H264_MEDIACODEC_DECODER || CONFIG_HEVC_MEDIACODEC_DECODER
77 static int h2645_ps_to_nalu(const uint8_t *src, int src_size, uint8_t **out, int *out_size)
79 int i;
80 int ret = 0;
81 uint8_t *p = NULL;
82 static const uint8_t nalu_header[] = { 0x00, 0x00, 0x00, 0x01 };
84 if (!out || !out_size) {
85 return AVERROR(EINVAL);
88 p = av_malloc(sizeof(nalu_header) + src_size);
89 if (!p) {
90 return AVERROR(ENOMEM);
93 *out = p;
94 *out_size = sizeof(nalu_header) + src_size;
96 memcpy(p, nalu_header, sizeof(nalu_header));
97 memcpy(p + sizeof(nalu_header), src, src_size);
99 /* Escape 0x00, 0x00, 0x0{0-3} pattern */
100 for (i = 4; i < *out_size; i++) {
101 if (i < *out_size - 3 &&
102 p[i + 0] == 0 &&
103 p[i + 1] == 0 &&
104 p[i + 2] <= 3) {
105 uint8_t *new;
107 *out_size += 1;
108 new = av_realloc(*out, *out_size);
109 if (!new) {
110 ret = AVERROR(ENOMEM);
111 goto done;
113 *out = p = new;
115 i = i + 2;
116 memmove(p + i + 1, p + i, *out_size - (i + 1));
117 p[i] = 0x03;
120 done:
121 if (ret < 0) {
122 av_freep(out);
123 *out_size = 0;
126 return ret;
128 #endif
130 #if CONFIG_H264_MEDIACODEC_DECODER
131 static int h264_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
133 int i;
134 int ret;
136 H264ParamSets ps;
137 const PPS *pps = NULL;
138 const SPS *sps = NULL;
139 int is_avc = 0;
140 int nal_length_size = 0;
142 memset(&ps, 0, sizeof(ps));
144 ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
145 &ps, &is_avc, &nal_length_size, 0, avctx);
146 if (ret < 0) {
147 goto done;
150 for (i = 0; i < MAX_PPS_COUNT; i++) {
151 if (ps.pps_list[i]) {
152 pps = ps.pps_list[i];
153 break;
157 if (pps) {
158 if (ps.sps_list[pps->sps_id]) {
159 sps = ps.sps_list[pps->sps_id];
163 if (pps && sps) {
164 uint8_t *data = NULL;
165 int data_size = 0;
167 avctx->profile = ff_h264_get_profile(sps);
168 avctx->level = sps->level_idc;
170 if ((ret = h2645_ps_to_nalu(sps->data, sps->data_size, &data, &data_size)) < 0) {
171 goto done;
173 ff_AMediaFormat_setBuffer(format, "csd-0", (void*)data, data_size);
174 av_freep(&data);
176 if ((ret = h2645_ps_to_nalu(pps->data, pps->data_size, &data, &data_size)) < 0) {
177 goto done;
179 ff_AMediaFormat_setBuffer(format, "csd-1", (void*)data, data_size);
180 av_freep(&data);
181 } else {
182 const int warn = is_avc && (avctx->codec_tag == MKTAG('a','v','c','1') ||
183 avctx->codec_tag == MKTAG('a','v','c','2'));
184 av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG,
185 "Could not extract PPS/SPS from extradata\n");
186 ret = 0;
189 done:
190 ff_h264_ps_uninit(&ps);
192 return ret;
194 #endif
196 #if CONFIG_HEVC_MEDIACODEC_DECODER
197 static int hevc_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
199 int i;
200 int ret;
202 HEVCParamSets ps;
203 HEVCSEI sei;
205 const HEVCVPS *vps = NULL;
206 const HEVCPPS *pps = NULL;
207 const HEVCSPS *sps = NULL;
208 int is_nalff = 0;
209 int nal_length_size = 0;
211 uint8_t *vps_data = NULL;
212 uint8_t *sps_data = NULL;
213 uint8_t *pps_data = NULL;
214 int vps_data_size = 0;
215 int sps_data_size = 0;
216 int pps_data_size = 0;
218 memset(&ps, 0, sizeof(ps));
219 memset(&sei, 0, sizeof(sei));
221 ret = ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size,
222 &ps, &sei, &is_nalff, &nal_length_size, 0, 1, avctx);
223 if (ret < 0) {
224 goto done;
227 for (i = 0; i < HEVC_MAX_VPS_COUNT; i++) {
228 if (ps.vps_list[i]) {
229 vps = ps.vps_list[i];
230 break;
234 for (i = 0; i < HEVC_MAX_PPS_COUNT; i++) {
235 if (ps.pps_list[i]) {
236 pps = ps.pps_list[i];
237 break;
241 if (pps) {
242 if (ps.sps_list[pps->sps_id]) {
243 sps = ps.sps_list[pps->sps_id];
247 if (vps && pps && sps) {
248 uint8_t *data;
249 int data_size;
251 avctx->profile = sps->ptl.general_ptl.profile_idc;
252 avctx->level = sps->ptl.general_ptl.level_idc;
254 if ((ret = h2645_ps_to_nalu(vps->data, vps->data_size, &vps_data, &vps_data_size)) < 0 ||
255 (ret = h2645_ps_to_nalu(sps->data, sps->data_size, &sps_data, &sps_data_size)) < 0 ||
256 (ret = h2645_ps_to_nalu(pps->data, pps->data_size, &pps_data, &pps_data_size)) < 0) {
257 goto done;
260 data_size = vps_data_size + sps_data_size + pps_data_size;
261 data = av_mallocz(data_size);
262 if (!data) {
263 ret = AVERROR(ENOMEM);
264 goto done;
267 memcpy(data , vps_data, vps_data_size);
268 memcpy(data + vps_data_size , sps_data, sps_data_size);
269 memcpy(data + vps_data_size + sps_data_size, pps_data, pps_data_size);
271 ff_AMediaFormat_setBuffer(format, "csd-0", data, data_size);
273 av_freep(&data);
274 } else {
275 const int warn = is_nalff && avctx->codec_tag == MKTAG('h','v','c','1');
276 av_log(avctx, warn ? AV_LOG_WARNING : AV_LOG_DEBUG,
277 "Could not extract VPS/PPS/SPS from extradata\n");
278 ret = 0;
281 done:
282 ff_hevc_ps_uninit(&ps);
284 av_freep(&vps_data);
285 av_freep(&sps_data);
286 av_freep(&pps_data);
288 return ret;
290 #endif
292 #if CONFIG_MPEG2_MEDIACODEC_DECODER || \
293 CONFIG_MPEG4_MEDIACODEC_DECODER || \
294 CONFIG_VP8_MEDIACODEC_DECODER || \
295 CONFIG_VP9_MEDIACODEC_DECODER || \
296 CONFIG_AV1_MEDIACODEC_DECODER || \
297 CONFIG_AAC_MEDIACODEC_DECODER || \
298 CONFIG_AMRNB_MEDIACODEC_DECODER || \
299 CONFIG_AMRWB_MEDIACODEC_DECODER || \
300 CONFIG_MP3_MEDIACODEC_DECODER
301 static int common_set_extradata(AVCodecContext *avctx, FFAMediaFormat *format)
303 int ret = 0;
305 if (avctx->extradata) {
306 ff_AMediaFormat_setBuffer(format, "csd-0", avctx->extradata, avctx->extradata_size);
309 return ret;
311 #endif
313 static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
315 int ret;
316 int sdk_int;
318 const char *codec_mime = NULL;
320 FFAMediaFormat *format = NULL;
321 MediaCodecH264DecContext *s = avctx->priv_data;
323 if (s->use_ndk_codec < 0)
324 s->use_ndk_codec = !av_jni_get_java_vm(avctx);
326 format = ff_AMediaFormat_new(s->use_ndk_codec);
327 if (!format) {
328 av_log(avctx, AV_LOG_ERROR, "Failed to create media format\n");
329 ret = AVERROR_EXTERNAL;
330 goto done;
333 switch (avctx->codec_id) {
334 #if CONFIG_AV1_MEDIACODEC_DECODER
335 case AV_CODEC_ID_AV1:
336 codec_mime = "video/av01";
338 ret = common_set_extradata(avctx, format);
339 if (ret < 0)
340 goto done;
341 break;
342 #endif
343 #if CONFIG_H264_MEDIACODEC_DECODER
344 case AV_CODEC_ID_H264:
345 codec_mime = "video/avc";
347 ret = h264_set_extradata(avctx, format);
348 if (ret < 0)
349 goto done;
350 break;
351 #endif
352 #if CONFIG_HEVC_MEDIACODEC_DECODER
353 case AV_CODEC_ID_HEVC:
354 codec_mime = "video/hevc";
356 ret = hevc_set_extradata(avctx, format);
357 if (ret < 0)
358 goto done;
359 break;
360 #endif
361 #if CONFIG_MPEG2_MEDIACODEC_DECODER
362 case AV_CODEC_ID_MPEG2VIDEO:
363 codec_mime = "video/mpeg2";
365 ret = common_set_extradata(avctx, format);
366 if (ret < 0)
367 goto done;
368 break;
369 #endif
370 #if CONFIG_MPEG4_MEDIACODEC_DECODER
371 case AV_CODEC_ID_MPEG4:
372 codec_mime = "video/mp4v-es",
374 ret = common_set_extradata(avctx, format);
375 if (ret < 0)
376 goto done;
377 break;
378 #endif
379 #if CONFIG_VP8_MEDIACODEC_DECODER
380 case AV_CODEC_ID_VP8:
381 codec_mime = "video/x-vnd.on2.vp8";
383 ret = common_set_extradata(avctx, format);
384 if (ret < 0)
385 goto done;
386 break;
387 #endif
388 #if CONFIG_VP9_MEDIACODEC_DECODER
389 case AV_CODEC_ID_VP9:
390 codec_mime = "video/x-vnd.on2.vp9";
392 ret = common_set_extradata(avctx, format);
393 if (ret < 0)
394 goto done;
395 break;
396 #endif
397 #if CONFIG_AAC_MEDIACODEC_DECODER
398 case AV_CODEC_ID_AAC:
399 codec_mime = "audio/mp4a-latm";
401 ret = common_set_extradata(avctx, format);
402 if (ret < 0)
403 goto done;
404 break;
405 #endif
406 #if CONFIG_AMRNB_MEDIACODEC_DECODER
407 case AV_CODEC_ID_AMR_NB:
408 codec_mime = "audio/3gpp";
410 ret = common_set_extradata(avctx, format);
411 if (ret < 0)
412 goto done;
413 break;
414 #endif
415 #if CONFIG_AMRWB_MEDIACODEC_DECODER
416 case AV_CODEC_ID_AMR_WB:
417 codec_mime = "audio/amr-wb";
419 ret = common_set_extradata(avctx, format);
420 if (ret < 0)
421 goto done;
422 break;
423 #endif
424 #if CONFIG_MP3_MEDIACODEC_DECODER
425 case AV_CODEC_ID_MP3:
426 codec_mime = "audio/mpeg";
428 ret = common_set_extradata(avctx, format);
429 if (ret < 0)
430 goto done;
431 break;
432 #endif
433 default:
434 av_assert0(0);
437 ff_AMediaFormat_setString(format, "mime", codec_mime);
439 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
440 ff_AMediaFormat_setInt32(format, "width", avctx->width);
441 ff_AMediaFormat_setInt32(format, "height", avctx->height);
442 } else {
443 ff_AMediaFormat_setInt32(format, "channel-count", avctx->ch_layout.nb_channels);
444 ff_AMediaFormat_setInt32(format, "sample-rate", avctx->sample_rate);
446 if (s->operating_rate > 0)
447 ff_AMediaFormat_setInt32(format, "operating-rate", s->operating_rate);
449 s->ctx = av_mallocz(sizeof(*s->ctx));
450 if (!s->ctx) {
451 av_log(avctx, AV_LOG_ERROR, "Failed to allocate MediaCodecDecContext\n");
452 ret = AVERROR(ENOMEM);
453 goto done;
456 s->ctx->delay_flush = s->delay_flush;
457 s->ctx->use_ndk_codec = s->use_ndk_codec;
459 if ((ret = ff_mediacodec_dec_init(avctx, s->ctx, codec_mime, format)) < 0) {
460 s->ctx = NULL;
461 goto done;
464 av_log(avctx, AV_LOG_INFO,
465 "MediaCodec started successfully: codec = %s, ret = %d\n",
466 s->ctx->codec_name, ret);
468 sdk_int = ff_Build_SDK_INT(avctx);
469 /* ff_Build_SDK_INT can fail when target API < 24 and JVM isn't available.
470 * If we don't check sdk_int > 0, the workaround might be enabled by
471 * mistake.
472 * JVM is required to make the workaround works reliably. On the other hand,
473 * missing a workaround should not be a serious issue, we do as best we can.
475 if (sdk_int > 0 && sdk_int <= 23 &&
476 strcmp(s->ctx->codec_name, "OMX.amlogic.mpeg2.decoder.awesome") == 0) {
477 av_log(avctx, AV_LOG_INFO, "Enabling workaround for %s on API=%d\n",
478 s->ctx->codec_name, sdk_int);
479 s->amlogic_mpeg2_api23_workaround = 1;
482 done:
483 if (format) {
484 ff_AMediaFormat_delete(format);
487 if (ret < 0) {
488 mediacodec_decode_close(avctx);
491 return ret;
494 static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
496 MediaCodecH264DecContext *s = avctx->priv_data;
497 int ret;
498 ssize_t index;
500 /* In delay_flush mode, wait until the user has released or rendered
501 all retained frames. */
502 if (s->delay_flush && ff_mediacodec_dec_is_flushing(avctx, s->ctx)) {
503 if (!ff_mediacodec_dec_flush(avctx, s->ctx)) {
504 return AVERROR(EAGAIN);
508 /* poll for new frame */
509 ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false);
510 if (ret != AVERROR(EAGAIN))
511 return ret;
513 /* feed decoder */
514 while (1) {
515 if (s->ctx->current_input_buffer < 0 && !s->ctx->draining) {
516 /* poll for input space */
517 index = ff_AMediaCodec_dequeueInputBuffer(s->ctx->codec, 0);
518 if (index < 0) {
519 /* no space, block for an output frame to appear */
520 ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
521 /* Try again if both input port and output port return EAGAIN.
522 * If no data is consumed and no frame in output, it can make
523 * both avcodec_send_packet() and avcodec_receive_frame()
524 * return EAGAIN, which violate the design.
526 if (ff_AMediaCodec_infoTryAgainLater(s->ctx->codec, index) &&
527 ret == AVERROR(EAGAIN))
528 continue;
529 return ret;
531 s->ctx->current_input_buffer = index;
534 /* try to flush any buffered packet data */
535 if (s->buffered_pkt.size > 0) {
536 ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt, false);
537 if (ret >= 0) {
538 s->buffered_pkt.size -= ret;
539 s->buffered_pkt.data += ret;
540 if (s->buffered_pkt.size <= 0) {
541 av_packet_unref(&s->buffered_pkt);
542 } else {
543 av_log(avctx, AV_LOG_WARNING,
544 "could not send entire packet in single input buffer (%d < %d)\n",
545 ret, s->buffered_pkt.size+ret);
547 } else if (ret < 0 && ret != AVERROR(EAGAIN)) {
548 return ret;
551 if (s->amlogic_mpeg2_api23_workaround && s->buffered_pkt.size <= 0) {
552 /* fallthrough to fetch next packet regardless of input buffer space */
553 } else {
554 /* poll for space again */
555 continue;
559 /* fetch new packet or eof */
560 ret = ff_decode_get_packet(avctx, &s->buffered_pkt);
561 if (ret == AVERROR_EOF) {
562 AVPacket null_pkt = { 0 };
563 ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, true);
564 if (ret < 0)
565 return ret;
566 return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
567 } else if (ret == AVERROR(EAGAIN) && s->ctx->current_input_buffer < 0) {
568 return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
569 } else if (ret < 0) {
570 return ret;
574 return AVERROR(EAGAIN);
577 static void mediacodec_decode_flush(AVCodecContext *avctx)
579 MediaCodecH264DecContext *s = avctx->priv_data;
581 av_packet_unref(&s->buffered_pkt);
583 ff_mediacodec_dec_flush(avctx, s->ctx);
586 static const AVCodecHWConfigInternal *const mediacodec_hw_configs[] = {
587 &(const AVCodecHWConfigInternal) {
588 .public = {
589 .pix_fmt = AV_PIX_FMT_MEDIACODEC,
590 .methods = AV_CODEC_HW_CONFIG_METHOD_AD_HOC |
591 AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX,
592 .device_type = AV_HWDEVICE_TYPE_MEDIACODEC,
594 .hwaccel = NULL,
596 NULL
599 #define OFFSET(x) offsetof(MediaCodecH264DecContext, x)
600 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
601 static const AVOption ff_mediacodec_vdec_options[] = {
602 { "delay_flush", "Delay flush until hw output buffers are returned to the decoder",
603 OFFSET(delay_flush), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VD },
604 { "ndk_codec", "Use MediaCodec from NDK",
605 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VD },
606 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified",
607 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VD },
608 { NULL }
611 #define DECLARE_MEDIACODEC_VCLASS(short_name) \
612 static const AVClass ff_##short_name##_mediacodec_dec_class = { \
613 .class_name = #short_name "_mediacodec", \
614 .item_name = av_default_item_name, \
615 .option = ff_mediacodec_vdec_options, \
616 .version = LIBAVUTIL_VERSION_INT, \
619 #define DECLARE_MEDIACODEC_VDEC(short_name, full_name, codec_id, bsf) \
620 DECLARE_MEDIACODEC_VCLASS(short_name) \
621 const FFCodec ff_ ## short_name ## _mediacodec_decoder = { \
622 .p.name = #short_name "_mediacodec", \
623 CODEC_LONG_NAME(full_name " Android MediaCodec decoder"), \
624 .p.type = AVMEDIA_TYPE_VIDEO, \
625 .p.id = codec_id, \
626 .p.priv_class = &ff_##short_name##_mediacodec_dec_class, \
627 .priv_data_size = sizeof(MediaCodecH264DecContext), \
628 .init = mediacodec_decode_init, \
629 FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame), \
630 .flush = mediacodec_decode_flush, \
631 .close = mediacodec_decode_close, \
632 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
633 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
634 .bsfs = bsf, \
635 .hw_configs = mediacodec_hw_configs, \
636 .p.wrapper_name = "mediacodec", \
637 }; \
639 #if CONFIG_H264_MEDIACODEC_DECODER
640 DECLARE_MEDIACODEC_VDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb")
641 #endif
643 #if CONFIG_HEVC_MEDIACODEC_DECODER
644 DECLARE_MEDIACODEC_VDEC(hevc, "H.265", AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
645 #endif
647 #if CONFIG_MPEG2_MEDIACODEC_DECODER
648 DECLARE_MEDIACODEC_VDEC(mpeg2, "MPEG-2", AV_CODEC_ID_MPEG2VIDEO, NULL)
649 #endif
651 #if CONFIG_MPEG4_MEDIACODEC_DECODER
652 DECLARE_MEDIACODEC_VDEC(mpeg4, "MPEG-4", AV_CODEC_ID_MPEG4, NULL)
653 #endif
655 #if CONFIG_VP8_MEDIACODEC_DECODER
656 DECLARE_MEDIACODEC_VDEC(vp8, "VP8", AV_CODEC_ID_VP8, NULL)
657 #endif
659 #if CONFIG_VP9_MEDIACODEC_DECODER
660 DECLARE_MEDIACODEC_VDEC(vp9, "VP9", AV_CODEC_ID_VP9, NULL)
661 #endif
663 #if CONFIG_AV1_MEDIACODEC_DECODER
664 DECLARE_MEDIACODEC_VDEC(av1, "AV1", AV_CODEC_ID_AV1, NULL)
665 #endif
667 #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
668 static const AVOption ff_mediacodec_adec_options[] = {
669 { "ndk_codec", "Use MediaCodec from NDK",
670 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AD },
671 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified",
672 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AD },
673 { NULL }
676 #define DECLARE_MEDIACODEC_ACLASS(short_name) \
677 static const AVClass ff_##short_name##_mediacodec_dec_class = { \
678 .class_name = #short_name "_mediacodec", \
679 .item_name = av_default_item_name, \
680 .option = ff_mediacodec_adec_options, \
681 .version = LIBAVUTIL_VERSION_INT, \
684 #define DECLARE_MEDIACODEC_ADEC(short_name, full_name, codec_id, bsf) \
685 DECLARE_MEDIACODEC_VCLASS(short_name) \
686 const FFCodec ff_ ## short_name ## _mediacodec_decoder = { \
687 .p.name = #short_name "_mediacodec", \
688 CODEC_LONG_NAME(full_name " Android MediaCodec decoder"), \
689 .p.type = AVMEDIA_TYPE_AUDIO, \
690 .p.id = codec_id, \
691 .p.priv_class = &ff_##short_name##_mediacodec_dec_class, \
692 .priv_data_size = sizeof(MediaCodecH264DecContext), \
693 .init = mediacodec_decode_init, \
694 FF_CODEC_RECEIVE_FRAME_CB(mediacodec_receive_frame), \
695 .flush = mediacodec_decode_flush, \
696 .close = mediacodec_decode_close, \
697 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
698 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
699 .bsfs = bsf, \
700 .p.wrapper_name = "mediacodec", \
701 }; \
703 #if CONFIG_AAC_MEDIACODEC_DECODER
704 DECLARE_MEDIACODEC_ADEC(aac, "AAC", AV_CODEC_ID_AAC, "aac_adtstoasc")
705 #endif
707 #if CONFIG_AMRNB_MEDIACODEC_DECODER
708 DECLARE_MEDIACODEC_ADEC(amrnb, "AMR-NB", AV_CODEC_ID_AMR_NB, NULL)
709 #endif
711 #if CONFIG_AMRWB_MEDIACODEC_DECODER
712 DECLARE_MEDIACODEC_ADEC(amrwb, "AMR-WB", AV_CODEC_ID_AMR_WB, NULL)
713 #endif
715 #if CONFIG_MP3_MEDIACODEC_DECODER
716 DECLARE_MEDIACODEC_ADEC(mp3, "MP3", AV_CODEC_ID_MP3, NULL)
717 #endif