1 /*
2 * Copyright (c) 2017-2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file codechal_encode_mpeg2.cpp
24 //! \brief Defines base class for MPEG2 dual-pipe encoder.
25 //!
26 #include "codechal_encode_mpeg2.h"
27 #include "codechal_mmc_encode_mpeg2.h"
28 #include "codechal_kernel_hme.h"
29 #include "codeckrnheader.h"
30
31 #define CODECHAL_ENCODE_MPEG2_FCODE_X(width) ((width < 200) ? 3 : (width < 500) ? 4 : (width < 1400) ? 5 : 6)
32 #define CODECHAL_ENCODE_MPEG2_FCODE_Y(fcodeX) ((fcodeX > 5) ? 5 : fcodeX)
33
34 //!
35 //! \enum ProfileIdc
36 //! \brief Profile idc
37 //!
38 enum ProfileIdc
39 {
40 highProfile = 0x10,
41 spatialProfile = 0x20,
42 snrProfile = 0x30,
43 mainProfile = 0x40,
44 simpleProfile = 0x50
45 } ;
46
47 //!
48 //! \enum LevelIdc
49 //! \brief Level idc
50 //!
51 enum LevelIdc
52 {
53 levelHigh = 4,
54 levelHigh1440 = 6,
55 levelMain = 8,
56 levelLow = 10
57 } ;
58
59 //!
60 //! \enum StartCode
61 //! \brief Start code
62 //!
63 enum StartCode
64 {
65 startCodePrefix = 0x000001, // bit string 0000 0000 0000 0000 0000 0001
66 startCodePicture = 0x00,
67 // slice_start_code = 0x01..0xAF, it is the slice_vertical_position for the slice
68 // 0xB0, 0xB1, 0xB6 - Reserved
69 startCodeUserData = 0xB2,
70 startCodeSequenceHeader = 0xB3,
71 startCodeSequenceError = 0xB4,
72 startCodeExtension = 0xB5,
73 startCodeSequenceEnd = 0xB7,
74 startCodeGroupStart = 0xB8
75 // system start codes = 0xB9..0xFF
76 } ;
77
78 //!
79 //! \enum BingdingTableOffsetBrcInitReset
80 //! \brief Bingding table offset brc init reset
81 //!
82 enum BingdingTableOffsetBrcInitReset
83 {
84 brcInitResetHistory = 0,
85 brcInitResetDistortion = 1,
86 brcInitResetNumBindingTableEntries = 2
87 } ;
88
89 //!
90 //! \enum BindingTableOffsetBrcUpdate
91 //! \brief Binding table offset brc update
92 //!
93 enum BindingTableOffsetBrcUpdate
94 {
95 brcUpdateHistory = 0,
96 brcUpdatePakStaticOutput = 1,
97 brcUpdatePictureStateRead = 2,
98 brcUpdatePictureStateWrite = 3,
99 brcUpdateMbencCurbeRead = 4,
100 brcUpdateMbencCurbeWrite = 5,
101 brcUpdateDistortion = 6,
102 brcUpdateConstantData = 7,
103 brcUpdatePicHeaderInputData = 8,
104 brcUpdateOutputData = 9,
105 brcUpdateNumBindingTableEntries = 10
106 } ;
107
108 //!
109 //! \class BrcInitResetCurbe
110 //! \brief Brc initialization reset curbe
111 //!
112 class BrcInitResetCurbe
113 {
114 public:
115 //!
116 //! \struct CurbeData
117 //! \brief Curbe data
118 //!
119 struct CurbeData
120 {
121 union
122 {
123 struct
124 {
125 uint32_t m_profileLevelMaxFrame : MOS_BITFIELD_RANGE(0,31);
126 };
127 struct
128 {
129 uint32_t m_value;
130 };
131 } DW0;
132
133 union
134 {
135 struct
136 {
137 uint32_t m_initBufFullInBits : MOS_BITFIELD_RANGE(0,31);
138 };
139 struct
140 {
141 uint32_t m_value;
142 };
143 } DW1;
144
145 union
146 {
147 struct
148 {
149 uint32_t m_bufSizeInBits : MOS_BITFIELD_RANGE(0,31);
150 };
151 struct
152 {
153 uint32_t m_value;
154 };
155 } DW2;
156
157 union
158 {
159 struct
160 {
161 uint32_t m_averageBitRate : MOS_BITFIELD_RANGE(0,31);
162 };
163 struct
164 {
165 uint32_t m_value;
166 };
167 } DW3;
168
169 union
170 {
171 struct
172 {
173 uint32_t m_maxBitRate : MOS_BITFIELD_RANGE(0,31);
174 };
175 struct
176 {
177 uint32_t m_value;
178 };
179 } DW4;
180
181 union
182 {
183 struct
184 {
185 uint32_t m_minBitRate : MOS_BITFIELD_RANGE(0,31);
186 };
187 struct
188 {
189 uint32_t m_value;
190 };
191 } DW5;
192
193 union
194 {
195 struct
196 {
197 uint32_t m_frameRateM : MOS_BITFIELD_RANGE(0,31);
198 };
199 struct
200 {
201 uint32_t m_value;
202 };
203 } DW6;
204
205 union
206 {
207 struct
208 {
209 uint32_t m_frameRateD : MOS_BITFIELD_RANGE(0,31);
210 };
211 struct
212 {
213 uint32_t m_value;
214 };
215 } DW7;
216
217 union
218 {
219 struct
220 {
221 uint32_t m_brcFlag : MOS_BITFIELD_RANGE(0,15);
222 uint32_t m_gopP : MOS_BITFIELD_RANGE(16,31);
223 };
224 struct
225 {
226 uint32_t m_value;
227 };
228 } DW8;
229
230 union
231 {
232 struct
233 {
234 uint32_t m_gopB : MOS_BITFIELD_RANGE(0,15);
235 uint32_t m_frameWidthInBytes : MOS_BITFIELD_RANGE(16,31);
236 };
237 struct
238 {
239 uint32_t m_value;
240 };
241 } DW9;
242
243 union
244 {
245 struct
246 {
247 uint32_t m_frameHeightInBytes : MOS_BITFIELD_RANGE(0,15);
248 uint32_t m_avbrAccuracy : MOS_BITFIELD_RANGE(16,31);
249 };
250 struct
251 {
252 uint32_t m_value;
253 };
254 } DW10;
255
256 union
257 {
258 struct
259 {
260 uint32_t m_avbrConvergence : MOS_BITFIELD_RANGE(0,15);
261 uint32_t m_minQP : MOS_BITFIELD_RANGE(16,31);
262 };
263 struct
264 {
265 uint32_t m_value;
266 };
267 } DW11;
268
269 union
270 {
271 struct
272 {
273 uint32_t m_maxQP : MOS_BITFIELD_RANGE(0,15);
274 uint32_t m_noSlices : MOS_BITFIELD_RANGE(16,31);
275 };
276 struct
277 {
278 uint32_t m_value;
279 };
280 } DW12;
281
282 union
283 {
284 struct
285 {
286 uint32_t m_instantRateThreshold0ForP : MOS_BITFIELD_RANGE(0,7);
287 uint32_t m_instantRateThreshold1ForP : MOS_BITFIELD_RANGE(8,15);
288 uint32_t m_instantRateThreshold2ForP : MOS_BITFIELD_RANGE(16,23);
289 uint32_t m_instantRateThreshold3ForP : MOS_BITFIELD_RANGE(24,31);
290 };
291 struct
292 {
293 uint32_t m_value;
294 };
295 } DW13;
296
297 union
298 {
299 struct
300 {
301 uint32_t m_instantRateThreshold0ForB : MOS_BITFIELD_RANGE(0,7);
302 uint32_t m_instantRateThreshold1ForB : MOS_BITFIELD_RANGE(8,15);
303 uint32_t m_instantRateThreshold2ForB : MOS_BITFIELD_RANGE(16,23);
304 uint32_t m_instantRateThreshold3ForB : MOS_BITFIELD_RANGE(24,31);
305 };
306 struct
307 {
308 uint32_t m_value;
309 };
310 } DW14;
311
312 union
313 {
314 struct
315 {
316 uint32_t m_instantRateThreshold0ForI : MOS_BITFIELD_RANGE(0,7);
317 uint32_t m_instantRateThreshold1ForI : MOS_BITFIELD_RANGE(8,15);
318 uint32_t m_instantRateThreshold2ForI : MOS_BITFIELD_RANGE(16,23);
319 uint32_t m_instantRateThreshold3ForI : MOS_BITFIELD_RANGE(24,31);
320 };
321 struct
322 {
323 uint32_t m_value;
324 };
325 } DW15;
326
327 union
328 {
329 struct
330 {
331 uint32_t m_deviationThreshold0ForPandB : MOS_BITFIELD_RANGE(0,7); // Signed byte
332 uint32_t m_deviationThreshold1ForPandB : MOS_BITFIELD_RANGE(8,15); // Signed byte
333 uint32_t m_deviationThreshold2ForPandB : MOS_BITFIELD_RANGE(16,23); // Signed byte
334 uint32_t m_deviationThreshold3ForPandB : MOS_BITFIELD_RANGE(24,31); // Signed byte
335 };
336 struct
337 {
338 uint32_t m_value;
339 };
340 } DW16;
341
342 union
343 {
344 struct
345 {
346 uint32_t m_deviationThreshold4ForPandB : MOS_BITFIELD_RANGE(0,7); // Signed byte
347 uint32_t m_deviationThreshold5ForPandB : MOS_BITFIELD_RANGE(8,15); // Signed byte
348 uint32_t m_deviationThreshold6ForPandB : MOS_BITFIELD_RANGE(16,23); // Signed byte
349 uint32_t m_deviationThreshold7ForPandB : MOS_BITFIELD_RANGE(24,31); // Signed byte
350 };
351 struct
352 {
353 uint32_t m_value;
354 };
355 } DW17;
356
357 union
358 {
359 struct
360 {
361 uint32_t m_deviationThreshold0ForVBR : MOS_BITFIELD_RANGE(0,7); // Signed byte
362 uint32_t m_deviationThreshold1ForVBR : MOS_BITFIELD_RANGE(8,15); // Signed byte
363 uint32_t m_deviationThreshold2ForVBR : MOS_BITFIELD_RANGE(16,23); // Signed byte
364 uint32_t m_deviationThreshold3ForVBR : MOS_BITFIELD_RANGE(24,31); // Signed byte
365 };
366 struct
367 {
368 uint32_t m_value;
369 };
370 } DW18;
371
372 union
373 {
374 struct
375 {
376 uint32_t m_deviationThreshold4ForVBR : MOS_BITFIELD_RANGE(0,7); // Signed byte
377 uint32_t m_deviationThreshold5ForVBR : MOS_BITFIELD_RANGE(8,15); // Signed byte
378 uint32_t m_deviationThreshold6ForVBR : MOS_BITFIELD_RANGE(16,23); // Signed byte
379 uint32_t m_deviationThreshold7ForVBR : MOS_BITFIELD_RANGE(24,31); // Signed byte
380 };
381 struct
382 {
383 uint32_t m_value;
384 };
385 } DW19;
386
387 union
388 {
389 struct
390 {
391 uint32_t m_deviationThreshold0ForI : MOS_BITFIELD_RANGE(0,7); // Signed byte
392 uint32_t m_deviationThreshold1ForI : MOS_BITFIELD_RANGE(8,15); // Signed byte
393 uint32_t m_deviationThreshold2ForI : MOS_BITFIELD_RANGE(16,23); // Signed byte
394 uint32_t m_deviationThreshold3ForI : MOS_BITFIELD_RANGE(24,31); // Signed byte
395 };
396 struct
397 {
398 uint32_t m_value;
399 };
400 } DW20;
401
402 union
403 {
404 struct
405 {
406 uint32_t m_deviationThreshold4ForI : MOS_BITFIELD_RANGE(0,7); // Signed byte
407 uint32_t m_deviationThreshold5ForI : MOS_BITFIELD_RANGE(8,15); // Signed byte
408 uint32_t m_deviationThreshold6ForI : MOS_BITFIELD_RANGE(16,23); // Signed byte
409 uint32_t m_deviationThreshold7ForI : MOS_BITFIELD_RANGE(24,31); // Signed byte
410 };
411 struct
412 {
413 uint32_t m_value;
414 };
415 } DW21;
416
417 union
418 {
419 struct
420 {
421 uint32_t m_value;
422 };
423 } DW22;
424
425 union
426 {
427 struct
428 {
429 uint32_t m_value;
430 };
431 } DW23;
432
433 union
434 {
435 struct
436 {
437 uint32_t m_value;
438 };
439 } DW24;
440
441 union
442 {
443 struct
444 {
445 uint32_t m_value;
446 };
447 } DW25;
448 }m_curbeData;
449
450 //!
451 //! \brief Constructor
452 //!
453 BrcInitResetCurbe();
454
455 //!
456 //! \brief Destructor
457 //!
~BrcInitResetCurbe()458 ~BrcInitResetCurbe(){};
459
460 static const size_t m_byteSize = sizeof(CurbeData);
461
462 };
463
464 //!
465 //! \struct BrcUpdateCurbe
466 //! \brief BRC update curbe
467 //!
468 class BrcUpdateCurbe
469 {
470 public:
471 //!
472 //! \struct CurbeData
473 //! \brief Curbe data
474 //!
475 struct CurbeData
476 {
477 union
478 {
479 struct
480 {
481 uint32_t m_targetSize : MOS_BITFIELD_RANGE(0,31);
482 };
483 struct
484 {
485 uint32_t m_value;
486 };
487 } DW0;
488
489 union
490 {
491 struct
492 {
493 uint32_t m_frameNumber : MOS_BITFIELD_RANGE(0,31);
494 };
495 struct
496 {
497 uint32_t m_value;
498 };
499 } DW1;
500
501 union
502 {
503 struct
504 {
505 uint32_t m_sliceNumber : MOS_BITFIELD_RANGE(0,31);
506 };
507 struct
508 {
509 uint32_t m_value;
510 };
511 } DW2;
512
513 union
514 {
515 struct
516 {
517 uint32_t m_startGAdjFrame0 : MOS_BITFIELD_RANGE(0,15);
518 uint32_t m_startGAdjFrame1 : MOS_BITFIELD_RANGE(16,31);
519 };
520 struct
521 {
522 uint32_t m_value;
523 };
524 } DW3;
525
526 union
527 {
528 struct
529 {
530 uint32_t m_startGAdjFrame2 : MOS_BITFIELD_RANGE(0,15);
531 uint32_t m_startGAdjFrame3 : MOS_BITFIELD_RANGE(16,31);
532 };
533 struct
534 {
535 uint32_t m_value;
536 };
537 } DW4;
538
539 union
540 {
541 struct
542 {
543 uint32_t m_targetSizeFlag : MOS_BITFIELD_RANGE(0,7);
544 uint32_t m_brcFlag : MOS_BITFIELD_RANGE(8,15);
545 uint32_t m_maxNumPAKs : MOS_BITFIELD_RANGE(16,23);
546 uint32_t m_currFrameType : MOS_BITFIELD_RANGE(24,31);
547 };
548 struct
549 {
550 uint32_t m_value;
551 };
552 } DW5;
553
554 // This offset indicates the byte position of the q_scale_type bit
555 // in the 2nd level batch buffer containing the INSERT_OBJ command
556 // for inserting the picture header data into the bitstream.
557 // This offset includes the 8 bytes of the INSERT command at the
558 // beginning of the buffer.
559 union
560 {
561 struct
562 {
563 uint32_t m_qScaleTypeOffset : MOS_BITFIELD_RANGE(0,15);
564 uint32_t m_vbvDelay : MOS_BITFIELD_RANGE(16,31);
565 };
566 struct
567 {
568 uint32_t m_value;
569 };
570 } DW6;
571
572 // This size is the size of the entire 2nd level batch buffer
573 // containing the INSERT_OBJ command for inserting the
574 // picture header data into the bitstream. It includes the batch buffer end
575 // command at the end of the buffer.
576 union
577 {
578 struct
579 {
580 uint32_t m_picHeaderDataBufferSize :MOS_BITFIELD_RANGE(0,31);
581 };
582 struct
583 {
584 uint32_t m_value;
585 };
586
587 } DW7;
588
589 union
590 {
591 struct
592 {
593 uint32_t m_startGlobalAdjustMult0 : MOS_BITFIELD_RANGE(0,7);
594 uint32_t m_startGlobalAdjustMult1 : MOS_BITFIELD_RANGE(8,15);
595 uint32_t m_startGlobalAdjustMult2 : MOS_BITFIELD_RANGE(16,23);
596 uint32_t m_startGlobalAdjustMult3 : MOS_BITFIELD_RANGE(24,31);
597 };
598 struct
599 {
600 uint32_t m_value;
601 };
602 } DW8;
603
604 union
605 {
606 struct
607 {
608 uint32_t m_startGlobalAdjustMult4 : MOS_BITFIELD_RANGE(0,7);
609 uint32_t m_startGlobalAdjustDiv0 : MOS_BITFIELD_RANGE(8,15);
610 uint32_t m_startGlobalAdjustDiv1 : MOS_BITFIELD_RANGE(16,23);
611 uint32_t m_startGlobalAdjustDiv2 : MOS_BITFIELD_RANGE(24,31);
612 };
613 struct
614 {
615 uint32_t m_value;
616 };
617 } DW9;
618
619 union
620 {
621 struct
622 {
623 uint32_t m_startGlobalAdjustDiv3 : MOS_BITFIELD_RANGE(0,7);
624 uint32_t m_startGlobalAdjustDiv4 : MOS_BITFIELD_RANGE(8,15);
625 uint32_t m_qpThreshold0 : MOS_BITFIELD_RANGE(16,23);
626 uint32_t m_qpThreshold1 : MOS_BITFIELD_RANGE(24,31);
627 };
628 struct
629 {
630 uint32_t m_value;
631 };
632 } DW10;
633
634 union
635 {
636 struct
637 {
638 uint32_t m_qpThreshold2 : MOS_BITFIELD_RANGE(0,7);
639 uint32_t m_qpThreshold3 : MOS_BITFIELD_RANGE(8,15);
640 uint32_t m_gRateRatioThreshold0 : MOS_BITFIELD_RANGE(16,23);
641 uint32_t m_gRateRatioThreshold1 : MOS_BITFIELD_RANGE(24,31);
642 };
643 struct
644 {
645 uint32_t m_value;
646 };
647 } DW11;
648
649 union
650 {
651 struct
652 {
653 uint32_t m_gRateRatioThreshold2 : MOS_BITFIELD_RANGE(0,7);
654 uint32_t m_gRateRatioThreshold3 : MOS_BITFIELD_RANGE(8,15);
655 uint32_t m_gRateRatioThreshold4 : MOS_BITFIELD_RANGE(16,23);
656 uint32_t m_gRateRatioThreshold5 : MOS_BITFIELD_RANGE(24,31);
657 };
658 struct
659 {
660 uint32_t m_value;
661 };
662 } DW12;
663
664 union
665 {
666 struct
667 {
668 uint32_t m_gRateRatioThresholdQP0 : MOS_BITFIELD_RANGE(0,7);
669 uint32_t m_gRateRatioThresholdQP1 : MOS_BITFIELD_RANGE(8,15);
670 uint32_t m_gRateRatioThresholdQP2 : MOS_BITFIELD_RANGE(16,23);
671 uint32_t m_gRateRatioThresholdQP3 : MOS_BITFIELD_RANGE(24,31);
672 };
673 struct
674 {
675 uint32_t m_value;
676 };
677 } DW13;
678
679 union
680 {
681 struct
682 {
683 uint32_t m_gRateRatioThresholdQP4 : MOS_BITFIELD_RANGE(0,7);
684 uint32_t m_gRateRatioThresholdQP5 : MOS_BITFIELD_RANGE(8,15);
685 uint32_t m_gRateRatioThresholdQP6 : MOS_BITFIELD_RANGE(16,23);
686 uint32_t m_forceToSkip : MOS_BITFIELD_RANGE(24,24);
687 uint32_t m_reserved25 : MOS_BITFIELD_RANGE(25,31);
688 };
689 struct
690 {
691 uint32_t m_value;
692 };
693 } DW14;
694
695 union
696 {
697 struct
698 {
699 uint32_t m_extraHeaders : MOS_BITFIELD_RANGE(0,15);
700 uint32_t m_intraDcPrecisionOffset : MOS_BITFIELD_RANGE(16,31);
701 };
702 struct
703 {
704 uint32_t m_value;
705 };
706 } DW15;
707
708 union
709 {
710 struct
711 {
712 uint32_t m_value;
713 };
714 } DW16[16];
715
716 union
717 {
718 struct
719 {
720 uint32_t m_bindingTableIndex : MOS_BITFIELD_RANGE(0,31);
721 };
722 struct
723 {
724 uint32_t m_value;
725 };
726 } DW32[10];
727 }m_curbeData;
728
729 //!
730 //! \brief Constructor
731 //!
732 BrcUpdateCurbe();
733
734 //!
735 //! \brief Destructor
736 //!
~BrcUpdateCurbe()737 ~BrcUpdateCurbe(){};
738
739 static const size_t m_byteSize = sizeof(CurbeData);
740
741 } ;
742
743 //!
744 //! \struct VLCode
745 //! \brief VL code
746 //!
747 struct VLCode{
748 uint32_t m_code;
749 uint32_t m_len;
750 };
751
752 //!
753 //! \struct MediaObjectInlineDataMpeg2
754 //! \brief Media object inline data
755 //!
756 struct MediaObjectInlineDataMpeg2
757 {
758 // DW0
759 union
760 {
761 struct
762 {
763 uint32_t m_mbX : 8; //<! in MB unit
764 uint32_t m_mbY : 8; //<! in MB unit
765 uint32_t m_reserved : 16;
766 };
767 struct
768 {
769 uint32_t m_value;
770 };
771 } DW0;
772
773 // uint32_t 1
774 union
775 {
776 struct
777 {
778 uint32_t m_lastMbInSliceGroup : 8;
779 uint32_t m_firstMbInSliceGroup : 8;
780 uint32_t m_lastMbInSlice : 8;
781 uint32_t m_firstMbInSlice : 8;
782 };
783 struct
784 {
785 uint32_t m_value;
786 };
787 } DW1;
788
789 // uint32_t 2
790 union
791 {
792 struct
793 {
794 uint32_t m_batchBufferEnd : 32;
795 };
796 struct
797 {
798 uint32_t m_value;
799 };
800 } DW2;
801 } ;
802
803 //!
804 //! \struct SliceRecord
805 //! \brief Slice record
806 //!
807 struct SliceRecord
808 {
809 // DW 1
810 union
811 {
812 struct
813 {
814 uint32_t m_lastMbInSliceGroup : 8;
815 uint32_t m_firstMbInSliceGroup : 8;
816 uint32_t m_lastMbInSlice : 8;
817 uint32_t m_firstMbInSlice : 8;
818 };
819 struct
820 {
821 uint32_t m_value;
822 };
823 } DW1;
824
825 // DW 2
826 union
827 {
828 struct
829 {
830 uint32_t m_batchBufferEnd : 32;
831 };
832 struct
833 {
834 uint32_t m_value;
835 };
836 } DW2;
837 } ;
838
839 /* VL codes for macroblock_address_increment ISO/IEC 13818-2, B.1, Table B-1. */
840 static const VLCode mpeg2AddrIncreamentTbl[35] =
841 {
842 { 0x00, 0 }, // forbidden m_value
843 { 0x01, 1 },
844 { 0x03, 3 }, { 0x02, 3 },
845 { 0x03, 4 }, { 0x02, 4 },
846 { 0x03, 5 }, { 0x02, 5 },
847 { 0x07, 7 }, { 0x06, 7 },
848 { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 }, { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 },
849 { 0x17, 10 }, { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 }, { 0x12, 10 },
850 { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 }, { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 }, { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 }, { 0x18, 11 },
851 { 0x08, 11 } // macroblock_escape
852 };
853
854 /* VL codes for macroblock_type ISO/IEC 13818-2, B.2, Tables B-2, B-3, B-4. */
855 static const VLCode mpeg2MbTypeTbl[3][32] =
856 {
857 /* I */
858 {
859 { 0x00, 0 }, { 0x01, 1 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
860 { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
861 { 0x00, 0 }, { 0x01, 2 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
862 { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }
863 },
864 /* P */
865 {
866 { 0x00, 0 }, { 0x03, 5 }, { 0x01, 2 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
867 { 0x01, 3 }, { 0x00, 0 }, { 0x01, 1 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
868 { 0x00, 0 }, { 0x01, 6 }, { 0x01, 5 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
869 { 0x00, 0 }, { 0x00, 0 }, { 0x02, 5 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }
870 },
871 /* B */
872 {
873 { 0x00, 0 }, { 0x03, 5 }, { 0x00, 0 }, { 0x00, 0 }, { 0x02, 3 }, { 0x00, 0 }, { 0x03, 3 }, { 0x00, 0 },
874 { 0x02, 4 }, { 0x00, 0 }, { 0x03, 4 }, { 0x00, 0 }, { 0x02, 2 }, { 0x00, 0 }, { 0x03, 2 }, { 0x00, 0 },
875 { 0x00, 0 }, { 0x01, 6 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x02, 6 }, { 0x00, 0 },
876 { 0x00, 0 }, { 0x00, 0 }, { 0x03, 6 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x02, 5 }, { 0x00, 0 }
877 }
878 };
879
880 /* VL codes for motion_code+16 ISO/IEC 13818-2, B.4, Table B-10. */
881 static const VLCode mpeg2MvVlcTbl[33] =
882 {
883 // negative motion_code
884 { 0x19, 11 }, { 0x1b, 11 }, { 0x1d, 11 }, { 0x1f, 11 }, { 0x21, 11 }, { 0x23, 11 },
885 { 0x13, 10 }, { 0x15, 10 }, { 0x17, 10 },
886 { 0x07, 8 }, { 0x09, 8 }, { 0x0b, 8 },
887 { 0x07, 7 },
888 { 0x03, 5 },
889 { 0x03, 4 },
890 { 0x03, 3 },
891 // zero motion_code
892 { 0x01, 1 },
893 // positive motion_code
894 { 0x02, 3 },
895 { 0x02, 4 },
896 { 0x02, 5 },
897 { 0x06, 7 },
898 { 0x0a, 8 }, { 0x08, 8 }, { 0x06, 8 },
899 { 0x16, 10 }, { 0x14, 10 }, { 0x12, 10 },
900 { 0x22, 11 }, { 0x20, 11 }, { 0x1e, 11 }, { 0x1c, 11 }, { 0x1a, 11 }, { 0x18, 11 }
901 };
902
BrcInitResetCurbe()903 BrcInitResetCurbe::BrcInitResetCurbe()
904 {
905 CODECHAL_ENCODE_FUNCTION_ENTER;
906
907 MOS_ZeroMemory(&m_curbeData, m_byteSize);
908
909 m_curbeData.DW10.m_avbrAccuracy = 30;
910 m_curbeData.DW11.m_avbrConvergence = 150;
911 m_curbeData.DW11.m_minQP = 1;
912 m_curbeData.DW12.m_maxQP = 112;
913 m_curbeData.DW12.m_noSlices = 1;
914 m_curbeData.DW13.m_instantRateThreshold0ForP = 30;
915 m_curbeData.DW13.m_instantRateThreshold1ForP = 50;
916 m_curbeData.DW13.m_instantRateThreshold2ForP = 70;
917 m_curbeData.DW13.m_instantRateThreshold3ForP = 120;
918 m_curbeData.DW14.m_instantRateThreshold0ForB = 25;
919 m_curbeData.DW14.m_instantRateThreshold1ForB = 50;
920 m_curbeData.DW14.m_instantRateThreshold2ForB = 70;
921 m_curbeData.DW14.m_instantRateThreshold3ForB = 120;
922 m_curbeData.DW15.m_instantRateThreshold0ForI = 30;
923 m_curbeData.DW15.m_instantRateThreshold1ForI = 50;
924 m_curbeData.DW15.m_instantRateThreshold2ForI = 90;
925 m_curbeData.DW15.m_instantRateThreshold3ForI = 115;
926 m_curbeData.DW16.m_deviationThreshold0ForPandB = MOS_BITFIELD_VALUE((uint32_t)-45, 8);
927 m_curbeData.DW16.m_deviationThreshold1ForPandB = MOS_BITFIELD_VALUE((uint32_t)-33, 8);
928 m_curbeData.DW16.m_deviationThreshold2ForPandB = MOS_BITFIELD_VALUE((uint32_t)-23, 8);
929 m_curbeData.DW16.m_deviationThreshold3ForPandB = MOS_BITFIELD_VALUE((uint32_t)-15, 8);
930 m_curbeData.DW17.m_deviationThreshold4ForPandB = 15;
931 m_curbeData.DW17.m_deviationThreshold5ForPandB = 23;
932 m_curbeData.DW17.m_deviationThreshold6ForPandB = 35;
933 m_curbeData.DW17.m_deviationThreshold7ForPandB = 45;
934 m_curbeData.DW18.m_deviationThreshold0ForVBR = MOS_BITFIELD_VALUE((uint32_t)-45, 8);
935 m_curbeData.DW18.m_deviationThreshold1ForVBR = MOS_BITFIELD_VALUE((uint32_t)-35, 8);
936 m_curbeData.DW18.m_deviationThreshold2ForVBR = MOS_BITFIELD_VALUE((uint32_t)-25, 8);
937 m_curbeData.DW18.m_deviationThreshold3ForVBR = MOS_BITFIELD_VALUE((uint32_t)-15, 8);
938 m_curbeData.DW19.m_deviationThreshold4ForVBR = 40;
939 m_curbeData.DW19.m_deviationThreshold5ForVBR = 50;
940 m_curbeData.DW19.m_deviationThreshold6ForVBR = 75;
941 m_curbeData.DW19.m_deviationThreshold7ForVBR = 90;
942 m_curbeData.DW20.m_deviationThreshold0ForI = MOS_BITFIELD_VALUE((uint32_t)-40, 8);
943 m_curbeData.DW20.m_deviationThreshold1ForI = MOS_BITFIELD_VALUE((uint32_t)-30, 8);
944 m_curbeData.DW20.m_deviationThreshold2ForI = MOS_BITFIELD_VALUE((uint32_t)-17, 8);
945 m_curbeData.DW20.m_deviationThreshold3ForI = MOS_BITFIELD_VALUE((uint32_t)-10, 8);
946 m_curbeData.DW21.m_deviationThreshold4ForI = 10;
947 m_curbeData.DW21.m_deviationThreshold5ForI = 20;
948 m_curbeData.DW21.m_deviationThreshold6ForI = 33;
949 m_curbeData.DW21.m_deviationThreshold7ForI = 45;
950 m_curbeData.DW25.m_value = 1;
951 }
952
BrcUpdateCurbe()953 BrcUpdateCurbe::BrcUpdateCurbe()
954 {
955 CODECHAL_ENCODE_FUNCTION_ENTER;
956
957 MOS_ZeroMemory(&m_curbeData, m_byteSize);
958
959 m_curbeData.DW3.m_startGAdjFrame0 = 10;
960 m_curbeData.DW3.m_startGAdjFrame1 = 50;
961 m_curbeData.DW4.m_startGAdjFrame2 = 100;
962 m_curbeData.DW4.m_startGAdjFrame3 = 150;
963 m_curbeData.DW7.m_picHeaderDataBufferSize = 0;
964 m_curbeData.DW8.m_startGlobalAdjustMult0 = 1;
965 m_curbeData.DW8.m_startGlobalAdjustMult1 = 1;
966 m_curbeData.DW8.m_startGlobalAdjustMult2 = 3;
967 m_curbeData.DW8.m_startGlobalAdjustMult3 = 2;
968 m_curbeData.DW9.m_startGlobalAdjustMult4 = 1;
969 m_curbeData.DW9.m_startGlobalAdjustDiv0 = 40;
970 m_curbeData.DW9.m_startGlobalAdjustDiv1 = 5;
971 m_curbeData.DW9.m_startGlobalAdjustDiv2 = 5;
972 m_curbeData.DW10.m_startGlobalAdjustDiv3 = 3;
973 m_curbeData.DW10.m_startGlobalAdjustDiv4 = 1;
974 m_curbeData.DW10.m_qpThreshold0 = 7;
975 m_curbeData.DW10.m_qpThreshold1 = 18;
976 m_curbeData.DW11.m_qpThreshold2 = 25;
977 m_curbeData.DW11.m_qpThreshold3 = 37;
978 m_curbeData.DW11.m_gRateRatioThreshold0 = 40;
979 m_curbeData.DW11.m_gRateRatioThreshold1 = 75;
980 m_curbeData.DW12.m_gRateRatioThreshold2 = 97;
981 m_curbeData.DW12.m_gRateRatioThreshold3 = 103;
982 m_curbeData.DW12.m_gRateRatioThreshold4 = 125;
983 m_curbeData.DW12.m_gRateRatioThreshold5 = 160;
984 m_curbeData.DW13.m_gRateRatioThresholdQP0 = MOS_BITFIELD_VALUE((uint32_t)-3, 8);
985 m_curbeData.DW13.m_gRateRatioThresholdQP1 = MOS_BITFIELD_VALUE((uint32_t)-2, 8);
986 m_curbeData.DW13.m_gRateRatioThresholdQP2 = MOS_BITFIELD_VALUE((uint32_t)-1, 8);
987 m_curbeData.DW13.m_gRateRatioThresholdQP3 = 0;
988 m_curbeData.DW14.m_gRateRatioThresholdQP4 = 1;
989 m_curbeData.DW14.m_gRateRatioThresholdQP5 = 2;
990 m_curbeData.DW14.m_gRateRatioThresholdQP6 = 3;
991 m_curbeData.DW14.m_forceToSkip = 1;
992 m_curbeData.DW15.m_value = 0;
993 m_curbeData.DW16[0].m_value = 0x06040200;
994 m_curbeData.DW16[1].m_value = 0x0e0c0a08;
995 m_curbeData.DW16[2].m_value = 0x16141210;
996 m_curbeData.DW16[3].m_value = 0x1e1c1a18;
997 m_curbeData.DW16[4].m_value = 0x26242220;
998 m_curbeData.DW16[5].m_value = 0x2e2c2a28;
999 m_curbeData.DW16[6].m_value = 0x36343230;
1000 m_curbeData.DW16[7].m_value = 0x3e3c3a38;
1001 m_curbeData.DW16[8].m_value = 0x03020100;
1002 m_curbeData.DW16[9].m_value = 0x07060504;
1003 m_curbeData.DW16[10].m_value = 0x0e0c0a08;
1004 m_curbeData.DW16[11].m_value = 0x16141210;
1005 m_curbeData.DW16[12].m_value = 0x24201c18;
1006 m_curbeData.DW16[13].m_value = 0x34302c28;
1007 m_curbeData.DW16[14].m_value = 0x50484038;
1008 m_curbeData.DW16[15].m_value = 0x70686058;
1009
1010 for (uint8_t idx = 0; idx < 10 ; idx++)
1011 {
1012 m_curbeData.DW32[idx].m_bindingTableIndex = idx;
1013 }
1014 }
1015
1016 const uint8_t CodechalEncodeMpeg2::m_qpAdjustmentDistThresholdMaxFrameThresholdI[] = {
1017 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x01, 0x02, 0x03, 0x04,
1018 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
1019 0xff, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xfe, 0xff, 0x00, 0x00,
1020 0xfd, 0xfd, 0xff, 0xff, 0x00, 0xfc, 0xfd, 0xfe, 0xff, 0xff,
1021 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x04, 0x1e, 0x3c, 0x50,
1022 0x78, 0x8c, 0xc8, 0xff, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x00,
1023 0x00, 0x00, 0x00, 0x00};
1024
1025 const uint8_t CodechalEncodeMpeg2::m_qpAdjustmentDistThresholdMaxFrameThresholdP[] = {
1026 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x01, 0x02, 0x03, 0x04,
1027 0x00, 0x01, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
1028 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00,
1029 0xfe, 0xff, 0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0xff, 0x00,
1030 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x04, 0x1e, 0x3c, 0x50,
1031 0x78, 0x8c, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00,
1032 0x00, 0x00, 0x00, 0x00 };
1033
1034 const uint8_t CodechalEncodeMpeg2::m_qpAdjustmentDistThresholdMaxFrameThresholdB[] = {
1035 0x01, 0x01, 0x02, 0x03, 0x04, 0x01, 0x01, 0x01, 0x02, 0x03,
1036 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01,
1037 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
1038 0xfe, 0xff, 0xff, 0xff, 0x00, 0xfd, 0xfe, 0xff, 0xff, 0x01,
1039 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x02, 0x14, 0x28, 0x46,
1040 0x82, 0xa0, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00,
1041 0x00, 0x00, 0x00, 0x00 };
1042
1043 const uint8_t CodechalEncodeMpeg2::m_distQpAdjustmentI[] = {
1044 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x00,
1045 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0xff, 0x00,
1046 0x00, 0x00, 0x01, 0x02, 0x02, 0x04, 0x05, 0xff, 0xff, 0x00,
1047 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0xfd, 0xfe, 0xff, 0x00,
1048 0x00, 0x00, 0x01, 0x02, 0x04, 0xfe, 0xfe, 0xff, 0xff, 0x00,
1049 0x00, 0x00, 0x01, 0x03, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0x00,
1050 0x00, 0x00, 0x02, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff,
1051 0x00, 0x01, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
1052 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1053 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1054
1055 const uint8_t CodechalEncodeMpeg2::m_distQpAdjustmentP[] = {
1056 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x00,
1057 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0xff, 0x00,
1058 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0xff, 0xff, 0x00,
1059 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0xfe, 0xff, 0xff, 0x00,
1060 0x00, 0x00, 0x01, 0x01, 0x03, 0xfe, 0xfe, 0xff, 0xff, 0x00,
1061 0x00, 0x00, 0x01, 0x02, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0x00,
1062 0x00, 0x00, 0x02, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff,
1063 0x00, 0x01, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
1064 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1066
1067 const uint8_t CodechalEncodeMpeg2::m_distQpAdjustmentB[] = {
1068 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x00,
1069 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x00, 0x00,
1070 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0xff, 0x00, 0x00,
1071 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0xfe, 0xff, 0x00, 0x00,
1072 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xfe, 0xff, 0x00, 0x00,
1073 0x00, 0x00, 0x01, 0x01, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x00,
1074 0x00, 0x00, 0x01, 0xfc, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0x00,
1075 0x00, 0x00, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
1076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1078
1079 const uint8_t CodechalEncodeMpeg2::m_targetUsageToKernelMode[] = {
1080 encodeNormalMode, encodeNormalMode,
1081 encodeNormalMode, encodeNormalMode,
1082 encodeNormalMode, encodeNormalMode,
1083 encodeNormalMode, encodeNormalMode };
1084
1085 const uint32_t CodechalEncodeMpeg2::m_vmeLutXyP[] = { 0x34262410, 0x46454436 };
1086
1087 const uint32_t CodechalEncodeMpeg2::m_vmeLutXyB[] = { 0x44363410, 0x56555446 };
1088
1089 const uint32_t CodechalEncodeMpeg2::m_vmeSPathP0[] = {
1090 0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x02F1F1F1, 0x1F201111,
1091 0xF1EFFF0C, 0xF01104F1, 0x10FF0A50, 0x000FF1C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1092 };
1093
1094 const uint32_t CodechalEncodeMpeg2::m_vmeSPathP1[] = {
1095 0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0xF1FB06FC, 0x0000D33F, 0x00000000, 0x00000000, 0x00000000,
1096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1097 };
1098
1099 const uint32_t CodechalEncodeMpeg2::m_vmeSPathB0[] = {
1100 0x120FF10F, 0x20E20F1F, 0x201EE2FD, 0x000D02D1, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1101 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1102 };
1103
1104 const uint32_t CodechalEncodeMpeg2::m_vmeSPathB1[] = {
1105 0x120FF10F, 0x20E20F1F, 0x0000E2FD, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1106 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1107 };
1108
InitMmcState()1109 MOS_STATUS CodechalEncodeMpeg2::InitMmcState()
1110 {
1111 CODECHAL_ENCODE_FUNCTION_ENTER;
1112
1113 #ifdef _MMC_SUPPORTED
1114 m_mmcState = MOS_New(CodechalMmcEncodeMpeg2, m_hwInterface, this);
1115 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
1116 #endif
1117 return MOS_STATUS_SUCCESS;
1118 }
1119
CodechalEncodeMpeg2(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1120 CodechalEncodeMpeg2::CodechalEncodeMpeg2(
1121 CodechalHwInterface* hwInterface,
1122 CodechalDebugInterface* debugInterface,
1123 PCODECHAL_STANDARD_INFO standardInfo) :
1124 CodechalEncoderState(hwInterface, debugInterface, standardInfo)
1125 {
1126 CODECHAL_ENCODE_FUNCTION_ENTER;
1127
1128 CODECHAL_ENCODE_ASSERT(hwInterface);
1129 m_hwInterface = hwInterface;
1130 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetOsInterface());
1131 m_osInterface = m_hwInterface->GetOsInterface();
1132 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetMfxInterface());
1133 m_mfxInterface = m_hwInterface->GetMfxInterface();
1134 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetHcpInterface());
1135 m_hcpInterface = m_hwInterface->GetHcpInterface();
1136 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetHucInterface());
1137 m_hucInterface = m_hwInterface->GetHucInterface();
1138 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetVdencInterface());
1139 m_vdencInterface = m_hwInterface->GetVdencInterface();
1140 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetMiInterface());
1141 m_miInterface = m_hwInterface->GetMiInterface();
1142 auto renderInterface = m_hwInterface->GetRenderInterface();
1143 CODECHAL_ENCODE_ASSERT(renderInterface);
1144 m_stateHeapInterface = renderInterface->m_stateHeapInterface;
1145 CODECHAL_ENCODE_ASSERT(m_stateHeapInterface);
1146
1147 MOS_ZeroMemory(&m_picIdx, sizeof(m_picIdx));
1148 MOS_ZeroMemory(&m_refList, sizeof(m_refList));
1149 MOS_ZeroMemory(&m_4xMEMVDataBuffer, sizeof(m_4xMEMVDataBuffer));
1150 MOS_ZeroMemory(&m_batchBufForMEDistBuffer, sizeof(m_batchBufForMEDistBuffer));
1151 MOS_ZeroMemory(&m_mbEncBindingTable, sizeof(m_mbEncBindingTable));
1152 MOS_ZeroMemory(&m_4xMEDistortionBuffer, sizeof(m_4xMEDistortionBuffer));
1153 MOS_ZeroMemory(&m_brcBuffers, sizeof(m_brcBuffers));
1154 MOS_ZeroMemory(&m_mbQpDataSurface, sizeof(m_mbQpDataSurface));
1155
1156 uint8_t i;
1157 for (i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++)
1158 {
1159 m_brcKernelStates[i] = MHW_KERNEL_STATE();
1160 }
1161 for (i = 0; i < mbEncKernelIdxNum; i++)
1162 {
1163 m_mbEncKernelStates[i] = MHW_KERNEL_STATE();
1164 }
1165
1166 m_interlacedFieldDisabled = true;
1167
1168 // Always true since interlaced field is no longer supported.
1169 m_firstField = true;
1170 m_hwWalker = true;
1171 m_fieldScalingOutputInterleaved = true;
1172 m_hmeSupported = true;
1173 m_kuid = IDR_CODEC_AllMPEG2Enc;
1174
1175 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1176 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1177 MOS_UserFeature_ReadValue_ID(
1178 nullptr,
1179 __MEDIA_USER_FEATURE_VALUE_SINGLE_TASK_PHASE_ENABLE_ID,
1180 &userFeatureData);
1181 m_singleTaskPhaseSupported = (userFeatureData.i32Data) ? true : false;
1182
1183 m_hwInterface->GetStateHeapSettings()->dwNumSyncTags = m_numSyncTags;
1184 m_hwInterface->GetStateHeapSettings()->dwDshSize = m_initDshSize;
1185
1186 m_useCmScalingKernel = true;
1187
1188 }
1189
~CodechalEncodeMpeg2()1190 CodechalEncodeMpeg2::~CodechalEncodeMpeg2()
1191 {
1192 MOS_Delete(m_hmeKernel);
1193 }
1194
Initialize(CodechalSetting * codecHalSettings)1195 MOS_STATUS CodechalEncodeMpeg2::Initialize(CodechalSetting * codecHalSettings)
1196 {
1197 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1198
1199 CODECHAL_ENCODE_FUNCTION_ENTER;
1200
1201 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::Initialize(codecHalSettings));
1202
1203 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface);
1204 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hwInterface);
1205 CODECHAL_ENCODE_CHK_NULL_RETURN(m_miInterface);
1206 CODECHAL_ENCODE_CHK_NULL_RETURN(m_stateHeapInterface);
1207
1208 m_frameNumB = 0;
1209
1210 // Offset + Size of MB + size of MV
1211 m_mbCodeStrideInDW = 16;
1212 uint32_t fieldNumMBs = m_picWidthInMb * ((m_picHeightInMb + 1) >> 1);
1213 // 12 DW for MB + 4 DW for MV
1214 m_mbCodeSize = fieldNumMBs * 2 * 16 * sizeof(uint32_t);
1215
1216 #if (_DEBUG || _RELEASE_INTERNAL)
1217 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1218 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1219 MOS_UserFeature_ReadValue_ID(
1220 nullptr,
1221 __MEDIA_USER_FEATURE_VALUE_MPEG2_ENCODE_BRC_DISTORTION_BUFFER_ENABLE_ID,
1222 &userFeatureData);
1223 m_brcDistortionBufferSupported = (userFeatureData.i32Data) ? true : false;
1224
1225 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1226 MOS_UserFeature_ReadValue_ID(
1227 nullptr,
1228 __MEDIA_USER_FEATURE_VALUE_MPEG2_SLICE_STATE_ENABLE_ID,
1229 &userFeatureData);
1230 m_sliceStateEnable = (userFeatureData.i32Data) ? true : false;
1231
1232 #endif
1233 // Initialize kernel State
1234 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelState());
1235
1236 if (m_singleTaskPhaseSupported)
1237 {
1238 m_maxBtCount = GetMaxBtCount();
1239 }
1240
1241 // Picture Level Commands
1242 m_hwInterface->GetMfxStateCommandsDataSize(
1243 CODECHAL_ENCODE_MODE_MPEG2,
1244 &m_pictureStatesSize,
1245 &m_picturePatchListSize,
1246 0);
1247
1248 // Slice Level Commands (cannot be placed in 2nd level batch)
1249 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1250 CODECHAL_ENCODE_MODE_MPEG2,
1251 &m_sliceStatesSize,
1252 &m_slicePatchListSize,
1253 0);
1254
1255 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState());
1256
1257 return eStatus;
1258 }
1259
AllocateBuffer(PMOS_RESOURCE buffer,uint32_t bufSize,PCCHAR name)1260 MOS_STATUS CodechalEncodeMpeg2::AllocateBuffer(
1261 PMOS_RESOURCE buffer,
1262 uint32_t bufSize,
1263 PCCHAR name)
1264 {
1265 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1266
1267 CODECHAL_ENCODE_CHK_NULL_RETURN(buffer);
1268
1269 MOS_ALLOC_GFXRES_PARAMS allocParams;
1270 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1271 allocParams.Type = MOS_GFXRES_BUFFER;
1272 allocParams.TileType = MOS_TILE_LINEAR;
1273 allocParams.Format = Format_Buffer;
1274 allocParams.dwBytes = bufSize;
1275 allocParams.pBufName = name;
1276
1277 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
1278 m_osInterface,
1279 &allocParams,
1280 buffer);
1281
1282 if (eStatus != MOS_STATUS_SUCCESS)
1283 {
1284 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
1285 return eStatus;
1286 }
1287
1288 CodechalResLock bufLock(m_osInterface, buffer);
1289 auto data = bufLock.Lock(CodechalResLock::writeOnly);
1290 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1291
1292 MOS_ZeroMemory(data, bufSize);
1293
1294 return eStatus;
1295 }
1296
AllocateBuffer2D(PMOS_SURFACE surface,uint32_t surfWidth,uint32_t surfHeight,PCCHAR name)1297 MOS_STATUS CodechalEncodeMpeg2::AllocateBuffer2D(
1298 PMOS_SURFACE surface,
1299 uint32_t surfWidth,
1300 uint32_t surfHeight,
1301 PCCHAR name)
1302 {
1303 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1304
1305 CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
1306
1307 MOS_ZeroMemory(surface, sizeof(*surface));
1308
1309 surface->TileType = MOS_TILE_LINEAR;
1310 surface->bArraySpacing = true;
1311 surface->Format = Format_Buffer_2D;
1312 surface->dwWidth = MOS_ALIGN_CEIL(surfWidth, 64);
1313 surface->dwHeight = surfHeight;
1314 surface->dwPitch = surface->dwWidth;
1315
1316 MOS_ALLOC_GFXRES_PARAMS AllocParamsForBuffer2D;
1317 MOS_ZeroMemory(&AllocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1318 AllocParamsForBuffer2D.Type = MOS_GFXRES_2D;
1319 AllocParamsForBuffer2D.TileType = surface->TileType;
1320 AllocParamsForBuffer2D.Format = surface->Format;
1321 AllocParamsForBuffer2D.dwWidth = surface->dwWidth;
1322 AllocParamsForBuffer2D.dwHeight = surface->dwHeight;
1323 AllocParamsForBuffer2D.pBufName = name;
1324
1325 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
1326 m_osInterface,
1327 &AllocParamsForBuffer2D,
1328 &surface->OsResource);
1329
1330 if (eStatus != MOS_STATUS_SUCCESS)
1331 {
1332 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
1333 return eStatus;
1334 }
1335
1336 CodechalResLock bufLock(m_osInterface, &surface->OsResource);
1337 auto data = bufLock.Lock(CodechalResLock::writeOnly);
1338 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1339
1340 MOS_ZeroMemory(data, surface->dwWidth * surface->dwHeight);
1341
1342 return eStatus;
1343 }
1344
AllocateBatchBuffer(PMHW_BATCH_BUFFER batchBuffer,uint32_t bufSize,PCCHAR name)1345 MOS_STATUS CodechalEncodeMpeg2::AllocateBatchBuffer(
1346 PMHW_BATCH_BUFFER batchBuffer,
1347 uint32_t bufSize,
1348 PCCHAR name)
1349 {
1350 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1351
1352 CODECHAL_ENCODE_CHK_NULL_RETURN(batchBuffer);
1353
1354 MOS_ZeroMemory(
1355 batchBuffer,
1356 sizeof(MHW_BATCH_BUFFER));
1357
1358 batchBuffer->bSecondLevel = true;
1359
1360 eStatus = Mhw_AllocateBb(
1361 m_osInterface,
1362 batchBuffer,
1363 nullptr,
1364 bufSize);
1365
1366 if (eStatus != MOS_STATUS_SUCCESS)
1367 {
1368 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
1369 return eStatus;
1370 }
1371
1372 eStatus = Mhw_LockBb(m_osInterface, batchBuffer);
1373
1374 if (eStatus != MOS_STATUS_SUCCESS)
1375 {
1376 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to lock %s.", name);
1377 return eStatus;
1378 }
1379
1380 MOS_ZeroMemory(batchBuffer->pData, bufSize);
1381
1382 eStatus = Mhw_UnlockBb(
1383 m_osInterface,
1384 batchBuffer,
1385 false);
1386
1387 if (eStatus != MOS_STATUS_SUCCESS)
1388 {
1389 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to unlock %s.", name);
1390 return eStatus;
1391 }
1392
1393 return eStatus;
1394 }
1395
AllocateBrcResources()1396 MOS_STATUS CodechalEncodeMpeg2::AllocateBrcResources()
1397 {
1398 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1399
1400 CODECHAL_ENCODE_FUNCTION_ENTER;
1401
1402 // BRC history buffer
1403 uint32_t bufSize = m_brcHistoryBufferSize;
1404 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1405 &m_brcBuffers.resBrcHistoryBuffer,
1406 bufSize,
1407 "BRC History Buffer"));
1408
1409 // PAK Statistics buffer
1410 bufSize = m_brcPakStatisticsSize;
1411 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1412 &m_brcBuffers.resBrcPakStatisticBuffer[0],
1413 bufSize,
1414 "BRC PAK Statistics Buffer"));
1415
1416 // PAK IMG_STATEs buffer
1417 bufSize = BRC_IMG_STATE_SIZE_PER_PASS * m_mfxInterface->GetBrcNumPakPasses();
1418 for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1419 {
1420 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1421 &m_brcBuffers.resBrcImageStatesReadBuffer[i],
1422 bufSize,
1423 "PAK IMG State Read Buffer"));
1424 }
1425
1426 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1427 &m_brcBuffers.resBrcImageStatesWriteBuffer,
1428 bufSize,
1429 "PAK IMG State Write Buffer"));
1430
1431 // Picture header input and output buffers
1432 bufSize = m_brcPicHeaderSurfaceSize;
1433 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1434 &m_brcBuffers.resBrcPicHeaderInputBuffer,
1435 bufSize,
1436 "Picture Header Input Buffer"));
1437 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1438 &m_brcBuffers.resBrcPicHeaderOutputBuffer,
1439 bufSize,
1440 "Picture Header Output Buffer"));
1441
1442 uint32_t surfWidth = m_hwInterface->m_mpeg2BrcConstantSurfaceWidth;
1443 uint32_t surfHeight = m_hwInterface->m_mpeg2BrcConstantSurfaceHeight;
1444 for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1445 {
1446 //BRC Constant Data Surfaces
1447 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1448 &m_brcBuffers.sBrcConstantDataBuffer[i],
1449 surfWidth,
1450 surfHeight,
1451 "BRC Constant Data Buffer"));
1452 }
1453
1454 // BRC Distortion Surface
1455 uint32_t downscaledFieldHeightInMB4x =
1456 (m_downscaledHeightInMb4x + 1) >> 1;
1457 surfWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
1458 surfHeight = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4), 8);
1459 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1460 &m_brcBuffers.sMeBrcDistortionBuffer,
1461 surfWidth,
1462 surfHeight,
1463 "BRC Distortion Surface Buffer"));
1464
1465 // VME batch buffer for distortion surface
1466 for (uint8_t i = 0; i < NUM_ENCODE_BB_TYPE; i++)
1467 {
1468 uint32_t currNumMBs;
1469 if (i == MB_ENC_Frame_BB)
1470 {
1471 currNumMBs = m_downscaledWidthInMb4x * m_downscaledHeightInMb4x;
1472 }
1473 else
1474 {
1475 currNumMBs = m_downscaledWidthInMb4x * downscaledFieldHeightInMB4x;
1476 }
1477
1478 bufSize = m_hwInterface->GetMediaObjectBufferSize(
1479 currNumMBs,
1480 sizeof(MediaObjectInlineDataMpeg2));
1481
1482 AllocateBatchBuffer(&m_batchBufForMEDistBuffer[i], bufSize, "ME Distortion Buffer");
1483 }
1484
1485 return eStatus;
1486 }
1487
AllocateEncResources()1488 MOS_STATUS CodechalEncodeMpeg2::AllocateEncResources()
1489 {
1490 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1491
1492 CODECHAL_ENCODE_FUNCTION_ENTER;
1493
1494 uint32_t downscaledFieldHeightInMB4x = (m_downscaledHeightInMb4x + 1) >> 1;
1495
1496 if (m_hmeSupported)
1497 {
1498 if (m_hmeKernel)
1499 {
1500 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->AllocateResources());
1501 }
1502 else
1503 {
1504 uint32_t bufWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear.
1505 uint32_t bufHeight = (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
1506 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1507 &m_4xMEMVDataBuffer,
1508 bufWidth,
1509 bufHeight,
1510 "4xME MV Data Buffer"));
1511
1512 bufWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
1513 bufHeight = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4 * 10), 8);
1514 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1515 &m_4xMEDistortionBuffer,
1516 bufWidth,
1517 bufHeight,
1518 "4xME Distortion Buffer"));
1519 }
1520 }
1521
1522 return eStatus;
1523 }
1524
AllocateResources()1525 MOS_STATUS CodechalEncodeMpeg2::AllocateResources()
1526 {
1527 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1528
1529 CODECHAL_ENCODE_FUNCTION_ENTER;
1530
1531 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources());
1532
1533 // Allocate Ref Lists
1534 CodecHalAllocateDataList(
1535 m_refList,
1536 CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);
1537
1538 if (eStatus != MOS_STATUS_SUCCESS)
1539 {
1540 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate PAK resources.");
1541 return eStatus;
1542 }
1543
1544 if (m_encEnabled)
1545 {
1546 eStatus = AllocateEncResources();
1547 if (eStatus != MOS_STATUS_SUCCESS)
1548 {
1549 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate ENC resources.");
1550 return eStatus;
1551 }
1552
1553 eStatus = AllocateBrcResources();
1554 if (eStatus != MOS_STATUS_SUCCESS)
1555 {
1556 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC resources.");
1557 return eStatus;
1558 }
1559 }
1560
1561 return eStatus;
1562 }
1563
FreeBrcResources()1564 MOS_STATUS CodechalEncodeMpeg2::FreeBrcResources()
1565 {
1566 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1567 CODECHAL_ENCODE_FUNCTION_ENTER;
1568
1569 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcHistoryBuffer))
1570 {
1571 m_osInterface->pfnFreeResource(
1572 m_osInterface,
1573 &m_brcBuffers.resBrcHistoryBuffer);
1574 }
1575
1576 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcPakStatisticBuffer[0]))
1577 {
1578 m_osInterface->pfnFreeResource(
1579 m_osInterface,
1580 &m_brcBuffers.resBrcPakStatisticBuffer[0]);
1581 }
1582
1583 uint32_t i;
1584 for (i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1585 {
1586 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcImageStatesReadBuffer[i]))
1587 {
1588 m_osInterface->pfnFreeResource(
1589 m_osInterface,
1590 &m_brcBuffers.resBrcImageStatesReadBuffer[i]);
1591 }
1592 }
1593
1594 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcImageStatesWriteBuffer))
1595 {
1596 m_osInterface->pfnFreeResource(
1597 m_osInterface,
1598 &m_brcBuffers.resBrcImageStatesWriteBuffer);
1599 }
1600
1601 for (i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1602 {
1603 if (!Mos_ResourceIsNull(&m_brcBuffers.sBrcConstantDataBuffer[i].OsResource))
1604 {
1605 m_osInterface->pfnFreeResource(
1606 m_osInterface,
1607 &m_brcBuffers.sBrcConstantDataBuffer[i].OsResource);
1608 }
1609 }
1610
1611 if (!Mos_ResourceIsNull(&m_brcBuffers.sMeBrcDistortionBuffer.OsResource))
1612 {
1613 m_osInterface->pfnFreeResource(
1614 m_osInterface,
1615 &m_brcBuffers.sMeBrcDistortionBuffer.OsResource);
1616 }
1617
1618 if(!Mos_ResourceIsNull(&m_brcBuffers.resBrcPicHeaderInputBuffer))
1619 {
1620 m_osInterface->pfnFreeResource(
1621 m_osInterface,
1622 &m_brcBuffers.resBrcPicHeaderInputBuffer);
1623 }
1624 if(!Mos_ResourceIsNull(&m_brcBuffers.resBrcPicHeaderOutputBuffer))
1625 {
1626 m_osInterface->pfnFreeResource(
1627 m_osInterface,
1628 &m_brcBuffers.resBrcPicHeaderOutputBuffer);
1629 }
1630
1631 for (i = 0; i < NUM_ENCODE_BB_TYPE; i++)
1632 {
1633 if (!Mos_ResourceIsNull(&m_batchBufForMEDistBuffer[i].OsResource))
1634 {
1635 Mhw_FreeBb(m_osInterface, &m_batchBufForMEDistBuffer[i], nullptr);
1636 }
1637 }
1638
1639 return eStatus;
1640 }
1641
FreeEncResources()1642 MOS_STATUS CodechalEncodeMpeg2::FreeEncResources()
1643 {
1644 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1645
1646 CODECHAL_ENCODE_FUNCTION_ENTER;
1647
1648 if (m_hmeSupported)
1649 {
1650 // 4xME ME MV data buffer
1651 if (!Mos_ResourceIsNull(&m_4xMEMVDataBuffer.OsResource))
1652 {
1653 m_osInterface->pfnFreeResource(
1654 m_osInterface,
1655 &m_4xMEMVDataBuffer.OsResource);
1656 }
1657
1658 // 4xME distortion buffer
1659 if (!Mos_ResourceIsNull(&m_4xMEDistortionBuffer.OsResource))
1660 {
1661 m_osInterface->pfnFreeResource(
1662 m_osInterface,
1663 &m_4xMEDistortionBuffer.OsResource);
1664 }
1665 }
1666
1667 return eStatus;
1668
1669 }
1670
FreeResources()1671 void CodechalEncodeMpeg2::FreeResources()
1672 {
1673 CODECHAL_ENCODE_FUNCTION_ENTER;
1674
1675 CodechalEncoderState::FreeResources();
1676
1677 // Release Ref Lists
1678 CodecHalFreeDataList(m_refList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);
1679
1680 if (m_encEnabled)
1681 {
1682 FreeBrcResources();
1683
1684 FreeEncResources();
1685 }
1686 }
1687
CheckProfileAndLevel()1688 MOS_STATUS CodechalEncodeMpeg2::CheckProfileAndLevel()
1689 {
1690 MOS_STATUS eStatus = MOS_STATUS_INVALID_PARAMETER;
1691
1692 CODECHAL_ENCODE_FUNCTION_ENTER;
1693
1694 switch(m_seqParams->m_profile)
1695 {
1696 case highProfile:
1697 case mainProfile:
1698 case simpleProfile:
1699 break;
1700 default:
1701 return eStatus;
1702 break;
1703 }
1704
1705 switch(m_seqParams->m_level)
1706 {
1707 case levelHigh:
1708 case levelHigh1440:
1709 case levelMain:
1710 case levelLow:
1711 break;
1712 default:
1713 return eStatus;
1714 break;
1715 }
1716
1717 eStatus = MOS_STATUS_SUCCESS;
1718
1719 return eStatus;
1720 }
1721
SetSequenceStructs()1722 MOS_STATUS CodechalEncodeMpeg2::SetSequenceStructs()
1723 {
1724 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1725
1726 CODECHAL_ENCODE_FUNCTION_ENTER;
1727
1728 m_oriFrameHeight = m_seqParams->m_frameHeight;
1729 m_oriFrameWidth = m_seqParams->m_frameWidth;
1730 if (m_seqParams->m_progressiveSequence)
1731 {
1732 m_picHeightInMb =
1733 (uint16_t)(CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight));
1734 }
1735 else
1736 {
1737 // For interlaced frame, align to 32 pixels.
1738 m_picHeightInMb =
1739 (uint16_t)((CODECHAL_GET_WIDTH_IN_BLOCKS(m_oriFrameHeight, (CODECHAL_MACROBLOCK_WIDTH << 1))) << 1);
1740 }
1741 m_picWidthInMb =
1742 (uint16_t)(CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth));
1743 m_frameWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
1744 m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
1745
1746 // HME Scaling WxH
1747 m_downscaledWidthInMb4x =
1748 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
1749 m_downscaledHeightInMb4x =
1750 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
1751 m_downscaledWidth4x =
1752 m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
1753 m_downscaledHeight4x =
1754 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
1755
1756 MotionEstimationDisableCheck();
1757
1758 m_targetUsage = m_seqParams->m_targetUsage & 0x7;
1759 m_kernelMode = m_targetUsageToKernelMode[m_targetUsage];
1760
1761 CODECHAL_ENCODE_CHK_STATUS_RETURN(CheckProfileAndLevel());
1762
1763 m_brcEnabled = CodecHalIsRateControlBrc(m_seqParams->m_rateControlMethod, CODECHAL_MPEG2);
1764
1765 // Mb Qp data is only enabled for CQP
1766 if (m_brcEnabled)
1767 {
1768 m_mbQpDataEnabled = false;
1769 }
1770
1771 m_brcReset = m_seqParams->m_resetBRC;
1772
1773 m_avbrAccuracy = 30;
1774 m_avbrConvergence = 150;
1775
1776 return eStatus;
1777 }
1778
SetPictureStructs()1779 MOS_STATUS CodechalEncodeMpeg2::SetPictureStructs()
1780 {
1781 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1782
1783 CODECHAL_ENCODE_FUNCTION_ENTER;
1784
1785 if ((m_picParams->m_pictureCodingType < I_TYPE) ||
1786 (m_picParams->m_pictureCodingType > B_TYPE))
1787 {
1788 eStatus = MOS_STATUS_INVALID_PARAMETER;
1789 return eStatus;
1790 }
1791
1792 if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
1793 (!m_picParams->m_useRawPicForRef || m_pakEnabled))
1794 {
1795 eStatus = MOS_STATUS_INVALID_PARAMETER;
1796 return eStatus;
1797 }
1798
1799 // Sync initialize
1800 if ((m_firstFrame) ||
1801 (m_codecFunction == CODECHAL_FUNCTION_ENC) ||
1802 (!m_brcEnabled && m_picParams->m_useRawPicForRef) ||
1803 (!m_brcEnabled && (m_picParams->m_pictureCodingType == I_TYPE)))
1804 {
1805 m_waitForPak = false;
1806 }
1807 else
1808 {
1809 m_waitForPak = true;
1810 }
1811
1812 if (m_codecFunction != CODECHAL_FUNCTION_ENC)
1813 {
1814 m_signalEnc = true;
1815 }
1816 else
1817 {
1818 m_signalEnc = false;
1819 }
1820 m_pictureCodingType = m_picParams->m_pictureCodingType;
1821 m_mbEncForcePictureCodingType = 0;
1822
1823 // f_code checking.
1824 uint32_t fcodeX = CODECHAL_ENCODE_MPEG2_FCODE_X(m_frameWidth);
1825 uint32_t fcodeY = CODECHAL_ENCODE_MPEG2_FCODE_Y(fcodeX);
1826
1827 if (m_pictureCodingType == I_TYPE)
1828 {
1829 if ((m_picParams->m_fcode00 > fcodeX) ||
1830 (m_picParams->m_fcode01 > fcodeY) ||
1831 (m_picParams->m_fcode00 == 0) ||
1832 (m_picParams->m_fcode01 == 0))
1833 {
1834 m_picParams->m_fcode00 = fcodeX;
1835 m_picParams->m_fcode01 = fcodeY;
1836 }
1837 }
1838 else if (m_pictureCodingType == P_TYPE)
1839 {
1840 if ((m_picParams->m_fcode00 > fcodeX) ||
1841 (m_picParams->m_fcode01 > fcodeY) ||
1842 (m_picParams->m_fcode00 == 0) ||
1843 (m_picParams->m_fcode01 == 0))
1844 {
1845 m_picParams->m_fcode00 = fcodeX;
1846 m_picParams->m_fcode01 = fcodeY;
1847 }
1848 }
1849 else // B picture
1850 {
1851 if ((m_picParams->m_fcode00 > fcodeX) ||
1852 (m_picParams->m_fcode01 > fcodeY) ||
1853 (m_picParams->m_fcode10 > fcodeX) ||
1854 (m_picParams->m_fcode11 > fcodeY) ||
1855 (m_picParams->m_fcode00 == 0) ||
1856 (m_picParams->m_fcode01 == 0) ||
1857 (m_picParams->m_fcode10 == 0) ||
1858 (m_picParams->m_fcode11 == 0))
1859 {
1860 m_picParams->m_fcode00 = fcodeX;
1861 m_picParams->m_fcode01 = fcodeY;
1862 m_picParams->m_fcode10 = fcodeX;
1863 m_picParams->m_fcode11 = fcodeY;
1864 }
1865 }
1866
1867 if (m_picParams->m_fieldCodingFlag == 0)
1868 {
1869 m_frameFieldHeight = m_frameHeight;
1870 m_frameFieldHeightInMb = m_picHeightInMb;
1871 m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x;
1872 }
1873 else
1874 {
1875 m_frameFieldHeight = ((m_frameHeight + 1) >> 1);
1876 m_frameFieldHeightInMb = ((m_picHeightInMb + 1) >> 1);
1877 m_downscaledFrameFieldHeightInMb4x = ((m_downscaledHeightInMb4x + 1) >> 1);
1878 }
1879
1880 m_statusReportFeedbackNumber = m_picParams->m_statusReportFeedbackNumber;
1881 m_lastPicInStream = m_picParams->m_lastPicInStream;
1882 m_currOriginalPic = m_picParams->m_currOriginalPic;
1883 m_currReconstructedPic = m_picParams->m_currReconstructedPic;
1884
1885 uint8_t currRefIdx = m_picParams->m_currReconstructedPic.FrameIdx;
1886
1887 m_refList[currRefIdx]->sRefRawBuffer = m_rawSurface;
1888 m_refList[currRefIdx]->sRefReconBuffer = m_reconSurface;
1889 m_refList[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer;
1890
1891 if (m_pictureCodingType == I_TYPE)
1892 {
1893 m_picIdx[0].bValid = m_picIdx[1].bValid = 0;
1894 m_refList[currRefIdx]->bUsedAsRef = true;
1895 m_refList[currRefIdx]->ucNumRef = 0;
1896 }
1897 else if (m_pictureCodingType == P_TYPE)
1898 {
1899 if (m_picParams->m_refFrameList[0].PicFlags != PICTURE_INVALID)
1900 {
1901 m_picIdx[0].bValid = 1;
1902 m_picIdx[0].ucPicIdx = m_picParams->m_refFrameList[0].FrameIdx;
1903 }
1904 m_picIdx[1].bValid = 0;
1905 m_refList[currRefIdx]->bUsedAsRef = true;
1906 m_refList[currRefIdx]->RefList[0] = m_picParams->m_refFrameList[0];
1907 m_refList[currRefIdx]->ucNumRef = 1;
1908 }
1909 else// B_TYPE
1910 {
1911 if (m_picParams->m_refFrameList[0].PicFlags != PICTURE_INVALID)
1912 {
1913 m_picIdx[0].bValid = 1;
1914 m_picIdx[0].ucPicIdx = m_picParams->m_refFrameList[0].FrameIdx;
1915 }
1916
1917 if (m_picParams->m_refFrameList[1].PicFlags != PICTURE_INVALID)
1918 {
1919 m_picIdx[1].bValid = 1;
1920 m_picIdx[1].ucPicIdx = m_picParams->m_refFrameList[1].FrameIdx;
1921 }
1922 m_refList[currRefIdx]->bUsedAsRef = false;
1923 }
1924 m_currRefList = m_refList[currRefIdx];
1925
1926 if (m_codecFunction == CODECHAL_FUNCTION_ENC)
1927 {
1928 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encodeParams.presMbCodeSurface);
1929 m_resMbCodeSurface = *(m_encodeParams.presMbCodeSurface);
1930 }
1931 else if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
1932 {
1933 // the actual MbCode/MvData surface to be allocated later
1934 m_trackedBuf->SetAllocationFlag(true);
1935 }
1936
1937 m_hmeEnabled = m_hmeSupported && m_pictureCodingType != I_TYPE;
1938
1939 if (m_brcEnabled)
1940 {
1941 m_numPasses = (uint8_t)(m_mfxInterface->GetBrcNumPakPasses() - 1); // 1 original plus extra to handle BRC
1942 }
1943
1944 // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer
1945 m_gopIsIdrFrameOnly = (m_picParams->m_gopPicSize == 1 && m_picParams->m_gopRefDist == 0);
1946
1947 return eStatus;
1948 }
1949
SetSliceGroups()1950 MOS_STATUS CodechalEncodeMpeg2::SetSliceGroups()
1951 {
1952 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1953
1954 CODECHAL_ENCODE_FUNCTION_ENTER;
1955
1956 uint32_t mbCount = 0;
1957 auto bsBuffer = &m_bsBuffer;
1958 auto slcParams = m_sliceParams;
1959 auto slcData = m_slcData;
1960 PCODEC_ENCODER_SLCDATA slcDataPrevStart = nullptr;
1961
1962 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
1963 {
1964 // Slice width should equal picture width, MBs should be on same row
1965 CODECHAL_ENCODE_CHK_NULL_RETURN(slcData);
1966 CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);
1967 CODECHAL_ENCODE_ASSERT((slcParams->m_numMbsForSlice % m_picWidthInMb) == 0);
1968 CODECHAL_ENCODE_ASSERT(slcParams->m_numMbsForSlice <= m_picWidthInMb);
1969
1970 if ((slcParams->m_quantiserScaleCode < 1) ||
1971 (slcParams->m_quantiserScaleCode > 31))
1972 {
1973 slcParams->m_quantiserScaleCode = 1;
1974 }
1975
1976 // Determine slice groups
1977 if (slcCount == 0)
1978 {
1979 // First slice
1980 slcDataPrevStart = slcData;
1981 slcData->SliceGroup |= SLICE_GROUP_START;
1982
1983 if (m_codecFunction == (CODECHAL_FUNCTION_ENC | CODECHAL_FUNCTION_PAK))
1984 {
1985 slcData->SliceOffset = bsBuffer->SliceOffset;
1986 // Make slice header uint8_t aligned, all start codes are uint8_t aligned
1987 while (bsBuffer->BitOffset)
1988 {
1989 PutBit(bsBuffer, 0);
1990 }
1991 for (uint32_t i = 0; i < 8; i++)
1992 {
1993 PutBit(bsBuffer, 0);
1994 }
1995
1996 slcData->BitSize = bsBuffer->BitSize =
1997 (uint32_t)((bsBuffer->pCurrent - bsBuffer->SliceOffset - bsBuffer->pBase) * 8 + bsBuffer->BitOffset);
1998 bsBuffer->SliceOffset =
1999 (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase + (bsBuffer->BitOffset != 0)); // start at next byte
2000 }
2001 else
2002 {
2003 slcData->SliceOffset = bsBuffer->SliceOffset;
2004 slcData->BitSize = bsBuffer->BitSize;
2005 }
2006 }
2007 else
2008 {
2009 // Compare with prev slice to see if curr slice is start of new slice group
2010 PCODEC_ENCODER_SLCDATA slcDataPrev = slcData - 1;
2011 CodecEncodeMpeg2SliceParmas *slcParamsPrev = slcParams - 1;
2012
2013 if (!slcDataPrev || !slcParamsPrev)
2014 {
2015 eStatus = MOS_STATUS_INVALID_PARAMETER;
2016 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid slice pointer.");
2017 return eStatus;
2018 }
2019
2020 // Start of a new slice group if gap in slices or quantiser_scale_code/IntraSlice changes
2021 uint32_t mbPrevEnd =
2022 (slcParamsPrev->m_firstMbY * m_picWidthInMb) +
2023 slcParamsPrev->m_firstMbX +
2024 slcParamsPrev->m_numMbsForSlice;
2025 uint32_t mbCurrStart = (slcParams->m_firstMbY * m_picWidthInMb) + slcParams->m_firstMbX;
2026
2027 if ((mbPrevEnd != mbCurrStart) ||
2028 (slcParamsPrev->m_quantiserScaleCode != slcParams->m_quantiserScaleCode) ||
2029 (slcParamsPrev->m_intraSlice != slcParams->m_intraSlice))
2030 {
2031 slcDataPrev->SliceGroup |= SLICE_GROUP_END;
2032 slcData->SliceGroup |= SLICE_GROUP_START;
2033
2034 slcDataPrevStart->NextSgMbXCnt = slcParams->m_firstMbX;
2035 slcDataPrevStart->NextSgMbYCnt = slcParams->m_firstMbY;
2036 slcDataPrevStart = slcData;
2037
2038 slcData->SliceOffset = bsBuffer->SliceOffset;
2039 // Make slice header uint8_t aligned, all start codes are uint8_t aligned
2040 while (bsBuffer->BitOffset)
2041 {
2042 PutBit(bsBuffer, 0);
2043 }
2044 for (uint32_t i = 0; i < 8; i++)
2045 {
2046 PutBit(bsBuffer, 0);
2047 }
2048
2049 slcData->BitSize = bsBuffer->BitSize =
2050 (uint32_t)((bsBuffer->pCurrent - bsBuffer->SliceOffset - bsBuffer->pBase) * 8 + bsBuffer->BitOffset);
2051 bsBuffer->SliceOffset =
2052 (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase + (bsBuffer->BitOffset != 0)); // start at next byte
2053 }
2054 }
2055
2056 if (slcCount == (m_numSlices - 1))
2057 {
2058 // Last slice
2059 slcData->SliceGroup |= SLICE_GROUP_END;
2060 slcDataPrevStart->SliceGroup |= SLICE_GROUP_LAST;
2061 slcDataPrevStart->NextSgMbXCnt = 0;
2062 slcDataPrevStart->NextSgMbYCnt = m_frameFieldHeightInMb;
2063 }
2064
2065 slcData->CmdOffset = mbCount * m_mbCodeStrideInDW * sizeof(uint32_t);
2066
2067 mbCount += slcParams->m_numMbsForSlice;
2068 slcParams++;
2069 slcData++;
2070 }
2071
2072 return eStatus;
2073
2074 }
2075
GetCurByteOffset(BSBuffer * bsBuffer)2076 uint32_t CodechalEncodeMpeg2::GetCurByteOffset(BSBuffer* bsBuffer)
2077 {
2078 return (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase);
2079 }
2080
PackDisplaySeqExtension()2081 MOS_STATUS CodechalEncodeMpeg2::PackDisplaySeqExtension()
2082 {
2083 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2084
2085 CODECHAL_ENCODE_FUNCTION_ENTER;
2086
2087 auto bsBuffer = &m_bsBuffer;
2088
2089 // Make start code uint8_t aligned
2090 while (bsBuffer->BitOffset)
2091 {
2092 PutBit(bsBuffer, 0);
2093 }
2094
2095 // extension_start_code
2096 PutBits(bsBuffer, startCodePrefix, 24);
2097 PutBits(bsBuffer, startCodeExtension, 8);
2098
2099 // extension_start_code_identifier
2100 PutBits(bsBuffer, Mpeg2sequenceDisplayExtension, 4);
2101
2102 // video_format
2103 PutBits(bsBuffer, m_vuiParams->m_videoFormat, 3);
2104
2105 // colour_description
2106 PutBit(bsBuffer, m_vuiParams->m_colourDescription);
2107
2108 if (m_vuiParams->m_colourDescription)
2109 {
2110 // colour_primaries
2111 PutBits(bsBuffer, m_vuiParams->m_colourPrimaries, 8);
2112
2113 // transfer_characteristics
2114 PutBits(bsBuffer, m_vuiParams->m_transferCharacteristics, 8);
2115
2116 // matrix_coefficients
2117 PutBits(bsBuffer, m_vuiParams->m_matrixCoefficients, 8);
2118 }
2119
2120 // display_horizontal_size
2121 PutBits(bsBuffer, m_vuiParams->m_displayHorizontalSize, 14);
2122
2123 // marker_bit
2124 PutBit(bsBuffer, 1);
2125
2126 // display_vertical_size
2127 PutBits(bsBuffer, m_vuiParams->m_displayVerticalSize, 14);
2128
2129 return eStatus;
2130
2131 }
2132
PackSeqExtension()2133 MOS_STATUS CodechalEncodeMpeg2::PackSeqExtension()
2134 {
2135 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2136
2137 CODECHAL_ENCODE_FUNCTION_ENTER;
2138
2139 auto bsBuffer = &m_bsBuffer;
2140
2141 // Make start code uint8_t aligned
2142 while (bsBuffer->BitOffset)
2143 {
2144 PutBit(bsBuffer, 0);
2145 }
2146
2147 // extension_start_code
2148 PutBits(bsBuffer, startCodePrefix, 24);
2149 PutBits(bsBuffer, startCodeExtension, 8);
2150
2151 // extension_start_code_identifier
2152 PutBits(bsBuffer, Mpeg2sequenceExtension, 4);
2153
2154 // profile_and_level_indication
2155 PutBits(bsBuffer, ((m_seqParams->m_profile & 0x70) | (m_seqParams->m_level & 0xF)), 8);
2156
2157 // progressive_sequence
2158 PutBit(bsBuffer, m_seqParams->m_progressiveSequence);
2159
2160 // chroma_format
2161 PutBits(bsBuffer, m_seqParams->m_chromaFormat, 2);
2162
2163 // horizontal_size_extension
2164 PutBits(bsBuffer, ((m_seqParams->m_frameWidth >> 12) & 0x3), 2);
2165
2166 // vertical_size_extension
2167 PutBits(bsBuffer, ((m_seqParams->m_frameHeight >> 12) & 0x3), 2);
2168
2169 // bit_rate_extension
2170 PutBits(bsBuffer, ((MOS_ROUNDUP_DIVIDE(m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS, 400)) >> 18) & 0xFFF, 12);
2171
2172 // marker_bit
2173 PutBit(bsBuffer, 1);
2174
2175 // vbv_buffer_size_extension 8 uimsbf
2176 PutBits(bsBuffer, ((m_seqParams->m_vbvBufferSize >> 10) & 0xFF), 8);
2177
2178 // low_delay
2179 PutBit(bsBuffer, m_seqParams->m_lowDelay);
2180
2181 // frame_rate_extension_n
2182 PutBits(bsBuffer, m_seqParams->m_frameRateExtN, 2);
2183
2184 // frame_rate_extension_d
2185 PutBits(bsBuffer, m_seqParams->m_frameRateExtD, 5);
2186
2187 return eStatus;
2188
2189 }
2190
PackSeqHeader()2191 MOS_STATUS CodechalEncodeMpeg2::PackSeqHeader()
2192 {
2193 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2194
2195 CODECHAL_ENCODE_FUNCTION_ENTER;
2196
2197 auto bsBuffer = &m_bsBuffer;
2198
2199 // Make start code uint8_t aligned
2200 while (bsBuffer->BitOffset)
2201 {
2202 PutBit(bsBuffer, 0);
2203 }
2204
2205 // sequence_start_code
2206 PutBits(bsBuffer, startCodePrefix, 24);
2207 PutBits(bsBuffer, startCodeSequenceHeader, 8);
2208
2209 // horizontal_size_value
2210 CODECHAL_ENCODE_ASSERT((m_seqParams->m_frameWidth & 0xFFF) != 0); // Avoid start code emulation
2211 PutBits(bsBuffer, (m_seqParams->m_frameWidth & 0xFFF), 12);
2212
2213 // vertical_size_value
2214 CODECHAL_ENCODE_ASSERT((m_seqParams->m_frameHeight & 0xFFF) != 0); // Avoid start code emulation
2215 PutBits(bsBuffer, (m_seqParams->m_frameHeight & 0xFFF), 12);
2216
2217 // aspect_ratio_information
2218 CODECHAL_ENCODE_ASSERT((m_seqParams->m_aspectRatio > 0) && (m_seqParams->m_aspectRatio < 5));
2219 PutBits(bsBuffer, m_seqParams->m_aspectRatio, 4);
2220
2221 // frame_rate_code
2222 CODECHAL_ENCODE_ASSERT((m_seqParams->m_frameRateCode > 0) & (m_seqParams->m_frameRateCode < 15));
2223 PutBits(bsBuffer, m_seqParams->m_frameRateCode, 4);
2224
2225 // bit_rate_value
2226 if (m_seqParams->m_rateControlMethod == RATECONTROL_VBR)
2227 {
2228 // In Architecture prototype, the bit_rate_value of sequence header is set to m_maxBitRate not the target bit-rate for VBR case.
2229 PutBits(bsBuffer, ((MOS_ROUNDUP_DIVIDE(m_seqParams->m_maxBitRate * CODECHAL_ENCODE_BRC_KBPS, 400)) & 0x3FFFF), 18);
2230 }
2231 else
2232 {
2233 PutBits(bsBuffer, ((MOS_ROUNDUP_DIVIDE(m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS, 400)) & 0x3FFFF), 18);
2234 }
2235
2236 // marker_bit
2237 PutBit(bsBuffer, 1);
2238
2239 // vbv_buffer_size_value
2240 PutBits(bsBuffer, (m_seqParams->m_vbvBufferSize & 0x3FF), 10);
2241
2242 // constrained_parameters_flag
2243 PutBit(bsBuffer, 0);
2244
2245 // m_loadIntraQuantiserMatrix
2246 PutBit(bsBuffer, m_qMatrixParams->m_newQmatrix[0]);
2247 if (m_qMatrixParams->m_newQmatrix[0])
2248 {
2249 // m_intraQuantiserMatrix[64]
2250 for (uint8_t i = 0; i < 64; i++)
2251 {
2252 // Already in zig-zag scan order
2253 PutBits(bsBuffer, m_qMatrixParams->m_qmatrix[0][i], 8);
2254 }
2255 }
2256
2257 // m_loadNonIntraQuantiserMatrix
2258 PutBit(bsBuffer, m_qMatrixParams->m_newQmatrix[1]);
2259 if (m_qMatrixParams->m_newQmatrix[1])
2260 {
2261 // m_nonIntraQuantiserMatrix[64]
2262 for (uint8_t i = 0; i < 64; i++)
2263 {
2264 // Already in zig-zag scan order
2265 PutBits(bsBuffer, m_qMatrixParams->m_qmatrix[1][i], 8);
2266 }
2267 }
2268
2269 return eStatus;
2270
2271 }
2272
PackSequenceParams()2273 MOS_STATUS CodechalEncodeMpeg2::PackSequenceParams()
2274 {
2275 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2276
2277 CODECHAL_ENCODE_FUNCTION_ENTER;
2278
2279 // picture header
2280 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackSeqHeader());
2281
2282 // picture coding extension
2283 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackSeqExtension());
2284
2285 // optional sequence display extension (& user data)
2286 if (m_newVuiData)
2287 {
2288 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackDisplaySeqExtension());
2289
2290 m_newVuiData = false;
2291 }
2292
2293 return eStatus;
2294 }
2295
PackPicCodingExtension()2296 MOS_STATUS CodechalEncodeMpeg2::PackPicCodingExtension()
2297 {
2298 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2299
2300 CODECHAL_ENCODE_FUNCTION_ENTER;
2301
2302 auto bsBuffer = &m_bsBuffer;
2303
2304 // All start codes are uint8_t aligned
2305 while (bsBuffer->BitOffset)
2306 {
2307 PutBit(bsBuffer, 0);
2308 }
2309
2310 // extension_start_code
2311 PutBits(bsBuffer, startCodePrefix, 24);
2312 PutBits(bsBuffer, startCodeExtension, 8);
2313
2314 // extension_start_code_identifier
2315 PutBits(bsBuffer, Mpeg2pictureCodingExtension, 4);
2316
2317 // f_codes values 1-9 or 15; 0 or 1-14 are reserved
2318 if ((m_picParams->m_pictureCodingType == I_TYPE) && !m_picParams->m_concealmentMotionVectors)
2319 {
2320 // f_code[0][0], forward horizontal
2321 PutBits(bsBuffer, 0xF, 4);
2322 // f_code[0][1], forward vertical
2323 PutBits(bsBuffer, 0xF, 4);
2324 // f_code[1][0], backward horizontal
2325 PutBits(bsBuffer, 0xF, 4);
2326 // f_code[1][1], backward vertical
2327 PutBits(bsBuffer, 0xF, 4);
2328 }
2329 else
2330 {
2331 // f_code[0][0], forward horizontal
2332 PutBits(bsBuffer, m_picParams->m_fcode00, 4);
2333 // f_code[0][1], forward vertical
2334 PutBits(bsBuffer, m_picParams->m_fcode01, 4);
2335
2336 if ((m_picParams->m_pictureCodingType == I_TYPE) || (m_picParams->m_pictureCodingType == P_TYPE))
2337 {
2338 // f_code[1][0], backward horizontal
2339 PutBits(bsBuffer, 0xF, 4);
2340 // f_code[1][1], backward vertical
2341 PutBits(bsBuffer, 0xF, 4);
2342 }
2343 else
2344 {
2345 // f_code[1][0], backward horizontal
2346 PutBits(bsBuffer, m_picParams->m_fcode10, 4);
2347 // f_code[1][1], backward vertical
2348 PutBits(bsBuffer, m_picParams->m_fcode11, 4);
2349 }
2350 }
2351
2352 // store byte offset of intra_dc_precision
2353 m_intraDcPrecisionOffset = GetCurByteOffset(bsBuffer);
2354 // intra_dc_precision
2355 PutBits(bsBuffer, m_picParams->m_intraDCprecision, 2);
2356
2357 // picture_structure
2358 PutBits(bsBuffer, (!m_picParams->m_fieldCodingFlag) ? 3 : ((m_picParams->m_interleavedFieldBFF) ? 2 : 1), 2);
2359
2360 bool progressiveSequence = m_seqParams->m_progressiveSequence & 0x1;
2361 bool actual_tff = (!m_picParams->m_fieldCodingFlag && !progressiveSequence) || (m_picParams->m_repeatFirstField != 0);
2362
2363 // top_field_first
2364 PutBit(bsBuffer, (actual_tff ) ? (!m_picParams->m_interleavedFieldBFF) : 0);
2365 bool progressive = true;
2366 if (m_picParams->m_fieldCodingFlag || m_picParams->m_fieldFrameCodingFlag)
2367 {
2368 progressive = false;
2369 }
2370
2371 // frame_pred_frame_dct
2372 if (progressive)
2373 {
2374 PutBit(bsBuffer, 1);
2375 }
2376 else if (m_picParams->m_fieldCodingFlag)
2377 {
2378 PutBit(bsBuffer, 0);
2379 }
2380 else
2381 {
2382 PutBit(bsBuffer, m_picParams->m_framePredFrameDCT);
2383 }
2384
2385 // concealment_motion_vectors
2386 PutBit(bsBuffer, m_picParams->m_concealmentMotionVectors);
2387
2388 // Store the byte offset of the q_scale_type
2389 m_qScaleTypeByteOffse = GetCurByteOffset(bsBuffer);
2390 // q_scale_type
2391 PutBit(bsBuffer, m_picParams->m_qscaleType);
2392
2393 // intra_vlc_format
2394 PutBit(bsBuffer, m_picParams->m_intraVlcFormat);
2395
2396 // alternate_scan
2397 PutBit(bsBuffer, m_picParams->m_alternateScan);
2398
2399 // repeat_first_field
2400 PutBit(bsBuffer, (!m_picParams->m_fieldCodingFlag) ? m_picParams->m_repeatFirstField : 0);
2401
2402 // chroma_420_type
2403 PutBit(bsBuffer, progressive);
2404
2405 // progressive_frame
2406 PutBit(bsBuffer, progressive);
2407
2408 // composite_display_flag
2409 PutBit(bsBuffer, m_picParams->m_compositeDisplayFlag);
2410
2411 if (m_picParams->m_compositeDisplayFlag)
2412 {
2413 // v_axis
2414 PutBit(bsBuffer, m_picParams->m_vaxis);
2415 // field_sequence
2416 PutBits(bsBuffer, m_picParams->m_fieldSequence, 3);
2417 // sub_carrier
2418 PutBit(bsBuffer, m_picParams->m_subCarrier);
2419 // burst_amplitude
2420 PutBits(bsBuffer, m_picParams->m_burstAmplitude, 7);
2421 // sub_carrier_phase
2422 PutBits(bsBuffer, m_picParams->m_subCarrierPhase, 8);
2423 }
2424
2425 return eStatus;
2426 }
2427
PackPicUserData()2428 MOS_STATUS CodechalEncodeMpeg2::PackPicUserData()
2429 {
2430 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2431
2432 CODECHAL_ENCODE_FUNCTION_ENTER;
2433
2434 auto userDataListHead = (CodecEncodeMpeg2UserDataList *)m_encodeParams.pMpeg2UserDataListHead;
2435 CODECHAL_ENCODE_CHK_NULL_RETURN(userDataListHead);
2436
2437 auto bsBuffer = &m_bsBuffer;
2438
2439 for (auto p = userDataListHead; p; p = p->m_nextItem)
2440 {
2441 auto userData = (uint8_t*)p->m_userData;
2442
2443 while (bsBuffer->BitOffset)
2444 {
2445 PutBit(bsBuffer, 0);
2446 }
2447
2448 for(unsigned int i = 0; i < p->m_userDataSize; ++i)
2449 {
2450 PutBits(bsBuffer, (uint32_t) (userData[i]), 8);
2451 }
2452 }
2453
2454 return eStatus;
2455 }
2456
PackPicHeader()2457 MOS_STATUS CodechalEncodeMpeg2::PackPicHeader()
2458 {
2459 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2460
2461 CODECHAL_ENCODE_FUNCTION_ENTER;
2462
2463 auto bsBuffer = &m_bsBuffer;
2464
2465 // All start codes are uint8_t aligned
2466 while (bsBuffer->BitOffset)
2467 {
2468 PutBit(bsBuffer, 0);
2469 }
2470
2471 // picture_start_code
2472 PutBits(bsBuffer, startCodePrefix, 24);
2473 PutBits(bsBuffer, startCodePicture, 8);
2474
2475 // temporal_reference
2476 PutBits(bsBuffer, m_picParams->m_temporalReference, 10);
2477
2478 // picture_coding_type
2479 PutBits(bsBuffer, m_picParams->m_pictureCodingType, 3);
2480
2481 // Store the byte offset of the q_scale_type
2482 m_vbvDelayOffset = GetCurByteOffset(bsBuffer);
2483 // vbv_delay
2484 PutBits(bsBuffer, m_picParams->m_vbvDelay, 16);
2485
2486 if ((m_picParams->m_pictureCodingType == P_TYPE) || (m_picParams->m_pictureCodingType == B_TYPE))
2487 {
2488 // full_pel_forward_vector, '0'
2489 PutBit(bsBuffer, 0);
2490 // forward_f_code, '111'
2491 PutBits(bsBuffer, 0x7, 3);
2492 }
2493
2494 if (m_picParams->m_pictureCodingType == B_TYPE)
2495 {
2496 // full_pel_backward_vector, '0'
2497 PutBit(bsBuffer, 0);
2498 // backward_f_code '111'
2499 PutBits(bsBuffer, 0x7, 3);
2500 }
2501
2502 // extra_bit_picture, '0'
2503 PutBit(bsBuffer, 0);
2504
2505 return eStatus;
2506
2507 }
2508
PackGroupOfPicHeader()2509 MOS_STATUS CodechalEncodeMpeg2::PackGroupOfPicHeader()
2510 {
2511 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2512
2513 CODECHAL_ENCODE_FUNCTION_ENTER;
2514
2515 auto bsBuffer = &m_bsBuffer;
2516
2517 // All start codes are uint8_t aligned
2518 while (bsBuffer->BitOffset)
2519 {
2520 PutBit(bsBuffer, 0);
2521 }
2522
2523 // group_start_code
2524 PutBits(bsBuffer, startCodePrefix, 24);
2525 PutBits(bsBuffer, startCodeGroupStart, 8);
2526
2527 // time_code, 25 bits total
2528 // drop_flag
2529 PutBit(bsBuffer, ((m_picParams->m_timeCode >> 24) & 1));
2530 // hour
2531 PutBits(bsBuffer, ((m_picParams->m_timeCode >> 19) & 0x1F), 5);
2532 // minute
2533 PutBits(bsBuffer, ((m_picParams->m_timeCode >> 13) & 0x3F), 6);
2534 // marker_bit
2535 PutBit(bsBuffer, 1);
2536 // sec
2537 PutBits(bsBuffer, ((m_picParams->m_timeCode >> 6) & 0x3F), 6);
2538 // frame
2539 PutBits(bsBuffer, ((m_picParams->m_timeCode) & 0x3F), 6);
2540
2541 // closed_gop
2542 PutBit(bsBuffer, m_picParams->m_gopOptFlag & 1);
2543 // broken_link, used in editing
2544 PutBit(bsBuffer, 0);
2545
2546 return eStatus;
2547
2548 }
2549
PackPictureParams()2550 MOS_STATUS CodechalEncodeMpeg2::PackPictureParams()
2551 {
2552 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2553
2554 CODECHAL_ENCODE_FUNCTION_ENTER;
2555
2556 // optional GOP header (& user data)
2557 if (m_picParams->m_newGop)
2558 {
2559 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackGroupOfPicHeader());
2560 }
2561
2562 // picture header
2563 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPicHeader());
2564
2565 // picture coding extension
2566 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPicCodingExtension());
2567
2568 // user data
2569 if(m_encodeParams.pMpeg2UserDataListHead)
2570 {
2571 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPicUserData());
2572 }
2573
2574 return eStatus;
2575 }
2576
PackPictureHeader()2577 MOS_STATUS CodechalEncodeMpeg2::PackPictureHeader()
2578 {
2579 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2580
2581 CODECHAL_ENCODE_FUNCTION_ENTER;
2582
2583 auto bsBuffer = &m_bsBuffer;
2584
2585 *(bsBuffer->pBase) = 0; // init first byte to 0
2586 bsBuffer->pCurrent = bsBuffer->pBase;
2587 bsBuffer->SliceOffset = 0;
2588 bsBuffer->BitOffset = 0;
2589 bsBuffer->BitSize = 0;
2590
2591 // If this is a new sequence, write the seq set
2592 if (m_newSeq)
2593 {
2594 // Pack SPS
2595 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackSequenceParams());
2596 }
2597
2598 // Pack PPS
2599 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPictureParams());
2600
2601 // HW will insert next slice start code, but need to byte align for HW
2602 while (bsBuffer->BitOffset)
2603 {
2604 PutBit(bsBuffer, 0);
2605 }
2606 bsBuffer->BitSize = (uint32_t)(bsBuffer->pCurrent - bsBuffer->SliceOffset - bsBuffer->pBase) * 8 + bsBuffer->BitOffset;
2607
2608 return eStatus;
2609 }
2610
InitializePicture(const EncoderParams & params)2611 MOS_STATUS CodechalEncodeMpeg2::InitializePicture(const EncoderParams& params)
2612 {
2613 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2614
2615 CODECHAL_ENCODE_FUNCTION_ENTER;
2616
2617 m_seqParams = (CodecEncodeMpeg2SequenceParams *)(params.pSeqParams);
2618 m_vuiParams = (CodecEncodeMpeg2VuiParams *)(params.pVuiParams);
2619 m_picParams = (CodecEncodeMpeg2PictureParams *)(params.pPicParams);
2620 m_sliceParams = (CodecEncodeMpeg2SliceParmas *)(params.pSliceParams);
2621 m_qMatrixParams = (CodecEncodeMpeg2QmatixParams *)(params.pIQMatrixBuffer);
2622
2623 CODECHAL_ENCODE_CHK_NULL_RETURN(m_seqParams);
2624 CODECHAL_ENCODE_CHK_NULL_RETURN(m_vuiParams);
2625 CODECHAL_ENCODE_CHK_NULL_RETURN(m_picParams);
2626 CODECHAL_ENCODE_CHK_NULL_RETURN(m_sliceParams);
2627 CODECHAL_ENCODE_CHK_NULL_RETURN(m_qMatrixParams);
2628
2629 // Mb Qp data
2630 m_mbQpDataEnabled = params.bMbQpDataEnabled;
2631 if (m_mbQpDataEnabled)
2632 {
2633 m_mbQpDataSurface = *(params.psMbQpDataSurface);
2634 }
2635 m_skipFrameFlag = m_picParams->m_skipFrameFlag;
2636
2637 m_verticalLineStride = CODECHAL_VLINESTRIDE_FRAME;
2638 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
2639 m_mbcodeBottomFieldOffset = 0;
2640 m_mvBottomFieldOffset = 0;
2641 m_scaledBottomFieldOffset = 0;
2642 m_scaled16xBottomFieldOffset = 0;
2643
2644 if (m_newSeq)
2645 {
2646 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
2647 }
2648
2649 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
2650
2651 // 4x downscaled surface needed by MbEnc IDist (for BRC) kernel or HME kernel
2652 m_scalingEnabled = (m_hmeSupported || m_brcEnabled);
2653
2654 if (CodecHal_PictureIsField(m_currOriginalPic))
2655 {
2656 m_verticalLineStride = CODECHAL_VLINESTRIDE_FIELD;
2657 m_frameHeight = m_frameFieldHeightInMb * 2 * 16;
2658 m_picHeightInMb = (uint16_t)(m_frameHeight / 16);
2659 if (CodecHal_PictureIsBottomField(m_currOriginalPic))
2660 {
2661 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD;
2662 m_mbcodeBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64;
2663 m_mvBottomFieldOffset = MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), 0x1000);
2664 }
2665 }
2666
2667 if (m_pictureCodingType == B_TYPE)
2668 {
2669 m_frameNumB += 1;
2670 }
2671 else
2672 {
2673 m_frameNumB = 0;
2674 }
2675
2676 if (m_pakEnabled)
2677 {
2678 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPictureHeader());
2679
2680 if (m_brcEnabled)
2681 {
2682 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
2683 uint32_t dwPicHeaderDataStartOffset,dwPicHeaderDataBufferSize;
2684
2685 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
2686 pakInsertObjectParams.pBsBuffer = &m_bsBuffer;
2687 pakInsertObjectParams.pdwMpeg2PicHeaderDataStartOffset = &dwPicHeaderDataStartOffset;
2688 pakInsertObjectParams.pdwMpeg2PicHeaderTotalBufferSize = &dwPicHeaderDataBufferSize;
2689
2690 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfcMpeg2PakInsertBrcBuffer(
2691 &m_brcBuffers.resBrcPicHeaderInputBuffer,
2692 &pakInsertObjectParams));
2693
2694 // The q_scale_type offset is relative to the beginning of the picture header buffer.
2695 // Since it starts off with the INSERT command, include its size in the offset for the
2696 // q_scale_type. Do the same for the vbv_delay offset.
2697 m_picHeaderDataBufferSize = dwPicHeaderDataBufferSize;
2698 m_qScaleTypeByteOffse += dwPicHeaderDataStartOffset;
2699 m_vbvDelayOffset += dwPicHeaderDataStartOffset;
2700 m_intraDcPrecisionOffset += dwPicHeaderDataStartOffset;
2701 }
2702
2703 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceGroups());
2704 }
2705
2706 CODECHAL_DEBUG_TOOL(
2707 m_debugInterface->m_currPic = m_picParams->m_currOriginalPic;
2708 m_debugInterface->m_bufferDumpFrameNum = m_storeData;
2709 m_debugInterface->m_frameType = m_pictureCodingType;
2710
2711 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpVuiParams(
2712 m_vuiParams));
2713
2714 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams(
2715 m_picParams));
2716
2717 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
2718 m_seqParams));
2719
2720 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSliceParams(
2721 m_sliceParams));)
2722
2723 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(
2724 m_refList[m_currReconstructedPic.FrameIdx]));
2725
2726 m_bitstreamUpperBound = m_encodeParams.dwBitstreamSize;
2727
2728 return eStatus;
2729 }
2730
InitKernelStateBrc()2731 MOS_STATUS CodechalEncodeMpeg2::InitKernelStateBrc()
2732 {
2733 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2734
2735 CODECHAL_ENCODE_FUNCTION_ENTER;
2736 uint32_t brcBtCount[CODECHAL_ENCODE_BRC_IDX_NUM] = {
2737 brcInitResetNumBindingTableEntries,
2738 brcUpdateNumBindingTableEntries,
2739 brcInitResetNumBindingTableEntries,
2740 0, // IFrameDist uses MBEnc I kernel
2741 0, // BlockCopy kernel is not needed
2742 0 // MbBRCUpdate kernel is not needed
2743 };
2744
2745 uint32_t brcCurbeSize[CODECHAL_ENCODE_BRC_IDX_NUM] = {
2746 BrcInitResetCurbe::m_byteSize,
2747 BrcUpdateCurbe::m_byteSize,
2748 BrcInitResetCurbe::m_byteSize,
2749 0, // IFrameDist uses MBEnc I kernel
2750 0, // BlockCopy kernel is not needed
2751 0 // MbBRCUpdate kernel is not needed
2752 };
2753
2754 CODECHAL_KERNEL_HEADER currKrnHeader;
2755 // CODECHAL_ENCODE_BRC_IDX_NUM - 2: BlockCopy and MbBRCUpdate kernel not needed
2756 for (uint8_t krnStateIdx = 0; krnStateIdx < CODECHAL_ENCODE_BRC_IDX_NUM - 2; krnStateIdx++)
2757 {
2758 // IFrameDist doesn't have separate kernel for MPEG2, needs to use MbEnc I kernel
2759 if (krnStateIdx == CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST)
2760 {
2761 m_brcKernelStates[krnStateIdx] = m_mbEncKernelStates[mbEncKernelIdxI];
2762 continue;
2763 }
2764
2765 auto kernelState = &m_brcKernelStates[krnStateIdx];
2766 uint32_t kernelSize = m_combinedKernelSize;
2767 CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize(
2768 m_kernelBinary,
2769 ENC_BRC,
2770 krnStateIdx,
2771 &currKrnHeader,
2772 &kernelSize));
2773
2774 kernelState->KernelParams.iBTCount = brcBtCount[krnStateIdx];
2775 kernelState->KernelParams.iThreadCount = m_hwInterface->GetRenderInterface()->GetHwCaps()->dwMaxThreads;
2776 kernelState->KernelParams.iCurbeLength = brcCurbeSize[krnStateIdx];
2777 kernelState->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
2778 kernelState->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
2779 kernelState->KernelParams.iIdCount = 1;
2780
2781 kernelState->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
2782 kernelState->KernelParams.pBinary = m_kernelBinary + (currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
2783 kernelState->KernelParams.iSize = kernelSize;
2784
2785 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
2786 m_stateHeapInterface,
2787 kernelState->KernelParams.iBTCount,
2788 &kernelState->dwSshSize,
2789 &kernelState->dwBindingTableSize));
2790
2791 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelState));
2792 }
2793
2794 return eStatus;
2795 }
2796
GetMaxBtCount()2797 uint32_t CodechalEncodeMpeg2::GetMaxBtCount()
2798 {
2799 uint32_t scalingBtCount = MOS_ALIGN_CEIL(
2800 m_scaling4xKernelStates[0].KernelParams.iBTCount,
2801 m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
2802 uint32_t meBtCount = MOS_ALIGN_CEIL(
2803 m_hmeKernel ? m_hmeKernel->GetBTCount() : m_meKernelStates[0].KernelParams.iBTCount,
2804 m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
2805 uint32_t mbEncBtCount = MOS_ALIGN_CEIL(
2806 m_mbEncKernelStates[0].KernelParams.iBTCount,
2807 m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
2808
2809 uint32_t brcBtCount = 0;
2810 for (uint32_t i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++)
2811 {
2812 brcBtCount += MOS_ALIGN_CEIL(
2813 m_brcKernelStates[i].KernelParams.iBTCount,
2814 m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
2815 }
2816
2817 return MOS_MAX(scalingBtCount + meBtCount, mbEncBtCount + brcBtCount);
2818 }
2819
EncodeMeKernel()2820 MOS_STATUS CodechalEncodeMpeg2::EncodeMeKernel()
2821 {
2822 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2823
2824 CODECHAL_ENCODE_FUNCTION_ENTER;
2825
2826 PerfTagSetting perfTag;
2827 perfTag.Value = 0;
2828 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
2829 perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_ME_KERNEL;
2830 perfTag.PictureCodingType = m_pictureCodingType;
2831 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
2832
2833 uint32_t krnStateIdx =
2834 (m_pictureCodingType == P_TYPE) ? CODECHAL_ENCODE_ME_IDX_P : CODECHAL_ENCODE_ME_IDX_B;
2835
2836 if (m_pictureCodingType == B_TYPE && CodecHal_PictureIsInvalid(m_picParams->m_refFrameList[1]))
2837 {
2838 krnStateIdx = CODECHAL_ENCODE_ME_IDX_P;
2839 }
2840
2841 auto kernelState = &m_meKernelStates[krnStateIdx];
2842
2843 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
2844 {
2845 uint32_t maxBtCount = m_singleTaskPhaseSupported ?
2846 m_maxBtCount : kernelState->KernelParams.iBTCount;
2847 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
2848 m_stateHeapInterface,
2849 maxBtCount));
2850 m_vmeStatesSize =
2851 m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
2852 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
2853 }
2854
2855 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
2856 m_stateHeapInterface,
2857 kernelState,
2858 false,
2859 0,
2860 false,
2861 m_storeData));
2862
2863 MHW_INTERFACE_DESCRIPTOR_PARAMS interfaceParams;
2864 MOS_ZeroMemory(&interfaceParams, sizeof(interfaceParams));
2865 interfaceParams.pKernelState = kernelState;
2866 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
2867 m_stateHeapInterface,
2868 1,
2869 &interfaceParams));
2870
2871 // This parameter is used to select correct mode mv cost
2872 // and search path from the predefined tables specifically
2873 // for Mpeg2 BRC encoding path
2874 m_seqParams->m_targetUsage = 8;
2875 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMe());
2876
2877 CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_4X_ME;
2878
2879 CODECHAL_DEBUG_TOOL(
2880 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2881 encFunctionType,
2882 MHW_DSH_TYPE,
2883 kernelState));
2884 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
2885 encFunctionType,
2886 kernelState));
2887 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2888 encFunctionType,
2889 MHW_ISH_TYPE,
2890 kernelState));
2891 )
2892
2893 MOS_COMMAND_BUFFER cmdBuffer;
2894 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
2895 m_osInterface,
2896 &cmdBuffer,
2897 0));
2898
2899 SendKernelCmdsParams sendKernelCmdsParams;
2900 sendKernelCmdsParams.EncFunctionType = encFunctionType;
2901 sendKernelCmdsParams.pKernelState = kernelState;
2902
2903 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(
2904 &cmdBuffer,
2905 &sendKernelCmdsParams));
2906
2907 // Add binding table
2908 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
2909 m_stateHeapInterface,
2910 kernelState));
2911
2912 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendMeSurfaces(&cmdBuffer));
2913
2914 // Dump SSH for ME kernel
2915 CODECHAL_DEBUG_TOOL(
2916 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2917 encFunctionType,
2918 MHW_SSH_TYPE,
2919 kernelState)));
2920
2921 // HW walker
2922 CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
2923 MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
2924 walkerCodecParams.WalkerMode = m_walkerMode;
2925 walkerCodecParams.dwResolutionX = m_downscaledWidthInMb4x;
2926 walkerCodecParams.dwResolutionY = m_downscaledFrameFieldHeightInMb4x;
2927 walkerCodecParams.bNoDependency = true;
2928
2929 MHW_WALKER_PARAMS walkerParams;
2930 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
2931 m_hwInterface,
2932 &walkerParams,
2933 &walkerCodecParams));
2934
2935 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObjectWalkerCmd(
2936 &cmdBuffer,
2937 &walkerParams));
2938
2939 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
2940 m_stateHeapInterface,
2941 kernelState));
2942 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
2943 {
2944 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
2945 m_stateHeapInterface));
2946
2947 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
2948 &cmdBuffer,
2949 nullptr));
2950 }
2951
2952 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
2953 &cmdBuffer,
2954 encFunctionType,
2955 nullptr)));
2956
2957 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(
2958 &cmdBuffer,
2959 m_singleTaskPhaseSupported,
2960 m_lastTaskInPhase));
2961
2962 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
2963
2964 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
2965 {
2966 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
2967 m_osInterface,
2968 &cmdBuffer,
2969 m_renderContextUsesNullHw));
2970 m_lastTaskInPhase = false;
2971 }
2972
2973 return eStatus;
2974 }
2975
CalcFrameRateValue(uint16_t frameRateCode,uint32_t factor)2976 uint32_t CodechalEncodeMpeg2::CalcFrameRateValue(
2977 uint16_t frameRateCode,
2978 uint32_t factor)
2979 {
2980 uint32_t ret;
2981 switch(frameRateCode)
2982 {
2983 // Note a frame rate code of 0 is forbidden according to MPEG-2 spec
2984 case 0x1:
2985 ret = (uint32_t)((24000/1001.0)*factor);
2986 break;
2987 case 0x2:
2988 ret = 24 * factor;
2989 break;
2990 case 0x3:
2991 ret = 25*factor;
2992 break;
2993 case 0x4:
2994 ret = (uint32_t)((30000/1001.0)*factor);
2995 break;
2996 case 0x5:
2997 ret = 30 * factor;
2998 break;
2999 case 0x6:
3000 ret = 50 * factor;
3001 break;
3002 case 0x7:
3003 ret = (uint32_t)((60000/1001.0)*factor);
3004 break;
3005 case 0x8:
3006 ret = 60*factor;
3007 break;
3008 default:
3009 ret = 0xdeadbeef;
3010 }
3011
3012 return ret;
3013 }
3014
SetCurbeBrcInitReset()3015 MOS_STATUS CodechalEncodeMpeg2::SetCurbeBrcInitReset()
3016 {
3017 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3018
3019 CODECHAL_ENCODE_FUNCTION_ENTER;
3020
3021 BrcInitResetCurbe cmd;
3022
3023 cmd.m_curbeData.DW1.m_initBufFullInBits = m_seqParams->m_initVBVBufferFullnessInBit;
3024 cmd.m_curbeData.DW2.m_bufSizeInBits = m_seqParams->m_vbvBufferSize * CODEC_ENCODE_MPEG2_VBV_BUFFER_SIZE_UNITS;
3025 cmd.m_curbeData.DW3.m_averageBitRate = m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS;
3026 cmd.m_curbeData.DW4.m_maxBitRate = m_seqParams->m_maxBitRate * CODECHAL_ENCODE_BRC_KBPS;
3027
3028 if (m_picParams->m_gopPicSize == 1)
3029 {
3030 cmd.m_curbeData.DW8.m_gopP = 0;
3031 cmd.m_curbeData.DW9.m_gopB = 0;
3032 }
3033 else
3034 {
3035 cmd.m_curbeData.DW8.m_gopP = (m_picParams->m_gopRefDist) ? ((m_picParams->m_gopPicSize - 1) / m_picParams->m_gopRefDist) : 0;
3036 cmd.m_curbeData.DW9.m_gopB = (m_picParams->m_gopRefDist - 1) * cmd.m_curbeData.DW8.m_gopP;
3037 }
3038 cmd.m_curbeData.DW9.m_frameWidthInBytes = m_frameWidth;
3039 cmd.m_curbeData.DW10.m_frameHeightInBytes = m_frameHeight;
3040 cmd.m_curbeData.DW11.m_minQP = 1;
3041 cmd.m_curbeData.DW12.m_noSlices = ((m_frameHeight + 31) >> 5) << 1;
3042
3043 // Frame Rate m_value Scaled by m_frameRateDenom
3044 uint32_t scaledFrameRateValue = CalcFrameRateValue(m_seqParams->m_frameRateCode, m_frameRateDenom);
3045
3046 if (CodecHal_PictureIsFrame(m_picParams->m_currOriginalPic))
3047 {
3048 cmd.m_curbeData.DW6.m_frameRateM = scaledFrameRateValue;
3049 }
3050 else // This else clause will only be taken when interlaced field support is added to MPEG-2.
3051 {
3052 cmd.m_curbeData.DW6.m_frameRateM = scaledFrameRateValue * 2;
3053 }
3054
3055 cmd.m_curbeData.DW7.m_frameRateD = m_frameRateDenom;
3056 cmd.m_curbeData.DW8.m_brcFlag = (CodecHal_PictureIsFrame(m_picParams->m_currOriginalPic)) ? (0) : (CODECHAL_ENCODE_BRCINIT_FIELD_PIC);
3057
3058 if (m_seqParams->m_rateControlMethod == RATECONTROL_CBR)
3059 {
3060 cmd.m_curbeData.DW4.m_maxBitRate = cmd.m_curbeData.DW3.m_averageBitRate;
3061 cmd.m_curbeData.DW8.m_brcFlag = cmd.m_curbeData.DW8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISCBR;
3062 }
3063 else if (m_seqParams->m_rateControlMethod == RATECONTROL_VBR)
3064 {
3065 cmd.m_curbeData.DW8.m_brcFlag = cmd.m_curbeData.DW8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISVBR;
3066 }
3067 else if (m_seqParams->m_rateControlMethod == RATECONTROL_AVBR)
3068 {
3069 cmd.m_curbeData.DW10.m_avbrAccuracy = m_avbrAccuracy;
3070 cmd.m_curbeData.DW11.m_avbrConvergence = m_avbrConvergence;
3071 cmd.m_curbeData.DW8.m_brcFlag = cmd.m_curbeData.DW8.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISAVBR;
3072 // For AVBR, only honor bitrate from app => InitVBV = Bitrate, Buffer size = 2*Bitrate, max bitrate = target bitrate,
3073 cmd.m_curbeData.DW1.m_initBufFullInBits = m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS; //m_seqParams->bit_rate * ENCODE_BRC_KBPS;
3074 cmd.m_curbeData.DW2.m_bufSizeInBits = 2 * m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS; //m_seqParams->bit_rate * ENCODE_BRC_KBPS;
3075 cmd.m_curbeData.DW3.m_averageBitRate = m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS;
3076 cmd.m_curbeData.DW4.m_maxBitRate = m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS;
3077 }
3078
3079 // Profile & level max frame size
3080 uint32_t defaultFrameSize = m_frameWidth * m_frameHeight;
3081 if (m_seqParams->m_userMaxFrameSize > 0)
3082 {
3083 cmd.m_curbeData.DW0.m_profileLevelMaxFrame = MOS_MIN(m_seqParams->m_userMaxFrameSize, defaultFrameSize);
3084 }
3085 else
3086 {
3087 cmd.m_curbeData.DW0.m_profileLevelMaxFrame = defaultFrameSize;
3088 }
3089
3090 uint32_t brcKernelIdx = (m_brcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET;
3091 PMHW_KERNEL_STATE kernelState = &m_brcKernelStates[brcKernelIdx];
3092 if (m_brcInit)
3093 {
3094 m_brcInitCurrentTargetBufFullInBits = cmd.m_curbeData.DW1.m_initBufFullInBits;
3095 }
3096 m_brcInitResetBufSizeInBits = (double)cmd.m_curbeData.DW2.m_bufSizeInBits;
3097 m_brcInitResetInputBitsPerFrame =
3098 ((double)(cmd.m_curbeData.DW4.m_maxBitRate) * (double)(cmd.m_curbeData.DW7.m_frameRateD) /(double)(cmd.m_curbeData.DW6.m_frameRateM));
3099
3100 CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData(
3101 &cmd,
3102 kernelState->dwCurbeOffset,
3103 cmd.m_byteSize));
3104
3105 return eStatus;
3106
3107 }
3108
SendBrcInitResetSurfaces(PMOS_COMMAND_BUFFER cmdBuffer)3109 MOS_STATUS CodechalEncodeMpeg2::SendBrcInitResetSurfaces(
3110 PMOS_COMMAND_BUFFER cmdBuffer)
3111 {
3112 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3113
3114 CODECHAL_ENCODE_FUNCTION_ENTER;
3115
3116 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
3117
3118 uint32_t brcKernelIdx = (m_brcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET;
3119 PMHW_KERNEL_STATE kernelState = &m_brcKernelStates[brcKernelIdx];
3120
3121 // BRC history buffer
3122 CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
3123 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3124 surfaceCodecParams.bIsWritable = true;
3125 surfaceCodecParams.presBuffer = &m_brcBuffers.resBrcHistoryBuffer;
3126 surfaceCodecParams.dwSize = m_brcHistoryBufferSize;
3127 surfaceCodecParams.dwBindingTableOffset = brcInitResetHistory;
3128 surfaceCodecParams.bIsWritable = true;
3129
3130 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3131 m_hwInterface,
3132 cmdBuffer,
3133 &surfaceCodecParams,
3134 kernelState));
3135
3136 // AVC_ME BRC Distortion data buffer - output
3137 m_brcBuffers.sMeBrcDistortionBuffer.dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
3138 m_brcBuffers.sMeBrcDistortionBuffer.dwHeight = MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8);
3139 m_brcBuffers.sMeBrcDistortionBuffer.dwPitch = m_brcBuffers.sMeBrcDistortionBuffer.dwWidth;
3140
3141 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3142 surfaceCodecParams.bIs2DSurface = true;
3143 surfaceCodecParams.bMediaBlockRW = true;
3144 surfaceCodecParams.bIsWritable = true;
3145 surfaceCodecParams.psSurface = &m_brcBuffers.sMeBrcDistortionBuffer;
3146 surfaceCodecParams.dwOffset = m_brcBuffers.dwMeBrcDistortionBottomFieldOffset;
3147 surfaceCodecParams.dwBindingTableOffset = brcInitResetDistortion;
3148 surfaceCodecParams.bIsWritable = true;
3149 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3150 m_hwInterface,
3151 cmdBuffer,
3152 &surfaceCodecParams,
3153 kernelState));
3154
3155 return eStatus;
3156 }
3157
EncodeBrcInitResetKernel()3158 MOS_STATUS CodechalEncodeMpeg2::EncodeBrcInitResetKernel()
3159 {
3160 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3161
3162 CODECHAL_ENCODE_FUNCTION_ENTER;
3163
3164 PerfTagSetting perfTag;
3165 perfTag.Value = 0;
3166 perfTag.Mode = (uint32_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
3167 perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET;
3168 perfTag.PictureCodingType = m_pictureCodingType;
3169 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
3170
3171 uint32_t brcKernelIdx = (m_brcInit) ? CODECHAL_ENCODE_BRC_IDX_INIT : CODECHAL_ENCODE_BRC_IDX_RESET;
3172 PMHW_KERNEL_STATE kernelState = &m_brcKernelStates[brcKernelIdx];
3173
3174 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
3175 {
3176 uint32_t maxBtCount = m_singleTaskPhaseSupported ?
3177 m_maxBtCount : kernelState->KernelParams.iBTCount;
3178 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
3179 m_stateHeapInterface,
3180 maxBtCount));
3181 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
3182 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
3183 }
3184
3185 // Setup Mpeg2 Curbe
3186 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
3187 m_stateHeapInterface,
3188 kernelState,
3189 false,
3190 0,
3191 false,
3192 m_storeData));
3193
3194 MHW_INTERFACE_DESCRIPTOR_PARAMS interfaceParams;
3195 MOS_ZeroMemory(&interfaceParams, sizeof(interfaceParams));
3196 interfaceParams.pKernelState = kernelState;
3197 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
3198 m_stateHeapInterface,
3199 1,
3200 &interfaceParams));
3201
3202 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeBrcInitReset());
3203
3204 CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_INIT_RESET;
3205 CODECHAL_DEBUG_TOOL(
3206 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3207 encFunctionType,
3208 MHW_DSH_TYPE,
3209 kernelState));
3210 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
3211 encFunctionType,
3212 kernelState));
3213 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3214 encFunctionType,
3215 MHW_ISH_TYPE,
3216 kernelState));
3217 )
3218
3219 MOS_COMMAND_BUFFER cmdBuffer;
3220 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
3221
3222 SendKernelCmdsParams sendKernelCmdsParams;
3223 sendKernelCmdsParams.EncFunctionType = encFunctionType;
3224 sendKernelCmdsParams.bBrcResetRequested = m_brcReset;
3225 sendKernelCmdsParams.pKernelState = kernelState;
3226
3227 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
3228
3229 // Add binding table
3230 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
3231 m_stateHeapInterface,
3232 kernelState));
3233
3234 //Add surface states
3235 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendBrcInitResetSurfaces(&cmdBuffer));
3236
3237 CODECHAL_DEBUG_TOOL(
3238 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3239 encFunctionType,
3240 MHW_SSH_TYPE,
3241 kernelState));
3242 )
3243
3244 MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
3245 MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
3246 MediaObjectInlineDataMpeg2 mediaObjectInlineData;
3247 MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
3248 mediaObjectParams.pInlineData = &mediaObjectInlineData;
3249 mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);
3250 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObject(
3251 &cmdBuffer,
3252 nullptr,
3253 &mediaObjectParams));
3254
3255 // add end of commands here for eStatus report
3256 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
3257
3258 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
3259 m_stateHeapInterface,
3260 kernelState));
3261 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3262 {
3263 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
3264 m_stateHeapInterface));
3265
3266 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
3267 &cmdBuffer,
3268 nullptr));
3269 }
3270
3271 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3272 &cmdBuffer,
3273 encFunctionType,
3274 nullptr)));
3275
3276 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(
3277 &cmdBuffer,
3278 m_singleTaskPhaseSupported,
3279 m_lastTaskInPhase));
3280
3281 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3282
3283 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3284 {
3285 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
3286 m_osInterface, &cmdBuffer,
3287 m_renderContextUsesNullHw));
3288 m_lastTaskInPhase = false;
3289 }
3290 return eStatus;
3291 }
3292
EncodeMbEncKernel(bool mbEncIFrameDistEnabled)3293 MOS_STATUS CodechalEncodeMpeg2::EncodeMbEncKernel(bool mbEncIFrameDistEnabled)
3294 {
3295 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3296
3297 CODECHAL_ENCODE_FUNCTION_ENTER;
3298
3299 PerfTagSetting perfTag;
3300 perfTag.Value = 0;
3301 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
3302 perfTag.CallType =
3303 (mbEncIFrameDistEnabled) ? CODECHAL_ENCODE_PERFTAG_CALL_INTRA_DIST : CODECHAL_ENCODE_PERFTAG_CALL_MBENC_KERNEL;
3304 perfTag.PictureCodingType = m_pictureCodingType;
3305 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
3306
3307 CODECHAL_MEDIA_STATE_TYPE encFunctionType;
3308 if (mbEncIFrameDistEnabled)
3309 {
3310 encFunctionType = CODECHAL_MEDIA_STATE_ENC_I_FRAME_DIST;
3311 }
3312 else if (m_kernelMode == encodeNormalMode)
3313 {
3314 encFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL;
3315 }
3316 else if (m_kernelMode == encodePerformanceMode)
3317 {
3318 encFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE;
3319 }
3320 else
3321 {
3322 encFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY;
3323 }
3324
3325 PMHW_KERNEL_STATE kernelState;
3326 uint8_t codingType = m_mbEncForcePictureCodingType ?
3327 m_mbEncForcePictureCodingType : (uint8_t)m_pictureCodingType;
3328 // Initialize DSH kernel region
3329 if (mbEncIFrameDistEnabled)
3330 {
3331 kernelState = &m_brcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST];
3332 }
3333 else
3334 {
3335 // wPictureCodingType: I_TYPE = 1, P_TYPE = 2, B_TYPE = 3
3336 // KernelStates are I: 0, P: 1, B: 2
3337 // m_mbEncKernelStates: I: m_mbEncKernelStates[0], P: m_mbEncKernelStates[1], B: m_mbEncKernelStates[2]
3338 uint32_t krnStateIdx = codingType - 1;
3339
3340 kernelState = &m_mbEncKernelStates[krnStateIdx];
3341 }
3342
3343 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
3344 {
3345 uint32_t maxBtCount = m_singleTaskPhaseSupported ?
3346 m_maxBtCount : kernelState->KernelParams.iBTCount;
3347 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
3348 m_stateHeapInterface,
3349 maxBtCount));
3350 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
3351 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
3352 }
3353
3354 if (m_mbEncCurbeSetInBrcUpdate)
3355 {
3356 // single task phase disabled for MPEG2 MbEnc
3357 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
3358 m_stateHeapInterface,
3359 kernelState,
3360 true,
3361 0,
3362 m_singleTaskPhaseSupported,
3363 m_storeData));
3364 }
3365 else
3366 {
3367 // Set up the DSH as normal
3368 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
3369 m_stateHeapInterface,
3370 kernelState,
3371 false,
3372 0,
3373 false,
3374 m_storeData));
3375
3376 MHW_INTERFACE_DESCRIPTOR_PARAMS interfaceParams;
3377 MOS_ZeroMemory(&interfaceParams, sizeof(interfaceParams));
3378 interfaceParams.pKernelState = kernelState;
3379 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
3380 m_stateHeapInterface,
3381 1,
3382 &interfaceParams));
3383
3384 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMbEnc(mbEncIFrameDistEnabled, m_mbQpDataEnabled));
3385
3386 CODECHAL_DEBUG_TOOL(
3387 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3388 encFunctionType,
3389 MHW_DSH_TYPE,
3390 kernelState));
3391 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
3392 encFunctionType,
3393 kernelState));
3394 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3395 encFunctionType,
3396 MHW_ISH_TYPE,
3397 kernelState));
3398 )
3399 }
3400
3401 for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
3402 {
3403 if (m_picIdx[i].bValid)
3404 {
3405 auto Index = m_picIdx[i].ucPicIdx;
3406 m_refList[Index]->sRefBuffer = m_picParams->m_useRawPicForRef ?
3407 m_refList[Index]->sRefRawBuffer : m_refList[Index]->sRefReconBuffer;
3408
3409 if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
3410 {
3411 auto pResRefMbCodeBuffer = (MOS_RESOURCE*)m_allocator->GetResource(m_standard, mbCodeBuffer, m_refList[Index]->ucMbCodeIdx);
3412
3413 if (pResRefMbCodeBuffer)
3414 {
3415 m_refList[Index]->resRefMbCodeBuffer = *pResRefMbCodeBuffer;
3416 }
3417 }
3418
3419 CodecHalGetResourceInfo(m_osInterface, &m_refList[Index]->sRefBuffer);
3420 }
3421 }
3422
3423 MOS_COMMAND_BUFFER cmdBuffer;
3424 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
3425
3426 SendKernelCmdsParams sendKernelCmdsParams;
3427 sendKernelCmdsParams.EncFunctionType = encFunctionType;
3428 sendKernelCmdsParams.pKernelState = kernelState;
3429
3430 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
3431
3432 // Add binding table
3433 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
3434 m_stateHeapInterface,
3435 kernelState));
3436
3437 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendMbEncSurfaces(&cmdBuffer, mbEncIFrameDistEnabled));
3438
3439 if ((codingType != B_TYPE) && (!mbEncIFrameDistEnabled))
3440 {
3441 m_prevMBCodeIdx = m_currReconstructedPic.FrameIdx;
3442 }
3443
3444 // HW walker
3445 CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
3446 MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
3447 walkerCodecParams.WalkerMode = m_walkerMode;
3448 walkerCodecParams.bUseScoreboard = m_useHwScoreboard;
3449 walkerCodecParams.dwResolutionX = mbEncIFrameDistEnabled ?
3450 m_downscaledWidthInMb4x : (uint32_t)m_picWidthInMb;
3451 walkerCodecParams.dwResolutionY = mbEncIFrameDistEnabled ?
3452 m_downscaledFrameFieldHeightInMb4x : (uint32_t)m_frameFieldHeightInMb;
3453
3454 if (codingType == I_TYPE)
3455 {
3456 walkerCodecParams.bUseScoreboard = false;
3457 walkerCodecParams.bNoDependency = true; /* Enforce no dependency dispatch order for I frame */
3458 }
3459 else if (codingType == P_TYPE)
3460 {
3461 // walkerCodecParams.wPictureCodingType can be different from m_pictureCodingType
3462 walkerCodecParams.wPictureCodingType = I_TYPE; /* Enforce 45 degree dispatch order for P frame, as by default it's 26 degree */
3463 }
3464 else// B_TYPE
3465 {
3466 walkerCodecParams.bUseVerticalRasterScan = true;
3467 }
3468
3469 MHW_WALKER_PARAMS walkerParams;
3470 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
3471 m_hwInterface,
3472 &walkerParams,
3473 &walkerCodecParams));
3474
3475 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObjectWalkerCmd(
3476 &cmdBuffer,
3477 &walkerParams));
3478
3479 // add end of commands here for eStatus report
3480 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
3481
3482 CODECHAL_DEBUG_TOOL(
3483 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3484 encFunctionType,
3485 MHW_SSH_TYPE,
3486 kernelState));
3487
3488 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3489 &cmdBuffer,
3490 encFunctionType,
3491 nullptr));
3492 )
3493
3494 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
3495 m_stateHeapInterface,
3496 kernelState));
3497 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3498 {
3499 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
3500 m_stateHeapInterface));
3501
3502 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
3503 }
3504
3505 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
3506
3507 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3508
3509 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3510 {
3511 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw));
3512 m_lastTaskInPhase = false;
3513 }
3514
3515 return eStatus;
3516 }
3517
SendBrcUpdateSurfaces(PMOS_COMMAND_BUFFER cmdBuffer)3518 MOS_STATUS CodechalEncodeMpeg2::SendBrcUpdateSurfaces(
3519 PMOS_COMMAND_BUFFER cmdBuffer)
3520 {
3521 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3522
3523 CODECHAL_ENCODE_FUNCTION_ENTER;
3524
3525 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
3526
3527 auto kernelState = &m_brcKernelStates[CODECHAL_ENCODE_BRC_IDX_FrameBRC_UPDATE];
3528 auto mbEncKernelState = m_brcBuffers.pMbEncKernelStateInUse;
3529
3530 // BRC history buffer
3531 CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
3532 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3533 surfaceCodecParams.bIsWritable = true;
3534 surfaceCodecParams.presBuffer = &m_brcBuffers.resBrcHistoryBuffer;
3535 surfaceCodecParams.dwSize = m_brcHistoryBufferSize;
3536 surfaceCodecParams.dwBindingTableOffset = brcUpdateHistory;
3537 surfaceCodecParams.bIsWritable = true;
3538 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3539 m_hwInterface,
3540 cmdBuffer,
3541 &surfaceCodecParams,
3542 kernelState));
3543
3544 // PAK Statistics buffer
3545 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3546 surfaceCodecParams.presBuffer = &m_brcBuffers.resBrcPakStatisticBuffer[0];
3547 surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(m_brcPakStatisticsSize);
3548 surfaceCodecParams.dwBindingTableOffset = brcUpdatePakStaticOutput;
3549 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3550 m_hwInterface,
3551 cmdBuffer,
3552 &surfaceCodecParams,
3553 kernelState));
3554
3555 // PAK IMG_STATEs buffer - read only
3556 uint32_t bufSize = MOS_BYTES_TO_DWORDS(BRC_IMG_STATE_SIZE_PER_PASS * m_mfxInterface->GetBrcNumPakPasses());
3557 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3558 surfaceCodecParams.presBuffer =
3559 &m_brcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx];
3560 surfaceCodecParams.dwSize = bufSize;
3561 surfaceCodecParams.dwBindingTableOffset = brcUpdatePictureStateRead;
3562 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3563 m_hwInterface,
3564 cmdBuffer,
3565 &surfaceCodecParams,
3566 kernelState));
3567
3568 // PAK IMG_STATEs buffer - write only
3569 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3570 surfaceCodecParams.bIsWritable = true;
3571 surfaceCodecParams.presBuffer = &m_brcBuffers.resBrcImageStatesWriteBuffer;
3572 surfaceCodecParams.dwSize = bufSize;
3573 surfaceCodecParams.dwBindingTableOffset = brcUpdatePictureStateWrite;
3574 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3575 m_hwInterface,
3576 cmdBuffer,
3577 &surfaceCodecParams,
3578 kernelState));
3579
3580 // BRC ENC CURBE Buffer - read only
3581 MOS_RESOURCE *dsh = nullptr;
3582 CODECHAL_ENCODE_CHK_NULL_RETURN(dsh = mbEncKernelState->m_dshRegion.GetResource());
3583 bufSize = MOS_ALIGN_CEIL(
3584 mbEncKernelState->KernelParams.iCurbeLength,
3585 m_stateHeapInterface->pStateHeapInterface->GetCurbeAlignment());
3586 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3587 surfaceCodecParams.presBuffer = dsh;
3588 surfaceCodecParams.dwOffset =
3589 mbEncKernelState->m_dshRegion.GetOffset() +
3590 mbEncKernelState->dwCurbeOffset;
3591 surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(bufSize);
3592 surfaceCodecParams.dwBindingTableOffset = brcUpdateMbencCurbeRead;
3593 // If the protection DSH isn't used, the same DSH is used for both the MbEnc CURBE read and write
3594 surfaceCodecParams.bIsWritable = true;
3595 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3596 m_hwInterface,
3597 cmdBuffer,
3598 &surfaceCodecParams,
3599 kernelState));
3600
3601 // BRC ENC CURBE Buffer - write only
3602 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3603 surfaceCodecParams.presBuffer = dsh;
3604 surfaceCodecParams.dwOffset =
3605 mbEncKernelState->m_dshRegion.GetOffset() +
3606 mbEncKernelState->dwCurbeOffset;
3607 surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(bufSize);
3608 surfaceCodecParams.dwBindingTableOffset = brcUpdateMbencCurbeWrite;
3609 surfaceCodecParams.bRenderTarget = true;
3610 surfaceCodecParams.bIsWritable = true;
3611 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3612 m_hwInterface,
3613 cmdBuffer,
3614 &surfaceCodecParams,
3615 kernelState));
3616
3617 // MPEG2_ME BRC Distortion data buffer - input
3618 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3619 surfaceCodecParams.bIs2DSurface = true;
3620 surfaceCodecParams.bMediaBlockRW = true;
3621 surfaceCodecParams.psSurface = &m_brcBuffers.sMeBrcDistortionBuffer;
3622 surfaceCodecParams.dwOffset = m_brcBuffers.dwMeBrcDistortionBottomFieldOffset;
3623 surfaceCodecParams.dwSize = bufSize;
3624 surfaceCodecParams.dwBindingTableOffset = brcUpdateDistortion;
3625 surfaceCodecParams.bIsWritable = true;
3626 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3627 m_hwInterface,
3628 cmdBuffer,
3629 &surfaceCodecParams,
3630 kernelState));
3631
3632 // BRC Constant Data Surface
3633 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3634 surfaceCodecParams.bIs2DSurface = true;
3635 surfaceCodecParams.bMediaBlockRW = true;
3636 surfaceCodecParams.psSurface =
3637 &m_brcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx];
3638 surfaceCodecParams.dwBindingTableOffset = brcUpdateConstantData;
3639 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3640 m_hwInterface,
3641 cmdBuffer,
3642 &surfaceCodecParams,
3643 kernelState));
3644
3645 // Picture header input surface
3646 bufSize = m_picHeaderDataBufferSize;
3647 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3648 surfaceCodecParams.presBuffer =
3649 &m_brcBuffers.resBrcPicHeaderInputBuffer;
3650 surfaceCodecParams.dwSize = bufSize;
3651 surfaceCodecParams.dwBindingTableOffset = brcUpdatePicHeaderInputData;
3652 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3653 m_hwInterface,
3654 cmdBuffer,
3655 &surfaceCodecParams,
3656 kernelState));
3657
3658 // Picture header output surface
3659 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
3660 surfaceCodecParams.bIsWritable = true;
3661 surfaceCodecParams.presBuffer = &m_brcBuffers.resBrcPicHeaderOutputBuffer;
3662 surfaceCodecParams.dwSize = bufSize;
3663 surfaceCodecParams.dwBindingTableOffset = brcUpdateOutputData;
3664 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3665 m_hwInterface,
3666 cmdBuffer,
3667 &surfaceCodecParams,
3668 kernelState));
3669
3670 return eStatus;
3671 }
3672
SetCurbeBrcUpdate()3673 MOS_STATUS CodechalEncodeMpeg2::SetCurbeBrcUpdate()
3674 {
3675 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3676
3677 CODECHAL_ENCODE_FUNCTION_ENTER;
3678
3679 BrcUpdateCurbe cmd;
3680
3681 cmd.m_curbeData.DW5.m_targetSizeFlag = 0;
3682 if (m_brcInitCurrentTargetBufFullInBits > m_brcInitResetBufSizeInBits)
3683 {
3684 m_brcInitCurrentTargetBufFullInBits -= m_brcInitResetBufSizeInBits;
3685 cmd.m_curbeData.DW5.m_targetSizeFlag = 1;
3686 }
3687 cmd.m_curbeData.DW0.m_targetSize = (uint32_t)m_brcInitCurrentTargetBufFullInBits;
3688 cmd.m_curbeData.DW5.m_currFrameType = m_pictureCodingType - 1;
3689
3690 cmd.m_curbeData.DW5.m_brcFlag = (CodecHal_PictureIsFrame(m_picParams->m_currOriginalPic)) ? (0) : (CODECHAL_ENCODE_BRCINIT_FIELD_PIC);
3691
3692 if (m_seqParams->m_rateControlMethod == RATECONTROL_CBR)
3693 {
3694 cmd.m_curbeData.DW5.m_brcFlag = cmd.m_curbeData.DW5.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISCBR;
3695 }
3696 else if (m_seqParams->m_rateControlMethod == RATECONTROL_VBR)
3697 {
3698 cmd.m_curbeData.DW5.m_brcFlag = cmd.m_curbeData.DW5.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISVBR;
3699 }
3700 else if (m_seqParams->m_rateControlMethod == RATECONTROL_AVBR)
3701 {
3702 cmd.m_curbeData.DW5.m_brcFlag = cmd.m_curbeData.DW5.m_brcFlag | CODECHAL_ENCODE_BRCINIT_ISAVBR;
3703 }
3704
3705 cmd.m_curbeData.DW6.m_qScaleTypeOffset = m_qScaleTypeByteOffse;
3706 cmd.m_curbeData.DW6.m_vbvDelay = m_vbvDelayOffset;
3707 cmd.m_curbeData.DW7.m_picHeaderDataBufferSize = m_picHeaderDataBufferSize;
3708 cmd.m_curbeData.DW15.m_extraHeaders = 1;
3709 cmd.m_curbeData.DW15.m_intraDcPrecisionOffset = m_intraDcPrecisionOffset;
3710
3711 m_brcInitCurrentTargetBufFullInBits += m_brcInitResetInputBitsPerFrame;
3712
3713 if (m_seqParams->m_rateControlMethod == RATECONTROL_AVBR)
3714 {
3715 cmd.m_curbeData.DW3.m_startGAdjFrame0 = (uint32_t)((10 * m_avbrConvergence) / (double)150);
3716 cmd.m_curbeData.DW3.m_startGAdjFrame1 = (uint32_t)((50 * m_avbrConvergence) / (double)150);
3717 cmd.m_curbeData.DW4.m_startGAdjFrame2 = (uint32_t)((100 * m_avbrConvergence) / (double)150);
3718 cmd.m_curbeData.DW4.m_startGAdjFrame3 = (uint32_t)((150 * m_avbrConvergence) / (double)150);
3719 cmd.m_curbeData.DW11.m_gRateRatioThreshold0 = (uint32_t)((100 - (m_avbrAccuracy / (double)30) * (100 - 40)));
3720 cmd.m_curbeData.DW11.m_gRateRatioThreshold1 = (uint32_t)((100 - (m_avbrAccuracy / (double)30) * (100 - 75)));
3721 cmd.m_curbeData.DW12.m_gRateRatioThreshold2 = (uint32_t)((100 - (m_avbrAccuracy / (double)30) * (100 - 97)));
3722 cmd.m_curbeData.DW12.m_gRateRatioThreshold3 = (uint32_t)((100 + (m_avbrAccuracy / (double)30) * (103 - 100)));
3723 cmd.m_curbeData.DW12.m_gRateRatioThreshold4 = (uint32_t)((100 + (m_avbrAccuracy / (double)30) * (125 - 100)));
3724 cmd.m_curbeData.DW12.m_gRateRatioThreshold5 = (uint32_t)((100 + (m_avbrAccuracy / (double)30) * (160 - 100)));
3725 }
3726
3727 if (m_seqParams->m_forcePanicModeControl == 1) {
3728 cmd.m_curbeData.DW14.m_forceToSkip = m_seqParams->m_panicModeDisable ? 0 : 1;
3729 } else {
3730 cmd.m_curbeData.DW14.m_forceToSkip = m_panicEnable ? 1 : 0;
3731 }
3732 auto kernelState = &m_brcKernelStates[CODECHAL_ENCODE_BRC_IDX_FrameBRC_UPDATE];
3733 CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData(
3734 &cmd,
3735 kernelState->dwCurbeOffset,
3736 cmd.m_byteSize));
3737
3738 return eStatus;
3739 }
3740
InitBrcConstantBuffer()3741 MOS_STATUS CodechalEncodeMpeg2::InitBrcConstantBuffer()
3742 {
3743 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3744
3745 CODECHAL_ENCODE_FUNCTION_ENTER;
3746
3747 auto brcConstantDataBuffer =
3748 m_brcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx];
3749
3750 CodechalResLock bufLock(m_osInterface, &brcConstantDataBuffer.OsResource);
3751 auto data = (uint8_t *)bufLock.Lock(CodechalResLock::writeOnly);
3752 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3753
3754 MOS_ZeroMemory(data, brcConstantDataBuffer.dwWidth * brcConstantDataBuffer.dwHeight);
3755
3756 uint8_t *maxFrameThresholdArray = nullptr;
3757 uint8_t *distQPAdjustmentArray = nullptr;
3758 switch(m_pictureCodingType)
3759 {
3760 case I_TYPE:
3761 maxFrameThresholdArray = (uint8_t *)m_qpAdjustmentDistThresholdMaxFrameThresholdI;
3762 distQPAdjustmentArray = (uint8_t *)m_distQpAdjustmentI;
3763 break;
3764 case P_TYPE:
3765 maxFrameThresholdArray = (uint8_t *)m_qpAdjustmentDistThresholdMaxFrameThresholdP;
3766 distQPAdjustmentArray = (uint8_t *)m_distQpAdjustmentP;
3767 break;
3768 case B_TYPE:
3769 maxFrameThresholdArray = (uint8_t *)m_qpAdjustmentDistThresholdMaxFrameThresholdB;
3770 distQPAdjustmentArray = (uint8_t *)m_distQpAdjustmentB;
3771 break;
3772 default:
3773 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid picture coding type.");
3774 eStatus = MOS_STATUS_INVALID_PARAMETER;
3775 return eStatus;
3776 }
3777
3778 // Fill surface with QP Adjustment table, Distortion threshold table, MaxFrame threshold table for I frame
3779 // The surface width happens to be the size of the array.
3780 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
3781 data,
3782 m_frameThresholdArraySize,
3783 maxFrameThresholdArray,
3784 m_frameThresholdArraySize));
3785
3786 data += m_frameThresholdArraySize;
3787
3788 for (uint32_t i = 0; i < m_distQpAdjustmentArraySize; i += m_brcConstantSurfaceWidth)
3789 {
3790 uint32_t copySize;
3791 if ((m_distQpAdjustmentArraySize - i) > m_brcConstantSurfaceWidth)
3792 {
3793 copySize = m_brcConstantSurfaceWidth;
3794 }
3795 else
3796 {
3797 copySize = m_distQpAdjustmentArraySize - i;
3798 }
3799 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
3800 data + i,
3801 copySize,
3802 distQPAdjustmentArray + i,
3803 copySize));
3804 }
3805
3806 return eStatus;
3807 }
3808
EncodeBrcUpdateKernel()3809 MOS_STATUS CodechalEncodeMpeg2::EncodeBrcUpdateKernel()
3810 {
3811 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3812
3813 CODECHAL_ENCODE_FUNCTION_ENTER;
3814
3815 PerfTagSetting perfTag;
3816 perfTag.Value = 0;
3817 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
3818 perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE;
3819 perfTag.PictureCodingType = m_pictureCodingType;
3820 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
3821
3822 auto kernelState = &m_brcKernelStates[CODECHAL_ENCODE_BRC_IDX_FrameBRC_UPDATE];
3823
3824 if (m_firstTaskInPhase || !m_singleTaskPhaseSupported)
3825 {
3826 uint32_t maxBtCount = m_singleTaskPhaseSupported ?
3827 m_maxBtCount : kernelState->KernelParams.iBTCount;
3828 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
3829 m_stateHeapInterface,
3830 maxBtCount));
3831 m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
3832 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
3833 }
3834
3835 // wPictureCodingType: I_TYPE = 1, P_TYPE = 2, B_TYPE = 3
3836 // KernelStates are I: 0, P: 1, B: 2
3837 // m_mbEncKernelStates: I: m_mbEncKernelStates[0], P: m_mbEncKernelStates[1], B: m_mbEncKernelStates[2]
3838 uint32_t krnStateIdx = m_pictureCodingType - 1;
3839
3840 if (m_mbEncForcePictureCodingType)
3841 {
3842 krnStateIdx = m_mbEncForcePictureCodingType - 1;
3843 }
3844
3845 auto mbEncKernelState = &m_mbEncKernelStates[krnStateIdx];
3846
3847 // Setup MbEnc Curbe
3848 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
3849 m_stateHeapInterface,
3850 mbEncKernelState,
3851 false,
3852 0,
3853 !m_singleTaskPhaseSupported,
3854 m_storeData));
3855
3856 MHW_INTERFACE_DESCRIPTOR_PARAMS interfaceParams;
3857 MOS_ZeroMemory(&interfaceParams, sizeof(interfaceParams));
3858 interfaceParams.pKernelState = mbEncKernelState;
3859 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
3860 m_stateHeapInterface,
3861 1,
3862 &interfaceParams));
3863
3864 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeMbEnc(0, 0));
3865
3866 // Brc Update
3867 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
3868 m_stateHeapInterface,
3869 kernelState,
3870 false,
3871 0,
3872 false,
3873 m_storeData));
3874
3875 MOS_ZeroMemory(&interfaceParams, sizeof(interfaceParams));
3876 interfaceParams.pKernelState = kernelState;
3877 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
3878 m_stateHeapInterface,
3879 1,
3880 &interfaceParams));
3881
3882 m_mbEncCurbeSetInBrcUpdate = true;
3883
3884 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeBrcUpdate());
3885
3886 CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_BRC_UPDATE;
3887 CODECHAL_MEDIA_STATE_TYPE mbEncFunctionType;
3888 if (m_kernelMode == encodeNormalMode)
3889 {
3890 mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_NORMAL;
3891 }
3892 else if (m_kernelMode == encodePerformanceMode)
3893 {
3894 mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_PERFORMANCE;
3895 }
3896 else
3897 {
3898 mbEncFunctionType = CODECHAL_MEDIA_STATE_ENC_QUALITY;
3899 }
3900
3901 CODECHAL_DEBUG_TOOL(
3902 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3903 encFunctionType,
3904 MHW_DSH_TYPE,
3905 kernelState));
3906 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
3907 encFunctionType,
3908 kernelState));
3909 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3910 encFunctionType,
3911 MHW_ISH_TYPE,
3912 kernelState));
3913 )
3914
3915 MOS_COMMAND_BUFFER cmdBuffer;
3916 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
3917
3918 SendKernelCmdsParams sendKernelCmdsParams;
3919 sendKernelCmdsParams.EncFunctionType = encFunctionType;
3920 sendKernelCmdsParams.pKernelState = kernelState;
3921
3922 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
3923
3924 // Add binding table
3925 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
3926 m_stateHeapInterface,
3927 kernelState));
3928
3929 m_brcBuffers.pMbEncKernelStateInUse = mbEncKernelState;
3930
3931 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer());
3932
3933 //Set MFX_MPEG2_PIC_STATE command
3934 MHW_VDBOX_MPEG2_PIC_STATE mpeg2PicState;
3935 MOS_ZeroMemory(&mpeg2PicState, sizeof(mpeg2PicState));
3936 mpeg2PicState.pEncodeMpeg2PicParams = m_picParams;
3937 mpeg2PicState.pEncodeMpeg2SeqParams = m_seqParams;
3938 mpeg2PicState.wPicWidthInMb = m_picWidthInMb;
3939 mpeg2PicState.wPicHeightInMb = m_picHeightInMb;
3940 mpeg2PicState.ppRefList = &(m_refList[0]);
3941 mpeg2PicState.bBrcEnabled = true;
3942 mpeg2PicState.bTrellisQuantEnable = false;
3943 mpeg2PicState.ucKernelMode = m_kernelMode;
3944
3945 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxMpeg2PicBrcBuffer(
3946 &m_brcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx],
3947 &mpeg2PicState));
3948
3949 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendBrcUpdateSurfaces(&cmdBuffer));
3950
3951 CODECHAL_DEBUG_TOOL(
3952 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3953 encFunctionType,
3954 MHW_SSH_TYPE,
3955 kernelState));
3956 )
3957
3958 MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
3959 MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
3960 MediaObjectInlineData mediaObjectInlineData;
3961 MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
3962 mediaObjectParams.pInlineData = &mediaObjectInlineData;
3963 mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);
3964 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObject(
3965 &cmdBuffer,
3966 nullptr,
3967 &mediaObjectParams));
3968
3969 // add end of commands here for eStatus report
3970 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
3971
3972 CODECHAL_DEBUG_TOOL(
3973 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3974 &cmdBuffer,
3975 encFunctionType,
3976 nullptr));
3977
3978 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
3979 &m_brcBuffers.resBrcImageStatesReadBuffer[m_currRecycledBufIdx],
3980 CodechalDbgAttr::attrInput,
3981 "ImgStateRead",
3982 BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(),
3983 0,
3984 CODECHAL_MEDIA_STATE_BRC_UPDATE));
3985
3986 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
3987 &m_brcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].OsResource,
3988 CodechalDbgAttr::attrInput,
3989 "ConstData",
3990 m_brcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwPitch * m_brcBuffers.sBrcConstantDataBuffer[m_currRecycledBufIdx].dwHeight,
3991 0,
3992 CODECHAL_MEDIA_STATE_BRC_UPDATE));
3993
3994 // PAK statistics buffer is only dumped for BrcUpdate kernel input
3995 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
3996 &m_brcBuffers.resBrcPakStatisticBuffer[0],
3997 CodechalDbgAttr::attrInput,
3998 "PakStats",
3999 m_brcPakStatisticsSize,
4000 0,
4001 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4002
4003 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4004 &m_brcBuffers.sMeBrcDistortionBuffer.OsResource,
4005 CodechalDbgAttr::attrInput,
4006 "BrcDist",
4007 m_brcBuffers.sMeBrcDistortionBuffer.dwPitch * m_brcBuffers.sMeBrcDistortionBuffer.dwHeight,
4008 m_brcBuffers.dwMeBrcDistortionBottomFieldOffset,
4009 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4010
4011 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4012 &m_brcBuffers.resBrcHistoryBuffer,
4013 CodechalDbgAttr::attrInput,
4014 "HistoryRead",
4015 m_brcHistoryBufferSize,
4016 0,
4017 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4018 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4019 &m_resMbStatsBuffer,
4020 CodechalDbgAttr::attrInput,
4021 "MBStatsSurf",
4022 m_hwInterface->m_avcMbStatBufferSize,
4023 0,
4024 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4025
4026 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4027 &m_brcBuffers.resBrcPicHeaderInputBuffer,
4028 CodechalDbgAttr::attrInput,
4029 "PicHeaderRead",
4030 CODEC_ENCODE_MPEG2_BRC_PIC_HEADER_SURFACE_SIZE,
4031 0,
4032 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4033 )
4034
4035 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
4036 m_stateHeapInterface,
4037 kernelState));
4038 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
4039 {
4040 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
4041 m_stateHeapInterface));
4042
4043 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
4044 &cmdBuffer,
4045 nullptr));
4046 }
4047
4048 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(
4049 &cmdBuffer,
4050 m_singleTaskPhaseSupported,
4051 m_lastTaskInPhase));
4052
4053 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4054
4055 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
4056 {
4057 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
4058 m_osInterface,
4059 &cmdBuffer,
4060 m_renderContextUsesNullHw));
4061 m_lastTaskInPhase = false;
4062 }
4063
4064 return eStatus;
4065 }
ExecuteKernelFunctions()4066 MOS_STATUS CodechalEncodeMpeg2::ExecuteKernelFunctions()
4067 {
4068 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4069
4070 CODECHAL_ENCODE_FUNCTION_ENTER;
4071
4072 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
4073 m_rawSurfaceToEnc,
4074 CodechalDbgAttr::attrEncodeRawInputSurface,
4075 "SrcSurf")));
4076
4077 m_firstTaskInPhase = true;
4078 m_lastTaskInPhase = !m_singleTaskPhaseSupported;
4079 m_lastEncPhase = false;
4080
4081 UpdateSSDSliceCount();
4082
4083 // Csc, Downscaling, and/or 10-bit to 8-bit conversion
4084 // Scaling is only used to calculate distortions in case of Mpeg2
4085 CODECHAL_ENCODE_CHK_NULL_RETURN(m_cscDsState);
4086
4087 CodechalEncodeCscDs::KernelParams cscScalingKernelParams;
4088 MOS_ZeroMemory(&cscScalingKernelParams, sizeof(cscScalingKernelParams));
4089 cscScalingKernelParams.bLastTaskInPhaseCSC =
4090 cscScalingKernelParams.bLastTaskInPhase4xDS = m_pictureCodingType == I_TYPE;
4091
4092 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->KernelFunctions(&cscScalingKernelParams));
4093
4094 // P and B frames distortion calculations
4095 if (m_hmeSupported && (m_pictureCodingType != I_TYPE))
4096 {
4097 m_firstTaskInPhase = !m_singleTaskPhaseSupported;
4098 m_lastTaskInPhase = true;
4099
4100 CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeMeKernel());
4101 }
4102
4103 MOS_SYNC_PARAMS syncParams;
4104
4105 // Scaling and HME are not dependent on the output from PAK
4106 if (m_waitForPak &&
4107 m_semaphoreObjCount &&
4108 !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
4109 {
4110 // Wait on PAK
4111 syncParams = g_cInitSyncParams;
4112 syncParams.GpuContext = m_renderContext;
4113 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4114 syncParams.uiSemaphoreCount = m_semaphoreObjCount;
4115
4116 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4117 m_semaphoreObjCount = 0; //reset
4118 }
4119
4120 m_firstTaskInPhase = true;
4121 if (m_brcEnabled)
4122 {
4123 if (m_pictureCodingType == I_TYPE)
4124 {
4125 // The reset/init is only valid for I frames
4126 if (m_brcInit || m_brcReset)
4127 {
4128 CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeBrcInitResetKernel());
4129 m_firstTaskInPhase = !m_singleTaskPhaseSupported;
4130 }
4131
4132 CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeMbEncKernel(true));
4133 m_firstTaskInPhase = !m_singleTaskPhaseSupported;
4134 }
4135
4136 CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeBrcUpdateKernel());
4137 m_firstTaskInPhase = !m_singleTaskPhaseSupported;
4138 }
4139
4140 m_lastTaskInPhase = true;
4141 m_lastEncPhase = true;
4142 CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeMbEncKernel(false));
4143
4144 if (!Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
4145 {
4146 syncParams = g_cInitSyncParams;
4147 syncParams.GpuContext = m_renderContext;
4148 syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;
4149
4150 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
4151 }
4152
4153 CODECHAL_DEBUG_TOOL(
4154 if (m_hmeEnabled && m_brcEnabled)
4155 {
4156 CODECHAL_ME_OUTPUT_PARAMS meOutputParams;
4157 MOS_ZeroMemory(&meOutputParams, sizeof(CODECHAL_ME_OUTPUT_PARAMS));
4158 meOutputParams.psMeMvBuffer = m_hmeKernel ?
4159 m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMEMVDataBuffer;
4160 meOutputParams.psMeBrcDistortionBuffer =
4161 m_brcDistortionBufferSupported ? &m_brcBuffers.sMeBrcDistortionBuffer : nullptr;
4162 meOutputParams.psMeDistortionBuffer = m_hmeKernel ?
4163 m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMEDistortionBuffer;
4164 meOutputParams.b16xMeInUse = false;
4165 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4166 &meOutputParams.psMeMvBuffer->OsResource,
4167 CodechalDbgAttr::attrOutput,
4168 "MvData",
4169 meOutputParams.psMeMvBuffer->dwHeight *meOutputParams.psMeMvBuffer->dwPitch,
4170 CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64) * (m_downscaledFrameFieldHeightInMb4x * 4) : 0,
4171 CODECHAL_MEDIA_STATE_4X_ME));
4172 if (!m_vdencStreamInEnabled && meOutputParams.psMeBrcDistortionBuffer)
4173 {
4174 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4175 &meOutputParams.psMeBrcDistortionBuffer->OsResource,
4176 CodechalDbgAttr::attrOutput,
4177 "BrcDist",
4178 meOutputParams.psMeBrcDistortionBuffer->dwHeight *meOutputParams.psMeBrcDistortionBuffer->dwPitch,
4179 CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) * MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4), 8) : 0,
4180 CODECHAL_MEDIA_STATE_4X_ME));
4181 if (meOutputParams.psMeDistortionBuffer)
4182 {
4183 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4184 &meOutputParams.psMeDistortionBuffer->OsResource,
4185 CodechalDbgAttr::attrOutput,
4186 "MeDist",
4187 meOutputParams.psMeDistortionBuffer->dwHeight *meOutputParams.psMeDistortionBuffer->dwPitch,
4188 CodecHal_PictureIsBottomField(m_currOriginalPic) ? MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64) * MOS_ALIGN_CEIL((m_downscaledFrameFieldHeightInMb4x * 4 * 10), 8) : 0,
4189 CODECHAL_MEDIA_STATE_4X_ME));
4190 }
4191 }
4192 // dump VDEncStreamin
4193 if (m_vdencStreamInEnabled)
4194 {
4195 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4196 &m_resVdencStreamInBuffer[m_currRecycledBufIdx],
4197 CodechalDbgAttr::attrOutput,
4198 "MvData",
4199 m_picWidthInMb * m_picHeightInMb* CODECHAL_CACHELINE_SIZE,
4200 0,
4201 CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN));
4202 }
4203 }
4204
4205 if(m_mbQpDataEnabled)
4206 {
4207 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4208 &m_mbQpDataSurface.OsResource,
4209 CodechalDbgAttr::attrInput,
4210 "MbQp",
4211 m_mbQpDataSurface.dwHeight*m_mbQpDataSurface.dwPitch,
4212 0,
4213 CODECHAL_MEDIA_STATE_ENC_QUALITY));
4214 }
4215 if (m_brcEnabled)
4216 {
4217 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4218 &m_brcBuffers.resBrcImageStatesWriteBuffer,
4219 CodechalDbgAttr::attrOutput,
4220 "ImgStateWrite",
4221 BRC_IMG_STATE_SIZE_PER_PASS * m_hwInterface->GetMfxInterface()->GetBrcNumPakPasses(),
4222 0,
4223 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4224
4225 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4226 &m_brcBuffers.resBrcHistoryBuffer,
4227 CodechalDbgAttr::attrOutput,
4228 "HistoryWrite",
4229 m_brcHistoryBufferSize,
4230 0,
4231 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4232 if (m_brcBuffers.pMbEncKernelStateInUse)
4233 {
4234 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
4235 CODECHAL_MEDIA_STATE_BRC_UPDATE,
4236 m_brcBuffers.pMbEncKernelStateInUse));
4237 }
4238 if (m_mbencBrcBufferSize > 0)
4239 {
4240 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4241 &m_brcBuffers.resMbEncBrcBuffer,
4242 CodechalDbgAttr::attrOutput,
4243 "MbEncBRCWrite",
4244 m_mbencBrcBufferSize,
4245 0,
4246 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4247 }
4248
4249 CODECHAL_ENCODE_CHK_STATUS_RETURN(
4250 m_debugInterface->DumpBuffer(
4251 &m_brcBuffers.resBrcPicHeaderOutputBuffer,
4252 CodechalDbgAttr::attrOutput,
4253 "PicHeaderWrite",
4254 CODEC_ENCODE_MPEG2_BRC_PIC_HEADER_SURFACE_SIZE,
4255 0,
4256 CODECHAL_MEDIA_STATE_BRC_UPDATE));
4257 }
4258 )
4259
4260 // Reset after BRC Init has been processed
4261 m_brcInit = false;
4262
4263 m_setRequestedEUSlices = false;
4264
4265 // Reset indices for next frame
4266 if (m_brcEnabled)
4267 {
4268 m_mbEncCurbeSetInBrcUpdate = false;
4269 }
4270
4271 return eStatus;
4272 }
4273
ExecutePictureLevel()4274 MOS_STATUS CodechalEncodeMpeg2::ExecutePictureLevel()
4275 {
4276 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4277
4278 CODECHAL_ENCODE_FUNCTION_ENTER;
4279
4280 PerfTagSetting perfTag;
4281 perfTag.Value = 0;
4282 perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
4283 perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE;
4284 perfTag.PictureCodingType = m_pictureCodingType;
4285 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
4286
4287 // set MFX_PIPE_MODE_SELECT values
4288 MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
4289 pipeModeSelectParams.Mode = m_mode;
4290 pipeModeSelectParams.bStreamOutEnabled = true;
4291 bool suppressReconPic =
4292 (!m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) &&
4293 m_suppressReconPicSupported;
4294 pipeModeSelectParams.bPreDeblockOutEnable = !suppressReconPic;
4295 pipeModeSelectParams.bPostDeblockOutEnable = 0;
4296
4297 // set MFX_PIPE_BUF_ADDR_STATE values
4298 MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
4299 pipeBufAddrParams.Mode = m_mode;
4300 pipeBufAddrParams.psPreDeblockSurface = &m_reconSurface;
4301
4302 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
4303 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetPipeBufAddr(&pipeBufAddrParams));
4304
4305 pipeBufAddrParams.psPostDeblockSurface = &m_reconSurface;
4306 pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak;
4307 pipeBufAddrParams.presStreamOutBuffer = &m_resStreamOutBuffer[m_currRecycledBufIdx];
4308 pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resDeblockingFilterRowStoreScratchBuffer;
4309
4310 // Setting invalid entries to nullptr
4311 for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
4312 {
4313 pipeBufAddrParams.presReferences[i]= nullptr;
4314 }
4315
4316 //divide by two to account for interlace. for now only 0 and 1 will be valid.
4317 for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC / 2; i++)
4318 {
4319 if (m_picIdx[i].bValid)
4320 {
4321 uint8_t picIdx = m_picIdx[i].ucPicIdx;
4322 CodecHalGetResourceInfo(
4323 m_osInterface,
4324 &(m_refList[picIdx]->sRefReconBuffer));
4325 pipeBufAddrParams.presReferences[i] = &(m_refList[picIdx]->sRefReconBuffer.OsResource);
4326
4327 //HSW MPEG2 Interlaced VME refine, need extra references
4328 pipeBufAddrParams.presReferences[i + 2] = &(m_refList[picIdx]->sRefReconBuffer.OsResource);
4329
4330 CODECHAL_DEBUG_TOOL(
4331 CODECHAL_ENCODE_CHK_NULL_RETURN(m_debugInterface);
4332
4333 MOS_SURFACE refSurface;
4334 MOS_ZeroMemory(&refSurface, sizeof(refSurface));
4335 refSurface.Format = Format_NV12;
4336 refSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
4337 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
4338 m_osInterface,
4339 &refSurface));
4340
4341 m_debugInterface->m_refIndex = (uint16_t)i;
4342 std::string refSurfName = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
4343 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
4344 &refSurface,
4345 CodechalDbgAttr::attrReferenceSurfaces,
4346 refSurfName.c_str()));)
4347 }
4348 }
4349
4350 // set MFX_SURFACE_STATE values
4351 MHW_VDBOX_SURFACE_PARAMS surfaceParams;
4352 MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
4353 surfaceParams.Mode = m_mode;
4354
4355 // set MFX_IND_OBJ_BASE_ADDR_STATE values
4356 // MPEG2 doesn't really use presMvObjectBuffer, different from AVC, the MV Data portion of the bitstream is loaded as part of MB control data
4357 MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
4358 MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
4359 indObjBaseAddrParams.Mode = CODECHAL_ENCODE_MODE_MPEG2;
4360 indObjBaseAddrParams.presMvObjectBuffer = &m_resMbCodeSurface;
4361 indObjBaseAddrParams.dwMvObjectOffset = m_mvOffset + m_mvBottomFieldOffset;
4362 indObjBaseAddrParams.dwMvObjectSize = m_mbCodeSize - m_mvOffset;
4363 indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
4364 indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound;
4365
4366 // set MFX_BSP_BUF_BASE_ADDR_STATE values
4367 MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
4368 MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
4369 bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resMPCRowStoreScratchBuffer;
4370
4371 //Set MFX_MPEG2_PIC_STATE command
4372 MHW_VDBOX_MPEG2_PIC_STATE mpeg2PicState;
4373 MOS_ZeroMemory(&mpeg2PicState, sizeof(mpeg2PicState));
4374 mpeg2PicState.pEncodeMpeg2PicParams = m_picParams;
4375 mpeg2PicState.pEncodeMpeg2SeqParams = m_seqParams;
4376 mpeg2PicState.wPicWidthInMb = m_picWidthInMb;
4377 mpeg2PicState.wPicHeightInMb = m_picHeightInMb;
4378 mpeg2PicState.ppRefList = &(m_refList[0]);
4379 mpeg2PicState.bBrcEnabled = m_brcEnabled;
4380 mpeg2PicState.bTrellisQuantEnable = false;
4381 mpeg2PicState.ucKernelMode = m_kernelMode;
4382
4383 m_hwInterface->m_numRequestedEuSlices = (m_brcEnabled &&
4384 m_sliceStateEnable &&
4385 ((m_frameHeight * m_frameWidth) >= m_hwInterface->m_mpeg2SSDResolutionThreshold)) ?
4386 m_sliceShutdownRequestState : m_sliceShutdownDefaultState;
4387
4388 MHW_VDBOX_QM_PARAMS qmParams;
4389 qmParams.Standard = CODECHAL_MPEG2;
4390 qmParams.Mode = CODECHAL_ENCODE_MODE_MPEG2;
4391 qmParams.pMpeg2IqMatrix = (CodecMpeg2IqMatrix *)m_qMatrixParams;
4392
4393 MHW_VDBOX_QM_PARAMS fqmParams;
4394 fqmParams.Standard = CODECHAL_MPEG2;
4395 fqmParams.Mode = CODECHAL_ENCODE_MODE_MPEG2;
4396 fqmParams.pMpeg2IqMatrix = (CodecMpeg2IqMatrix *)m_qMatrixParams;
4397
4398 MOS_COMMAND_BUFFER cmdBuffer;
4399 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4400
4401 // Send command buffer header at the beginning (OS dependent)
4402 if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
4403 {
4404 // frame tracking tag is only added in the last command buffer header
4405 auto requestFrameTracking =
4406 m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
4407 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
4408
4409 m_hwInterface->m_numRequestedEuSlices = CODECHAL_SLICE_SHUTDOWN_DEFAULT;
4410 }
4411
4412 if (m_currPass)
4413 {
4414 // Insert conditional batch buffer end
4415 MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
4416 MOS_ZeroMemory(
4417 &miConditionalBatchBufferEndParams,
4418 sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
4419
4420 miConditionalBatchBufferEndParams.presSemaphoreBuffer =
4421 &m_encodeStatusBuf.resStatusBuffer;
4422 miConditionalBatchBufferEndParams.dwOffset =
4423 (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
4424 m_encodeStatusBuf.dwImageStatusMaskOffset +
4425 (sizeof(uint32_t) * 2);
4426 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
4427 &cmdBuffer,
4428 &miConditionalBatchBufferEndParams));
4429 }
4430
4431 if (!m_currPass && m_osInterface->bTagResourceSync)
4432 {
4433 // This is a solution to solve the sync tag issue: the sync tag write for PAK is inserted at the end of 2nd pass PAK BB
4434 // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning
4435 // of the BB and keep the current frame's tag at the end of the BB. There will be a delay for tag update but it should be fine
4436 // as long as Dec/VP/Enc won't depend on this PAK so soon.
4437 MOS_RESOURCE globalGpuContextSyncTagBuffer;
4438 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
4439 m_osInterface,
4440 &globalGpuContextSyncTagBuffer));
4441
4442 uint32_t statusTag = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
4443 MHW_MI_STORE_DATA_PARAMS params;
4444 params.pOsResource = &globalGpuContextSyncTagBuffer;
4445 params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
4446 params.dwValue = (statusTag > 0)? (statusTag - 1) : 0;
4447 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, ¶ms));
4448 }
4449
4450 CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4451
4452 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
4453
4454 // Ref surface
4455 surfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID;
4456 surfaceParams.psSurface = &m_reconSurface;
4457 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
4458 // Src surface
4459 surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID;
4460 surfaceParams.psSurface = m_rawSurfaceToPak;
4461 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
4462
4463 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
4464
4465 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
4466
4467 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
4468
4469 if (m_brcEnabled)
4470 {
4471 MHW_BATCH_BUFFER batchBuffer;
4472 MOS_ZeroMemory(&batchBuffer, sizeof(batchBuffer));
4473 batchBuffer.OsResource = m_brcBuffers.resBrcImageStatesWriteBuffer;
4474 batchBuffer.dwOffset = m_currPass * BRC_IMG_STATE_SIZE_PER_PASS;
4475 batchBuffer.bSecondLevel = true;
4476
4477 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
4478 &cmdBuffer,
4479 &batchBuffer));
4480 }
4481 else
4482 {
4483 auto picStateCmdStart = cmdBuffer.pCmdPtr;
4484 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxMpeg2PicCmd(&cmdBuffer, &mpeg2PicState));
4485
4486 CODECHAL_DEBUG_TOOL(
4487 auto picStateCmdEnd = cmdBuffer.pCmdPtr;
4488 uint32_t picStateCmdSize = ((uint32_t)(picStateCmdEnd - picStateCmdStart))*sizeof(uint32_t);
4489 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpData(
4490 (void *)picStateCmdStart,
4491 picStateCmdSize,
4492 CodechalDbgAttr::attrPicParams,
4493 "PicState")));
4494 }
4495
4496 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams));
4497
4498 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams));
4499
4500 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4501
4502 return eStatus;
4503
4504 }
4505
SendSliceParams(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_SLICE_STATE params)4506 MOS_STATUS CodechalEncodeMpeg2::SendSliceParams(
4507 PMOS_COMMAND_BUFFER cmdBuffer,
4508 PMHW_VDBOX_MPEG2_SLICE_STATE params)
4509 {
4510 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4511
4512 CODECHAL_ENCODE_FUNCTION_ENTER;
4513
4514 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4515 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
4516 CODECHAL_ENCODE_CHK_NULL_RETURN(params->presDataBuffer);
4517 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
4518 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSlcData);
4519
4520 if (params->pSlcData->SliceGroup & SLICE_GROUP_START)
4521 {
4522 // add Mpeg2 Slice group commands
4523 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfcMpeg2SliceGroupCmd(cmdBuffer, params));
4524 MHW_BATCH_BUFFER secondLevelBatchBuffer;
4525 if (params->bBrcEnabled && params->dwSliceIndex == 0)
4526 {
4527 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
4528 secondLevelBatchBuffer.OsResource = *(params->presPicHeaderBBSurf);
4529 secondLevelBatchBuffer.dwOffset = 0;
4530 secondLevelBatchBuffer.bSecondLevel = true;
4531 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
4532 }
4533 else
4534 {
4535 // Insert pre-slice headers
4536 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
4537 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
4538 pakInsertObjectParams.bLastHeader = true;
4539 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
4540 pakInsertObjectParams.dwBitSize = params->dwLength;
4541 pakInsertObjectParams.dwOffset = params->dwOffset;
4542
4543 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(cmdBuffer, nullptr, &pakInsertObjectParams));
4544 }
4545
4546 // Insert Batch Buffer Start command to send Mpeg2_PAK_OBJ data for MBs in this slice
4547 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
4548 secondLevelBatchBuffer.OsResource = *params->presDataBuffer;
4549 secondLevelBatchBuffer.dwOffset = params->dwDataBufferOffset;
4550 secondLevelBatchBuffer.bSecondLevel = true;
4551
4552 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
4553 }
4554
4555 return eStatus;
4556 }
4557
ExecuteSliceLevel()4558 MOS_STATUS CodechalEncodeMpeg2::ExecuteSliceLevel()
4559 {
4560 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4561
4562 CODECHAL_ENCODE_FUNCTION_ENTER;
4563
4564 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);
4565
4566 auto cpInterface = m_hwInterface->GetCpInterface();
4567
4568 MOS_COMMAND_BUFFER cmdBuffer;
4569 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4570
4571 if (m_osInterface->osCpInterface->IsCpEnabled())
4572 {
4573 MHW_CP_SLICE_INFO_PARAMS sliceInfoParam;
4574 sliceInfoParam.bLastPass = (m_currPass == m_numPasses) ? true : false;
4575 CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->SetMfxProtectionState(m_mfxInterface->IsDecodeInUse(), &cmdBuffer, nullptr, &sliceInfoParam));
4576
4577 CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->UpdateParams(false));
4578 }
4579
4580 MHW_VDBOX_MPEG2_SLICE_STATE sliceState;
4581 MOS_ZeroMemory(&sliceState, sizeof(sliceState));
4582 sliceState.presDataBuffer = &m_resMbCodeSurface;
4583 sliceState.pMpeg2PicIdx = &(m_picIdx[0]);
4584 sliceState.ppMpeg2RefList = &(m_refList[0]);
4585 sliceState.pEncodeMpeg2SeqParams = m_seqParams;
4586 sliceState.pEncodeMpeg2PicParams = m_picParams;
4587 sliceState.pEncodeMpeg2SliceParams = m_sliceParams;
4588 sliceState.pBsBuffer = &m_bsBuffer;
4589 sliceState.bBrcEnabled = m_brcEnabled;
4590 if (m_seqParams->m_forcePanicModeControl == 1) {
4591 sliceState.bRCPanicEnable = !m_seqParams->m_panicModeDisable;
4592 } else {
4593 sliceState.bRCPanicEnable = m_panicEnable;
4594 }
4595 sliceState.presPicHeaderBBSurf = &m_brcBuffers.resBrcPicHeaderOutputBuffer;
4596
4597 for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
4598 {
4599 //we should not need to call pfnPackSliceHeader this it's done by hw
4600 PCODEC_ENCODER_SLCDATA slcData = m_slcData;
4601 CODECHAL_ENCODE_CHK_NULL_RETURN(slcData);
4602 sliceState.dwDataBufferOffset =
4603 m_slcData[slcCount].CmdOffset + m_mbcodeBottomFieldOffset;
4604 sliceState.dwOffset = slcData[slcCount].SliceOffset;
4605 sliceState.dwLength = slcData[slcCount].BitSize;
4606 sliceState.dwSliceIndex = slcCount;
4607 sliceState.bFirstPass = true;
4608 sliceState.bLastPass = false;
4609 sliceState.pSlcData = &slcData[slcCount];
4610 sliceState.bFirstPass = (m_currPass == 0);
4611 sliceState.bLastPass = (m_currPass == m_numPasses);
4612
4613 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSliceParams(&cmdBuffer, &sliceState));
4614 }
4615
4616 // Insert end of stream if set
4617 if (m_lastPicInStream)
4618 {
4619 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
4620 MOS_ZeroMemory(&pakInsertObjectParams,sizeof(pakInsertObjectParams));
4621 pakInsertObjectParams.bLastPicInStream = true;
4622 if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
4623 {
4624 pakInsertObjectParams.bSetLastPicInStreamData = true;
4625 pakInsertObjectParams.dwBitSize = 32; // use dwBitSize for SrcDataEndingBitInclusion
4626 pakInsertObjectParams.dwLastPicInStreamData = (uint32_t)((1 << 16) | startCodeSequenceEnd << 24);
4627 }
4628 else
4629 {
4630 pakInsertObjectParams.bSetLastPicInStreamData = false;
4631 pakInsertObjectParams.dwBitSize = 8; // use dwBitSize for SrcDataEndingBitInclusion
4632 pakInsertObjectParams.dwLastPicInStreamData = 0;
4633 }
4634 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr, &pakInsertObjectParams));
4635 }
4636
4637 CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer));
4638
4639 // BRC PAK statistics different for each pass
4640 if (m_brcEnabled)
4641 {
4642 uint32_t frameOffset =
4643 (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
4644 m_encodeStatusBuf.dwNumPassesOffset + // Num passes offset
4645 sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource
4646
4647 EncodeReadBrcPakStatsParams readBrcPakStatsParams;
4648 readBrcPakStatsParams.pHwInterface = m_hwInterface;
4649 readBrcPakStatsParams.presBrcPakStatisticBuffer = &m_brcBuffers.resBrcPakStatisticBuffer[0];
4650 readBrcPakStatsParams.presStatusBuffer = &m_encodeStatusBuf.resStatusBuffer;
4651 readBrcPakStatsParams.dwStatusBufNumPassesOffset = frameOffset;
4652 readBrcPakStatsParams.ucPass = m_currPass;
4653 readBrcPakStatsParams.VideoContext = m_videoContext;
4654
4655 CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadBrcPakStatistics(
4656 &cmdBuffer,
4657 &readBrcPakStatsParams));
4658 }
4659
4660 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(
4661 &cmdBuffer,
4662 CODECHAL_NUM_MEDIA_STATES));
4663
4664 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
4665 {
4666 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
4667 &cmdBuffer,
4668 nullptr));
4669 }
4670
4671 std::string Pak_pass = "PAK_PASS[" + std::to_string(static_cast<uint32_t>(m_currPass))+"]";
4672 CODECHAL_DEBUG_TOOL(
4673 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
4674 &cmdBuffer,
4675 CODECHAL_NUM_MEDIA_STATES,
4676 Pak_pass.c_str()));
4677
4678 //CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
4679 // m_debugInterface,
4680 // &cmdBuffer));
4681 )
4682
4683 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4684
4685 MOS_SYNC_PARAMS syncParams;
4686 if ((m_currPass == 0) &&
4687 !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
4688 {
4689 syncParams = g_cInitSyncParams;
4690 syncParams.GpuContext = m_videoContext;
4691 syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;
4692
4693 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4694 }
4695
4696 if (!m_singleTaskPhaseSupported ||
4697 m_lastTaskInPhase)
4698 {
4699 CODECHAL_ENCODE_CHK_STATUS_RETURN(SubmitCommandBuffer(&cmdBuffer, m_videoContextUsesNullHw));
4700
4701 CODECHAL_DEBUG_TOOL(
4702 if (m_mmcState)
4703 {
4704 m_mmcState->UpdateUserFeatureKey(&m_reconSurface);
4705 }
4706 )
4707
4708 if ((m_currPass == m_numPasses) &&
4709 m_signalEnc &&
4710 !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
4711 {
4712 // Check if the signal obj count exceeds max m_value
4713 if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED))
4714 {
4715 syncParams = g_cInitSyncParams;
4716 syncParams.GpuContext = m_renderContext;
4717 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4718
4719 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4720 m_semaphoreObjCount--;
4721 }
4722
4723 // signal semaphore
4724 syncParams = g_cInitSyncParams;
4725 syncParams.GpuContext = m_videoContext;
4726 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4727
4728 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
4729 m_semaphoreObjCount++;
4730 }
4731 }
4732
4733 // Reset parameters for next PAK execution
4734 if (m_currPass == m_numPasses)
4735 {
4736 m_newPpsHeader = 0;
4737 m_newSeqHeader = 0;
4738 }
4739
4740 return eStatus;
4741 }
4742
PackSkippedMB(uint32_t mbIncrement)4743 MOS_STATUS CodechalEncodeMpeg2::PackSkippedMB(uint32_t mbIncrement)
4744 {
4745 CODECHAL_ENCODE_FUNCTION_ENTER;
4746
4747 auto bsBuffer = &m_bsBuffer;
4748 //macroblock_escap: The macroblock_escap`e is a fixed bit-string "0000 0001 000" which is used
4749 //when the difference between macroblock_address and previous_macroblock_address is greater than 33
4750 while(mbIncrement > 33)
4751 {
4752 PutBits(bsBuffer,0x08,11);
4753 mbIncrement -= 33;
4754 }
4755 // macroblock_address_increment: This is a variable length coded integer
4756 //which indicates the difference between macroblock_address and previous_macroblock_address
4757 PutBits(bsBuffer, mpeg2AddrIncreamentTbl[mbIncrement].m_code, mpeg2AddrIncreamentTbl[mbIncrement].m_len);
4758 // macroblock_modes()
4759 //macroblock_type: Variable length coded indicator which indicates the method of coding and
4760 //content of the macroblock according to the Tables B-2 through B-8 in spec ISO 13818-2,
4761 //for skip mb, we should choose "MC, NotCoded" for P frame which means there are no quant, backward mv, mb pattern ...
4762 //choose "Bwd,Not Coded" for B frame
4763 if(m_pictureCodingType == P_TYPE)
4764 {
4765 PutBits(bsBuffer, mpeg2MbTypeTbl[1][8].m_code, mpeg2MbTypeTbl[1][8].m_len);
4766 }
4767 else if(m_pictureCodingType == B_TYPE)
4768 {
4769 PutBits(bsBuffer, mpeg2MbTypeTbl[2][4].m_code, mpeg2MbTypeTbl[2][4].m_len);
4770 }
4771 // frame_motion_type This is a two bit code indicating the macroblock prediction, 0b10 -- frame-based
4772 // 0b01 --field based 0b11---Dual-Prime
4773 // attention: currently, mpeg2 encode only support frame encoding and field frame encoding , so Picture_Struct should be 3
4774 if(m_picParams->m_framePredFrameDCT == 0)
4775 {
4776 PutBits(bsBuffer, 2, 2);
4777 }
4778 // motion_vectors // motion_vector ( 0, 0 ) //
4779 // set the MV to zero for skip MB.
4780 PutBits(bsBuffer, mpeg2MvVlcTbl[16 + 0].m_code, mpeg2MvVlcTbl[16 + 0].m_len);
4781 PutBits(bsBuffer, mpeg2MvVlcTbl[16 + 0].m_code, mpeg2MvVlcTbl[16 + 0].m_len);
4782
4783 return MOS_STATUS_SUCCESS;
4784 }
PackSkipSliceData()4785 MOS_STATUS CodechalEncodeMpeg2::PackSkipSliceData()
4786 {
4787 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4788
4789 CODECHAL_ENCODE_FUNCTION_ENTER;
4790
4791 auto slcParams = m_sliceParams;
4792 auto bsBuffer = &m_bsBuffer;
4793
4794 while (bsBuffer->BitOffset)
4795 {
4796 PutBits(bsBuffer, 0, 1);
4797 }
4798
4799 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
4800 {
4801 //slice start code
4802 PutBits(bsBuffer,0x000001,24);
4803 PutBits(bsBuffer,slcParams->m_firstMbY + 1,8);
4804 // quantiser_scale_code
4805 PutBits(bsBuffer,slcParams->m_quantiserScaleCode, 5);
4806 // intra_slice_flag
4807 PutBits(bsBuffer, 1, 1);
4808 // intra_slice
4809 PutBits(bsBuffer, slcParams->m_intraSlice, 1);
4810 // reserved_bits
4811 PutBits(bsBuffer, 0, 7);
4812 // extra_bit_slice
4813 PutBits(bsBuffer, 0, 1);
4814
4815 PackSkippedMB(1);
4816 PackSkippedMB(slcParams->m_numMbsForSlice - 1);
4817 while (bsBuffer->BitOffset)
4818 {
4819 PutBits(bsBuffer, 0, 1);
4820 }
4821 slcParams++;
4822 }
4823
4824 return eStatus;
4825 }
4826
EncodeCopySkipFrame()4827 MOS_STATUS CodechalEncodeMpeg2::EncodeCopySkipFrame()
4828 {
4829 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4830
4831 CODECHAL_ENCODE_FUNCTION_ENTER;
4832
4833 PackSkipSliceData();
4834
4835 CodechalResLock bufLock(m_osInterface, &m_resBitstreamBuffer);
4836 auto data = bufLock.Lock(CodechalResLock::writeOnly);;
4837 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
4838
4839 auto bsBuffer = &m_bsBuffer;
4840 auto bsSize = (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase);
4841
4842 //copy skipped frame
4843 MOS_SecureMemcpy(data, bsSize, bsBuffer->pBase, bsSize);
4844 //unlock bitstream buffer
4845 m_osInterface->pfnUnlockResource( m_osInterface, &m_resBitstreamBuffer );
4846
4847 //get cmd buffer
4848 MOS_COMMAND_BUFFER cmdBuffer;
4849 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4850 //start status report
4851 CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4852
4853 //fill status report
4854 auto encodeStatus = (EncodeStatus*)(m_encodeStatusBuf.pEncodeStatus +
4855 m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize);
4856 encodeStatus->dwMFCBitstreamByteCountPerFrame = bsSize;
4857 encodeStatus->dwHeaderBytesInserted = 0; // set dwHeaderBytesInserted to 0
4858
4859 //end status report
4860 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4861
4862 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4863
4864 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw));
4865
4866 return eStatus;
4867 }
4868
SendMbEncSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,bool mbEncIFrameDistEnabled)4869 MOS_STATUS CodechalEncodeMpeg2::SendMbEncSurfaces(
4870 PMOS_COMMAND_BUFFER cmdBuffer,
4871 bool mbEncIFrameDistEnabled)
4872 {
4873 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4874
4875 CODECHAL_ENCODE_FUNCTION_ENTER;
4876
4877 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4878
4879 PMHW_KERNEL_STATE kernelState;
4880 if (mbEncIFrameDistEnabled)
4881 {
4882 kernelState = &m_brcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST];
4883 }
4884 else
4885 {
4886 // wPictureCodingType: I_TYPE = 1, P_TYPE = 2, B_TYPE = 3
4887 // KernelStates are I: 0, P: 1, B: 2
4888 // m_mbEncKernelStates: I: m_mbEncKernelStates[0], P: m_mbEncKernelStates[1], B: m_mbEncKernelStates[2]
4889 uint32_t krnStateIdx = m_pictureCodingType - 1;
4890
4891 if (m_mbEncForcePictureCodingType)
4892 {
4893 krnStateIdx = m_mbEncForcePictureCodingType - 1;
4894 }
4895
4896 kernelState = &m_mbEncKernelStates[krnStateIdx];
4897 }
4898
4899 auto presMbCodeBuffer = &m_refList[m_currReconstructedPic.FrameIdx]->resRefMbCodeBuffer;
4900 auto presPrevMbCodeBuffer = &m_refList[m_prevMBCodeIdx]->resRefMbCodeBuffer;
4901
4902 // Caution: if PAFF supports added, need to make sure each field get correct surface pointer
4903 // PAK Obj command buffer
4904 uint32_t pakSize = (uint32_t)m_picWidthInMb * m_frameFieldHeightInMb * 16 * 4; // 12 DW for MB + 4 DW for MV
4905 CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
4906
4907 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4908 surfaceCodecParams.presBuffer = presMbCodeBuffer;
4909 surfaceCodecParams.dwSize = pakSize;
4910 surfaceCodecParams.dwOffset = (uint32_t)m_mbcodeBottomFieldOffset;
4911 surfaceCodecParams.dwCacheabilityControl =
4912 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value;
4913 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncPakObj;
4914 surfaceCodecParams.bRenderTarget = true;
4915 surfaceCodecParams.bIsWritable = true;
4916 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4917 m_hwInterface,
4918 cmdBuffer,
4919 &surfaceCodecParams,
4920 kernelState));
4921
4922 // Prev PAK Obj command buffer
4923 pakSize = (uint32_t)m_picWidthInMb * m_frameFieldHeightInMb * 16 * 4; // 12 DW for MB + 4 DW for MV
4924
4925 // verify if the current frame is not the first frame
4926 if (!Mos_ResourceIsNull(presPrevMbCodeBuffer) &&
4927 !m_firstFrame)
4928 {
4929 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4930 surfaceCodecParams.presBuffer = presPrevMbCodeBuffer;
4931 surfaceCodecParams.dwSize = pakSize;
4932 surfaceCodecParams.dwOffset = (uint32_t)m_mbcodeBottomFieldOffset;
4933 surfaceCodecParams.dwCacheabilityControl =
4934 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value;
4935 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncPakObjPrev;
4936 surfaceCodecParams.bRenderTarget = true;
4937 surfaceCodecParams.bIsWritable = true;
4938 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4939 m_hwInterface,
4940 cmdBuffer,
4941 &surfaceCodecParams,
4942 kernelState));
4943 }
4944 auto currPicSurface = mbEncIFrameDistEnabled ? m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : m_rawSurfaceToEnc;
4945
4946 // Current Picture Y
4947 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4948 surfaceCodecParams.bIs2DSurface = true;
4949 surfaceCodecParams.psSurface = currPicSurface;
4950 surfaceCodecParams.dwCacheabilityControl =
4951 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
4952 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncCurrentY;
4953 surfaceCodecParams.dwVerticalLineStride = m_verticalLineStride;
4954 surfaceCodecParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
4955
4956 #ifdef _MMC_SUPPORTED
4957 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4958 #endif
4959 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4960 m_hwInterface,
4961 cmdBuffer,
4962 &surfaceCodecParams,
4963 kernelState));
4964
4965 bool currBottomField = CodecHal_PictureIsBottomField(m_currOriginalPic) ? 1 : 0;
4966 uint8_t vDirection = (CodecHal_PictureIsFrame(m_currOriginalPic)) ? CODECHAL_VDIRECTION_FRAME :
4967 (currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD;
4968
4969 // Current Picture
4970 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4971 surfaceCodecParams.bUseAdvState = true;
4972 surfaceCodecParams.psSurface = currPicSurface;
4973 surfaceCodecParams.dwCacheabilityControl =
4974 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
4975 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncCurrentPic;
4976 surfaceCodecParams.ucVDirection = vDirection;
4977
4978 #ifdef _MMC_SUPPORTED
4979 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4980 #endif
4981 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4982 m_hwInterface,
4983 cmdBuffer,
4984 &surfaceCodecParams,
4985 kernelState));
4986
4987 uint8_t picIdx0 = CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2;
4988 uint8_t picIdx1 = CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2;
4989 bool refL0BottomField = false;
4990 bool refL1BottomField = false;
4991
4992 if (m_picIdx[0].bValid)
4993 {
4994 picIdx0 = m_picIdx[0].ucPicIdx;
4995 refL0BottomField = (CodecHal_PictureIsBottomField(m_currOriginalPic)) ? 1 : 0;
4996 }
4997
4998 if (m_picIdx[1].bValid)
4999 {
5000 picIdx1 = m_picIdx[1].ucPicIdx;
5001 refL1BottomField = (CodecHal_PictureIsBottomField(m_currOriginalPic)) ? 1 : 0;
5002 }
5003
5004 // forward reference
5005 if (picIdx0 < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
5006 {
5007 if (m_verticalLineStride == CODECHAL_VLINESTRIDE_FIELD)
5008 {
5009 vDirection = (refL0BottomField ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
5010 }
5011
5012 // Picture Y
5013 CodecHalGetResourceInfo(m_osInterface, &m_refList[picIdx0]->sRefBuffer);
5014
5015 // Picture Y VME
5016 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5017 surfaceCodecParams.bUseAdvState = true;
5018 surfaceCodecParams.psSurface = &m_refList[picIdx0]->sRefBuffer;
5019 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncForwardPic;
5020 surfaceCodecParams.ucVDirection = vDirection;
5021 surfaceCodecParams.dwCacheabilityControl =
5022 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
5023
5024 #ifdef _MMC_SUPPORTED
5025 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5026 #endif
5027 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5028 m_hwInterface,
5029 cmdBuffer,
5030 &surfaceCodecParams,
5031 kernelState));
5032 }
5033
5034 // backward reference
5035 if (picIdx1 < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
5036 {
5037 if (m_verticalLineStride == CODECHAL_VLINESTRIDE_FIELD)
5038 {
5039 vDirection = (refL1BottomField ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
5040 }
5041
5042 CodecHalGetResourceInfo(m_osInterface, &m_refList[picIdx1]->sRefBuffer);
5043
5044 // Picture Y VME
5045 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5046 surfaceCodecParams.bUseAdvState = true;
5047 surfaceCodecParams.psSurface = &m_refList[picIdx1]->sRefBuffer;
5048 surfaceCodecParams.dwCacheabilityControl =
5049 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
5050 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncBackwardPic;
5051 surfaceCodecParams.ucVDirection = vDirection;
5052
5053 #ifdef _MMC_SUPPORTED
5054 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5055 #endif
5056 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5057 m_hwInterface,
5058 cmdBuffer,
5059 &surfaceCodecParams,
5060 kernelState));
5061 }
5062
5063 // Interlace Frame
5064 if ((CodecHal_PictureIsFrame(m_picParams->m_currOriginalPic)) &&
5065 (m_picParams->m_fieldCodingFlag || m_picParams->m_fieldFrameCodingFlag))
5066 {
5067 // Current Picture Interlace
5068 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5069 surfaceCodecParams.bUseAdvState = true;
5070 surfaceCodecParams.psSurface = currPicSurface;
5071 surfaceCodecParams.dwCacheabilityControl =
5072 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
5073 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncInterlaceFrameCurrentPic;
5074 surfaceCodecParams.ucVDirection = vDirection;
5075
5076 #ifdef _MMC_SUPPORTED
5077 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5078 #endif
5079 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5080 m_hwInterface,
5081 cmdBuffer,
5082 &surfaceCodecParams,
5083 kernelState));
5084
5085 if (picIdx1 < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
5086 {
5087 // Picture Y VME
5088 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5089 surfaceCodecParams.bUseAdvState = true;
5090 surfaceCodecParams.psSurface = &m_refList[picIdx1]->sRefBuffer;
5091 surfaceCodecParams.dwCacheabilityControl =
5092 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
5093 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncInterlaceFrameBackwardPic;
5094 surfaceCodecParams.ucVDirection = vDirection;
5095
5096 #ifdef _MMC_SUPPORTED
5097 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5098 #endif
5099 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5100 m_hwInterface,
5101 cmdBuffer,
5102 &surfaceCodecParams,
5103 kernelState));
5104 }
5105 }
5106
5107 // BRC distortion data buffer for I frame
5108 if (mbEncIFrameDistEnabled)
5109 {
5110 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5111 surfaceCodecParams.bIs2DSurface = true;
5112 surfaceCodecParams.bMediaBlockRW = true;
5113 surfaceCodecParams.psSurface = &m_brcBuffers.sMeBrcDistortionBuffer;
5114 surfaceCodecParams.dwOffset = m_brcBuffers.dwMeBrcDistortionBottomFieldOffset;
5115 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncBrcDistortionSurface;
5116 surfaceCodecParams.bRenderTarget = true;
5117 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5118 m_hwInterface,
5119 cmdBuffer,
5120 &surfaceCodecParams,
5121 kernelState));
5122 }
5123
5124 // MB-control surface for MB level QP, SkipEnable and NonSkipEnable
5125 if (m_mbQpDataEnabled)
5126 {
5127 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5128 surfaceCodecParams.bIs2DSurface = true;
5129 surfaceCodecParams.bMediaBlockRW = true;
5130 surfaceCodecParams.psSurface = &m_mbQpDataSurface;
5131 surfaceCodecParams.dwCacheabilityControl =
5132 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MB_QP_CODEC].Value;
5133 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncMbControl;
5134 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5135 m_hwInterface,
5136 cmdBuffer,
5137 &surfaceCodecParams,
5138 kernelState));
5139 }
5140
5141 return eStatus;
5142 }
5143
SendPrologWithFrameTracking(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTracking,MHW_MI_MMIOREGISTERS * mmioRegister)5144 MOS_STATUS CodechalEncodeMpeg2::SendPrologWithFrameTracking(
5145 PMOS_COMMAND_BUFFER cmdBuffer,
5146 bool frameTracking,
5147 MHW_MI_MMIOREGISTERS *mmioRegister)
5148 {
5149 return CodechalEncoderState::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister);
5150 }
5151
UpdateSSDSliceCount()5152 void CodechalEncodeMpeg2::UpdateSSDSliceCount()
5153 {
5154 m_setRequestedEUSlices = (m_brcEnabled &&
5155 m_sliceStateEnable &&
5156 (m_frameHeight * m_frameWidth) >= m_hwInterface->m_mpeg2SSDResolutionThreshold) ? true : false;
5157
5158 m_hwInterface->m_numRequestedEuSlices = (m_setRequestedEUSlices) ?
5159 m_sliceShutdownRequestState : m_sliceShutdownDefaultState;
5160 }
5161
AddMediaVfeCmd(PMOS_COMMAND_BUFFER cmdBuffer,SendKernelCmdsParams * params)5162 MOS_STATUS CodechalEncodeMpeg2::AddMediaVfeCmd(
5163 PMOS_COMMAND_BUFFER cmdBuffer,
5164 SendKernelCmdsParams *params)
5165 {
5166 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
5167
5168 MHW_VFE_PARAMS vfeParams = {};
5169 vfeParams.pKernelState = params->pKernelState;
5170 vfeParams.eVfeSliceDisable = MHW_VFE_SLICE_ALL;
5171 vfeParams.dwMaximumNumberofThreads = m_encodeVfeMaxThreads;
5172
5173 if (!m_useHwScoreboard)
5174 {
5175 vfeParams.Scoreboard.ScoreboardMask = 0;
5176 }
5177 else
5178 {
5179 vfeParams.Scoreboard.ScoreboardEnable = true;
5180 vfeParams.Scoreboard.ScoreboardType = m_hwScoreboardType;
5181 vfeParams.Scoreboard.ScoreboardMask = 0xFF;
5182
5183 // Scoreboard 0
5184 vfeParams.Scoreboard.ScoreboardDelta[0].x = 0xF;
5185 vfeParams.Scoreboard.ScoreboardDelta[0].y = 0;
5186
5187 // Scoreboard 1
5188 vfeParams.Scoreboard.ScoreboardDelta[1].x = 0;
5189 vfeParams.Scoreboard.ScoreboardDelta[1].y = 0xF;
5190
5191 // Scoreboard 2
5192 vfeParams.Scoreboard.ScoreboardDelta[2].x = 0xE;
5193 vfeParams.Scoreboard.ScoreboardDelta[2].y = 0;
5194 }
5195
5196 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaVfeCmd(cmdBuffer, &vfeParams));
5197
5198 return MOS_STATUS_SUCCESS;
5199 }
5200
5201 #if USE_CODECHAL_DEBUG_TOOL
DumpSeqParams(CodecEncodeMpeg2SequenceParams * seqParams)5202 MOS_STATUS CodechalEncodeMpeg2::DumpSeqParams(
5203 CodecEncodeMpeg2SequenceParams *seqParams)
5204 {
5205 CODECHAL_DEBUG_FUNCTION_ENTER;
5206
5207 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
5208 {
5209 return MOS_STATUS_SUCCESS;
5210 }
5211
5212 CODECHAL_DEBUG_CHK_NULL(seqParams);
5213
5214 std::ostringstream oss;
5215 oss.setf(std::ios::showbase | std::ios::uppercase);
5216
5217 oss << "m_frameWidth: " << +seqParams->m_frameWidth << std::endl;
5218 oss << "m_frameHeight: " << +seqParams->m_frameHeight << std::endl;
5219 oss << "m_profile: " << +seqParams->m_profile << std::endl;
5220 oss << "m_profile: " << +seqParams->m_level << std::endl;
5221 oss << "m_chromaFormat: " << +seqParams->m_chromaFormat << std::endl;
5222 oss << "m_targetUsage: " << +seqParams->m_targetUsage << std::endl;
5223 oss << "m_aratioFrate: " << +seqParams->m_aratioFrate << std::endl;
5224 oss << "m_aspectRatio: " << +seqParams->m_aspectRatio << std::endl;
5225 oss << "m_frameRateCode: " << +seqParams->m_frameRateCode << std::endl;
5226 oss << "m_frameRateExtN: " << +seqParams->m_frameRateExtN << std::endl;
5227 oss << "m_frameRateExtD: " << +seqParams->m_frameRateExtD << std::endl;
5228 oss << "m_bitrate: " << +seqParams->m_bitrate << std::endl;
5229 oss << "m_vbvBufferSize: " << +seqParams->m_vbvBufferSize << std::endl;
5230 oss << "m_progressiveSequence: " << +seqParams->m_progressiveSequence << std::endl;
5231 oss << "m_lowDelay: " << +seqParams->m_lowDelay << std::endl;
5232 oss << "m_resetBRC: " << +seqParams->m_resetBRC << std::endl;
5233 oss << "m_noAcceleratorSPSInsertion: " << +seqParams->m_noAcceleratorSPSInsertion << std::endl;
5234 oss << "m_reserved0: " << +seqParams->m_reserved0 << std::endl;
5235 oss << "m_rateControlMethod: " << +seqParams->m_rateControlMethod << std::endl;
5236 oss << "m_reserved1: " << +seqParams->m_reserved1 << std::endl;
5237 oss << "m_maxBitRate: " << +seqParams->m_maxBitRate << std::endl;
5238 oss << "m_minBitRate: " << +seqParams->m_minBitRate << std::endl;
5239 oss << "m_userMaxFrameSize: " << +seqParams->m_userMaxFrameSize << std::endl;
5240 oss << "m_initVBVBufferFullnessInBit: " << +seqParams->m_initVBVBufferFullnessInBit << std::endl;
5241
5242 const char *fileName = m_debugInterface->CreateFileName(
5243 "_DDIEnc",
5244 CodechalDbgBufferType::bufSeqParams,
5245 CodechalDbgExtType::txt);
5246
5247 std::ofstream ofs(fileName, std::ios::out);
5248 ofs << oss.str();
5249 ofs.close();
5250 return MOS_STATUS_SUCCESS;
5251 }
5252
DumpPicParams(CodecEncodeMpeg2PictureParams * picParams)5253 MOS_STATUS CodechalEncodeMpeg2::DumpPicParams(
5254 CodecEncodeMpeg2PictureParams *picParams)
5255 {
5256 CODECHAL_DEBUG_FUNCTION_ENTER;
5257
5258 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
5259 {
5260 return MOS_STATUS_SUCCESS;
5261 }
5262
5263 CODECHAL_DEBUG_CHK_NULL(picParams);
5264
5265 std::ostringstream oss;
5266 oss.setf(std::ios::showbase | std::ios::uppercase);
5267
5268 oss << "m_currOriginalPic: " << +picParams->m_currOriginalPic.FrameIdx << std::endl;
5269 oss << "m_currReconstructedPic: " << +picParams->m_currReconstructedPic.FrameIdx << std::endl;
5270 oss << "m_pictureCodingType: " << +picParams->m_pictureCodingType << std::endl;
5271 oss << "m_fieldCodingFlag: " << +picParams->m_fieldCodingFlag << std::endl;
5272 oss << "m_fieldFrameCodingFlag: " << +picParams->m_fieldFrameCodingFlag << std::endl;
5273 oss << "m_interleavedFieldBFF: " << +picParams->m_interleavedFieldBFF << std::endl;
5274 oss << "m_progressiveField: " << +picParams->m_progressiveField << std::endl;
5275 oss << "m_numSlice: " << +picParams->m_numSlice << std::endl;
5276 oss << "m_picBackwardPrediction: " << +picParams->m_picBackwardPrediction << std::endl;
5277 oss << "m_bidirectionalAveragingMode: " << +picParams->m_bidirectionalAveragingMode << std::endl;
5278 oss << "m_pic4MVallowed: " << +picParams->m_pic4MVallowed << std::endl;
5279 oss << "m_refFrameList: " << +picParams->m_refFrameList[0].FrameIdx << " " << +picParams->m_refFrameList[1].FrameIdx << std::endl;
5280 oss << "m_useRawPicForRef: " << +picParams->m_useRawPicForRef << std::endl;
5281 oss << "m_statusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl;
5282 oss << "m_alternateScan: " << +picParams->m_alternateScan << std::endl;
5283 oss << "m_intraVlcFormat: " << +picParams->m_intraVlcFormat << std::endl;
5284 oss << "m_qscaleType: " << +picParams->m_qscaleType << std::endl;
5285 oss << "m_concealmentMotionVectors: " << +picParams->m_concealmentMotionVectors << std::endl;
5286 oss << "m_framePredFrameDCT: " << +picParams->m_framePredFrameDCT << std::endl;
5287 oss << "m_disableMismatchControl: " << +picParams->m_disableMismatchControl << std::endl;
5288 oss << "m_intraDCprecision: " << +picParams->m_intraDCprecision << std::endl;
5289 oss << "m_fcode00: " << +picParams->m_fcode00 << std::endl;
5290 oss << "m_fcode01: " << +picParams->m_fcode01 << std::endl;
5291 oss << "m_fcode10: " << +picParams->m_fcode10 << std::endl;
5292 oss << "m_fcode11: " << +picParams->m_fcode11 << std::endl;
5293 oss << "m_lastPicInStream: " << +picParams->m_lastPicInStream << std::endl;
5294 oss << "m_newGop: " << +picParams->m_newGop << std::endl;
5295 oss << "m_gopPicSize: " << +picParams->m_gopPicSize << std::endl;
5296 oss << "m_gopRefDist: " << +picParams->m_gopRefDist << std::endl;
5297 oss << "m_gopOptFlag: " << +picParams->m_gopOptFlag << std::endl;
5298 oss << "m_timeCode: " << +picParams->m_timeCode << std::endl;
5299 oss << "m_temporalReference: " << +picParams->m_temporalReference << std::endl;
5300 oss << "m_vbvDelay: " << +picParams->m_vbvDelay << std::endl;
5301 oss << "m_repeatFirstField: " << +picParams->m_repeatFirstField << std::endl;
5302 oss << "m_compositeDisplayFlag: " << +picParams->m_compositeDisplayFlag << std::endl;
5303 oss << "m_vaxis: " << +picParams->m_vaxis << std::endl;
5304 oss << "m_fieldSequence: " << +picParams->m_fieldSequence << std::endl;
5305 oss << "m_subCarrier: " << +picParams->m_subCarrier << std::endl;
5306 oss << "m_burstAmplitude: " << +picParams->m_burstAmplitude << std::endl;
5307 oss << "m_subCarrierPhase: " << +picParams->m_subCarrierPhase << std::endl;
5308
5309 const char *fileName = m_debugInterface->CreateFileName(
5310 "_DDIEnc",
5311 CodechalDbgBufferType::bufPicParams,
5312 CodechalDbgExtType::txt);
5313
5314 std::ofstream ofs(fileName, std::ios::out);
5315 ofs << oss.str();
5316 ofs.close();
5317 return MOS_STATUS_SUCCESS;
5318 }
5319
DumpSliceParams(CodecEncodeMpeg2SliceParmas * sliceParams)5320 MOS_STATUS CodechalEncodeMpeg2::DumpSliceParams(
5321 CodecEncodeMpeg2SliceParmas *sliceParams)
5322 {
5323 CODECHAL_DEBUG_FUNCTION_ENTER;
5324
5325 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
5326 {
5327 return MOS_STATUS_SUCCESS;
5328 }
5329
5330 CODECHAL_DEBUG_CHK_NULL(sliceParams);
5331
5332 std::ostringstream oss;
5333 oss.setf(std::ios::showbase | std::ios::uppercase);
5334
5335 oss << "m_numMbsForSlice: " << +sliceParams->m_numMbsForSlice << std::endl;
5336 oss << "m_firstMbX: " << +sliceParams->m_firstMbX << std::endl;
5337 oss << "m_firstMbY: " << +sliceParams->m_firstMbY << std::endl;
5338 oss << "m_intraSlice: " << +sliceParams->m_intraSlice << std::endl;
5339 oss << "m_quantiserScaleCode: " << +sliceParams->m_quantiserScaleCode << std::endl;
5340
5341 const char *fileName = m_debugInterface->CreateFileName(
5342 "_DDIEnc",
5343 CodechalDbgBufferType::bufSlcParams,
5344 CodechalDbgExtType::txt);
5345
5346 std::ofstream ofs(fileName, std::ios::out);
5347 ofs << oss.str();
5348 ofs.close();
5349
5350 return MOS_STATUS_SUCCESS;
5351 }
5352
DumpVuiParams(CodecEncodeMpeg2VuiParams * vuiParams)5353 MOS_STATUS CodechalEncodeMpeg2::DumpVuiParams(
5354 CodecEncodeMpeg2VuiParams *vuiParams)
5355 {
5356 CODECHAL_DEBUG_FUNCTION_ENTER;
5357 CODECHAL_DEBUG_CHK_NULL(vuiParams);
5358
5359 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrVuiParams))
5360 {
5361 return MOS_STATUS_SUCCESS;
5362 }
5363
5364 std::ostringstream oss;
5365 oss.setf(std::ios::showbase | std::ios::uppercase);
5366
5367 oss << "m_videoFormat: " << +vuiParams->m_videoFormat << std::endl;
5368 oss << "m_colourDescription: " << +vuiParams->m_colourDescription << std::endl;
5369 oss << "m_colourPrimaries: " << +vuiParams->m_colourPrimaries << std::endl;
5370 oss << "m_transferCharacteristics: " << +vuiParams->m_transferCharacteristics << std::endl;
5371 oss << "m_matrixCoefficients: " << +vuiParams->m_matrixCoefficients << std::endl;
5372 oss << "m_displayHorizontalSize: " << +vuiParams->m_displayHorizontalSize << std::endl;
5373 oss << "m_displayVerticalSize: " << +vuiParams->m_displayVerticalSize << std::endl;
5374
5375 const char *fileName = m_debugInterface->CreateFileName(
5376 "_DDIEnc",
5377 CodechalDbgBufferType::bufVuiParams,
5378 CodechalDbgExtType::txt);
5379
5380 std::ofstream ofs(fileName, std::ios::out);
5381 ofs << oss.str();
5382 ofs.close();
5383 return MOS_STATUS_SUCCESS;
5384 }
5385 #endif
5386
5387 /**************************************************************************
5388 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 6
5389 * 26 degree walking pattern
5390 * 0 1 2 3 4
5391 * -----------------------
5392 * 0 | 0 1 2 4 6
5393 * 1 | 3 5 7 9 11
5394 * 2 | 8 10 12 14 16
5395 * 3 | 13 15 17 19 21
5396 * 4 | 18 20 22 24 26
5397 * 5 | 23 25 27 28 29
5398 ***************************************************************************/
MBWalker(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5399 void CodechalEncodeMpeg2::MBWalker(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5400 {
5401 uint16_t i, j;
5402 uint16_t numMBs = picWidthInMB * picHeightInMB;
5403 uint16_t curX = 0, curY = 0, wflenX, wflenY;
5404 uint16_t wfstart = 0, wflen;
5405 uint16_t walkX, walkY;
5406
5407 wflenY = picHeightInMB - 1;
5408 for (i = 0; i < numMBs; i++)
5409 {
5410 // Get current region length
5411 wflenX = curX / 2;
5412 wflen = (wflenX < wflenY) ? wflenX : wflenY;
5413
5414 mbmap[wfstart] = curY * picWidthInMB + curX;
5415
5416 if (wfstart == (numMBs - 1))
5417 break;
5418
5419 walkX = curX - 2;
5420 walkY = curY + 1;
5421 for (j = 0; j < wflen; j++)
5422 {
5423 mbmap[wfstart + j + 1] = walkY * picWidthInMB + walkX;
5424 walkX -= 2;
5425 walkY++;
5426 }
5427
5428 // Start new region
5429 if (curX == (picWidthInMB - 1))
5430 {
5431 // Right picture boundary reached, adjustment required
5432 curX--;
5433 curY++;
5434 wflenY--;
5435 }
5436 else
5437 {
5438 curX++;
5439 }
5440 wfstart += (wflen + 1);
5441 }
5442 }
5443
5444 /**************************************************************************
5445 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 6
5446 * 45 degree pattern
5447 * 0 1 2 3 4
5448 * -----------------------
5449 * 0 | 0 1 3 6 10
5450 * 1 | 2 4 7 11 15
5451 * 2 | 5 8 12 16 20
5452 * 3 | 9 13 17 21 24
5453 * 4 | 14 18 22 25 27
5454 * 5 | 19 23 26 28 29
5455 ***************************************************************************/
MBWalker45Degree(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5456 void CodechalEncodeMpeg2::MBWalker45Degree(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5457 {
5458 uint16_t i, j;
5459 uint16_t numMBs = picWidthInMB * picHeightInMB;
5460 uint16_t curX = 0, curY = 0, wflenX, wflenY;
5461 uint16_t wfstart = 0, wflen;
5462 uint16_t walkX, walkY;
5463
5464 wflenY = picHeightInMB - 1;
5465 for (i = 0; i < numMBs; i++)
5466 {
5467 // Get current region length
5468 wflenX = curX;
5469 wflen = (wflenX < wflenY) ? wflenX : wflenY;
5470
5471 mbmap[wfstart] = curY * picWidthInMB + curX;
5472
5473 if (wfstart == (numMBs - 1))
5474 break;
5475
5476 walkX = curX - 1;
5477 walkY = curY + 1;
5478 for (j = 0; j < wflen; j++)
5479 {
5480 mbmap[wfstart + j + 1] = walkY * picWidthInMB + walkX;
5481 walkX -= 1;
5482 walkY++;
5483 }
5484
5485 // Start new region
5486 if (curX == (picWidthInMB - 1))
5487 {
5488 // Right picture boundary reached, adjustment required
5489 curY++;
5490 wflenY--;
5491 }
5492 else
5493 {
5494 curX++;
5495 }
5496 wfstart += (wflen + 1);
5497 }
5498 }
5499
5500 /**************************************************************************
5501 * MB sequence in a MBAFF picture with WidthInMB = 5 & HeightInMB = 6
5502 * 26 degree walking pattern
5503 * 0 1 2 3 4
5504 * -----------------------
5505 * 0 | 0 2 4 8 12
5506 * 1 | 1 3 6 10 15
5507 * 2 | 5 9 13 18 22
5508 * 3 | 7 11 16 20 24
5509 * 4 | 14 19 23 26 28
5510 * 5 | 17 21 25 27 29
5511 ***************************************************************************/
MBWalkerMBAFF(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5512 void CodechalEncodeMpeg2::MBWalkerMBAFF(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5513 {
5514 uint16_t i, j, k;
5515 uint16_t numMBs = picWidthInMB * picHeightInMB;
5516 uint16_t curX = 0, curY = 0, wflenX, wflenY;
5517 uint16_t wfstart = 0, wflen;
5518 uint16_t walkX, walkY;
5519
5520 wflenY = picHeightInMB / 2 - 1;
5521 for (i = 0; i < numMBs; i++)
5522 {
5523 // Get current region length
5524 wflenX = curX / 2;
5525 wflen = (wflenX < wflenY) ? wflenX : wflenY;
5526
5527 mbmap[wfstart] = curY * picWidthInMB + curX * 2;
5528 mbmap[wfstart + wflen + 1] = mbmap[wfstart] + 1;
5529
5530 if ((wfstart + wflen + 1) == (numMBs - 1))
5531 break;
5532
5533 walkX = curX - 2;
5534 walkY = curY + 2;
5535 for (j = 0; j < wflen; j++)
5536 {
5537 k = wfstart + j + 1;
5538 mbmap[k] = walkY * picWidthInMB + walkX * 2;
5539 mbmap[k + wflen + 1] = mbmap[k] + 1;
5540 walkX -= 2;
5541 walkY += 2;
5542 }
5543
5544 // Start new region
5545 if (curX == (picWidthInMB - 1))
5546 {
5547 // Right picture boundary reached, adjustment required
5548 curX--;
5549 curY += 2;
5550 wflenY--;
5551 }
5552 else
5553 {
5554 curX++;
5555 }
5556 wfstart += ((wflen + 1) * 2);
5557 }
5558 }
5559
5560 /**************************************************************************
5561 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 5
5562 * Raster scan pattern
5563 * 0 1 2 3 4
5564 * -----------------------
5565 * 0 | 0 1 2 3 4
5566 * 1 | 5 6 7 8 9
5567 * 2 | 10 11 12 13 14
5568 * 3 | 15 16 17 18 19
5569 * 4 | 20 21 22 23 24
5570 ***************************************************************************/
MBWalkerRasterScan(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5571 void CodechalEncodeMpeg2::MBWalkerRasterScan(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5572 {
5573 uint32_t i;
5574 uint32_t numMBs = picWidthInMB * picHeightInMB;
5575
5576 for (i = 0; i < numMBs; i++)
5577 {
5578 mbmap[i] = (uint16_t)i;
5579 }
5580 }
5581
5582 /**************************************************************************
5583 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 5
5584 * Vertical scan pattern
5585 * 0 1 2 3 4
5586 * -----------------------
5587 * 0 | 0 5 10 15 20
5588 * 1 | 1 6 11 16 21
5589 * 2 | 2 7 12 17 22
5590 * 3 | 3 8 13 18 23
5591 * 4 | 4 9 14 19 24
5592 ***************************************************************************/
MBWalkerVerticalScan(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5593 void CodechalEncodeMpeg2::MBWalkerVerticalScan(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5594 {
5595 uint32_t i, j, k;
5596
5597 for (i = 0, k = 0; i < picWidthInMB; i++)
5598 {
5599 for (j = 0; j < picHeightInMB; j++)
5600 {
5601 mbmap[k++] = (uint16_t)(i + j * picWidthInMB);
5602 }
5603 }
5604 }
5605