23 #include "config_components.h"
45 #define INPUT_DEQUEUE_TIMEOUT_US 8000
46 #define OUTPUT_DEQUEUE_TIMEOUT_US 8000
102 static const struct {
122 const char *
name =
s->name;
163 int crop_right =
s->width - avctx->
width;
164 int crop_bottom =
s->height - avctx->
height;
172 if (!crop_right && !crop_bottom && !
s->extract_extradata)
176 if (crop_right || crop_bottom) {
178 ret =
snprintf(str,
sizeof(str),
"h264_metadata=crop_right=%d:crop_bottom=%d",
179 crop_right, crop_bottom);
185 ret =
snprintf(str,
sizeof(str),
"hevc_metadata=width=%d:height=%d",
187 if (
ret >=
sizeof(str))
191 if (
s->extract_extradata) {
193 if (
ret >=
sizeof(str))
214 uint8_t *dst_data[4] = {};
215 int dst_linesize[4] = {};
219 dst_data[1] =
dst +
s->width *
s->height;
220 dst_data[2] = dst_data[1] +
s->width *
s->height / 4;
222 dst_linesize[0] =
s->width;
223 dst_linesize[1] = dst_linesize[2] =
s->width / 2;
226 dst_data[1] =
dst +
s->width *
s->height;
228 dst_linesize[0] =
s->width;
229 dst_linesize[1] =
s->width;
313 if (!
s->input_index || !
s->output_index || !
s->output_buf_info)
343 const char *codec_mime =
NULL;
354 if (
s->use_ndk_codec < 0)
359 codec_mime =
"video/avc";
362 codec_mime =
"video/hevc";
365 codec_mime =
"video/x-vnd.on2.vp8";
368 codec_mime =
"video/x-vnd.on2.vp9";
371 codec_mime =
"video/mp4v-es";
374 codec_mime =
"video/av01";
407 if (
s->width % 16 ||
s->height % 16)
409 "Video size %dx%d isn't align to 16, it may have device compatibility issue\n",
410 s->width,
s->height);
425 dev_ctx = device_ctx->
hwctx;
429 if (!
s->window && user_ctx && user_ctx->
surface)
434 av_log(avctx,
AV_LOG_ERROR,
"Missing hw_device_ctx or hwaccel_context for AV_PIX_FMT_MEDIACODEC\n");
441 if (!
s->use_ndk_codec && !
s->window->surface) {
444 "Please note that Java MediaCodec doesn't work with ANativeWindow.\n");
469 if (
s->bitrate_mode >= 0) {
485 "Use %d as the default MediaFormat i-frame-interval, "
486 "please set gop_size properly (>= fps)\n", gop);
506 "Enabling B frames will produce packets with no DTS. "
507 "Use -strict experimental to use it anyway.\n");
513 if (
s->pts_as_dts == -1)
515 if (
s->operating_rate > 0)
524 "support yuv420p as encoder input format.\n");
539 "Try MediaCodec async mode failed, %s, switch to sync mode\n",
581 if (!
s->async_mode) {
589 while (n < 0 && !s->encode_status) {
597 if (n < 0 && s->eof_sent && !
s->encode_status)
603 ret =
s->encode_status;
623 int extradata_size = 0;
657 if (out_info.
size <= 4) {
669 s->extradata_size = out_info.
size;
670 memcpy(
s->extradata, out_buf + out_info.
offset, out_info.
size);
680 if (
s->extradata_size) {
681 extradata_size =
s->extradata_size;
682 s->extradata_size = 0;
683 memcpy(
pkt->
data,
s->extradata, extradata_size);
694 " flags %d extradata %d\n",
709 if (!
s->async_mode) {
717 while (n < 0 && !s->encode_status) {
723 if (n < 0 && !s->encode_status)
727 ret =
s->encode_status;
740 uint8_t *input_buf =
NULL;
741 size_t input_size = 0;
816 if (!
s->frame->buf[0]) {
837 s->frame->width = avctx->
width;
838 s->frame->height = avctx->
height;
897 if (
s->async_mode || !
s->extract_extradata) {
899 "Mediacodec encoder doesn't support AV_CODEC_FLAG_GLOBAL_HEADER. "
900 "Use extract_extradata bsf when necessary.\n");
916 if (side && side_size > 0) {
923 memcpy(avctx->
extradata, side, side_size);
981 #define OFFSET(x) offsetof(MediaCodecEncContext, x)
982 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
983 #define COMMON_OPTION \
984 { "ndk_codec", "Use MediaCodec from NDK", \
985 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \
986 { "ndk_async", "Try NDK MediaCodec in async mode", \
987 OFFSET(async_mode), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE }, \
988 { "codec_name", "Select codec by name", \
989 OFFSET(name), AV_OPT_TYPE_STRING, {0}, 0, 0, VE }, \
990 { "bitrate_mode", "Bitrate control method", \
991 OFFSET(bitrate_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "bitrate_mode" }, \
992 { "cq", "Constant quality mode", \
993 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CQ}, 0, 0, VE, .unit = "bitrate_mode" }, \
994 { "vbr", "Variable bitrate mode", \
995 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_VBR}, 0, 0, VE, .unit = "bitrate_mode" }, \
996 { "cbr", "Constant bitrate mode", \
997 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR}, 0, 0, VE, .unit = "bitrate_mode" }, \
998 { "cbr_fd", "Constant bitrate mode with frame drops", \
999 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR_FD}, 0, 0, VE, .unit = "bitrate_mode" }, \
1000 { "pts_as_dts", "Use PTS as DTS. It is enabled automatically if avctx max_b_frames <= 0, " \
1001 "since most of Android devices don't output B frames by default.", \
1002 OFFSET(pts_as_dts), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \
1003 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified", \
1004 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE }, \
1006 #define MEDIACODEC_ENCODER_CLASS(name) \
1007 static const AVClass name ## _mediacodec_class = { \
1008 .class_name = #name "_mediacodec", \
1009 .item_name = av_default_item_name, \
1010 .option = name ## _options, \
1011 .version = LIBAVUTIL_VERSION_INT, \
1014 #define DECLARE_MEDIACODEC_ENCODER(short_name, long_name, codec_id) \
1015 MEDIACODEC_ENCODER_CLASS(short_name) \
1016 const FFCodec ff_ ## short_name ## _mediacodec_encoder = { \
1017 .p.name = #short_name "_mediacodec", \
1018 CODEC_LONG_NAME(long_name " Android MediaCodec encoder"), \
1019 .p.type = AVMEDIA_TYPE_VIDEO, \
1021 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | \
1022 AV_CODEC_CAP_HARDWARE | \
1023 AV_CODEC_CAP_ENCODER_FLUSH, \
1024 .priv_data_size = sizeof(MediaCodecEncContext), \
1025 .p.pix_fmts = avc_pix_fmts, \
1026 .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG, \
1027 .init = mediacodec_init, \
1028 FF_CODEC_RECEIVE_PACKET_CB(mediacodec_encode), \
1029 .close = mediacodec_close, \
1030 .flush = mediacodec_flush, \
1031 .p.priv_class = &short_name ## _mediacodec_class, \
1032 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
1033 .p.wrapper_name = "mediacodec", \
1034 .hw_configs = mediacodec_hw_configs, \
1037 #if CONFIG_H264_MEDIACODEC_ENCODER
1039 enum MediaCodecAvcLevel {
1052 AVCLevel41 = 0x1000,
1053 AVCLevel42 = 0x2000,
1055 AVCLevel51 = 0x8000,
1056 AVCLevel52 = 0x10000,
1057 AVCLevel6 = 0x20000,
1058 AVCLevel61 = 0x40000,
1059 AVCLevel62 = 0x80000,
1074 {
"level",
"Specify level",
1101 #endif // CONFIG_H264_MEDIACODEC_ENCODER
1103 #if CONFIG_HEVC_MEDIACODEC_ENCODER
1105 enum MediaCodecHevcLevel {
1106 HEVCMainTierLevel1 = 0x1,
1107 HEVCHighTierLevel1 = 0x2,
1108 HEVCMainTierLevel2 = 0x4,
1109 HEVCHighTierLevel2 = 0x8,
1110 HEVCMainTierLevel21 = 0x10,
1111 HEVCHighTierLevel21 = 0x20,
1112 HEVCMainTierLevel3 = 0x40,
1113 HEVCHighTierLevel3 = 0x80,
1114 HEVCMainTierLevel31 = 0x100,
1115 HEVCHighTierLevel31 = 0x200,
1116 HEVCMainTierLevel4 = 0x400,
1117 HEVCHighTierLevel4 = 0x800,
1118 HEVCMainTierLevel41 = 0x1000,
1119 HEVCHighTierLevel41 = 0x2000,
1120 HEVCMainTierLevel5 = 0x4000,
1121 HEVCHighTierLevel5 = 0x8000,
1122 HEVCMainTierLevel51 = 0x10000,
1123 HEVCHighTierLevel51 = 0x20000,
1124 HEVCMainTierLevel52 = 0x40000,
1125 HEVCHighTierLevel52 = 0x80000,
1126 HEVCMainTierLevel6 = 0x100000,
1127 HEVCHighTierLevel6 = 0x200000,
1128 HEVCMainTierLevel61 = 0x400000,
1129 HEVCHighTierLevel61 = 0x800000,
1130 HEVCMainTierLevel62 = 0x1000000,
1131 HEVCHighTierLevel62 = 0x2000000,
1140 {
"level",
"Specify tier and level",
1142 {
"m1",
"Main tier level 1",
1144 {
"h1",
"High tier level 1",
1146 {
"m2",
"Main tier level 2",
1148 {
"h2",
"High tier level 2",
1150 {
"m2.1",
"Main tier level 2.1",
1152 {
"h2.1",
"High tier level 2.1",
1154 {
"m3",
"Main tier level 3",
1156 {
"h3",
"High tier level 3",
1158 {
"m3.1",
"Main tier level 3.1",
1160 {
"h3.1",
"High tier level 3.1",
1162 {
"m4",
"Main tier level 4",
1164 {
"h4",
"High tier level 4",
1166 {
"m4.1",
"Main tier level 4.1",
1168 {
"h4.1",
"High tier level 4.1",
1170 {
"m5",
"Main tier level 5",
1172 {
"h5",
"High tier level 5",
1174 {
"m5.1",
"Main tier level 5.1",
1176 {
"h5.1",
"High tier level 5.1",
1178 {
"m5.2",
"Main tier level 5.2",
1180 {
"h5.2",
"High tier level 5.2",
1182 {
"m6",
"Main tier level 6",
1184 {
"h6",
"High tier level 6",
1186 {
"m6.1",
"Main tier level 6.1",
1188 {
"h6.1",
"High tier level 6.1",
1190 {
"m6.2",
"Main tier level 6.2",
1192 {
"h6.2",
"High tier level 6.2",
1199 #endif // CONFIG_HEVC_MEDIACODEC_ENCODER
1201 #if CONFIG_VP8_MEDIACODEC_ENCODER
1203 enum MediaCodecVP8Level {
1204 VP8Level_Version0 = 0x01,
1205 VP8Level_Version1 = 0x02,
1206 VP8Level_Version2 = 0x04,
1207 VP8Level_Version3 = 0x08,
1210 static const AVOption vp8_options[] = {
1212 {
"level",
"Specify tier and level",
1214 {
"V0",
"Level Version 0",
1216 {
"V1",
"Level Version 1",
1218 {
"V2",
"Level Version 2",
1220 {
"V3",
"Level Version 3",
1227 #endif // CONFIG_VP8_MEDIACODEC_ENCODER
1229 #if CONFIG_VP9_MEDIACODEC_ENCODER
1231 enum MediaCodecVP9Level {
1244 VP9Level61 = 0x1000,
1245 VP9Level62 = 0x2000,
1248 static const AVOption vp9_options[] = {
1256 {
"level",
"Specify tier and level",
1260 {
"1.1",
"Level 1.1",
1264 {
"2.1",
"Level 2.1",
1268 {
"3.1",
"Level 3.1",
1272 {
"4.1",
"Level 4.1",
1276 {
"5.1",
"Level 5.1",
1278 {
"5.2",
"Level 5.2",
1282 {
"6.1",
"Level 4.1",
1284 {
"6.2",
"Level 6.2",
1291 #endif // CONFIG_VP9_MEDIACODEC_ENCODER
1293 #if CONFIG_MPEG4_MEDIACODEC_ENCODER
1295 enum MediaCodecMpeg4Level {
1297 MPEG4Level0b = 0x02,
1301 MPEG4Level3b = 0x18,
1303 MPEG4Level4a = 0x40,
1305 MPEG4Level6 = 0x100,
1313 {
"level",
"Specify tier and level",
1340 #endif // CONFIG_MPEG4_MEDIACODEC_ENCODER
1342 #if CONFIG_AV1_MEDIACODEC_ENCODER
1344 enum MediaCodecAV1Level {
1358 AV1Level51 = 0x2000,
1359 AV1Level52 = 0x4000,
1360 AV1Level53 = 0x8000,
1361 AV1Level6 = 0x10000,
1362 AV1Level61 = 0x20000,
1363 AV1Level62 = 0x40000,
1364 AV1Level63 = 0x80000,
1365 AV1Level7 = 0x100000,
1366 AV1Level71 = 0x200000,
1367 AV1Level72 = 0x400000,
1368 AV1Level73 = 0x800000,
1376 {
"level",
"Specify tier and level",
1380 {
"2.1",
"Level 2.1",
1382 {
"2.2",
"Level 2.2",
1384 {
"2.3",
"Level 2.3",
1388 {
"3.1",
"Level 3.1",
1390 {
"3.2",
"Level 3.2",
1392 {
"3.3",
"Level 3.3",
1396 {
"4.1",
"Level 4.1",
1398 {
"4.2",
"Level 4.2",
1400 {
"4.3",
"Level 4.3",
1404 {
"5.1",
"Level 5.1",
1406 {
"5.2",
"Level 5.2",
1408 {
"5.3",
"Level 5.3",
1412 {
"6.1",
"Level 6.1",
1414 {
"6.2",
"Level 6.2",
1416 {
"6.3",
"Level 6.3",
1420 {
"7.1",
"Level 7.1",
1422 {
"7.2",
"Level 7.2",
1424 {
"7.3",
"Level 7.3",
1431 #endif // CONFIG_AV1_MEDIACODEC_ENCODER