1 /*
2 * AVS2 encoding using the xavs2 library
3 *
4 * Copyright (C) 2018 Yiqun Xu, <yiqun.xu@vipl.ict.ac.cn>
5 * Falei Luo, <falei.luo@gmail.com>
6 * Huiwen Ren, <hwrenx@gmail.com>
7 *
8 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "xavs2.h"
29
30 #define xavs2_opt_set2(name, format, ...) do{ \
31 char opt_str[16] = {0}; \
32 int err; \
33 av_strlcatf(opt_str, sizeof(opt_str), format, __VA_ARGS__); \
34 err = cae->api->opt_set2(cae->param, name, opt_str); \
35 if (err < 0) {\
36 av_log(avctx, AV_LOG_WARNING, "Invalid value for %s: %s\n", name, opt_str);\
37 }\
38 } while(0);
39
42
50
53
56
57 const xavs2_api_t *
api;
58
60
62 {
65
67
68 /* get API handler */
73 }
74
79 }
80
87
90
93
95
96 {
100 }
101
102 /* Rate control */
109 } else {
111 }
112
115
117
121 }
122
123 return 0;
124 }
125
127 {
128 uint16_t *p_plane;
129 uint8_t *p_buffer;
130 int plane;
131 int hIdx;
132 int wIdx;
133
134 for (plane = 0; plane < 3; plane++) {
135 p_plane = (uint16_t *)pic->img.img_planes[plane];
136 p_buffer =
frame->data[plane];
137 for (hIdx = 0; hIdx < pic->img.i_lines[plane]; hIdx++) {
138 memset(p_plane, 0, pic->img.i_stride[plane]);
139 for (wIdx = 0; wIdx < pic->img.i_width[plane]; wIdx++) {
140 p_plane[wIdx] = p_buffer[wIdx] << shift_in;
141 }
142 p_plane += pic->img.i_stride[plane];
143 p_buffer +=
frame->linesize[plane];
144 }
145 }
146 }
147
149 {
150 uint8_t *p_plane;
151 uint8_t *p_buffer;
152 int plane;
153 int hIdx;
155
156 for (plane = 0; plane < 3; plane++) {
157 p_plane = pic->img.img_planes[plane];
158 p_buffer =
frame->data[plane];
159 stride = pic->img.i_width[plane] * pic->img.in_sample_size;
160 for (hIdx = 0; hIdx < pic->img.i_lines[plane]; hIdx++) {
161 memcpy(p_plane, p_buffer,
stride);
162 p_plane += pic->img.i_stride[plane];
163 p_buffer +=
frame->linesize[plane];
164 }
165 }
166 }
167
170 {
172 xavs2_picture_t pic;
174
175 /* create the XAVS2 video encoder */
176 /* read frame data and send to the XAVS2 video encoder */
177 if (cae->
api->encoder_get_buffer(cae->
encoder, &pic) < 0) {
180 }
182 switch (
frame->format) {
184 if (pic.img.in_sample_size == pic.img.enc_sample_size) {
186 } else {
187 const int shift_in = atoi(cae->
api->opt_get(cae->
param,
"SampleShift"));
189 }
190 break;
192 if (pic.img.in_sample_size == pic.img.enc_sample_size) {
194 break;
195 }
196 default:
199 break;
200 }
201
202 pic.i_state = 0;
203 pic.i_pts =
frame->pts;
204 pic.i_type = XAVS2_TYPE_AUTO;
205
207
211 }
212
213 } else {
215 }
216
217 if ((cae->
packet.len) && (cae->
packet.state != XAVS2_STATE_FLUSH_END)) {
221 }
222
225
226 if (cae->
packet.type == XAVS2_TYPE_IDR ||
227 cae->
packet.type == XAVS2_TYPE_I ||
228 cae->
packet.type == XAVS2_TYPE_KEYFRAME) {
230 }
231
233
235
236 *got_packet = 1;
237 } else {
238 *got_packet = 0;
239 }
240
241 return 0;
242 }
243
245 {
247 /* destroy the encoder */
250
253 }
254 }
255 return 0;
256 }
257
258 #define OFFSET(x) offsetof(XAVS2EContext, x)
259 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
260
262 {
"lcu_row_threads" ,
"number of parallel threads for rows" ,
OFFSET(lcu_row_threads) ,
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX,
VE },
263 {
"initial_qp" ,
"Quantization initial parameter" ,
OFFSET(initial_qp) ,
AV_OPT_TYPE_INT, {.i64 = 34 }, 1, 63,
VE },
267 {
"speed_level" ,
"Speed level, higher is better but slower",
OFFSET(preset_level) ,
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 9,
VE },
268 {
"log_level" ,
"log level: -1: none, 0: error, 1: warning, 2: info, 3: debug",
OFFSET(log_level) ,
AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 3,
VE },
269 {
"xavs2-params" ,
"set the xavs2 configuration using a :-separated list of key=value parameters",
OFFSET(xavs2_opts),
AV_OPT_TYPE_DICT, { 0 }, 0, 0,
VE },
271 };
272
278 };
279
281 { "b", "0" },
282 { "g", "48"},
283 { "bf", "7" },
285 };
286
303 .wrapper_name = "libxavs2",
304 } ;