23 #include "config_components.h"
45 #define INPUT_DEQUEUE_TIMEOUT_US 8000
46 #define OUTPUT_DEQUEUE_TIMEOUT_US 8000
106 static const struct {
126 const char *
name =
s->name;
167 int crop_right =
s->width - avctx->
width;
168 int crop_bottom =
s->height - avctx->
height;
176 if (!crop_right && !crop_bottom && !
s->extract_extradata)
180 if (crop_right || crop_bottom) {
182 ret =
snprintf(str,
sizeof(str),
"h264_metadata=crop_right=%d:crop_bottom=%d",
183 crop_right, crop_bottom);
189 ret =
snprintf(str,
sizeof(str),
"hevc_metadata=width=%d:height=%d",
191 if (
ret >=
sizeof(str))
195 if (
s->extract_extradata) {
197 if (
ret >=
sizeof(str))
218 uint8_t *dst_data[4] = {};
219 int dst_linesize[4] = {};
223 dst_data[1] =
dst +
s->width *
s->height;
224 dst_data[2] = dst_data[1] +
s->width *
s->height / 4;
226 dst_linesize[0] =
s->width;
227 dst_linesize[1] = dst_linesize[2] =
s->width / 2;
230 dst_data[1] =
dst +
s->width *
s->height;
232 dst_linesize[0] =
s->width;
233 dst_linesize[1] =
s->width;
278 on_error(codec, userdata,
ret,
"av_fifo_write failed");
289 .buf_info = *out_info,
300 on_error(codec, userdata,
ret,
"av_fifo_write failed");
327 if (!
s->input_index || !
s->async_output)
356 const char *codec_mime =
NULL;
367 if (
s->use_ndk_codec < 0)
372 codec_mime =
"video/avc";
375 codec_mime =
"video/hevc";
378 codec_mime =
"video/x-vnd.on2.vp8";
381 codec_mime =
"video/x-vnd.on2.vp9";
384 codec_mime =
"video/mp4v-es";
387 codec_mime =
"video/av01";
420 if (
s->width % 16 ||
s->height % 16)
422 "Video size %dx%d isn't align to 16, it may have device compatibility issue\n",
423 s->width,
s->height);
438 dev_ctx = device_ctx->
hwctx;
442 if (!
s->window && user_ctx && user_ctx->
surface)
447 av_log(avctx,
AV_LOG_ERROR,
"Missing hw_device_ctx or hwaccel_context for AV_PIX_FMT_MEDIACODEC\n");
454 if (!
s->use_ndk_codec && !
s->window->surface) {
457 "Please note that Java MediaCodec doesn't work with ANativeWindow.\n");
482 if (
s->bitrate_mode >= 0) {
498 "Use %d as the default MediaFormat i-frame-interval, "
499 "please set gop_size properly (>= fps)\n", gop);
519 "Enabling B frames will produce packets with no DTS. "
520 "Use -strict experimental to use it anyway.\n");
526 if (
s->pts_as_dts == -1)
528 if (
s->operating_rate > 0)
537 "support yuv420p as encoder input format.\n");
552 "Try MediaCodec async mode failed, %s, switch to sync mode\n",
594 if (!
s->async_mode) {
601 while (!
s->encode_status) {
606 if (
s->eof_sent && !
s->encode_status)
612 ret =
s->encode_status;
618 *out_info =
output.buf_info;
634 int extradata_size = 0;
668 if (out_info.
size <= 4) {
680 s->extradata_size = out_info.
size;
681 memcpy(
s->extradata, out_buf + out_info.
offset, out_info.
size);
691 if (
s->extradata_size) {
692 extradata_size =
s->extradata_size;
693 s->extradata_size = 0;
694 memcpy(
pkt->
data,
s->extradata, extradata_size);
705 " flags %d extradata %d\n",
720 if (!
s->async_mode) {
728 while (n < 0 && !s->encode_status) {
734 if (n < 0 && !s->encode_status)
738 ret =
s->encode_status;
751 uint8_t *input_buf =
NULL;
752 size_t input_size = 0;
827 if (!
s->frame->buf[0]) {
848 s->frame->width = avctx->
width;
849 s->frame->height = avctx->
height;
908 if (
s->async_mode || !
s->extract_extradata) {
910 "Mediacodec encoder doesn't support AV_CODEC_FLAG_GLOBAL_HEADER. "
911 "Use extract_extradata bsf when necessary.\n");
927 if (side && side_size > 0) {
934 memcpy(avctx->
extradata, side, side_size);
992 #define OFFSET(x) offsetof(MediaCodecEncContext, x)
993 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
994 #define COMMON_OPTION \
995 { "ndk_codec", "Use MediaCodec from NDK", \
996 OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \
997 { "ndk_async", "Try NDK MediaCodec in async mode", \
998 OFFSET(async_mode), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE }, \
999 { "codec_name", "Select codec by name", \
1000 OFFSET(name), AV_OPT_TYPE_STRING, {0}, 0, 0, VE }, \
1001 { "bitrate_mode", "Bitrate control method", \
1002 OFFSET(bitrate_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "bitrate_mode" }, \
1003 { "cq", "Constant quality mode", \
1004 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CQ}, 0, 0, VE, .unit = "bitrate_mode" }, \
1005 { "vbr", "Variable bitrate mode", \
1006 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_VBR}, 0, 0, VE, .unit = "bitrate_mode" }, \
1007 { "cbr", "Constant bitrate mode", \
1008 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR}, 0, 0, VE, .unit = "bitrate_mode" }, \
1009 { "cbr_fd", "Constant bitrate mode with frame drops", \
1010 0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR_FD}, 0, 0, VE, .unit = "bitrate_mode" }, \
1011 { "pts_as_dts", "Use PTS as DTS. It is enabled automatically if avctx max_b_frames <= 0, " \
1012 "since most of Android devices don't output B frames by default.", \
1013 OFFSET(pts_as_dts), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE }, \
1014 { "operating_rate", "The desired operating rate that the codec will need to operate at, zero for unspecified", \
1015 OFFSET(operating_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE }, \
1017 #define MEDIACODEC_ENCODER_CLASS(name) \
1018 static const AVClass name ## _mediacodec_class = { \
1019 .class_name = #name "_mediacodec", \
1020 .item_name = av_default_item_name, \
1021 .option = name ## _options, \
1022 .version = LIBAVUTIL_VERSION_INT, \
1025 #define DECLARE_MEDIACODEC_ENCODER(short_name, long_name, codec_id) \
1026 MEDIACODEC_ENCODER_CLASS(short_name) \
1027 const FFCodec ff_ ## short_name ## _mediacodec_encoder = { \
1028 .p.name = #short_name "_mediacodec", \
1029 CODEC_LONG_NAME(long_name " Android MediaCodec encoder"), \
1030 .p.type = AVMEDIA_TYPE_VIDEO, \
1032 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | \
1033 AV_CODEC_CAP_HARDWARE | \
1034 AV_CODEC_CAP_ENCODER_FLUSH, \
1035 .priv_data_size = sizeof(MediaCodecEncContext), \
1036 .p.pix_fmts = avc_pix_fmts, \
1037 .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG, \
1038 .init = mediacodec_init, \
1039 FF_CODEC_RECEIVE_PACKET_CB(mediacodec_encode), \
1040 .close = mediacodec_close, \
1041 .flush = mediacodec_flush, \
1042 .p.priv_class = &short_name ## _mediacodec_class, \
1043 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
1044 .p.wrapper_name = "mediacodec", \
1045 .hw_configs = mediacodec_hw_configs, \
1048 #if CONFIG_H264_MEDIACODEC_ENCODER
1050 enum MediaCodecAvcLevel {
1063 AVCLevel41 = 0x1000,
1064 AVCLevel42 = 0x2000,
1066 AVCLevel51 = 0x8000,
1067 AVCLevel52 = 0x10000,
1068 AVCLevel6 = 0x20000,
1069 AVCLevel61 = 0x40000,
1070 AVCLevel62 = 0x80000,
1085 {
"level",
"Specify level",
1112 #endif // CONFIG_H264_MEDIACODEC_ENCODER
1114 #if CONFIG_HEVC_MEDIACODEC_ENCODER
1116 enum MediaCodecHevcLevel {
1117 HEVCMainTierLevel1 = 0x1,
1118 HEVCHighTierLevel1 = 0x2,
1119 HEVCMainTierLevel2 = 0x4,
1120 HEVCHighTierLevel2 = 0x8,
1121 HEVCMainTierLevel21 = 0x10,
1122 HEVCHighTierLevel21 = 0x20,
1123 HEVCMainTierLevel3 = 0x40,
1124 HEVCHighTierLevel3 = 0x80,
1125 HEVCMainTierLevel31 = 0x100,
1126 HEVCHighTierLevel31 = 0x200,
1127 HEVCMainTierLevel4 = 0x400,
1128 HEVCHighTierLevel4 = 0x800,
1129 HEVCMainTierLevel41 = 0x1000,
1130 HEVCHighTierLevel41 = 0x2000,
1131 HEVCMainTierLevel5 = 0x4000,
1132 HEVCHighTierLevel5 = 0x8000,
1133 HEVCMainTierLevel51 = 0x10000,
1134 HEVCHighTierLevel51 = 0x20000,
1135 HEVCMainTierLevel52 = 0x40000,
1136 HEVCHighTierLevel52 = 0x80000,
1137 HEVCMainTierLevel6 = 0x100000,
1138 HEVCHighTierLevel6 = 0x200000,
1139 HEVCMainTierLevel61 = 0x400000,
1140 HEVCHighTierLevel61 = 0x800000,
1141 HEVCMainTierLevel62 = 0x1000000,
1142 HEVCHighTierLevel62 = 0x2000000,
1151 {
"level",
"Specify tier and level",
1153 {
"m1",
"Main tier level 1",
1155 {
"h1",
"High tier level 1",
1157 {
"m2",
"Main tier level 2",
1159 {
"h2",
"High tier level 2",
1161 {
"m2.1",
"Main tier level 2.1",
1163 {
"h2.1",
"High tier level 2.1",
1165 {
"m3",
"Main tier level 3",
1167 {
"h3",
"High tier level 3",
1169 {
"m3.1",
"Main tier level 3.1",
1171 {
"h3.1",
"High tier level 3.1",
1173 {
"m4",
"Main tier level 4",
1175 {
"h4",
"High tier level 4",
1177 {
"m4.1",
"Main tier level 4.1",
1179 {
"h4.1",
"High tier level 4.1",
1181 {
"m5",
"Main tier level 5",
1183 {
"h5",
"High tier level 5",
1185 {
"m5.1",
"Main tier level 5.1",
1187 {
"h5.1",
"High tier level 5.1",
1189 {
"m5.2",
"Main tier level 5.2",
1191 {
"h5.2",
"High tier level 5.2",
1193 {
"m6",
"Main tier level 6",
1195 {
"h6",
"High tier level 6",
1197 {
"m6.1",
"Main tier level 6.1",
1199 {
"h6.1",
"High tier level 6.1",
1201 {
"m6.2",
"Main tier level 6.2",
1203 {
"h6.2",
"High tier level 6.2",
1210 #endif // CONFIG_HEVC_MEDIACODEC_ENCODER
1212 #if CONFIG_VP8_MEDIACODEC_ENCODER
1214 enum MediaCodecVP8Level {
1215 VP8Level_Version0 = 0x01,
1216 VP8Level_Version1 = 0x02,
1217 VP8Level_Version2 = 0x04,
1218 VP8Level_Version3 = 0x08,
1221 static const AVOption vp8_options[] = {
1223 {
"level",
"Specify tier and level",
1225 {
"V0",
"Level Version 0",
1227 {
"V1",
"Level Version 1",
1229 {
"V2",
"Level Version 2",
1231 {
"V3",
"Level Version 3",
1238 #endif // CONFIG_VP8_MEDIACODEC_ENCODER
1240 #if CONFIG_VP9_MEDIACODEC_ENCODER
1242 enum MediaCodecVP9Level {
1255 VP9Level61 = 0x1000,
1256 VP9Level62 = 0x2000,
1259 static const AVOption vp9_options[] = {
1267 {
"level",
"Specify tier and level",
1271 {
"1.1",
"Level 1.1",
1275 {
"2.1",
"Level 2.1",
1279 {
"3.1",
"Level 3.1",
1283 {
"4.1",
"Level 4.1",
1287 {
"5.1",
"Level 5.1",
1289 {
"5.2",
"Level 5.2",
1293 {
"6.1",
"Level 4.1",
1295 {
"6.2",
"Level 6.2",
1302 #endif // CONFIG_VP9_MEDIACODEC_ENCODER
1304 #if CONFIG_MPEG4_MEDIACODEC_ENCODER
1306 enum MediaCodecMpeg4Level {
1308 MPEG4Level0b = 0x02,
1312 MPEG4Level3b = 0x18,
1314 MPEG4Level4a = 0x40,
1316 MPEG4Level6 = 0x100,
1324 {
"level",
"Specify tier and level",
1351 #endif // CONFIG_MPEG4_MEDIACODEC_ENCODER
1353 #if CONFIG_AV1_MEDIACODEC_ENCODER
1355 enum MediaCodecAV1Level {
1369 AV1Level51 = 0x2000,
1370 AV1Level52 = 0x4000,
1371 AV1Level53 = 0x8000,
1372 AV1Level6 = 0x10000,
1373 AV1Level61 = 0x20000,
1374 AV1Level62 = 0x40000,
1375 AV1Level63 = 0x80000,
1376 AV1Level7 = 0x100000,
1377 AV1Level71 = 0x200000,
1378 AV1Level72 = 0x400000,
1379 AV1Level73 = 0x800000,
1387 {
"level",
"Specify tier and level",
1391 {
"2.1",
"Level 2.1",
1393 {
"2.2",
"Level 2.2",
1395 {
"2.3",
"Level 2.3",
1399 {
"3.1",
"Level 3.1",
1401 {
"3.2",
"Level 3.2",
1403 {
"3.3",
"Level 3.3",
1407 {
"4.1",
"Level 4.1",
1409 {
"4.2",
"Level 4.2",
1411 {
"4.3",
"Level 4.3",
1415 {
"5.1",
"Level 5.1",
1417 {
"5.2",
"Level 5.2",
1419 {
"5.3",
"Level 5.3",
1423 {
"6.1",
"Level 6.1",
1425 {
"6.2",
"Level 6.2",
1427 {
"6.3",
"Level 6.3",
1431 {
"7.1",
"Level 7.1",
1433 {
"7.2",
"Level 7.2",
1435 {
"7.3",
"Level 7.3",
1442 #endif // CONFIG_AV1_MEDIACODEC_ENCODER