1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <va/va.h>
20 #include <va/va_enc_jpeg.h>
21
27
37
38
39 // Standard JPEG quantisation tables, in zigzag order.
41 16, 11, 12, 14, 12, 10, 16, 14,
42 13, 14, 18, 17, 16, 19, 24, 40,
43 26, 24, 22, 22, 24, 49, 35, 37,
44 29, 40, 58, 51, 61, 60, 57, 51,
45 56, 55, 64, 72, 92, 78, 64, 68,
46 87, 69, 55, 56, 80, 109, 81, 87,
47 95, 98, 103, 104, 103, 62, 77, 113,
48 121, 112, 100, 120, 92, 101, 103, 99,
49 };
51 17, 18, 18, 24, 21, 24, 47, 26,
52 26, 47, 99, 66, 56, 66, 99, 99,
53 99, 99, 99, 99, 99, 99, 99, 99,
54 99, 99, 99, 99, 99, 99, 99, 99,
55 99, 99, 99, 99, 99, 99, 99, 99,
56 99, 99, 99, 99, 99, 99, 99, 99,
57 99, 99, 99, 99, 99, 99, 99, 99,
58 99, 99, 99, 99, 99, 99, 99, 99,
59 };
60
63
64 // User options.
67
68 // Derived settings.
71
72 // Writer structures.
78
82
86 char *
data,
size_t *data_len)
87 {
90 int err;
91
93 err = ff_cbs_insert_unit_content(frag, -1,
96 if (err < 0)
98 }
99
100 err = ff_cbs_insert_unit_content(frag, -1,
103 if (err < 0)
105
106 err = ff_cbs_insert_unit_content(frag, -1,
109 if (err < 0)
111
113 err = ff_cbs_insert_unit_content(frag, -1,
116 if (err < 0)
118 }
119
120 err = ff_cbs_insert_unit_content(frag, -1,
123 if (err < 0)
125
126 err = ff_cbs_write_fragment_data(priv->
cbc, frag);
127 if (err < 0) {
130 }
131
132 if (*data_len < 8 * frag->data_size) {
134 "%zu < %zu.\n", *data_len, 8 * frag->
data_size);
137 }
138
139 // Remove the EOI at the end of the fragment.
142
143 err = 0;
145 ff_cbs_fragment_reset(frag);
146 return err;
147 }
148
152 char *
data,
size_t *data_len)
153 {
156
158 // Write quantisation tables.
161 VAQMatrixBufferJPEG *
quant;
162
163 if (*data_len <
sizeof(*
quant))
165 *
type = VAQMatrixBufferType;
166 *data_len = sizeof(*quant);
167
170
171 quant->load_lum_quantiser_matrix = 1;
172 for (
i = 0;
i < 64;
i++)
173 quant->lum_quantiser_matrix[
i] =
dqt->table[fh->
Tq[0]].Q[
i];
174
176 quant->load_chroma_quantiser_matrix = 1;
177 for (
i = 0;
i < 64;
i++)
178 quant->chroma_quantiser_matrix[
i] =
179 dqt->table[fh->
Tq[1]].Q[
i];
180 }
181
182 }
else if (
index == 1) {
183 // Write huffman tables.
186 VAHuffmanTableBufferJPEGBaseline *huff;
187
188 if (*data_len < sizeof(*huff))
190 *
type = VAHuffmanTableBufferType;
191 *data_len = sizeof(*huff);
192
193 huff = (VAHuffmanTableBufferJPEGBaseline*)
data;
194 memset(huff, 0, sizeof(*huff));
195
196 for (t = 0; t < 1 + (sh->
Ns > 1); t++) {
198
199 huff->load_huffman_table[t] = 1;
200
201 ht = &
dht->table[2 * t];
202 for (
i = k = 0;
i < 16;
i++)
203 k += (huff->huffman_table[t].num_dc_codes[
i] = ht->
L[
i]);
204 av_assert0(k <=
sizeof(huff->huffman_table[t].dc_values));
205 for (
i = 0;
i < k;
i++)
206 huff->huffman_table[t].dc_values[
i] = ht->
V[
i];
207
208 ht = &
dht->table[2 * t + 1];
209 for (
i = k = 0;
i < 16;
i++)
210 k += (huff->huffman_table[t].num_ac_codes[
i] = ht->
L[
i]);
211 av_assert0(k <=
sizeof(huff->huffman_table[t].ac_values));
212 for (
i = 0;
i < k;
i++)
213 huff->huffman_table[t].ac_values[
i] = ht->
V[
i];
214 }
215
216 } else {
218 }
219 return 0;
220 }
221
224 {
232 const uint8_t components_rgb[3] = { 'R', 'G', 'B' };
233 const uint8_t components_yuv[3] = { 1, 2, 3 };
234 const uint8_t *components;
235 int t,
i, quant_scale,
len;
236
238
242 components = components_rgb;
243 else
244 components = components_yuv;
245
246 // Frame header.
247
251 fh->
Nf =
desc->nb_components;
252
253 for (
i = 0;
i < fh->
Nf;
i++) {
254 fh->
C[
i] = components[
i];
255 fh->
H[
i] = 1 + (
i == 0 ?
desc->log2_chroma_w : 0);
256 fh->
V[
i] = 1 + (
i == 0 ?
desc->log2_chroma_h : 0);
257
259 }
260
261 fh->
Lf = 8 + 3 * fh->
Nf;
262
263 // JFIF header.
267 int sar_w, sar_h;
269
272
274 bytestream2_put_be16(&pbc, 0x0102);
275 bytestream2_put_byte(&pbc, 0);
276
278 if (sar_w && sar_h) {
279 bytestream2_put_be16(&pbc, sar_w);
280 bytestream2_put_be16(&pbc, sar_h);
281 } else {
282 bytestream2_put_be16(&pbc, 1);
283 bytestream2_put_be16(&pbc, 1);
284 }
285
286 bytestream2_put_byte(&pbc, 0);
287 bytestream2_put_byte(&pbc, 0);
288
290
294 }
295
296 // Quantisation tables.
297
299 quant_scale = 5000 / priv->
quality;
300 else
301 quant_scale = 200 - 2 * priv->
quality;
302
304
305 for (t = 0; t < 1 + (fh->
Nf > 1); t++) {
307 const uint8_t *
data = t == 0 ?
310
313 for (
i = 0;
i < 64;
i++)
315
317 }
318
320
321 // Huffman tables.
322
324
325 for (t = 0; t < 2 + 2 * (fh->
Nf > 1); t++) {
327 const uint8_t *lengths, *
values;
328 int k;
329
330 switch (t) {
331 case 0:
334 break;
335 case 1:
338 break;
339 case 2:
342 break;
343 case 3:
346 break;
347 }
348
351
352 for (
i = k = 0;
i < 16;
i++)
353 k += (huff->
L[
i] = lengths[
i]);
354
355 for (
i = 0;
i < k;
i++)
357
359 }
360
362
363 // Scan header.
364
366
367 for (
i = 0;
i < fh->
Nf;
i++) {
368 sh->
Cs[
i] = fh->
C[
i];
371 }
372
377
378 sh->
Ls = 6 + 2 * sh->
Ns;
379
380
381 *vpic = (VAEncPictureParameterBufferJPEG) {
384
385 .picture_width = fh->
X,
386 .picture_height = fh->
Y,
387
388 .pic_flags.bits = {
389 .profile = 0,
390 .progressive = 0,
391 .huffman = 1,
392 .interleaved = 0,
393 .differential = 0,
394 },
395
396 .sample_bit_depth = fh->
P,
397 .num_scan = 1,
398 .num_components = fh->
Nf,
399
400 // The driver modifies the provided quantisation tables according
401 // to this quality value; the middle value of 50 makes that the
402 // identity so that they are used unchanged.
403 .quality = 50,
404 };
405
406 for (
i = 0;
i < fh->
Nf;
i++) {
407 vpic->component_id[
i] = fh->
C[
i];
408 vpic->quantiser_table_selector[
i] = fh->
Tq[
i];
409 }
410
412
413 return 0;
414 }
415
419 {
424
425 *vslice = (VAEncSliceParameterBufferJPEG) {
426 .restart_interval = 0,
427 .num_components = sh->
Ns,
428 };
429
430 for (
i = 0;
i < sh->
Ns;
i++) {
431 vslice->components[
i].component_selector = sh->
Cs[
i];
432 vslice->components[
i].dc_table_selector = sh->
Td[
i];
433 vslice->components[
i].ac_table_selector = sh->
Ta[
i];
434 }
435
436 return 0;
437 }
438
440 {
443
446
449
450 return 0;
451 }
452
454 {
457 int err;
458
462 "(must be 1-100).\n", priv->
quality);
464 }
465
466 // Hack: the implementation calls the JPEG image header (which we
467 // will use in the same way as a slice header) generic "raw data".
468 // Therefore, if after the packed header capability check we have
469 // PACKED_HEADER_RAW_DATA available, rewrite it as
470 // PACKED_HEADER_SLICE so that the header-writing code can do the
471 // right thing.
472 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_RAW_DATA) {
473 ctx->va_packed_headers &= ~VA_ENC_PACKED_HEADER_RAW_DATA;
474 ctx->va_packed_headers |= VA_ENC_PACKED_HEADER_SLICE;
475 }
476
478 if (err < 0)
479 return err;
480
481 return 0;
482 }
483
486 8, 1, 0, 0, VAProfileJPEGBaseline },
488 8, 3, 1, 1, VAProfileJPEGBaseline },
490 8, 3, 1, 0, VAProfileJPEGBaseline },
492 8, 3, 0, 0, VAProfileJPEGBaseline },
494 };
495
498
501
504
505 .default_quality = 80,
506
507 .picture_params_size = sizeof(VAEncPictureParameterBufferJPEG),
509
510 .slice_params_size = sizeof(VAEncSliceParameterBufferJPEG),
512
513 .slice_header_type = VAEncPackedHeaderRawData,
515
517 };
518
520 {
522
524
525 // The JPEG image header - see note above.
526 ctx->desired_packed_headers =
527 VA_ENC_PACKED_HEADER_RAW_DATA;
528
530 }
531
533 {
535
537 ff_cbs_close(&priv->
cbc);
538
540 }
541
542 #define OFFSET(x) offsetof(VAAPIEncodeMJPEGContext, x)
543 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
547
548 { "jfif", "Include JFIF header",
550 { .i64 = 0 }, 0, 1,
FLAGS },
551 { "huffman", "Include huffman tables",
553 { .i64 = 1 }, 0, 1,
FLAGS },
554
556 };
557
559 { "b", "0" },
561 };
562
568 };
569
571 .
p.
name =
"mjpeg_vaapi",
588 .p.wrapper_name = "vaapi",
589 };