23 #include "config_components.h"
45 #define INPUT_DEQUEUE_TIMEOUT_US 8000
46 #define OUTPUT_DEQUEUE_TIMEOUT_US 8000
113 static const struct {
133 const char *
name =
s->name;
174 int crop_right =
s->width - avctx->
width;
175 int crop_bottom =
s->height - avctx->
height;
183 if (!crop_right && !crop_bottom && !
s->extract_extradata)
187 if (crop_right || crop_bottom) {
189 ret =
snprintf(str,
sizeof(str),
"h264_metadata=crop_right=%d:crop_bottom=%d",
190 crop_right, crop_bottom);
196 ret =
snprintf(str,
sizeof(str),
"hevc_metadata=width=%d:height=%d",
198 if (
ret >=
sizeof(str))
202 if (
s->extract_extradata) {
204 if (
ret >=
sizeof(str))
225 uint8_t *dst_data[4] = {};
226 int dst_linesize[4] = {};
230 dst_data[1] =
dst +
s->width *
s->height;
231 dst_data[2] = dst_data[1] +
s->width *
s->height / 4;
233 dst_linesize[0] =
s->width;
234 dst_linesize[1] = dst_linesize[2] =
s->width / 2;
237 dst_data[1] =
dst +
s->width *
s->height;
239 dst_linesize[0] =
s->width;
240 dst_linesize[1] =
s->width;
285 on_error(codec, userdata,
ret,
"av_fifo_write failed");
296 .buf_info = *out_info,
307 on_error(codec, userdata,
ret,
"av_fifo_write failed");
334 if (!
s->input_index || !
s->async_output)
367 if (avctx->
qmin >= 0) {
373 if (avctx->
qmax >= 0) {
379 if (
s->qp_i_min >= 0)
381 if (
s->qp_p_min >= 0)
383 if (
s->qp_b_min >= 0)
386 if (
s->qp_i_max >= 0)
388 if (
s->qp_p_max >= 0)
390 if (
s->qp_b_max >= 0)
396 const char *codec_mime =
NULL;
407 if (
s->use_ndk_codec < 0)
412 codec_mime =
"video/avc";
415 codec_mime =
"video/hevc";
418 codec_mime =
"video/x-vnd.on2.vp8";
421 codec_mime =
"video/x-vnd.on2.vp9";
424 codec_mime =
"video/mp4v-es";
427 codec_mime =
"video/av01";
460 if (
s->width % 16 ||
s->height % 16)
462 "Video size %dx%d isn't align to 16, it may have device compatibility issue\n",
463 s->width,
s->height);
478 dev_ctx = device_ctx->
hwctx;
482 if (!
s->window && user_ctx && user_ctx->
surface)
487 av_log(avctx,
AV_LOG_ERROR,
"Missing hw_device_ctx or hwaccel_context for AV_PIX_FMT_MEDIACODEC\n");
494 if (!
s->use_ndk_codec && !
s->window->surface) {
497 "Please note that Java MediaCodec doesn't work with ANativeWindow.\n");
522 if (
s->bitrate_mode >= 0) {
540 "Use %d as the default MediaFormat i-frame-interval, "
541 "please set gop_size properly (>= fps)\n", gop);
561 "Enabling B frames will produce packets with no DTS. "
562 "Use -strict experimental to use it anyway.\n");
568 if (
s->pts_as_dts == -1)
570 if (
s->operating_rate > 0)
579 "support yuv420p as encoder input format.\n");
594 "Try MediaCodec async mode failed, %s, switch to sync mode\n",
636 if (!
s->async_mode) {
643 while (!
s->encode_status) {
648 if (
s->eof_sent && !
s->encode_status)
654 ret =
s->encode_status;
660 *out_info =
output.buf_info;
676 int extradata_size = 0;
710 if (out_info.
size <= 4) {
722 s->extradata_size = out_info.
size;
723 memcpy(
s->extradata, out_buf + out_info.
offset, out_info.
size);
733 if (
s->extradata_size) {
734 extradata_size =
s->extradata_size;
735 s->extradata_size = 0;
736 memcpy(
pkt->
data,
s->extradata, extradata_size);
747 " flags %d extradata %d\n",
762 if (!
s->async_mode) {
770 while (n < 0 && !s->encode_status) {
776 if (n < 0 && !s->encode_status)
780 ret =
s->encode_status;
793 uint8_t *input_buf =
NULL;
794 size_t input_size = 0;
869 if (!
s->frame->buf[0]) {
890 s->frame->width = avctx->
width;
891 s->frame->height = avctx->
height;
950 if (
s->async_mode || !
s->extract_extradata) {
952 "Mediacodec encoder doesn't support AV_CODEC_FLAG_GLOBAL_HEADER. "
953 "Use extract_extradata bsf when necessary.\n");
969 if (side && side_size > 0) {
976 memcpy(avctx->
extradata, side, side_size);
1040 #define OFFSET(x) offsetof(MediaCodecEncContext, x)
1041 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1042 #define COMMON_OPTION \
1043 { "ndk_codec", "Use MediaCodec from NDK", \
1044 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \
1045 { "ndk_async", "Try NDK MediaCodec in async mode", \
1046 OFFSET(async_mode), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE }, \
1047 { "codec_name", "Select codec by name", \
1048 OFFSET(name), AV_OPT_TYPE_STRING, {0}, 0, 0, VE }, \
1049 { "bitrate_mode", "Bitrate control method", \
1050 OFFSET(bitrate_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "bitrate_mode" }, \
1051 { "cq", "Constant quality mode", \
1052 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CQ}, 0, 0, VE, .unit = "bitrate_mode" }, \
1053 { "vbr", "Variable bitrate mode", \
1054 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_VBR}, 0, 0, VE, .unit = "bitrate_mode" }, \
1055 { "cbr", "Constant bitrate mode", \
1056 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR}, 0, 0, VE, .unit = "bitrate_mode" }, \
1057 { "cbr_fd", "Constant bitrate mode with frame drops", \
1058 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR_FD}, 0, 0, VE, .unit = "bitrate_mode" }, \
1059 { "pts_as_dts", "Use PTS as DTS. It is enabled automatically if avctx max_b_frames <= 0, " \
1060 "since most of Android devices don't output B frames by default.", \
1061 OFFSET(pts_as_dts), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \
1062 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified", \
1063 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE }, \
1064 { "qp_i_min", "minimum quantization parameter for I frame", \
1065 OFFSET(qp_i_min), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE }, \
1066 { "qp_p_min", "minimum quantization parameter for P frame", \
1067 OFFSET(qp_p_min), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE }, \
1068 { "qp_b_min", "minimum quantization parameter for B frame", \
1069 OFFSET(qp_b_min), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE }, \
1070 { "qp_i_max", "maximum quantization parameter for I frame", \
1071 OFFSET(qp_i_max), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE }, \
1072 { "qp_p_max", "maximum quantization parameter for P frame", \
1073 OFFSET(qp_p_max), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE }, \
1074 { "qp_b_max", "maximum quantization parameter for B frame", \
1075 OFFSET(qp_b_max), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE }, \
1078 #define MEDIACODEC_ENCODER_CLASS(name) \
1079 static const AVClass name ## _mediacodec_class = { \
1080 .class_name = #name "_mediacodec", \
1081 .item_name = av_default_item_name, \
1082 .option = name ## _options, \
1083 .version = LIBAVUTIL_VERSION_INT, \
1086 #define DECLARE_MEDIACODEC_ENCODER(short_name, long_name, codec_id) \
1087 MEDIACODEC_ENCODER_CLASS(short_name) \
1088 const FFCodec ff_ ## short_name ## _mediacodec_encoder = { \
1089 .p.name = #short_name "_mediacodec", \
1090 CODEC_LONG_NAME(long_name " Android MediaCodec encoder"), \
1091 .p.type = AVMEDIA_TYPE_VIDEO, \
1093 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | \
1094 AV_CODEC_CAP_HARDWARE | \
1095 AV_CODEC_CAP_ENCODER_FLUSH, \
1096 .priv_data_size = sizeof(MediaCodecEncContext), \
1097 .p.pix_fmts = avc_pix_fmts, \
1098 .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG, \
1099 .defaults = mediacodec_defaults, \
1100 .init = mediacodec_init, \
1101 FF_CODEC_RECEIVE_PACKET_CB(mediacodec_encode), \
1102 .close = mediacodec_close, \
1103 .flush = mediacodec_flush, \
1104 .p.priv_class = &short_name ## _mediacodec_class, \
1105 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
1106 .p.wrapper_name = "mediacodec", \
1107 .hw_configs = mediacodec_hw_configs, \
1110 #if CONFIG_H264_MEDIACODEC_ENCODER
1112 enum MediaCodecAvcLevel {
1125 AVCLevel41 = 0x1000,
1126 AVCLevel42 = 0x2000,
1128 AVCLevel51 = 0x8000,
1129 AVCLevel52 = 0x10000,
1130 AVCLevel6 = 0x20000,
1131 AVCLevel61 = 0x40000,
1132 AVCLevel62 = 0x80000,
1147 {
"level",
"Specify level",
1174 #endif // CONFIG_H264_MEDIACODEC_ENCODER
1176 #if CONFIG_HEVC_MEDIACODEC_ENCODER
1178 enum MediaCodecHevcLevel {
1179 HEVCMainTierLevel1 = 0x1,
1180 HEVCHighTierLevel1 = 0x2,
1181 HEVCMainTierLevel2 = 0x4,
1182 HEVCHighTierLevel2 = 0x8,
1183 HEVCMainTierLevel21 = 0x10,
1184 HEVCHighTierLevel21 = 0x20,
1185 HEVCMainTierLevel3 = 0x40,
1186 HEVCHighTierLevel3 = 0x80,
1187 HEVCMainTierLevel31 = 0x100,
1188 HEVCHighTierLevel31 = 0x200,
1189 HEVCMainTierLevel4 = 0x400,
1190 HEVCHighTierLevel4 = 0x800,
1191 HEVCMainTierLevel41 = 0x1000,
1192 HEVCHighTierLevel41 = 0x2000,
1193 HEVCMainTierLevel5 = 0x4000,
1194 HEVCHighTierLevel5 = 0x8000,
1195 HEVCMainTierLevel51 = 0x10000,
1196 HEVCHighTierLevel51 = 0x20000,
1197 HEVCMainTierLevel52 = 0x40000,
1198 HEVCHighTierLevel52 = 0x80000,
1199 HEVCMainTierLevel6 = 0x100000,
1200 HEVCHighTierLevel6 = 0x200000,
1201 HEVCMainTierLevel61 = 0x400000,
1202 HEVCHighTierLevel61 = 0x800000,
1203 HEVCMainTierLevel62 = 0x1000000,
1204 HEVCHighTierLevel62 = 0x2000000,
1213 {
"level",
"Specify tier and level",
1215 {
"m1",
"Main tier level 1",
1217 {
"h1",
"High tier level 1",
1219 {
"m2",
"Main tier level 2",
1221 {
"h2",
"High tier level 2",
1223 {
"m2.1",
"Main tier level 2.1",
1225 {
"h2.1",
"High tier level 2.1",
1227 {
"m3",
"Main tier level 3",
1229 {
"h3",
"High tier level 3",
1231 {
"m3.1",
"Main tier level 3.1",
1233 {
"h3.1",
"High tier level 3.1",
1235 {
"m4",
"Main tier level 4",
1237 {
"h4",
"High tier level 4",
1239 {
"m4.1",
"Main tier level 4.1",
1241 {
"h4.1",
"High tier level 4.1",
1243 {
"m5",
"Main tier level 5",
1245 {
"h5",
"High tier level 5",
1247 {
"m5.1",
"Main tier level 5.1",
1249 {
"h5.1",
"High tier level 5.1",
1251 {
"m5.2",
"Main tier level 5.2",
1253 {
"h5.2",
"High tier level 5.2",
1255 {
"m6",
"Main tier level 6",
1257 {
"h6",
"High tier level 6",
1259 {
"m6.1",
"Main tier level 6.1",
1261 {
"h6.1",
"High tier level 6.1",
1263 {
"m6.2",
"Main tier level 6.2",
1265 {
"h6.2",
"High tier level 6.2",
1272 #endif // CONFIG_HEVC_MEDIACODEC_ENCODER
1274 #if CONFIG_VP8_MEDIACODEC_ENCODER
1276 enum MediaCodecVP8Level {
1277 VP8Level_Version0 = 0x01,
1278 VP8Level_Version1 = 0x02,
1279 VP8Level_Version2 = 0x04,
1280 VP8Level_Version3 = 0x08,
1283 static const AVOption vp8_options[] = {
1285 {
"level",
"Specify tier and level",
1287 {
"V0",
"Level Version 0",
1289 {
"V1",
"Level Version 1",
1291 {
"V2",
"Level Version 2",
1293 {
"V3",
"Level Version 3",
1300 #endif // CONFIG_VP8_MEDIACODEC_ENCODER
1302 #if CONFIG_VP9_MEDIACODEC_ENCODER
1304 enum MediaCodecVP9Level {
1317 VP9Level61 = 0x1000,
1318 VP9Level62 = 0x2000,
1321 static const AVOption vp9_options[] = {
1329 {
"level",
"Specify tier and level",
1333 {
"1.1",
"Level 1.1",
1337 {
"2.1",
"Level 2.1",
1341 {
"3.1",
"Level 3.1",
1345 {
"4.1",
"Level 4.1",
1349 {
"5.1",
"Level 5.1",
1351 {
"5.2",
"Level 5.2",
1355 {
"6.1",
"Level 4.1",
1357 {
"6.2",
"Level 6.2",
1364 #endif // CONFIG_VP9_MEDIACODEC_ENCODER
1366 #if CONFIG_MPEG4_MEDIACODEC_ENCODER
1368 enum MediaCodecMpeg4Level {
1370 MPEG4Level0b = 0x02,
1374 MPEG4Level3b = 0x18,
1376 MPEG4Level4a = 0x40,
1378 MPEG4Level6 = 0x100,
1386 {
"level",
"Specify tier and level",
1413 #endif // CONFIG_MPEG4_MEDIACODEC_ENCODER
1415 #if CONFIG_AV1_MEDIACODEC_ENCODER
1417 enum MediaCodecAV1Level {
1431 AV1Level51 = 0x2000,
1432 AV1Level52 = 0x4000,
1433 AV1Level53 = 0x8000,
1434 AV1Level6 = 0x10000,
1435 AV1Level61 = 0x20000,
1436 AV1Level62 = 0x40000,
1437 AV1Level63 = 0x80000,
1438 AV1Level7 = 0x100000,
1439 AV1Level71 = 0x200000,
1440 AV1Level72 = 0x400000,
1441 AV1Level73 = 0x800000,
1449 {
"level",
"Specify tier and level",
1453 {
"2.1",
"Level 2.1",
1455 {
"2.2",
"Level 2.2",
1457 {
"2.3",
"Level 2.3",
1461 {
"3.1",
"Level 3.1",
1463 {
"3.2",
"Level 3.2",
1465 {
"3.3",
"Level 3.3",
1469 {
"4.1",
"Level 4.1",
1471 {
"4.2",
"Level 4.2",
1473 {
"4.3",
"Level 4.3",
1477 {
"5.1",
"Level 5.1",
1479 {
"5.2",
"Level 5.2",
1481 {
"5.3",
"Level 5.3",
1485 {
"6.1",
"Level 6.1",
1487 {
"6.2",
"Level 6.2",
1489 {
"6.3",
"Level 6.3",
1493 {
"7.1",
"Level 7.1",
1495 {
"7.2",
"Level 7.2",
1497 {
"7.3",
"Level 7.3",
1504 #endif // CONFIG_AV1_MEDIACODEC_ENCODER