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
38
41
45
49
57
61
65
67 {
72 return RA_PIXEL_RANGE_FULL;
73 }
74
77 return RA_PIXEL_RANGE_FULL;
79 default:
80 return RA_PIXEL_RANGE_LIMITED;
81 }
82 }
83
85 {
91 return RA_CHROMA_SAMPLING_CS420;
96 return RA_CHROMA_SAMPLING_CS422;
101 return RA_CHROMA_SAMPLING_CS444;
102 default:
104 }
105 }
106
108 {
109 switch (chroma_loc) {
111 return RA_CHROMA_SAMPLE_POSITION_VERTICAL;
113 return RA_CHROMA_SAMPLE_POSITION_COLOCATED;
114 default:
115 return RA_CHROMA_SAMPLE_POSITION_UNKNOWN;
116 }
117 }
118
120 {
122 RaData* buf = rav1e_twopass_out(
ctx->ctx);
123 if (!buf)
124 return 0;
125
126 if (!eos) {
128 ctx->pass_pos + buf->len);
130 rav1e_data_unref(buf);
132 }
133
135 memcpy(
ctx->pass_data +
ctx->pass_pos, buf->data, buf->len);
136 ctx->pass_pos += buf->len;
137 } else {
139
140 memcpy(
ctx->pass_data, buf->data, buf->len);
141
144 rav1e_data_unref(buf);
146 }
147
149
151 }
152
153 rav1e_data_unref(buf);
154
155 return 0;
156 }
157
159 {
162
163 while (
ret > 0 &&
ctx->pass_size -
ctx->pass_pos > 0) {
164 ret = rav1e_twopass_in(
ctx->ctx,
ctx->pass_data +
ctx->pass_pos,
ctx->pass_size);
168 }
169
170 return 0;
171 }
172
174 {
176
178 rav1e_context_unref(
ctx->ctx);
180 }
182 rav1e_frame_unref(
ctx->rframe);
184 }
185
188
189 return 0;
190 }
191
193 {
196 RaConfig *cfg =
NULL;
197 int rret;
199
203
204 cfg = rav1e_config_default();
205 if (!cfg) {
208 }
209
210 /*
211 * Rav1e currently uses the time base given to it only for ratecontrol... where
212 * the inverse is taken and used as a framerate. So, do what we do in other wrappers
213 * and use the framerate if we can.
214 */
216 rav1e_config_set_time_base(cfg, (RaRational) {
218 });
219 } else {
221 rav1e_config_set_time_base(cfg, (RaRational) {
223 #if FF_API_TICKS_PER_FRAME
225 #endif
227 });
229 }
230
234 goto end;
235 }
236
241 goto end;
242 }
243
244 ctx->pass_size = (strlen(avctx->
stats_in) * 3) / 4;
246 if (!
ctx->pass_data) {
249 goto end;
250 }
251
253 if (
ctx->pass_size < 0) {
256 goto end;
257 }
258 }
259
260 {
263 if (rav1e_config_parse(cfg, en->
key, en->
value) < 0)
265 }
266 }
267
268 rret = rav1e_config_parse_int(cfg,
"width", avctx->
width);
269 if (rret < 0) {
272 goto end;
273 }
274
275 rret = rav1e_config_parse_int(cfg,
"height", avctx->
height);
276 if (rret < 0) {
279 goto end;
280 }
281
283 rav1e_config_set_sample_aspect_ratio(cfg, (RaRational) {
286 });
287
288 rret = rav1e_config_parse_int(cfg,
"threads", avctx->
thread_count);
289 if (rret < 0)
291
292 if (
ctx->speed >= 0) {
293 rret = rav1e_config_parse_int(cfg,
"speed",
ctx->speed);
294 if (rret < 0) {
297 goto end;
298 }
299 }
300
301 /* rav1e handles precedence between 'tiles' and cols/rows for us. */
302 if (
ctx->tiles > 0) {
303 rret = rav1e_config_parse_int(cfg,
"tiles",
ctx->tiles);
304 if (rret < 0) {
307 goto end;
308 }
309 }
310 if (
ctx->tile_rows > 0) {
311 rret = rav1e_config_parse_int(cfg,
"tile_rows",
ctx->tile_rows);
312 if (rret < 0) {
315 goto end;
316 }
317 }
318 if (
ctx->tile_cols > 0) {
319 rret = rav1e_config_parse_int(cfg,
"tile_cols",
ctx->tile_cols);
320 if (rret < 0) {
323 goto end;
324 }
325 }
326
328 rret = rav1e_config_parse_int(cfg,
"key_frame_interval", avctx->
gop_size);
329 if (rret < 0) {
332 goto end;
333 }
334 }
335
337 rret = rav1e_config_parse_int(cfg,
"min_key_frame_interval", avctx->
keyint_min);
338 if (rret < 0) {
341 goto end;
342 }
343 }
344
346 int max_quantizer = avctx->
qmax >= 0 ? avctx->
qmax : 255;
347
348 rret = rav1e_config_parse_int(cfg, "quantizer", max_quantizer);
349 if (rret < 0) {
352 goto end;
353 }
354
355 if (avctx->
qmin >= 0) {
356 rret = rav1e_config_parse_int(cfg,
"min_quantizer", avctx->
qmin);
357 if (rret < 0) {
360 goto end;
361 }
362 }
363
364 rret = rav1e_config_parse_int(cfg,
"bitrate", avctx->
bit_rate);
365 if (rret < 0) {
368 goto end;
369 }
370 }
else if (
ctx->quantizer >= 0) {
373
374 rret = rav1e_config_parse_int(cfg,
"quantizer",
ctx->quantizer);
375 if (rret < 0) {
378 goto end;
379 }
380 }
381
382 rret = rav1e_config_set_pixel_format(cfg,
desc->comp[0].depth,
386 if (rret < 0) {
389 goto end;
390 }
391
392 /* rav1e's colorspace enums match standard values. */
393 rret = rav1e_config_set_color_description(cfg, (RaMatrixCoefficients) avctx->
colorspace,
395 (RaTransferCharacteristics) avctx->
color_trc);
396 if (rret < 0) {
400 goto end;
401 }
402 }
403
404 ctx->ctx = rav1e_context_new(cfg);
408 goto end;
409 }
410
412 RaData *seq_hdr = rav1e_container_sequence_header(
ctx->ctx);
413
414 if (seq_hdr)
417 rav1e_data_unref(seq_hdr);
420 goto end;
421 }
422
423 memcpy(avctx->
extradata, seq_hdr->data, seq_hdr->len);
425 rav1e_data_unref(seq_hdr);
426 }
427
429
430 end:
431
432 rav1e_config_unref(cfg);
433
435 }
436
438 {
440
441 if (!fd)
442 return;
443
446 }
447
449 {
451 RaFrame *rframe =
ctx->rframe;
452 RaPacket *rpkt =
NULL;
455
456 if (!rframe) {
458
462
465
467 if (!fd) {
470 }
473
478 }
479
480 rframe = rav1e_frame_new(
ctx->ctx);
481 if (!rframe) {
486 }
487
488 for (
int i = 0;
i <
desc->nb_components;
i++) {
490 int bytes =
desc->comp[0].depth == 8 ? 1 : 2;
491 rav1e_frame_fill_plane(rframe,
i,
frame->data[
i],
493 frame->linesize[
i], bytes);
494 }
497 }
498 }
499
500 ret = rav1e_send_frame(
ctx->ctx, rframe);
501 if (rframe)
502 if (
ret == RA_ENCODER_STATUS_ENOUGH_DATA) {
503 ctx->rframe = rframe;
/* Queue is full. Store the RaFrame to retry next call */
504 } else {
505 rav1e_frame_unref(rframe); /* No need to unref if flushing. */
507 }
508
510 case RA_ENCODER_STATUS_SUCCESS:
511 case RA_ENCODER_STATUS_ENOUGH_DATA:
512 break;
513 case RA_ENCODER_STATUS_FAILURE:
516 default:
519 }
520
521 retry:
522
525 if (sret < 0)
526 return sret;
529 if (sret < 0)
530 return sret;
531 }
532
533 ret = rav1e_receive_packet(
ctx->ctx, &rpkt);
535 case RA_ENCODER_STATUS_SUCCESS:
536 break;
537 case RA_ENCODER_STATUS_LIMIT_REACHED:
540 if (sret < 0)
541 return sret;
542 }
544 case RA_ENCODER_STATUS_ENCODED:
545 goto retry;
546 case RA_ENCODER_STATUS_NEED_MORE_DATA:
550 }
552 case RA_ENCODER_STATUS_FAILURE:
555 default:
556 av_log(avctx,
AV_LOG_ERROR,
"Unknown return code %d from rav1e_receive_packet: %s\n",
ret, rav1e_status_to_str(
ret));
558 }
559
563 rav1e_packet_unref(rpkt);
565 }
566
567 memcpy(
pkt->
data, rpkt->data, rpkt->len);
568
569 if (rpkt->frame_type == RA_FRAME_TYPE_KEY)
571
572 fd = rpkt->opaque;
575
580 }
581
583
588
590
594
597 rav1e_packet_unref(rpkt);
599 }
600
601 for (
int i = 0;
i <
desc->nb_components;
i++) {
603 rav1e_frame_extract_plane(rpkt->rec,
i,
frame->data[
i],
606 }
607 }
608
609 rav1e_packet_unref(rpkt);
610
611 return 0;
612 }
613
614 #define OFFSET(x) offsetof(librav1eContext, x)
615 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
616
623 {
"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 },
625 };
626
628 { "b", "0" },
629 { "g", "0" },
630 { "keyint_min", "0" },
631 { "qmax", "-1" },
632 { "qmin", "-1" },
634 };
635
650 };
651
657 };
658
660 .
p.
name =
"librav1e",
668 .p.priv_class = &class,
677 .p.wrapper_name = "librav1e",
678 };