23 #include "config_components.h" 
   41 #define INPUT_DEQUEUE_TIMEOUT_US 8000 
   42 #define OUTPUT_DEQUEUE_TIMEOUT_US 8000 
  119     int crop_right = 
s->width - avctx->
width;
 
  120     int crop_bottom = 
s->height - avctx->
height;
 
  122     if (!crop_right && !crop_bottom)
 
  126         ret = 
snprintf(str, 
sizeof(str), 
"h264_metadata=crop_right=%d:crop_bottom=%d",
 
  127                  crop_right, crop_bottom);
 
  129         ret = 
snprintf(str, 
sizeof(str), 
"hevc_metadata=crop_right=%d:crop_bottom=%d",
 
  130                  crop_right, crop_bottom);
 
  134     if (
ret >= 
sizeof(str))
 
  152     const char *codec_mime = 
NULL;
 
  158     if (
s->use_ndk_codec < 0)
 
  163         codec_mime = 
"video/avc";
 
  166         codec_mime = 
"video/hevc";
 
  169         codec_mime = 
"video/x-vnd.on2.vp8";
 
  172         codec_mime = 
"video/x-vnd.on2.vp9";
 
  175         codec_mime = 
"video/mp4v-es";
 
  178         codec_mime = 
"video/av01";
 
  219         if (
s->width % 16 || 
s->height % 16)
 
  221                     "Video size %dx%d isn't align to 16, it may have device compatibility issue\n",
 
  222                     s->width, 
s->height);
 
  237             dev_ctx = device_ctx->
hwctx;
 
  241         if (!
s->window && user_ctx && user_ctx->
surface)
 
  246             av_log(avctx, 
AV_LOG_ERROR, 
"Missing hw_device_ctx or hwaccel_context for AV_PIX_FMT_MEDIACODEC\n");
 
  253         if (!
s->use_ndk_codec && !
s->window->surface) {
 
  256                     "Please note that Java MediaCodec doesn't work with ANativeWindow.\n");
 
  281     if (
s->bitrate_mode >= 0) {
 
  297                 "Use %d as the default MediaFormat i-frame-interval, " 
  298                 "please set gop_size properly (>= fps)\n", gop);
 
  318                     "Enabling B frames will produce packets with no DTS. " 
  319                     "Use -strict experimental to use it anyway.\n");
 
  325     if (
s->pts_as_dts == -1)
 
  334                                         "support yuv420p as encoder input format.\n");
 
  351                 "Mediacodec encoder doesn't support AV_CODEC_FLAG_GLOBAL_HEADER. " 
  352                 "Use extract_extradata bsf when necessary.\n");
 
  374     int extradata_size = 0;
 
  408         s->extradata_size = out_info.
size;
 
  409         memcpy(
s->extradata, out_buf + out_info.
offset, out_info.
size);
 
  419     if (
s->extradata_size) {
 
  420         extradata_size = 
s->extradata_size;
 
  421         s->extradata_size = 0;
 
  422         memcpy(
pkt->
data, 
s->extradata, extradata_size);
 
  434            " flags %d extradata %d\n",
 
  445     uint8_t *dst_data[4] = {};
 
  446     int dst_linesize[4] = {};
 
  450         dst_data[1] = dst + 
s->width * 
s->height;
 
  451         dst_data[2] = dst_data[1] + 
s->width * 
s->height / 4;
 
  453         dst_linesize[0] = 
s->width;
 
  454         dst_linesize[1] = dst_linesize[2] = 
s->width / 2;
 
  457         dst_data[1] = dst + 
s->width * 
s->height;
 
  459         dst_linesize[0] = 
s->width;
 
  460         dst_linesize[1] = 
s->width;
 
  474     uint8_t *input_buf = 
NULL;
 
  475     size_t input_size = 0;
 
  549         if (!
s->frame->buf[0]) {
 
  598 #define OFFSET(x) offsetof(MediaCodecEncContext, x) 
  599 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 
  600 #define COMMON_OPTION                                                                                       \ 
  601     { "ndk_codec", "Use MediaCodec from NDK",                                                               \ 
  602                     OFFSET(use_ndk_codec), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE },                      \ 
  603     { "codec_name", "Select codec by name",                                                                 \ 
  604                     OFFSET(name), AV_OPT_TYPE_STRING, {0}, 0, 0, VE },                                      \ 
  605     { "bitrate_mode", "Bitrate control method",                                                             \ 
  606                     OFFSET(bitrate_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE, .unit = "bitrate_mode" },  \ 
  607     { "cq", "Constant quality mode",                                                                                \ 
  608                     0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CQ}, 0, 0, VE, .unit = "bitrate_mode" },             \ 
  609     { "vbr", "Variable bitrate mode",                                                                               \ 
  610                     0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_VBR}, 0, 0, VE, .unit = "bitrate_mode" },            \ 
  611     { "cbr", "Constant bitrate mode",                                                                               \ 
  612                     0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR}, 0, 0, VE, .unit = "bitrate_mode" },            \ 
  613     { "cbr_fd", "Constant bitrate mode with frame drops",                                                           \ 
  614                     0, AV_OPT_TYPE_CONST, {.i64 = BITRATE_MODE_CBR_FD}, 0, 0, VE, .unit = "bitrate_mode" },         \ 
  615     { "pts_as_dts", "Use PTS as DTS. It is enabled automatically if avctx max_b_frames <= 0, "              \ 
  616                     "since most of Android devices don't output B frames by default.",                      \ 
  617                     OFFSET(pts_as_dts), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE },                         \ 
  620 #define MEDIACODEC_ENCODER_CLASS(name)              \ 
  621 static const AVClass name ## _mediacodec_class = {  \ 
  622     .class_name = #name "_mediacodec",              \ 
  623     .item_name  = av_default_item_name,             \ 
  624     .option     = name ## _options,                 \ 
  625     .version    = LIBAVUTIL_VERSION_INT,            \ 
  628 #define DECLARE_MEDIACODEC_ENCODER(short_name, long_name, codec_id)     \ 
  629 MEDIACODEC_ENCODER_CLASS(short_name)                                    \ 
  630 const FFCodec ff_ ## short_name ## _mediacodec_encoder = {              \ 
  631     .p.name           = #short_name "_mediacodec",                      \ 
  632     CODEC_LONG_NAME(long_name " Android MediaCodec encoder"),           \ 
  633     .p.type           = AVMEDIA_TYPE_VIDEO,                             \ 
  635     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY           \ 
  636                         | AV_CODEC_CAP_HARDWARE,                        \ 
  637     .priv_data_size   = sizeof(MediaCodecEncContext),                   \ 
  638     .p.pix_fmts       = avc_pix_fmts,                                   \ 
  639     .init             = mediacodec_init,                                \ 
  640     FF_CODEC_RECEIVE_PACKET_CB(mediacodec_encode),                      \ 
  641     .close            = mediacodec_close,                               \ 
  642     .p.priv_class     = &short_name ## _mediacodec_class,               \ 
  643     .caps_internal    = FF_CODEC_CAP_INIT_CLEANUP,                      \ 
  644     .p.wrapper_name = "mediacodec",                                     \ 
  645     .hw_configs     = mediacodec_hw_configs,                            \ 
  648 #if CONFIG_H264_MEDIACODEC_ENCODER 
  650 enum MediaCodecAvcLevel {
 
  667     AVCLevel52      = 0x10000,
 
  669     AVCLevel61      = 0x40000,
 
  670     AVCLevel62      = 0x80000,
 
  685     { 
"level", 
"Specify level",
 
  712 #endif  // CONFIG_H264_MEDIACODEC_ENCODER 
  714 #if CONFIG_HEVC_MEDIACODEC_ENCODER 
  716 enum MediaCodecHevcLevel {
 
  717     HEVCMainTierLevel1  = 0x1,
 
  718     HEVCHighTierLevel1  = 0x2,
 
  719     HEVCMainTierLevel2  = 0x4,
 
  720     HEVCHighTierLevel2  = 0x8,
 
  721     HEVCMainTierLevel21 = 0x10,
 
  722     HEVCHighTierLevel21 = 0x20,
 
  723     HEVCMainTierLevel3  = 0x40,
 
  724     HEVCHighTierLevel3  = 0x80,
 
  725     HEVCMainTierLevel31 = 0x100,
 
  726     HEVCHighTierLevel31 = 0x200,
 
  727     HEVCMainTierLevel4  = 0x400,
 
  728     HEVCHighTierLevel4  = 0x800,
 
  729     HEVCMainTierLevel41 = 0x1000,
 
  730     HEVCHighTierLevel41 = 0x2000,
 
  731     HEVCMainTierLevel5  = 0x4000,
 
  732     HEVCHighTierLevel5  = 0x8000,
 
  733     HEVCMainTierLevel51 = 0x10000,
 
  734     HEVCHighTierLevel51 = 0x20000,
 
  735     HEVCMainTierLevel52 = 0x40000,
 
  736     HEVCHighTierLevel52 = 0x80000,
 
  737     HEVCMainTierLevel6  = 0x100000,
 
  738     HEVCHighTierLevel6  = 0x200000,
 
  739     HEVCMainTierLevel61 = 0x400000,
 
  740     HEVCHighTierLevel61 = 0x800000,
 
  741     HEVCMainTierLevel62 = 0x1000000,
 
  742     HEVCHighTierLevel62 = 0x2000000,
 
  751     { 
"level", 
"Specify tier and level",
 
  753     { 
"m1",    
"Main tier level 1",
 
  755     { 
"h1",    
"High tier level 1",
 
  757     { 
"m2",    
"Main tier level 2",
 
  759     { 
"h2",    
"High tier level 2",
 
  761     { 
"m2.1",  
"Main tier level 2.1",
 
  763     { 
"h2.1",  
"High tier level 2.1",
 
  765     { 
"m3",    
"Main tier level 3",
 
  767     { 
"h3",    
"High tier level 3",
 
  769     { 
"m3.1",  
"Main tier level 3.1",
 
  771     { 
"h3.1",  
"High tier level 3.1",
 
  773     { 
"m4",    
"Main tier level 4",
 
  775     { 
"h4",    
"High tier level 4",
 
  777     { 
"m4.1",  
"Main tier level 4.1",
 
  779     { 
"h4.1",  
"High tier level 4.1",
 
  781     { 
"m5",    
"Main tier level 5",
 
  783     { 
"h5",    
"High tier level 5",
 
  785     { 
"m5.1",  
"Main tier level 5.1",
 
  787     { 
"h5.1",  
"High tier level 5.1",
 
  789     { 
"m5.2",  
"Main tier level 5.2",
 
  791     { 
"h5.2",  
"High tier level 5.2",
 
  793     { 
"m6",    
"Main tier level 6",
 
  795     { 
"h6",    
"High tier level 6",
 
  797     { 
"m6.1",  
"Main tier level 6.1",
 
  799     { 
"h6.1",  
"High tier level 6.1",
 
  801     { 
"m6.2",  
"Main tier level 6.2",
 
  803     { 
"h6.2",  
"High tier level 6.2",
 
  810 #endif  // CONFIG_HEVC_MEDIACODEC_ENCODER 
  812 #if CONFIG_VP8_MEDIACODEC_ENCODER 
  814 enum MediaCodecVP8Level {
 
  815     VP8Level_Version0 = 0x01,
 
  816     VP8Level_Version1 = 0x02,
 
  817     VP8Level_Version2 = 0x04,
 
  818     VP8Level_Version3 = 0x08,
 
  821 static const AVOption vp8_options[] = {
 
  823     { 
"level", 
"Specify tier and level",
 
  825     { 
"V0",    
"Level Version 0",
 
  827     { 
"V1",    
"Level Version 1",
 
  829     { 
"V2",    
"Level Version 2",
 
  831     { 
"V3",    
"Level Version 3",
 
  838 #endif  // CONFIG_VP8_MEDIACODEC_ENCODER 
  840 #if CONFIG_VP9_MEDIACODEC_ENCODER 
  842 enum MediaCodecVP9Level {
 
  859 static const AVOption vp9_options[] = {
 
  867     { 
"level", 
"Specify tier and level",
 
  871     { 
"1.1",   
"Level 1.1",
 
  875     { 
"2.1",   
"Level 2.1",
 
  879     { 
"3.1",   
"Level 3.1",
 
  883     { 
"4.1",   
"Level 4.1",
 
  887     { 
"5.1",   
"Level 5.1",
 
  889     { 
"5.2",   
"Level 5.2",
 
  893     { 
"6.1",   
"Level 4.1",
 
  895     { 
"6.2",   
"Level 6.2",
 
  902 #endif  // CONFIG_VP9_MEDIACODEC_ENCODER 
  904 #if CONFIG_MPEG4_MEDIACODEC_ENCODER 
  906 enum MediaCodecMpeg4Level {
 
  924     { 
"level", 
"Specify tier and level",
 
  951 #endif  // CONFIG_MPEG4_MEDIACODEC_ENCODER 
  953 #if CONFIG_AV1_MEDIACODEC_ENCODER 
  955 enum MediaCodecAV1Level {
 
  973     AV1Level61 = 0x20000,
 
  974     AV1Level62 = 0x40000,
 
  975     AV1Level63 = 0x80000,
 
  976     AV1Level7  = 0x100000,
 
  977     AV1Level71 = 0x200000,
 
  978     AV1Level72 = 0x400000,
 
  979     AV1Level73 = 0x800000,
 
  987     { 
"level", 
"Specify tier and level",
 
  991     { 
"2.1",    
"Level 2.1",
 
  993     { 
"2.2",    
"Level 2.2",
 
  995     { 
"2.3",    
"Level 2.3",
 
  999     { 
"3.1",    
"Level 3.1",
 
 1001     { 
"3.2",    
"Level 3.2",
 
 1003     { 
"3.3",    
"Level 3.3",
 
 1007     { 
"4.1",    
"Level 4.1",
 
 1009     { 
"4.2",    
"Level 4.2",
 
 1011     { 
"4.3",    
"Level 4.3",
 
 1015     { 
"5.1",    
"Level 5.1",
 
 1017     { 
"5.2",    
"Level 5.2",
 
 1019     { 
"5.3",    
"Level 5.3",
 
 1023     { 
"6.1",    
"Level 6.1",
 
 1025     { 
"6.2",    
"Level 6.2",
 
 1027     { 
"6.3",    
"Level 6.3",
 
 1031     { 
"7.1",    
"Level 7.1",
 
 1033     { 
"7.2",    
"Level 7.2",
 
 1035     { 
"7.3",    
"Level 7.3",
 
 1042 #endif  // CONFIG_AV1_MEDIACODEC_ENCODER