You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

612 lines
23KB

  1. /*
  2. * Copyright (c) 2010, Google, Inc.
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * Libav is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #define AOM_DISABLE_CTRL_TYPECHECKS 1
  21. #include <aom/aom_encoder.h>
  22. #include <aom/aomcx.h>
  23. #include "libavutil/base64.h"
  24. #include "libavutil/common.h"
  25. #include "libavutil/mathematics.h"
  26. #include "libavutil/opt.h"
  27. #include "libavutil/pixdesc.h"
  28. #include "avcodec.h"
  29. #include "internal.h"
  30. #include "libaom.h"
  31. /*
  32. * Portion of struct aom_codec_cx_pkt from aom_encoder.h.
  33. * One encoded frame returned from the library.
  34. */
  35. struct FrameListData {
  36. void *buf; /* compressed data buffer */
  37. size_t sz; /* length of compressed data */
  38. int64_t pts; /* time stamp to show frame
  39. * (in timebase units) */
  40. unsigned long duration; /* duration to show frame
  41. * (in timebase units) */
  42. uint32_t flags; /* flags for this frame */
  43. struct FrameListData *next;
  44. };
  45. typedef struct AOMEncoderContext {
  46. AVClass *class;
  47. struct aom_codec_ctx encoder;
  48. struct aom_image rawimg;
  49. struct aom_fixed_buf twopass_stats;
  50. struct FrameListData *coded_frame_list;
  51. int cpu_used;
  52. int auto_alt_ref;
  53. int lag_in_frames;
  54. int error_resilient;
  55. int crf;
  56. int static_thresh;
  57. int drop_threshold;
  58. int noise_sensitivity;
  59. } AOMContext;
  60. static const char *const ctlidstr[] = {
  61. [AOME_SET_CPUUSED] = "AOME_SET_CPUUSED",
  62. [AOME_SET_CQ_LEVEL] = "AOME_SET_CQ_LEVEL",
  63. [AOME_SET_ENABLEAUTOALTREF] = "AOME_SET_ENABLEAUTOALTREF",
  64. [AOME_SET_STATIC_THRESHOLD] = "AOME_SET_STATIC_THRESHOLD",
  65. [AV1E_SET_CHROMA_SUBSAMPLING_X] = "AV1E_SET_CHROMA_SUBSAMPLING_X",
  66. [AV1E_SET_CHROMA_SUBSAMPLING_Y] = "AV1E_SET_CHROMA_SUBSAMPLING_Y",
  67. };
  68. static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
  69. {
  70. AOMContext *ctx = avctx->priv_data;
  71. const char *error = aom_codec_error(&ctx->encoder);
  72. const char *detail = aom_codec_error_detail(&ctx->encoder);
  73. av_log(avctx, AV_LOG_ERROR, "%s: %s\n", desc, error);
  74. if (detail)
  75. av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", detail);
  76. }
  77. static av_cold void dump_enc_cfg(AVCodecContext *avctx,
  78. const struct aom_codec_enc_cfg *cfg)
  79. {
  80. int width = -30;
  81. int level = AV_LOG_DEBUG;
  82. av_log(avctx, level, "aom_codec_enc_cfg\n");
  83. av_log(avctx, level, "generic settings\n"
  84. " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
  85. " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n",
  86. width, "g_usage:", cfg->g_usage,
  87. width, "g_threads:", cfg->g_threads,
  88. width, "g_profile:", cfg->g_profile,
  89. width, "g_w:", cfg->g_w,
  90. width, "g_h:", cfg->g_h,
  91. width, "g_timebase:", cfg->g_timebase.num, cfg->g_timebase.den,
  92. width, "g_error_resilient:", cfg->g_error_resilient,
  93. width, "g_pass:", cfg->g_pass,
  94. width, "g_lag_in_frames:", cfg->g_lag_in_frames);
  95. av_log(avctx, level, "rate control settings\n"
  96. " %*s%u\n %*s%d\n %*s%p(%zu)\n %*s%u\n",
  97. width, "rc_dropframe_thresh:", cfg->rc_dropframe_thresh,
  98. width, "rc_end_usage:", cfg->rc_end_usage,
  99. width, "rc_twopass_stats_in:", cfg->rc_twopass_stats_in.buf, cfg->rc_twopass_stats_in.sz,
  100. width, "rc_target_bitrate:", cfg->rc_target_bitrate);
  101. av_log(avctx, level, "quantizer settings\n"
  102. " %*s%u\n %*s%u\n",
  103. width, "rc_min_quantizer:", cfg->rc_min_quantizer,
  104. width, "rc_max_quantizer:", cfg->rc_max_quantizer);
  105. av_log(avctx, level, "bitrate tolerance\n"
  106. " %*s%u\n %*s%u\n",
  107. width, "rc_undershoot_pct:", cfg->rc_undershoot_pct,
  108. width, "rc_overshoot_pct:", cfg->rc_overshoot_pct);
  109. av_log(avctx, level, "decoder buffer model\n"
  110. " %*s%u\n %*s%u\n %*s%u\n",
  111. width, "rc_buf_sz:", cfg->rc_buf_sz,
  112. width, "rc_buf_initial_sz:", cfg->rc_buf_initial_sz,
  113. width, "rc_buf_optimal_sz:", cfg->rc_buf_optimal_sz);
  114. av_log(avctx, level, "2 pass rate control settings\n"
  115. " %*s%u\n %*s%u\n %*s%u\n",
  116. width, "rc_2pass_vbr_bias_pct:", cfg->rc_2pass_vbr_bias_pct,
  117. width, "rc_2pass_vbr_minsection_pct:", cfg->rc_2pass_vbr_minsection_pct,
  118. width, "rc_2pass_vbr_maxsection_pct:", cfg->rc_2pass_vbr_maxsection_pct);
  119. av_log(avctx, level, "keyframing settings\n"
  120. " %*s%d\n %*s%u\n %*s%u\n",
  121. width, "kf_mode:", cfg->kf_mode,
  122. width, "kf_min_dist:", cfg->kf_min_dist,
  123. width, "kf_max_dist:", cfg->kf_max_dist);
  124. av_log(avctx, level, "\n");
  125. }
  126. static void coded_frame_add(void *list, struct FrameListData *cx_frame)
  127. {
  128. struct FrameListData **p = list;
  129. while (*p)
  130. p = &(*p)->next;
  131. *p = cx_frame;
  132. cx_frame->next = NULL;
  133. }
  134. static av_cold void free_coded_frame(struct FrameListData *cx_frame)
  135. {
  136. av_freep(&cx_frame->buf);
  137. av_freep(&cx_frame);
  138. }
  139. static av_cold void free_frame_list(struct FrameListData *list)
  140. {
  141. struct FrameListData *p = list;
  142. while (p) {
  143. list = list->next;
  144. free_coded_frame(p);
  145. p = list;
  146. }
  147. }
  148. static av_cold int codecctl_int(AVCodecContext *avctx,
  149. enum aome_enc_control_id id, int val)
  150. {
  151. AOMContext *ctx = avctx->priv_data;
  152. char buf[80];
  153. int width = -30;
  154. int res;
  155. snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
  156. av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, val);
  157. res = aom_codec_control(&ctx->encoder, id, val);
  158. if (res != AOM_CODEC_OK) {
  159. snprintf(buf, sizeof(buf), "Failed to set %s codec control",
  160. ctlidstr[id]);
  161. log_encoder_error(avctx, buf);
  162. return AVERROR(EINVAL);
  163. }
  164. return 0;
  165. }
  166. static av_cold int aom_free(AVCodecContext *avctx)
  167. {
  168. AOMContext *ctx = avctx->priv_data;
  169. aom_codec_destroy(&ctx->encoder);
  170. av_freep(&ctx->twopass_stats.buf);
  171. av_freep(&avctx->stats_out);
  172. free_frame_list(ctx->coded_frame_list);
  173. return 0;
  174. }
  175. static av_cold int aom_init(AVCodecContext *avctx)
  176. {
  177. AOMContext *ctx = avctx->priv_data;
  178. struct aom_codec_enc_cfg enccfg = { 0 };
  179. AVCPBProperties *cpb_props;
  180. int res, h_shift, v_shift;
  181. const struct aom_codec_iface *iface = &aom_codec_av1_cx_algo;
  182. av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
  183. av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
  184. if ((res = aom_codec_enc_config_default(iface, &enccfg, 0)) != AOM_CODEC_OK) {
  185. av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n",
  186. aom_codec_err_to_string(res));
  187. return AVERROR(EINVAL);
  188. }
  189. dump_enc_cfg(avctx, &enccfg);
  190. enccfg.g_w = avctx->width;
  191. enccfg.g_h = avctx->height;
  192. enccfg.g_timebase.num = avctx->time_base.num;
  193. enccfg.g_timebase.den = avctx->time_base.den;
  194. enccfg.g_threads = avctx->thread_count;
  195. if (ctx->lag_in_frames >= 0)
  196. enccfg.g_lag_in_frames = ctx->lag_in_frames;
  197. if (avctx->flags & AV_CODEC_FLAG_PASS1)
  198. enccfg.g_pass = AOM_RC_FIRST_PASS;
  199. else if (avctx->flags & AV_CODEC_FLAG_PASS2)
  200. enccfg.g_pass = AOM_RC_LAST_PASS;
  201. else
  202. enccfg.g_pass = AOM_RC_ONE_PASS;
  203. if (!avctx->bit_rate)
  204. avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
  205. else
  206. enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
  207. AV_ROUND_NEAR_INF);
  208. if (ctx->crf)
  209. enccfg.rc_end_usage = AOM_CQ;
  210. else if (avctx->rc_min_rate == avctx->rc_max_rate &&
  211. avctx->rc_min_rate == avctx->bit_rate)
  212. enccfg.rc_end_usage = AOM_CBR;
  213. if (avctx->qmin > 0)
  214. enccfg.rc_min_quantizer = avctx->qmin;
  215. if (avctx->qmax > 0)
  216. enccfg.rc_max_quantizer = avctx->qmax;
  217. enccfg.rc_dropframe_thresh = ctx->drop_threshold;
  218. // 0-100 (0 => CBR, 100 => VBR)
  219. enccfg.rc_2pass_vbr_bias_pct = round(avctx->qcompress * 100);
  220. enccfg.rc_2pass_vbr_minsection_pct =
  221. avctx->rc_min_rate * 100LL / avctx->bit_rate;
  222. if (avctx->rc_max_rate)
  223. enccfg.rc_2pass_vbr_maxsection_pct =
  224. avctx->rc_max_rate * 100LL / avctx->bit_rate;
  225. if (avctx->rc_buffer_size)
  226. enccfg.rc_buf_sz =
  227. avctx->rc_buffer_size * 1000LL / avctx->bit_rate;
  228. if (avctx->rc_initial_buffer_occupancy)
  229. enccfg.rc_buf_initial_sz =
  230. avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate;
  231. enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6;
  232. // _enc_init() will balk if kf_min_dist differs from max w/AOM_KF_AUTO
  233. if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
  234. enccfg.kf_min_dist = avctx->keyint_min;
  235. if (avctx->gop_size >= 0)
  236. enccfg.kf_max_dist = avctx->gop_size;
  237. if (enccfg.g_pass == AOM_RC_FIRST_PASS)
  238. enccfg.g_lag_in_frames = 0;
  239. else if (enccfg.g_pass == AOM_RC_LAST_PASS) {
  240. int decode_size, ret;
  241. if (!avctx->stats_in) {
  242. av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n");
  243. return AVERROR_INVALIDDATA;
  244. }
  245. ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4;
  246. ret = av_reallocp(&ctx->twopass_stats.buf, ctx->twopass_stats.sz);
  247. if (ret < 0) {
  248. av_log(avctx, AV_LOG_ERROR,
  249. "Stat buffer alloc (%zu bytes) failed\n",
  250. ctx->twopass_stats.sz);
  251. return ret;
  252. }
  253. decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in,
  254. ctx->twopass_stats.sz);
  255. if (decode_size < 0) {
  256. av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n");
  257. return AVERROR_INVALIDDATA;
  258. }
  259. ctx->twopass_stats.sz = decode_size;
  260. enccfg.rc_twopass_stats_in = ctx->twopass_stats;
  261. }
  262. /* 0-3: For non-zero values the encoder increasingly optimizes for reduced
  263. * complexity playback on low powered devices at the expense of encode
  264. * quality. */
  265. if (avctx->profile != FF_PROFILE_UNKNOWN)
  266. enccfg.g_profile = avctx->profile;
  267. else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
  268. avctx->pix_fmt == AV_PIX_FMT_YUV420P10)
  269. avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_MAIN;
  270. else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
  271. avctx->pix_fmt == AV_PIX_FMT_YUV444P10)
  272. avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_HIGH;
  273. else {
  274. avctx->profile = enccfg.g_profile = FF_PROFILE_AV1_PROFESSIONAL;
  275. }
  276. enccfg.g_error_resilient = ctx->error_resilient;
  277. dump_enc_cfg(avctx, &enccfg);
  278. /* Construct Encoder Context */
  279. res = aom_codec_enc_init(&ctx->encoder, iface, &enccfg, 0);
  280. if (res != AOM_CODEC_OK) {
  281. log_encoder_error(avctx, "Failed to initialize encoder");
  282. return AVERROR(EINVAL);
  283. }
  284. // codec control failures are currently treated only as warnings
  285. av_log(avctx, AV_LOG_DEBUG, "aom_codec_control\n");
  286. if (ctx->cpu_used != INT_MIN)
  287. codecctl_int(avctx, AOME_SET_CPUUSED, ctx->cpu_used);
  288. if (ctx->auto_alt_ref >= 0)
  289. codecctl_int(avctx, AOME_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref);
  290. codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh);
  291. codecctl_int(avctx, AOME_SET_CQ_LEVEL, ctx->crf);
  292. res = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &h_shift, &v_shift);
  293. if (res < 0)
  294. return res;
  295. codecctl_int(avctx, AV1E_SET_CHROMA_SUBSAMPLING_X, h_shift);
  296. codecctl_int(avctx, AV1E_SET_CHROMA_SUBSAMPLING_Y, v_shift);
  297. // provide dummy value to initialize wrapper, values will be updated each _encode()
  298. aom_img_wrap(&ctx->rawimg, ff_aom_pixfmt_to_imgfmt(avctx->pix_fmt),
  299. avctx->width, avctx->height, 1, (unsigned char *)1);
  300. cpb_props = ff_add_cpb_side_data(avctx);
  301. if (!cpb_props)
  302. return AVERROR(ENOMEM);
  303. if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
  304. aom_fixed_buf_t *seq = aom_codec_get_global_headers(&ctx->encoder);
  305. if (!seq)
  306. return AVERROR_UNKNOWN;
  307. avctx->extradata = av_malloc(seq->sz + AV_INPUT_BUFFER_PADDING_SIZE);
  308. if (!avctx->extradata) {
  309. free(seq->buf);
  310. free(seq);
  311. return AVERROR(ENOMEM);
  312. }
  313. avctx->extradata_size = seq->sz;
  314. memcpy(avctx->extradata, seq->buf, seq->sz);
  315. memset(avctx->extradata + seq->sz, 0, AV_INPUT_BUFFER_PADDING_SIZE);
  316. /* Doxy says: "The caller owns the memory associated with this buffer.
  317. * Memory is allocated using malloc(), and should be freed
  318. * via call to free()"
  319. */
  320. free(seq->buf);
  321. free(seq);
  322. }
  323. if (enccfg.rc_end_usage == AOM_CBR ||
  324. enccfg.g_pass != AOM_RC_ONE_PASS) {
  325. cpb_props->max_bitrate = avctx->rc_max_rate;
  326. cpb_props->min_bitrate = avctx->rc_min_rate;
  327. cpb_props->avg_bitrate = avctx->bit_rate;
  328. }
  329. cpb_props->buffer_size = avctx->rc_buffer_size;
  330. return 0;
  331. }
  332. static inline void cx_pktcpy(struct FrameListData *dst,
  333. const struct aom_codec_cx_pkt *src)
  334. {
  335. dst->pts = src->data.frame.pts;
  336. dst->duration = src->data.frame.duration;
  337. dst->flags = src->data.frame.flags;
  338. dst->sz = src->data.frame.sz;
  339. dst->buf = src->data.frame.buf;
  340. }
  341. /**
  342. * Store coded frame information in format suitable for return from encode2().
  343. *
  344. * Write information from @a cx_frame to @a pkt
  345. * @return packet data size on success
  346. * @return a negative AVERROR on error
  347. */
  348. static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
  349. AVPacket *pkt)
  350. {
  351. int ret = ff_alloc_packet(pkt, cx_frame->sz);
  352. if (ret < 0) {
  353. av_log(avctx, AV_LOG_ERROR,
  354. "Error getting output packet of size %zu.\n", cx_frame->sz);
  355. return ret;
  356. }
  357. memcpy(pkt->data, cx_frame->buf, pkt->size);
  358. pkt->pts = pkt->dts = cx_frame->pts;
  359. if (!!(cx_frame->flags & AOM_FRAME_IS_KEY))
  360. pkt->flags |= AV_PKT_FLAG_KEY;
  361. return pkt->size;
  362. }
  363. /**
  364. * Queue multiple output frames from the encoder, returning the front-most.
  365. * In cases where aom_codec_get_cx_data() returns more than 1 frame append
  366. * the frame queue. Return the head frame if available.
  367. * @return Stored frame size
  368. * @return AVERROR(EINVAL) on output size error
  369. * @return AVERROR(ENOMEM) on coded frame queue data allocation error
  370. */
  371. static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
  372. {
  373. AOMContext *ctx = avctx->priv_data;
  374. const struct aom_codec_cx_pkt *pkt;
  375. const void *iter = NULL;
  376. int size = 0;
  377. if (ctx->coded_frame_list) {
  378. struct FrameListData *cx_frame = ctx->coded_frame_list;
  379. /* return the leading frame if we've already begun queueing */
  380. size = storeframe(avctx, cx_frame, pkt_out);
  381. if (size < 0)
  382. return size;
  383. ctx->coded_frame_list = cx_frame->next;
  384. free_coded_frame(cx_frame);
  385. }
  386. /* consume all available output from the encoder before returning. buffers
  387. * are only good through the next aom_codec call */
  388. while ((pkt = aom_codec_get_cx_data(&ctx->encoder, &iter))) {
  389. switch (pkt->kind) {
  390. case AOM_CODEC_CX_FRAME_PKT:
  391. if (!size) {
  392. struct FrameListData cx_frame;
  393. /* avoid storing the frame when the list is empty and we haven't yet
  394. * provided a frame for output */
  395. assert(!ctx->coded_frame_list);
  396. cx_pktcpy(&cx_frame, pkt);
  397. size = storeframe(avctx, &cx_frame, pkt_out);
  398. if (size < 0)
  399. return size;
  400. } else {
  401. struct FrameListData *cx_frame =
  402. av_malloc(sizeof(struct FrameListData));
  403. if (!cx_frame) {
  404. av_log(avctx, AV_LOG_ERROR,
  405. "Frame queue element alloc failed\n");
  406. return AVERROR(ENOMEM);
  407. }
  408. cx_pktcpy(cx_frame, pkt);
  409. cx_frame->buf = av_malloc(cx_frame->sz);
  410. if (!cx_frame->buf) {
  411. av_log(avctx, AV_LOG_ERROR,
  412. "Data buffer alloc (%zu bytes) failed\n",
  413. cx_frame->sz);
  414. av_freep(&cx_frame);
  415. return AVERROR(ENOMEM);
  416. }
  417. memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
  418. coded_frame_add(&ctx->coded_frame_list, cx_frame);
  419. }
  420. break;
  421. case AOM_CODEC_STATS_PKT:
  422. {
  423. struct aom_fixed_buf *stats = &ctx->twopass_stats;
  424. int err;
  425. if ((err = av_reallocp(&stats->buf,
  426. stats->sz +
  427. pkt->data.twopass_stats.sz)) < 0) {
  428. stats->sz = 0;
  429. av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
  430. return err;
  431. }
  432. memcpy((uint8_t *)stats->buf + stats->sz,
  433. pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
  434. stats->sz += pkt->data.twopass_stats.sz;
  435. break;
  436. }
  437. case AOM_CODEC_PSNR_PKT: // FIXME add support for AV_CODEC_FLAG_PSNR
  438. case AOM_CODEC_CUSTOM_PKT:
  439. // ignore unsupported/unrecognized packet types
  440. break;
  441. }
  442. }
  443. return size;
  444. }
  445. static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
  446. const AVFrame *frame, int *got_packet)
  447. {
  448. AOMContext *ctx = avctx->priv_data;
  449. struct aom_image *rawimg = NULL;
  450. int64_t timestamp = 0;
  451. int res, coded_size;
  452. aom_enc_frame_flags_t flags = 0;
  453. if (frame) {
  454. rawimg = &ctx->rawimg;
  455. rawimg->planes[AOM_PLANE_Y] = frame->data[0];
  456. rawimg->planes[AOM_PLANE_U] = frame->data[1];
  457. rawimg->planes[AOM_PLANE_V] = frame->data[2];
  458. rawimg->stride[AOM_PLANE_Y] = frame->linesize[0];
  459. rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
  460. rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
  461. timestamp = frame->pts;
  462. switch (frame->color_range) {
  463. case AVCOL_RANGE_MPEG:
  464. rawimg->range = AOM_CR_STUDIO_RANGE;
  465. break;
  466. case AVCOL_RANGE_JPEG:
  467. rawimg->range = AOM_CR_FULL_RANGE;
  468. break;
  469. }
  470. if (frame->pict_type == AV_PICTURE_TYPE_I)
  471. flags |= AOM_EFLAG_FORCE_KF;
  472. }
  473. res = aom_codec_encode(&ctx->encoder, rawimg, timestamp,
  474. avctx->ticks_per_frame, flags);
  475. if (res != AOM_CODEC_OK) {
  476. log_encoder_error(avctx, "Error encoding frame");
  477. return AVERROR_INVALIDDATA;
  478. }
  479. coded_size = queue_frames(avctx, pkt);
  480. if (!frame && avctx->flags & AV_CODEC_FLAG_PASS1) {
  481. size_t b64_size = AV_BASE64_SIZE(ctx->twopass_stats.sz);
  482. avctx->stats_out = av_malloc(b64_size);
  483. if (!avctx->stats_out) {
  484. av_log(avctx, AV_LOG_ERROR, "Stat buffer alloc (%zu bytes) failed\n",
  485. b64_size);
  486. return AVERROR(ENOMEM);
  487. }
  488. av_base64_encode(avctx->stats_out, b64_size, ctx->twopass_stats.buf,
  489. ctx->twopass_stats.sz);
  490. }
  491. *got_packet = !!coded_size;
  492. return 0;
  493. }
  494. #define OFFSET(x) offsetof(AOMContext, x)
  495. #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
  496. static const AVOption options[] = {
  497. { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, INT_MIN, INT_MAX, VE},
  498. { "auto-alt-ref", "Enable use of alternate reference "
  499. "frames (2-pass only)", OFFSET(auto_alt_ref), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
  500. { "lag-in-frames", "Number of frames to look ahead at for "
  501. "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
  502. { "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
  503. { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
  504. { "crf", "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE },
  505. { "static-thresh", "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
  506. { "drop-threshold", "Frame drop threshold", offsetof(AOMContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },
  507. { "noise-sensitivity", "Noise sensitivity", OFFSET(noise_sensitivity), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 4, VE},
  508. { NULL }
  509. };
  510. static const AVCodecDefault defaults[] = {
  511. { "qmin", "-1" },
  512. { "qmax", "-1" },
  513. { "g", "-1" },
  514. { "keyint_min", "-1" },
  515. { NULL },
  516. };
  517. static const AVClass class_aom = {
  518. .class_name = "libaom encoder",
  519. .item_name = av_default_item_name,
  520. .option = options,
  521. .version = LIBAVUTIL_VERSION_INT,
  522. };
  523. AVCodec ff_libaom_av1_encoder = {
  524. .name = "libaom-av1",
  525. .long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
  526. .type = AVMEDIA_TYPE_VIDEO,
  527. .id = AV_CODEC_ID_AV1,
  528. .priv_data_size = sizeof(AOMContext),
  529. .init = aom_init,
  530. .encode2 = aom_encode,
  531. .close = aom_free,
  532. .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_EXPERIMENTAL,
  533. .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
  534. .priv_class = &class_aom,
  535. .defaults = defaults,
  536. .wrapper_name = "libaom",
  537. };