1 /*
2 * librav1e encoder
3 *
4 * Copyright (c) 2019 Derek Buitenhuis
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <rav1e.h>
24
36
39
44
48
56
58 {
63 return RA_PIXEL_RANGE_FULL;
64 }
65
66 switch (range) {
68 return RA_PIXEL_RANGE_FULL;
70 default:
71 return RA_PIXEL_RANGE_LIMITED;
72 }
73 }
74
76 {
82 return RA_CHROMA_SAMPLING_CS420;
87 return RA_CHROMA_SAMPLING_CS422;
92 return RA_CHROMA_SAMPLING_CS444;
93 default:
95 }
96 }
97
99 {
100 switch (chroma_loc) {
102 return RA_CHROMA_SAMPLE_POSITION_VERTICAL;
104 return RA_CHROMA_SAMPLE_POSITION_COLOCATED;
105 default:
106 return RA_CHROMA_SAMPLE_POSITION_UNKNOWN;
107 }
108 }
109
111 {
113 RaData* buf = rav1e_twopass_out(
ctx->ctx);
114 if (!buf)
115 return 0;
116
117 if (!eos) {
119 ctx->pass_pos + buf->len);
121 rav1e_data_unref(buf);
123 }
124
126 memcpy(
ctx->pass_data +
ctx->pass_pos, buf->data, buf->len);
127 ctx->pass_pos += buf->len;
128 } else {
130
131 memcpy(
ctx->pass_data, buf->data, buf->len);
132
135 rav1e_data_unref(buf);
137 }
138
140
142 }
143
144 rav1e_data_unref(buf);
145
146 return 0;
147 }
148
150 {
153
154 while (
ret > 0 &&
ctx->pass_size -
ctx->pass_pos > 0) {
155 ret = rav1e_twopass_in(
ctx->ctx,
ctx->pass_data +
ctx->pass_pos,
ctx->pass_size);
159 }
160
161 return 0;
162 }
163
165 {
167
169 rav1e_context_unref(
ctx->ctx);
171 }
173 rav1e_frame_unref(
ctx->rframe);
175 }
176
180
181 return 0;
182 }
183
185 {
188 RaConfig *cfg =
NULL;
189 int rret;
191
195
196 cfg = rav1e_config_default();
197 if (!cfg) {
200 }
201
202 /*
203 * Rav1e currently uses the time base given to it only for ratecontrol... where
204 * the inverse is taken and used as a framerate. So, do what we do in other wrappers
205 * and use the framerate if we can.
206 */
208 rav1e_config_set_time_base(cfg, (RaRational) {
210 });
211 } else {
212 rav1e_config_set_time_base(cfg, (RaRational) {
215 });
216 }
217
221 goto end;
222 }
223
228 goto end;
229 }
230
231 ctx->pass_size = (strlen(avctx->
stats_in) * 3) / 4;
233 if (!
ctx->pass_data) {
236 goto end;
237 }
238
240 if (
ctx->pass_size < 0) {
243 goto end;
244 }
245 }
246
249 int bret;
250
253 "not found. This is a bug, please report it.\n");
255 goto end;
256 }
257
259 if (bret < 0) {
261 goto end;
262 }
263
265 if (bret < 0) {
267 goto end;
268 }
269
271 if (bret < 0) {
273 goto end;
274 }
275 }
276
277 {
280 int parse_ret = rav1e_config_parse(cfg, en->
key, en->
value);
281 if (parse_ret < 0)
283 }
284 }
285
286 rret = rav1e_config_parse_int(cfg,
"width", avctx->
width);
287 if (rret < 0) {
290 goto end;
291 }
292
293 rret = rav1e_config_parse_int(cfg,
"height", avctx->
height);
294 if (rret < 0) {
297 goto end;
298 }
299
300 rret = rav1e_config_parse_int(cfg,
"threads", avctx->
thread_count);
301 if (rret < 0)
303
304 if (
ctx->speed >= 0) {
305 rret = rav1e_config_parse_int(cfg,
"speed",
ctx->speed);
306 if (rret < 0) {
309 goto end;
310 }
311 }
312
313 /* rav1e handles precedence between 'tiles' and cols/rows for us. */
314 if (
ctx->tiles > 0) {
315 rret = rav1e_config_parse_int(cfg,
"tiles",
ctx->tiles);
316 if (rret < 0) {
319 goto end;
320 }
321 }
322 if (
ctx->tile_rows > 0) {
323 rret = rav1e_config_parse_int(cfg,
"tile_rows",
ctx->tile_rows);
324 if (rret < 0) {
327 goto end;
328 }
329 }
330 if (
ctx->tile_cols > 0) {
331 rret = rav1e_config_parse_int(cfg,
"tile_cols",
ctx->tile_cols);
332 if (rret < 0) {
335 goto end;
336 }
337 }
338
340 rret = rav1e_config_parse_int(cfg,
"key_frame_interval", avctx->
gop_size);
341 if (rret < 0) {
344 goto end;
345 }
346 }
347
349 rret = rav1e_config_parse_int(cfg,
"min_key_frame_interval", avctx->
keyint_min);
350 if (rret < 0) {
353 goto end;
354 }
355 }
356
358 int max_quantizer = avctx->
qmax >= 0 ? avctx->
qmax : 255;
359
360 rret = rav1e_config_parse_int(cfg, "quantizer", max_quantizer);
361 if (rret < 0) {
364 goto end;
365 }
366
367 if (avctx->
qmin >= 0) {
368 rret = rav1e_config_parse_int(cfg,
"min_quantizer", avctx->
qmin);
369 if (rret < 0) {
372 goto end;
373 }
374 }
375
376 rret = rav1e_config_parse_int(cfg,
"bitrate", avctx->
bit_rate);
377 if (rret < 0) {
380 goto end;
381 }
382 }
else if (
ctx->quantizer >= 0) {
385
386 rret = rav1e_config_parse_int(cfg,
"quantizer",
ctx->quantizer);
387 if (rret < 0) {
390 goto end;
391 }
392 }
393
394 rret = rav1e_config_set_pixel_format(cfg,
desc->comp[0].depth,
398 if (rret < 0) {
401 goto end;
402 }
403
404 /* rav1e's colorspace enums match standard values. */
405 rret = rav1e_config_set_color_description(cfg, (RaMatrixCoefficients) avctx->
colorspace,
407 (RaTransferCharacteristics) avctx->
color_trc);
408 if (rret < 0) {
412 goto end;
413 }
414 }
415
416 ctx->ctx = rav1e_context_new(cfg);
420 goto end;
421 }
422
424
425 end:
426
427 rav1e_config_unref(cfg);
428
430 }
431
433 {
435 RaFrame *rframe =
ctx->rframe;
436 RaPacket *rpkt =
NULL;
438
439 if (!rframe) {
441
445
448
453 }
455
456 rframe = rav1e_frame_new(
ctx->ctx);
457 if (!rframe) {
462 }
463
464 for (
int i = 0;
i <
desc->nb_components;
i++) {
466 int bytes =
desc->comp[0].depth == 8 ? 1 : 2;
467 rav1e_frame_fill_plane(rframe,
i,
frame->data[
i],
469 frame->linesize[
i], bytes);
470 }
473 }
474 }
475
476 ret = rav1e_send_frame(
ctx->ctx, rframe);
477 if (rframe)
478 if (
ret == RA_ENCODER_STATUS_ENOUGH_DATA) {
479 ctx->rframe = rframe;
/* Queue is full. Store the RaFrame to retry next call */
480 } else {
481 rav1e_frame_unref(rframe); /* No need to unref if flushing. */
483 }
484
486 case RA_ENCODER_STATUS_SUCCESS:
487 case RA_ENCODER_STATUS_ENOUGH_DATA:
488 break;
489 case RA_ENCODER_STATUS_FAILURE:
492 default:
495 }
496
497 retry:
498
501 if (sret < 0)
502 return sret;
505 if (sret < 0)
506 return sret;
507 }
508
509 ret = rav1e_receive_packet(
ctx->ctx, &rpkt);
511 case RA_ENCODER_STATUS_SUCCESS:
512 break;
513 case RA_ENCODER_STATUS_LIMIT_REACHED:
516 if (sret < 0)
517 return sret;
518 }
520 case RA_ENCODER_STATUS_ENCODED:
521 goto retry;
522 case RA_ENCODER_STATUS_NEED_MORE_DATA:
526 }
528 case RA_ENCODER_STATUS_FAILURE:
531 default:
532 av_log(avctx,
AV_LOG_ERROR,
"Unknown return code %d from rav1e_receive_packet: %s\n",
ret, rav1e_status_to_str(
ret));
534 }
535
539 rav1e_packet_unref(rpkt);
541 }
542
543 memcpy(
pkt->
data, rpkt->data, rpkt->len);
544
545 if (rpkt->frame_type == RA_FRAME_TYPE_KEY)
547
550 rav1e_packet_unref(rpkt);
551
558 }
559
565 }
566 }
567
568 return 0;
569 }
570
571 #define OFFSET(x) offsetof(librav1eContext, x)
572 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
573
580 {
"rav1e-params",
"set the rav1e configuration using a :-separated list of key=value parameters",
OFFSET(rav1e_opts),
AV_OPT_TYPE_DICT, { 0 }, 0, 0,
VE },
582 };
583
585 { "b", "0" },
586 { "g", "0" },
587 { "keyint_min", "0" },
588 { "qmax", "-1" },
589 { "qmin", "-1" },
591 };
592
607 };
608
614 };
615
625 .priv_class = &class,
631 .wrapper_name = "librav1e",
632 };