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_mpeg2.h>
21
24
31
34
35 // User options.
38
39 // Derived settings.
43
46
48
51
52 // Stream state.
54
55 // Writer structures.
62
66
67
69 char *
data,
size_t *data_len,
71 {
73 int err;
74
75 err = ff_cbs_write_fragment_data(priv->
cbc, frag);
76 if (err < 0) {
78 return err;
79 }
80
83 "%zu < %zu.\n", *data_len,
86 }
87
90
91 return 0;
92 }
93
97 {
98 int err;
99
101 if (err < 0) {
103 "type = %d.\n",
type);
104 return err;
105 }
106
107 return 0;
108 }
109
111 char *
data,
size_t *data_len)
112 {
115 int err;
116
119 if (err < 0)
121
124 if (err < 0)
126
129 if (err < 0)
131
134 if (err < 0)
136
139 ff_cbs_fragment_reset(frag);
140 return 0;
141 }
142
145 char *
data,
size_t *data_len)
146 {
149 int err;
150
153 if (err < 0)
155
158 if (err < 0)
160
163 ff_cbs_fragment_reset(frag);
164 return 0;
165 }
166
168 {
178 VAEncSequenceParameterBufferMPEG2 *vseq =
ctx->codec_sequence_params;
179 VAEncPictureParameterBufferMPEG2 *vpic =
ctx->codec_picture_params;
180 int code, ext_n, ext_d;
181
182 memset(sh, 0, sizeof(*sh));
183 memset(
se, 0,
sizeof(*
se));
184 memset(sde, 0, sizeof(*sde));
185 memset(goph, 0, sizeof(*goph));
186 memset(
ph, 0,
sizeof(*
ph));
187 memset(pce, 0, sizeof(*pce));
188
189
190 if (
ctx->va_bit_rate > 0) {
192 } else {
193 // Unknown (not a bitrate-targetting mode), so just use the
194 // highest value.
196 }
199 } else {
200 // Unknown, so guess a value from the bitrate.
202 }
203
204 switch (avctx->
level) {
205 case 4: // High.
206 case 6: // High 1440.
209 break;
210 case 8: // Main.
213 break;
214 case 10: // Low.
215 default:
218 break;
219 }
220
221
222 // Sequence header
223
225
228
232 (
AVRational) { avctx->width, avctx->height });
233
242 } else {
244 "representable, signalling square pixels instead.\n",
248 }
249 } else {
250 // Unknown - assume square pixels.
252 }
253
256 else
259 &
code, &ext_n, &ext_d, 0);
261
264
268
269
270 // Sequence extension
271
275
276 se->profile_and_level_indication = avctx->
profile << 4 | avctx->
level;
277 se->progressive_sequence = 1;
278 se->chroma_format = 1;
279
280 se->horizontal_size_extension = avctx->
width >> 12;
281 se->vertical_size_extension = avctx->
height >> 12;
282
283 se->bit_rate_extension = priv->
bit_rate >> 18;
286
287 se->frame_rate_extension_n = ext_n;
288 se->frame_rate_extension_d = ext_d;
289
290
291 // Sequence display extension
292
297
298 // Unspecified video format, from table 6-6.
300
308
311
312
313 // GOP header
314
316
317 // Marker bit in the middle of time_code.
321
322
323 // Defaults for picture header
324
326
327 ph->vbv_delay = 0xffff;
// Not currently calculated.
328
329 ph->full_pel_forward_vector = 0;
330 ph->forward_f_code = 7;
331 ph->full_pel_backward_vector = 0;
332 ph->forward_f_code = 7;
333
334
335 // Defaults for picture coding extension
336
341
353
354
355
356 *vseq = (VAEncSequenceParameterBufferMPEG2) {
358 .ip_period = base_ctx->
b_per_p + 1,
359
360 .picture_width = avctx->
width,
361 .picture_height = avctx->
height,
362
363 .bits_per_second =
ctx->va_bit_rate,
367
368 .sequence_extension.bits = {
369 .profile_and_level_indication =
se->profile_and_level_indication,
370 .progressive_sequence =
se->progressive_sequence,
371 .chroma_format =
se->chroma_format,
372 .low_delay =
se->low_delay,
373 .frame_rate_extension_n =
se->frame_rate_extension_n,
374 .frame_rate_extension_d =
se->frame_rate_extension_d,
375 },
376
377 .new_gop_header = 1,
378 .gop_header.bits = {
382 },
383 };
384
385 *vpic = (VAEncPictureParameterBufferMPEG2) {
386 .forward_reference_picture = VA_INVALID_ID,
387 .backward_reference_picture = VA_INVALID_ID,
388 .reconstructed_picture = VA_INVALID_ID,
389 .coded_buf = VA_INVALID_ID,
390
391 .vbv_delay = 0xffff,
392 .f_code = { { 15, 15 }, { 15, 15 } },
393
394 .picture_coding_extension.bits = {
406 },
407
408 .composite_display.bits = {
414 },
415 };
416
417 return 0;
418 }
419
422 {
428
430 ph->temporal_reference = 0;
431 ph->picture_coding_type = 1;
433 } else {
436 }
437
441 } else {
444 }
448 } else {
451 }
452
455
459 vpic->picture_type = VAEncPictureTypeIntra;
460 break;
462 vpic->picture_type = VAEncPictureTypePredictive;
464 break;
466 vpic->picture_type = VAEncPictureTypeBidirectional;
469 break;
470 default:
472 }
473
474 vpic->temporal_reference =
ph->temporal_reference;
475 vpic->f_code[0][0] = pce->
f_code[0][0];
476 vpic->f_code[0][1] = pce->
f_code[0][1];
477 vpic->f_code[1][0] = pce->
f_code[1][0];
478 vpic->f_code[1][1] = pce->
f_code[1][1];
479
480 return 0;
481 }
482
486 {
489 int qp;
490
493
498 break;
501 break;
504 break;
505 default:
507 }
508
509 vslice->quantiser_scale_code = qp;
512
513 return 0;
514 }
515
517 {
520 int err;
521
523 if (err < 0)
524 return err;
525
526 if (
ctx->va_rc_mode == VA_RC_CQP) {
532 else
538 else
540
542 "%d / %d / %d for I- / P- / B-frames.\n",
544
545 } else {
549 }
550
553
554 ctx->nb_slices =
ctx->slice_block_rows;
556
557 ctx->roi_quant_range = 31;
558
559 return 0;
560 }
561
566 };
567
570
572
574
575 .default_quality = 10,
576
577 .sequence_params_size = sizeof(VAEncSequenceParameterBufferMPEG2),
579
580 .picture_params_size = sizeof(VAEncPictureParameterBufferMPEG2),
582
583 .slice_params_size = sizeof(VAEncSliceParameterBufferMPEG2),
585
586 .sequence_header_type = VAEncPackedHeaderSequence,
588
589 .picture_header_type = VAEncPackedHeaderPicture,
591 };
592
594 {
597
599
604
605 // Reject unknown levels (these are required to set f_code for
606 // motion vector encoding).
607 switch (avctx->
level) {
608 case 4: // High
609 case 6: // High 1440
610 case 8: // Main
611 case 10: // Low
612 break;
613 default:
617 }
618
619 if (avctx->
height % 4096 == 0 || avctx->
width % 4096 == 0) {
621 "height or width divisible by 4096.\n");
623 }
624
625 ctx->desired_packed_headers = VA_ENC_PACKED_HEADER_SEQUENCE |
626 VA_ENC_PACKED_HEADER_PICTURE;
627
629 }
630
632 {
634
636 ff_cbs_close(&priv->
cbc);
637
639 }
640
641 #define OFFSET(x) offsetof(VAAPIEncodeMPEG2Context, x)
642 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
647
648 { "profile", "Set profile (in profile_and_level_indication)",
651
652 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
653 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
656 #undef PROFILE
657
658 { "level", "Set level (in profile_and_level_indication)",
660 { .i64 = 4 }, 0, 15,
FLAGS, .unit =
"level" },
661
662 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
663 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
664 {
LEVEL(
"low", 10) },
665 {
LEVEL(
"main", 8) },
666 {
LEVEL(
"high_1440", 6) },
667 {
LEVEL(
"high", 4) },
668 #undef LEVEL
669
671 };
672
674 { "b", "0" },
675 { "bf", "1" },
676 { "g", "120" },
677 { "i_qfactor", "1" },
678 { "i_qoffset", "0" },
679 { "b_qfactor", "6/5" },
680 { "b_qoffset", "0" },
681 { "qmin", "-1" },
682 { "qmax", "-1" },
684 };
685
691 };
692
694 .
p.
name =
"mpeg2_vaapi",
711 .p.wrapper_name = "vaapi",
712 };