2 * Scalable Video Technology for AV1 encoder library plugin
4 * Copyright (c) 2018 Intel Corporation
6 * This file is part of FFmpeg.
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.
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.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <EbSvtAv1ErrorCodes.h>
25 #include <EbSvtAv1Enc.h>
26 #include <EbSvtAv1Metadata.h>
28 #include "libavutil/common.h"
29 #include "libavutil/frame.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavutil/mastering_display_metadata.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/pixdesc.h"
36 #include "libavutil/avassert.h"
38 #include "codec_internal.h"
41 #include "packet_internal.h"
45 typedef enum eos_status
{
51 typedef struct SvtContext
{
54 EbSvtAv1EncConfiguration enc_params
;
55 EbComponentType
*svt_handle
;
57 EbBufferHeaderType
*in_buf
;
70 AVDictionary
*svtav1_opts
;
81 { EB_ErrorNone
, 0, "success" },
82 { EB_ErrorInsufficientResources
, AVERROR(ENOMEM
), "insufficient resources" },
83 { EB_ErrorUndefined
, AVERROR(EINVAL
), "undefined error" },
84 { EB_ErrorInvalidComponent
, AVERROR(EINVAL
), "invalid component" },
85 { EB_ErrorBadParameter
, AVERROR(EINVAL
), "bad parameter" },
86 { EB_ErrorDestroyThreadFailed
, AVERROR_EXTERNAL
, "failed to destroy thread" },
87 { EB_ErrorSemaphoreUnresponsive
, AVERROR_EXTERNAL
, "semaphore unresponsive" },
88 { EB_ErrorDestroySemaphoreFailed
, AVERROR_EXTERNAL
, "failed to destroy semaphore"},
89 { EB_ErrorCreateMutexFailed
, AVERROR_EXTERNAL
, "failed to create mutex" },
90 { EB_ErrorMutexUnresponsive
, AVERROR_EXTERNAL
, "mutex unresponsive" },
91 { EB_ErrorDestroyMutexFailed
, AVERROR_EXTERNAL
, "failed to destroy mutex" },
92 { EB_NoErrorEmptyQueue
, AVERROR(EAGAIN
), "empty queue" },
95 static int svt_map_error(EbErrorType eb_err
, const char **desc
)
100 for (i
= 0; i
< FF_ARRAY_ELEMS(svt_errors
); i
++) {
101 if (svt_errors
[i
].eb_err
== eb_err
) {
102 *desc
= svt_errors
[i
].desc
;
103 return svt_errors
[i
].av_err
;
106 *desc
= "unknown error";
107 return AVERROR_UNKNOWN
;
110 static int svt_print_error(void *log_ctx
, EbErrorType err
,
111 const char *error_string
)
114 int ret
= svt_map_error(err
, &desc
);
116 av_log(log_ctx
, AV_LOG_ERROR
, "%s: %s (0x%x)\n", error_string
, desc
, err
);
121 static int alloc_buffer(EbSvtAv1EncConfiguration
*config
, SvtContext
*svt_enc
)
123 const size_t luma_size
= config
->source_width
* config
->source_height
*
124 (config
->encoder_bit_depth
> 8 ? 2 : 1);
126 EbSvtIOFormat
*in_data
;
128 svt_enc
->raw_size
= luma_size
* 3 / 2;
130 // allocate buffer for in and out
131 svt_enc
->in_buf
= av_mallocz(sizeof(*svt_enc
->in_buf
));
132 if (!svt_enc
->in_buf
)
133 return AVERROR(ENOMEM
);
135 svt_enc
->in_buf
->p_buffer
= av_mallocz(sizeof(*in_data
));
136 if (!svt_enc
->in_buf
->p_buffer
)
137 return AVERROR(ENOMEM
);
139 svt_enc
->in_buf
->size
= sizeof(*svt_enc
->in_buf
);
145 static void handle_mdcv(struct EbSvtAv1MasteringDisplayInfo
*dst
,
146 const AVMasteringDisplayMetadata
*mdcv
)
148 if (mdcv
->has_primaries
) {
149 const struct EbSvtAv1ChromaPoints
*const points
[] = {
155 for (int i
= 0; i
< 3; i
++) {
156 const struct EbSvtAv1ChromaPoints
*dst
= points
[i
];
157 const AVRational
*src
= mdcv
->display_primaries
[i
];
160 av_rescale_q(1, src
[0], (AVRational
){ 1, (1 << 16) }));
162 av_rescale_q(1, src
[1], (AVRational
){ 1, (1 << 16) }));
165 AV_WB16(&dst
->white_point
.x
,
166 av_rescale_q(1, mdcv
->white_point
[0],
167 (AVRational
){ 1, (1 << 16) }));
168 AV_WB16(&dst
->white_point
.y
,
169 av_rescale_q(1, mdcv
->white_point
[1],
170 (AVRational
){ 1, (1 << 16) }));
173 if (mdcv
->has_luminance
) {
174 AV_WB32(&dst
->max_luma
,
175 av_rescale_q(1, mdcv
->max_luminance
,
176 (AVRational
){ 1, (1 << 8) }));
177 AV_WB32(&dst
->min_luma
,
178 av_rescale_q(1, mdcv
->min_luminance
,
179 (AVRational
){ 1, (1 << 14) }));
183 static void handle_side_data(AVCodecContext
*avctx
,
184 EbSvtAv1EncConfiguration
*param
)
186 const AVFrameSideData
*cll_sd
=
187 av_frame_side_data_get(avctx
->decoded_side_data
,
188 avctx
->nb_decoded_side_data
, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
);
189 const AVFrameSideData
*mdcv_sd
=
190 av_frame_side_data_get(avctx
->decoded_side_data
,
191 avctx
->nb_decoded_side_data
,
192 AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
);
195 const AVContentLightMetadata
*cll
=
196 (AVContentLightMetadata
*)cll_sd
->data
;
198 AV_WB16(¶m
->content_light_level
.max_cll
, cll
->MaxCLL
);
199 AV_WB16(¶m
->content_light_level
.max_fall
, cll
->MaxFALL
);
203 handle_mdcv(¶m
->mastering_display
,
204 (AVMasteringDisplayMetadata
*)mdcv_sd
->data
);
208 static int config_enc_params(EbSvtAv1EncConfiguration
*param
,
209 AVCodecContext
*avctx
)
211 SvtContext
*svt_enc
= avctx
->priv_data
;
212 const AVPixFmtDescriptor
*desc
;
213 const AVDictionaryEntry av_unused
*en
= NULL
;
215 // Update param from options
216 if (svt_enc
->enc_mode
>= -1)
217 param
->enc_mode
= svt_enc
->enc_mode
;
219 if (avctx
->bit_rate
) {
220 param
->target_bit_rate
= avctx
->bit_rate
;
221 if (avctx
->rc_max_rate
!= avctx
->bit_rate
)
222 param
->rate_control_mode
= 1;
224 param
->rate_control_mode
= 2;
226 param
->max_qp_allowed
= avctx
->qmax
;
227 param
->min_qp_allowed
= avctx
->qmin
;
229 param
->max_bit_rate
= avctx
->rc_max_rate
;
230 if ((avctx
->bit_rate
> 0 || avctx
->rc_max_rate
> 0) && avctx
->rc_buffer_size
)
231 param
->maximum_buffer_size_ms
=
232 avctx
->rc_buffer_size
* 1000LL /
233 FFMAX(avctx
->bit_rate
, avctx
->rc_max_rate
);
235 if (svt_enc
->crf
> 0) {
236 param
->qp
= svt_enc
->crf
;
237 param
->rate_control_mode
= 0;
238 } else if (svt_enc
->qp
> 0) {
239 param
->qp
= svt_enc
->qp
;
240 param
->rate_control_mode
= 0;
241 param
->enable_adaptive_quantization
= 0;
244 desc
= av_pix_fmt_desc_get(avctx
->pix_fmt
);
245 param
->color_primaries
= avctx
->color_primaries
;
246 param
->matrix_coefficients
= (desc
->flags
& AV_PIX_FMT_FLAG_RGB
) ?
247 AVCOL_SPC_RGB
: avctx
->colorspace
;
248 param
->transfer_characteristics
= avctx
->color_trc
;
250 if (avctx
->color_range
!= AVCOL_RANGE_UNSPECIFIED
)
251 param
->color_range
= avctx
->color_range
== AVCOL_RANGE_JPEG
;
253 param
->color_range
= !!(desc
->flags
& AV_PIX_FMT_FLAG_RGB
);
255 #if SVT_AV1_CHECK_VERSION(1, 0, 0)
256 if (avctx
->chroma_sample_location
!= AVCHROMA_LOC_UNSPECIFIED
) {
258 av_chroma_location_name(avctx
->chroma_sample_location
);
260 switch (avctx
->chroma_sample_location
) {
261 case AVCHROMA_LOC_LEFT
:
262 param
->chroma_sample_position
= EB_CSP_VERTICAL
;
264 case AVCHROMA_LOC_TOPLEFT
:
265 param
->chroma_sample_position
= EB_CSP_COLOCATED
;
271 av_log(avctx
, AV_LOG_WARNING
,
272 "Specified chroma sample location %s is unsupported "
273 "on the AV1 bit stream level. Usage of a container that "
274 "allows passing this information - such as Matroska - "
282 if (avctx
->profile
!= AV_PROFILE_UNKNOWN
)
283 param
->profile
= avctx
->profile
;
285 if (avctx
->level
!= AV_LEVEL_UNKNOWN
)
286 param
->level
= avctx
->level
;
288 // gop_size == 1 case is handled when encoding each frame by setting
289 // pic_type to EB_AV1_KEY_PICTURE. For gop_size > 1, set the
290 // intra_period_length. Even though setting intra_period_length to 0 should
291 // work in this case, it does not.
292 // See: https://gitlab.com/AOMediaCodec/SVT-AV1/-/issues/2076
293 if (avctx
->gop_size
> 1)
294 param
->intra_period_length
= avctx
->gop_size
- 1;
296 #if SVT_AV1_CHECK_VERSION(1, 1, 0)
297 // In order for SVT-AV1 to force keyframes by setting pic_type to
298 // EB_AV1_KEY_PICTURE on any frame, force_key_frames has to be set. Note
299 // that this does not force all frames to be keyframes (it only forces a
300 // keyframe with pic_type is set to EB_AV1_KEY_PICTURE). As of now, SVT-AV1
301 // does not support arbitrary keyframe requests by setting pic_type to
302 // EB_AV1_KEY_PICTURE, so it is done only when gop_size == 1.
303 // FIXME: When SVT-AV1 supports arbitrary keyframe requests, this code needs
304 // to be updated to set force_key_frames accordingly.
305 if (avctx
->gop_size
== 1)
306 param
->force_key_frames
= 1;
309 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
310 param
->frame_rate_numerator
= avctx
->framerate
.num
;
311 param
->frame_rate_denominator
= avctx
->framerate
.den
;
313 param
->frame_rate_numerator
= avctx
->time_base
.den
;
314 FF_DISABLE_DEPRECATION_WARNINGS
315 param
->frame_rate_denominator
= avctx
->time_base
.num
316 #if FF_API_TICKS_PER_FRAME
317 * avctx
->ticks_per_frame
320 FF_ENABLE_DEPRECATION_WARNINGS
323 /* 2 = IDR, closed GOP, 1 = CRA, open GOP */
324 param
->intra_refresh_type
= avctx
->flags
& AV_CODEC_FLAG_CLOSED_GOP
? 2 : 1;
326 handle_side_data(avctx
, param
);
328 #if SVT_AV1_CHECK_VERSION(0, 9, 1)
329 while ((en
= av_dict_iterate(svt_enc
->svtav1_opts
, en
))) {
330 EbErrorType ret
= svt_av1_enc_parse_parameter(param
, en
->key
, en
->value
);
331 if (ret
!= EB_ErrorNone
) {
332 int level
= (avctx
->err_recognition
& AV_EF_EXPLODE
) ? AV_LOG_ERROR
: AV_LOG_WARNING
;
333 av_log(avctx
, level
, "Error parsing option %s: %s.\n", en
->key
, en
->value
);
334 if (avctx
->err_recognition
& AV_EF_EXPLODE
)
335 return AVERROR(EINVAL
);
339 if (av_dict_count(svt_enc
->svtav1_opts
)) {
340 int level
= (avctx
->err_recognition
& AV_EF_EXPLODE
) ? AV_LOG_ERROR
: AV_LOG_WARNING
;
341 av_log(avctx
, level
, "svt-params needs libavcodec to be compiled with SVT-AV1 "
342 "headers >= 0.9.1.\n");
343 if (avctx
->err_recognition
& AV_EF_EXPLODE
)
344 return AVERROR(ENOSYS
);
348 param
->source_width
= avctx
->width
;
349 param
->source_height
= avctx
->height
;
351 param
->encoder_bit_depth
= desc
->comp
[0].depth
;
353 if (desc
->log2_chroma_w
== 1 && desc
->log2_chroma_h
== 1)
354 param
->encoder_color_format
= EB_YUV420
;
355 else if (desc
->log2_chroma_w
== 1 && desc
->log2_chroma_h
== 0)
356 param
->encoder_color_format
= EB_YUV422
;
357 else if (!desc
->log2_chroma_w
&& !desc
->log2_chroma_h
)
358 param
->encoder_color_format
= EB_YUV444
;
360 av_log(avctx
, AV_LOG_ERROR
, "Unsupported pixel format\n");
361 return AVERROR(EINVAL
);
364 if ((param
->encoder_color_format
== EB_YUV422
|| param
->encoder_bit_depth
> 10)
365 && param
->profile
!= AV_PROFILE_AV1_PROFESSIONAL
) {
366 av_log(avctx
, AV_LOG_WARNING
, "Forcing Professional profile\n");
367 param
->profile
= AV_PROFILE_AV1_PROFESSIONAL
;
368 } else if (param
->encoder_color_format
== EB_YUV444
&& param
->profile
!= AV_PROFILE_AV1_HIGH
) {
369 av_log(avctx
, AV_LOG_WARNING
, "Forcing High profile\n");
370 param
->profile
= AV_PROFILE_AV1_HIGH
;
373 avctx
->bit_rate
= param
->rate_control_mode
> 0 ?
374 param
->target_bit_rate
: 0;
375 avctx
->rc_max_rate
= param
->max_bit_rate
;
376 avctx
->rc_buffer_size
= param
->maximum_buffer_size_ms
*
377 FFMAX(avctx
->bit_rate
, avctx
->rc_max_rate
) / 1000LL;
379 if (avctx
->bit_rate
|| avctx
->rc_max_rate
|| avctx
->rc_buffer_size
) {
380 AVCPBProperties
*cpb_props
= ff_encode_add_cpb_side_data(avctx
);
382 return AVERROR(ENOMEM
);
384 cpb_props
->buffer_size
= avctx
->rc_buffer_size
;
385 cpb_props
->max_bitrate
= avctx
->rc_max_rate
;
386 cpb_props
->avg_bitrate
= avctx
->bit_rate
;
392 static int read_in_data(EbSvtAv1EncConfiguration
*param
, const AVFrame
*frame
,
393 EbBufferHeaderType
*header_ptr
)
395 EbSvtIOFormat
*in_data
= (EbSvtIOFormat
*)header_ptr
->p_buffer
;
396 ptrdiff_t linesizes
[4];
398 int bytes_shift
= param
->encoder_bit_depth
> 8 ? 1 : 0;
401 for (int i
= 0; i
< 4; i
++)
402 linesizes
[i
] = frame
->linesize
[i
];
404 ret
= av_image_fill_plane_sizes(sizes
, frame
->format
, frame
->height
,
410 for (int i
= 0; i
< 4; i
++) {
411 if (sizes
[i
] > INT_MAX
- frame_size
)
412 return AVERROR(EINVAL
);
413 frame_size
+= sizes
[i
];
416 in_data
->luma
= frame
->data
[0];
417 in_data
->cb
= frame
->data
[1];
418 in_data
->cr
= frame
->data
[2];
420 in_data
->y_stride
= AV_CEIL_RSHIFT(frame
->linesize
[0], bytes_shift
);
421 in_data
->cb_stride
= AV_CEIL_RSHIFT(frame
->linesize
[1], bytes_shift
);
422 in_data
->cr_stride
= AV_CEIL_RSHIFT(frame
->linesize
[2], bytes_shift
);
424 header_ptr
->n_filled_len
= frame_size
;
425 svt_metadata_array_free(&header_ptr
->metadata
);
430 static av_cold
int eb_enc_init(AVCodecContext
*avctx
)
432 SvtContext
*svt_enc
= avctx
->priv_data
;
436 svt_enc
->eos_flag
= EOS_NOT_REACHED
;
438 svt_ret
= svt_av1_enc_init_handle(&svt_enc
->svt_handle
, svt_enc
, &svt_enc
->enc_params
);
439 if (svt_ret
!= EB_ErrorNone
) {
440 return svt_print_error(avctx
, svt_ret
, "Error initializing encoder handle");
443 ret
= config_enc_params(&svt_enc
->enc_params
, avctx
);
445 av_log(avctx
, AV_LOG_ERROR
, "Error configuring encoder parameters\n");
449 svt_ret
= svt_av1_enc_set_parameter(svt_enc
->svt_handle
, &svt_enc
->enc_params
);
450 if (svt_ret
!= EB_ErrorNone
) {
451 return svt_print_error(avctx
, svt_ret
, "Error setting encoder parameters");
454 svt_ret
= svt_av1_enc_init(svt_enc
->svt_handle
);
455 if (svt_ret
!= EB_ErrorNone
) {
456 return svt_print_error(avctx
, svt_ret
, "Error initializing encoder");
459 svt_enc
->dovi
.logctx
= avctx
;
460 ret
= ff_dovi_configure(&svt_enc
->dovi
, avctx
);
464 if (avctx
->flags
& AV_CODEC_FLAG_GLOBAL_HEADER
) {
465 EbBufferHeaderType
*headerPtr
= NULL
;
467 svt_ret
= svt_av1_enc_stream_header(svt_enc
->svt_handle
, &headerPtr
);
468 if (svt_ret
!= EB_ErrorNone
) {
469 return svt_print_error(avctx
, svt_ret
, "Error building stream header");
472 avctx
->extradata_size
= headerPtr
->n_filled_len
;
473 avctx
->extradata
= av_mallocz(avctx
->extradata_size
+ AV_INPUT_BUFFER_PADDING_SIZE
);
474 if (!avctx
->extradata
) {
475 av_log(avctx
, AV_LOG_ERROR
,
476 "Cannot allocate AV1 header of size %d.\n", avctx
->extradata_size
);
477 return AVERROR(ENOMEM
);
480 memcpy(avctx
->extradata
, headerPtr
->p_buffer
, avctx
->extradata_size
);
482 svt_ret
= svt_av1_enc_stream_header_release(headerPtr
);
483 if (svt_ret
!= EB_ErrorNone
) {
484 return svt_print_error(avctx
, svt_ret
, "Error freeing stream header");
488 svt_enc
->frame
= av_frame_alloc();
490 return AVERROR(ENOMEM
);
492 return alloc_buffer(&svt_enc
->enc_params
, svt_enc
);
495 static int eb_send_frame(AVCodecContext
*avctx
, const AVFrame
*frame
)
497 SvtContext
*svt_enc
= avctx
->priv_data
;
498 EbBufferHeaderType
*headerPtr
= svt_enc
->in_buf
;
504 EbBufferHeaderType headerPtrLast
;
506 if (svt_enc
->eos_flag
== EOS_SENT
)
509 memset(&headerPtrLast
, 0, sizeof(headerPtrLast
));
510 headerPtrLast
.pic_type
= EB_AV1_INVALID_PICTURE
;
511 headerPtrLast
.flags
= EB_BUFFERFLAG_EOS
;
513 svt_av1_enc_send_picture(svt_enc
->svt_handle
, &headerPtrLast
);
514 svt_enc
->eos_flag
= EOS_SENT
;
518 ret
= read_in_data(&svt_enc
->enc_params
, frame
, headerPtr
);
522 headerPtr
->flags
= 0;
523 headerPtr
->p_app_private
= NULL
;
524 headerPtr
->pts
= frame
->pts
;
526 switch (frame
->pict_type
) {
527 case AV_PICTURE_TYPE_I
:
528 headerPtr
->pic_type
= EB_AV1_KEY_PICTURE
;
531 // Actually means auto, or default.
532 headerPtr
->pic_type
= EB_AV1_INVALID_PICTURE
;
536 if (avctx
->gop_size
== 1)
537 headerPtr
->pic_type
= EB_AV1_KEY_PICTURE
;
539 sd
= av_frame_get_side_data(frame
, AV_FRAME_DATA_DOVI_METADATA
);
540 if (svt_enc
->dovi
.cfg
.dv_profile
&& sd
) {
541 const AVDOVIMetadata
*metadata
= (const AVDOVIMetadata
*)sd
->data
;
544 if ((ret
= ff_dovi_rpu_generate(&svt_enc
->dovi
, metadata
, FF_DOVI_WRAP_T35
,
547 ret
= svt_add_metadata(headerPtr
, EB_AV1_METADATA_TYPE_ITUT_T35
, t35
, size
);
550 return AVERROR(ENOMEM
);
551 } else if (svt_enc
->dovi
.cfg
.dv_profile
) {
552 av_log(avctx
, AV_LOG_ERROR
, "Dolby Vision enabled, but received frame "
553 "without AV_FRAME_DATA_DOVI_METADATA\n");
554 return AVERROR_INVALIDDATA
;
558 svt_ret
= svt_av1_enc_send_picture(svt_enc
->svt_handle
, headerPtr
);
559 if (svt_ret
!= EB_ErrorNone
)
560 return svt_print_error(avctx
, svt_ret
, "Error sending a frame to encoder");
565 static AVBufferRef
*get_output_ref(AVCodecContext
*avctx
, SvtContext
*svt_enc
, int filled_len
)
567 if (filled_len
> svt_enc
->max_tu_size
) {
568 const int max_frames
= 8;
571 if (filled_len
> svt_enc
->raw_size
* max_frames
) {
572 av_log(avctx
, AV_LOG_ERROR
, "TU size > %d raw frame size.\n", max_frames
);
576 max_tu_size
= 1 << av_ceil_log2(filled_len
);
577 av_buffer_pool_uninit(&svt_enc
->pool
);
578 svt_enc
->pool
= av_buffer_pool_init(max_tu_size
+ AV_INPUT_BUFFER_PADDING_SIZE
, NULL
);
582 svt_enc
->max_tu_size
= max_tu_size
;
584 av_assert0(svt_enc
->pool
);
586 return av_buffer_pool_get(svt_enc
->pool
);
589 static int eb_receive_packet(AVCodecContext
*avctx
, AVPacket
*pkt
)
591 SvtContext
*svt_enc
= avctx
->priv_data
;
592 EbBufferHeaderType
*headerPtr
;
593 AVFrame
*frame
= svt_enc
->frame
;
596 int ret
= 0, pict_type
;
598 if (svt_enc
->eos_flag
== EOS_RECEIVED
)
601 ret
= ff_encode_get_frame(avctx
, frame
);
602 if (ret
< 0 && ret
!= AVERROR_EOF
)
604 if (ret
== AVERROR_EOF
)
607 ret
= eb_send_frame(avctx
, frame
);
610 av_frame_unref(svt_enc
->frame
);
612 svt_ret
= svt_av1_enc_get_packet(svt_enc
->svt_handle
, &headerPtr
, svt_enc
->eos_flag
);
613 if (svt_ret
== EB_NoErrorEmptyQueue
)
614 return AVERROR(EAGAIN
);
615 else if (svt_ret
!= EB_ErrorNone
)
616 return svt_print_error(avctx
, svt_ret
, "Error getting an output packet from encoder");
618 #if SVT_AV1_CHECK_VERSION(2, 0, 0)
619 if (headerPtr
->flags
& EB_BUFFERFLAG_EOS
) {
620 svt_enc
->eos_flag
= EOS_RECEIVED
;
621 svt_av1_enc_release_out_buffer(&headerPtr
);
626 ref
= get_output_ref(avctx
, svt_enc
, headerPtr
->n_filled_len
);
628 av_log(avctx
, AV_LOG_ERROR
, "Failed to allocate output packet.\n");
629 svt_av1_enc_release_out_buffer(&headerPtr
);
630 return AVERROR(ENOMEM
);
633 pkt
->data
= ref
->data
;
635 memcpy(pkt
->data
, headerPtr
->p_buffer
, headerPtr
->n_filled_len
);
636 memset(pkt
->data
+ headerPtr
->n_filled_len
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
638 pkt
->size
= headerPtr
->n_filled_len
;
639 pkt
->pts
= headerPtr
->pts
;
640 pkt
->dts
= headerPtr
->dts
;
642 switch (headerPtr
->pic_type
) {
643 case EB_AV1_KEY_PICTURE
:
644 pkt
->flags
|= AV_PKT_FLAG_KEY
;
646 case EB_AV1_INTRA_ONLY_PICTURE
:
647 pict_type
= AV_PICTURE_TYPE_I
;
649 case EB_AV1_INVALID_PICTURE
:
650 pict_type
= AV_PICTURE_TYPE_NONE
;
653 pict_type
= AV_PICTURE_TYPE_P
;
657 if (headerPtr
->pic_type
== EB_AV1_NON_REF_PICTURE
)
658 pkt
->flags
|= AV_PKT_FLAG_DISPOSABLE
;
660 #if !(SVT_AV1_CHECK_VERSION(2, 0, 0))
661 if (headerPtr
->flags
& EB_BUFFERFLAG_EOS
)
662 svt_enc
->eos_flag
= EOS_RECEIVED
;
665 ff_side_data_set_encoder_stats(pkt
, headerPtr
->qp
* FF_QP2LAMBDA
, NULL
, 0, pict_type
);
667 svt_av1_enc_release_out_buffer(&headerPtr
);
672 static av_cold
int eb_enc_close(AVCodecContext
*avctx
)
674 SvtContext
*svt_enc
= avctx
->priv_data
;
676 if (svt_enc
->svt_handle
) {
677 svt_av1_enc_deinit(svt_enc
->svt_handle
);
678 svt_av1_enc_deinit_handle(svt_enc
->svt_handle
);
680 if (svt_enc
->in_buf
) {
681 av_free(svt_enc
->in_buf
->p_buffer
);
682 svt_metadata_array_free(&svt_enc
->in_buf
->metadata
);
683 av_freep(&svt_enc
->in_buf
);
686 av_buffer_pool_uninit(&svt_enc
->pool
);
687 av_frame_free(&svt_enc
->frame
);
688 ff_dovi_ctx_unref(&svt_enc
->dovi
);
693 #define OFFSET(x) offsetof(SvtContext, x)
694 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
695 static const AVOption options
[] = {
696 { "preset", "Encoding preset",
697 OFFSET(enc_mode
), AV_OPT_TYPE_INT
, { .i64
= -2 }, -2, MAX_ENC_PRESET
, VE
},
701 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
702 { .i64 = value }, 0, 0, VE, .unit = "avctx.level"
703 { LEVEL("2.0", 20) },
704 { LEVEL("2.1", 21) },
705 { LEVEL("2.2", 22) },
706 { LEVEL("2.3", 23) },
707 { LEVEL("3.0", 30) },
708 { LEVEL("3.1", 31) },
709 { LEVEL("3.2", 32) },
710 { LEVEL("3.3", 33) },
711 { LEVEL("4.0", 40) },
712 { LEVEL("4.1", 41) },
713 { LEVEL("4.2", 42) },
714 { LEVEL("4.3", 43) },
715 { LEVEL("5.0", 50) },
716 { LEVEL("5.1", 51) },
717 { LEVEL("5.2", 52) },
718 { LEVEL("5.3", 53) },
719 { LEVEL("6.0", 60) },
720 { LEVEL("6.1", 61) },
721 { LEVEL("6.2", 62) },
722 { LEVEL("6.3", 63) },
723 { LEVEL("7.0", 70) },
724 { LEVEL("7.1", 71) },
725 { LEVEL("7.2", 72) },
726 { LEVEL("7.3", 73) },
729 { "crf", "Constant Rate Factor value", OFFSET(crf
),
730 AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 63, VE
},
731 { "qp", "Initial Quantizer level value", OFFSET(qp
),
732 AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 63, VE
},
733 { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svtav1_opts
), AV_OPT_TYPE_DICT
, { 0 }, 0, 0, VE
},
735 { "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi
.enable
), AV_OPT_TYPE_BOOL
, {.i64
= FF_DOVI_AUTOMATIC
}, -1, 1, VE
, .unit
= "dovi" },
736 { "auto", NULL
, 0, AV_OPT_TYPE_CONST
, {.i64
= FF_DOVI_AUTOMATIC
}, .flags
= VE
, .unit
= "dovi" },
741 static const AVClass
class = {
742 .class_name
= "libsvtav1",
743 .item_name
= av_default_item_name
,
745 .version
= LIBAVUTIL_VERSION_INT
,
748 static const FFCodecDefault eb_enc_defaults
[] = {
750 { "flags", "+cgop" },
757 const FFCodec ff_libsvtav1_encoder
= {
758 .p
.name
= "libsvtav1",
759 CODEC_LONG_NAME("SVT-AV1(Scalable Video Technology for AV1) encoder"),
760 .priv_data_size
= sizeof(SvtContext
),
761 .p
.type
= AVMEDIA_TYPE_VIDEO
,
762 .p
.id
= AV_CODEC_ID_AV1
,
764 FF_CODEC_RECEIVE_PACKET_CB(eb_receive_packet
),
765 .close
= eb_enc_close
,
766 .p
.capabilities
= AV_CODEC_CAP_DELAY
| AV_CODEC_CAP_OTHER_THREADS
,
767 .caps_internal
= FF_CODEC_CAP_NOT_INIT_THREADSAFE
|
768 FF_CODEC_CAP_AUTO_THREADS
| FF_CODEC_CAP_INIT_CLEANUP
,
769 .p
.pix_fmts
= (const enum AVPixelFormat
[]){ AV_PIX_FMT_YUV420P
,
770 AV_PIX_FMT_YUV420P10
,
772 .color_ranges
= AVCOL_RANGE_MPEG
| AVCOL_RANGE_JPEG
,
773 .p
.priv_class
= &class,
774 .defaults
= eb_enc_defaults
,
775 .p
.wrapper_name
= "libsvtav1",