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 #include "mos_os_cp_interface_specific.h"
31
32 #define CODECHAL_ENCODE_MPEG2_FCODE_X(width) ((width < 200) ? 3 : (width < 500) ? 4 : (width < 1400) ? 5 : 6)
33 #define CODECHAL_ENCODE_MPEG2_FCODE_Y(fcodeX) ((fcodeX > 5) ? 5 : fcodeX)
34
35 //!
36 //! \enum ProfileIdc
37 //! \brief Profile idc
38 //!
39 enum ProfileIdc
40 {
41 highProfile = 0x10,
42 spatialProfile = 0x20,
43 snrProfile = 0x30,
44 mainProfile = 0x40,
45 simpleProfile = 0x50
46 } ;
47
48 //!
49 //! \enum LevelIdc
50 //! \brief Level idc
51 //!
52 enum LevelIdc
53 {
54 levelHighP = 2,
55 levelHigh = 4,
56 levelHigh1440 = 6,
57 levelMain = 8,
58 levelLow = 10
59 } ;
60
61 //!
62 //! \enum StartCode
63 //! \brief Start code
64 //!
65 enum StartCode
66 {
67 startCodePrefix = 0x000001, // bit string 0000 0000 0000 0000 0000 0001
68 startCodePicture = 0x00,
69 // slice_start_code = 0x01..0xAF, it is the slice_vertical_position for the slice
70 // 0xB0, 0xB1, 0xB6 - Reserved
71 startCodeUserData = 0xB2,
72 startCodeSequenceHeader = 0xB3,
73 startCodeSequenceError = 0xB4,
74 startCodeExtension = 0xB5,
75 startCodeSequenceEnd = 0xB7,
76 startCodeGroupStart = 0xB8
77 // system start codes = 0xB9..0xFF
78 } ;
79
80 //!
81 //! \enum BingdingTableOffsetBrcInitReset
82 //! \brief Bingding table offset brc init reset
83 //!
84 enum BingdingTableOffsetBrcInitReset
85 {
86 brcInitResetHistory = 0,
87 brcInitResetDistortion = 1,
88 brcInitResetNumBindingTableEntries = 2
89 } ;
90
91 //!
92 //! \enum BindingTableOffsetBrcUpdate
93 //! \brief Binding table offset brc update
94 //!
95 enum BindingTableOffsetBrcUpdate
96 {
97 brcUpdateHistory = 0,
98 brcUpdatePakStaticOutput = 1,
99 brcUpdatePictureStateRead = 2,
100 brcUpdatePictureStateWrite = 3,
101 brcUpdateMbencCurbeRead = 4,
102 brcUpdateMbencCurbeWrite = 5,
103 brcUpdateDistortion = 6,
104 brcUpdateConstantData = 7,
105 brcUpdatePicHeaderInputData = 8,
106 brcUpdateOutputData = 9,
107 brcUpdateNumBindingTableEntries = 10
108 } ;
109
110 //!
111 //! \class BrcInitResetCurbe
112 //! \brief Brc initialization reset curbe
113 //!
114 class BrcInitResetCurbe
115 {
116 public:
117 //!
118 //! \struct CurbeData
119 //! \brief Curbe data
120 //!
121 struct CurbeData
122 {
123 union
124 {
125 struct
126 {
127 uint32_t m_profileLevelMaxFrame : MOS_BITFIELD_RANGE(0,31);
128 };
129 struct
130 {
131 uint32_t m_value;
132 };
133 } DW0;
134
135 union
136 {
137 struct
138 {
139 uint32_t m_initBufFullInBits : MOS_BITFIELD_RANGE(0,31);
140 };
141 struct
142 {
143 uint32_t m_value;
144 };
145 } DW1;
146
147 union
148 {
149 struct
150 {
151 uint32_t m_bufSizeInBits : MOS_BITFIELD_RANGE(0,31);
152 };
153 struct
154 {
155 uint32_t m_value;
156 };
157 } DW2;
158
159 union
160 {
161 struct
162 {
163 uint32_t m_averageBitRate : MOS_BITFIELD_RANGE(0,31);
164 };
165 struct
166 {
167 uint32_t m_value;
168 };
169 } DW3;
170
171 union
172 {
173 struct
174 {
175 uint32_t m_maxBitRate : MOS_BITFIELD_RANGE(0,31);
176 };
177 struct
178 {
179 uint32_t m_value;
180 };
181 } DW4;
182
183 union
184 {
185 struct
186 {
187 uint32_t m_minBitRate : MOS_BITFIELD_RANGE(0,31);
188 };
189 struct
190 {
191 uint32_t m_value;
192 };
193 } DW5;
194
195 union
196 {
197 struct
198 {
199 uint32_t m_frameRateM : MOS_BITFIELD_RANGE(0,31);
200 };
201 struct
202 {
203 uint32_t m_value;
204 };
205 } DW6;
206
207 union
208 {
209 struct
210 {
211 uint32_t m_frameRateD : MOS_BITFIELD_RANGE(0,31);
212 };
213 struct
214 {
215 uint32_t m_value;
216 };
217 } DW7;
218
219 union
220 {
221 struct
222 {
223 uint32_t m_brcFlag : MOS_BITFIELD_RANGE(0,15);
224 uint32_t m_gopP : MOS_BITFIELD_RANGE(16,31);
225 };
226 struct
227 {
228 uint32_t m_value;
229 };
230 } DW8;
231
232 union
233 {
234 struct
235 {
236 uint32_t m_gopB : MOS_BITFIELD_RANGE(0,15);
237 uint32_t m_frameWidthInBytes : MOS_BITFIELD_RANGE(16,31);
238 };
239 struct
240 {
241 uint32_t m_value;
242 };
243 } DW9;
244
245 union
246 {
247 struct
248 {
249 uint32_t m_frameHeightInBytes : MOS_BITFIELD_RANGE(0,15);
250 uint32_t m_avbrAccuracy : MOS_BITFIELD_RANGE(16,31);
251 };
252 struct
253 {
254 uint32_t m_value;
255 };
256 } DW10;
257
258 union
259 {
260 struct
261 {
262 uint32_t m_avbrConvergence : MOS_BITFIELD_RANGE(0,15);
263 uint32_t m_minQP : MOS_BITFIELD_RANGE(16,31);
264 };
265 struct
266 {
267 uint32_t m_value;
268 };
269 } DW11;
270
271 union
272 {
273 struct
274 {
275 uint32_t m_maxQP : MOS_BITFIELD_RANGE(0,15);
276 uint32_t m_noSlices : MOS_BITFIELD_RANGE(16,31);
277 };
278 struct
279 {
280 uint32_t m_value;
281 };
282 } DW12;
283
284 union
285 {
286 struct
287 {
288 uint32_t m_instantRateThreshold0ForP : MOS_BITFIELD_RANGE(0,7);
289 uint32_t m_instantRateThreshold1ForP : MOS_BITFIELD_RANGE(8,15);
290 uint32_t m_instantRateThreshold2ForP : MOS_BITFIELD_RANGE(16,23);
291 uint32_t m_instantRateThreshold3ForP : MOS_BITFIELD_RANGE(24,31);
292 };
293 struct
294 {
295 uint32_t m_value;
296 };
297 } DW13;
298
299 union
300 {
301 struct
302 {
303 uint32_t m_instantRateThreshold0ForB : MOS_BITFIELD_RANGE(0,7);
304 uint32_t m_instantRateThreshold1ForB : MOS_BITFIELD_RANGE(8,15);
305 uint32_t m_instantRateThreshold2ForB : MOS_BITFIELD_RANGE(16,23);
306 uint32_t m_instantRateThreshold3ForB : MOS_BITFIELD_RANGE(24,31);
307 };
308 struct
309 {
310 uint32_t m_value;
311 };
312 } DW14;
313
314 union
315 {
316 struct
317 {
318 uint32_t m_instantRateThreshold0ForI : MOS_BITFIELD_RANGE(0,7);
319 uint32_t m_instantRateThreshold1ForI : MOS_BITFIELD_RANGE(8,15);
320 uint32_t m_instantRateThreshold2ForI : MOS_BITFIELD_RANGE(16,23);
321 uint32_t m_instantRateThreshold3ForI : MOS_BITFIELD_RANGE(24,31);
322 };
323 struct
324 {
325 uint32_t m_value;
326 };
327 } DW15;
328
329 union
330 {
331 struct
332 {
333 uint32_t m_deviationThreshold0ForPandB : MOS_BITFIELD_RANGE(0,7); // Signed byte
334 uint32_t m_deviationThreshold1ForPandB : MOS_BITFIELD_RANGE(8,15); // Signed byte
335 uint32_t m_deviationThreshold2ForPandB : MOS_BITFIELD_RANGE(16,23); // Signed byte
336 uint32_t m_deviationThreshold3ForPandB : MOS_BITFIELD_RANGE(24,31); // Signed byte
337 };
338 struct
339 {
340 uint32_t m_value;
341 };
342 } DW16;
343
344 union
345 {
346 struct
347 {
348 uint32_t m_deviationThreshold4ForPandB : MOS_BITFIELD_RANGE(0,7); // Signed byte
349 uint32_t m_deviationThreshold5ForPandB : MOS_BITFIELD_RANGE(8,15); // Signed byte
350 uint32_t m_deviationThreshold6ForPandB : MOS_BITFIELD_RANGE(16,23); // Signed byte
351 uint32_t m_deviationThreshold7ForPandB : MOS_BITFIELD_RANGE(24,31); // Signed byte
352 };
353 struct
354 {
355 uint32_t m_value;
356 };
357 } DW17;
358
359 union
360 {
361 struct
362 {
363 uint32_t m_deviationThreshold0ForVBR : MOS_BITFIELD_RANGE(0,7); // Signed byte
364 uint32_t m_deviationThreshold1ForVBR : MOS_BITFIELD_RANGE(8,15); // Signed byte
365 uint32_t m_deviationThreshold2ForVBR : MOS_BITFIELD_RANGE(16,23); // Signed byte
366 uint32_t m_deviationThreshold3ForVBR : MOS_BITFIELD_RANGE(24,31); // Signed byte
367 };
368 struct
369 {
370 uint32_t m_value;
371 };
372 } DW18;
373
374 union
375 {
376 struct
377 {
378 uint32_t m_deviationThreshold4ForVBR : MOS_BITFIELD_RANGE(0,7); // Signed byte
379 uint32_t m_deviationThreshold5ForVBR : MOS_BITFIELD_RANGE(8,15); // Signed byte
380 uint32_t m_deviationThreshold6ForVBR : MOS_BITFIELD_RANGE(16,23); // Signed byte
381 uint32_t m_deviationThreshold7ForVBR : MOS_BITFIELD_RANGE(24,31); // Signed byte
382 };
383 struct
384 {
385 uint32_t m_value;
386 };
387 } DW19;
388
389 union
390 {
391 struct
392 {
393 uint32_t m_deviationThreshold0ForI : MOS_BITFIELD_RANGE(0,7); // Signed byte
394 uint32_t m_deviationThreshold1ForI : MOS_BITFIELD_RANGE(8,15); // Signed byte
395 uint32_t m_deviationThreshold2ForI : MOS_BITFIELD_RANGE(16,23); // Signed byte
396 uint32_t m_deviationThreshold3ForI : MOS_BITFIELD_RANGE(24,31); // Signed byte
397 };
398 struct
399 {
400 uint32_t m_value;
401 };
402 } DW20;
403
404 union
405 {
406 struct
407 {
408 uint32_t m_deviationThreshold4ForI : MOS_BITFIELD_RANGE(0,7); // Signed byte
409 uint32_t m_deviationThreshold5ForI : MOS_BITFIELD_RANGE(8,15); // Signed byte
410 uint32_t m_deviationThreshold6ForI : MOS_BITFIELD_RANGE(16,23); // Signed byte
411 uint32_t m_deviationThreshold7ForI : MOS_BITFIELD_RANGE(24,31); // Signed byte
412 };
413 struct
414 {
415 uint32_t m_value;
416 };
417 } DW21;
418
419 union
420 {
421 struct
422 {
423 uint32_t m_value;
424 };
425 } DW22;
426
427 union
428 {
429 struct
430 {
431 uint32_t m_value;
432 };
433 } DW23;
434
435 union
436 {
437 struct
438 {
439 uint32_t m_value;
440 };
441 } DW24;
442
443 union
444 {
445 struct
446 {
447 uint32_t m_value;
448 };
449 } DW25;
450 }m_curbeData;
451
452 //!
453 //! \brief Constructor
454 //!
455 BrcInitResetCurbe();
456
457 //!
458 //! \brief Destructor
459 //!
~BrcInitResetCurbe()460 ~BrcInitResetCurbe(){};
461
462 static const size_t m_byteSize = sizeof(CurbeData);
463
464 };
465
466 //!
467 //! \struct BrcUpdateCurbe
468 //! \brief BRC update curbe
469 //!
470 class BrcUpdateCurbe
471 {
472 public:
473 //!
474 //! \struct CurbeData
475 //! \brief Curbe data
476 //!
477 struct CurbeData
478 {
479 union
480 {
481 struct
482 {
483 uint32_t m_targetSize : MOS_BITFIELD_RANGE(0,31);
484 };
485 struct
486 {
487 uint32_t m_value;
488 };
489 } DW0;
490
491 union
492 {
493 struct
494 {
495 uint32_t m_frameNumber : MOS_BITFIELD_RANGE(0,31);
496 };
497 struct
498 {
499 uint32_t m_value;
500 };
501 } DW1;
502
503 union
504 {
505 struct
506 {
507 uint32_t m_sliceNumber : MOS_BITFIELD_RANGE(0,31);
508 };
509 struct
510 {
511 uint32_t m_value;
512 };
513 } DW2;
514
515 union
516 {
517 struct
518 {
519 uint32_t m_startGAdjFrame0 : MOS_BITFIELD_RANGE(0,15);
520 uint32_t m_startGAdjFrame1 : MOS_BITFIELD_RANGE(16,31);
521 };
522 struct
523 {
524 uint32_t m_value;
525 };
526 } DW3;
527
528 union
529 {
530 struct
531 {
532 uint32_t m_startGAdjFrame2 : MOS_BITFIELD_RANGE(0,15);
533 uint32_t m_startGAdjFrame3 : MOS_BITFIELD_RANGE(16,31);
534 };
535 struct
536 {
537 uint32_t m_value;
538 };
539 } DW4;
540
541 union
542 {
543 struct
544 {
545 uint32_t m_targetSizeFlag : MOS_BITFIELD_RANGE(0,7);
546 uint32_t m_brcFlag : MOS_BITFIELD_RANGE(8,15);
547 uint32_t m_maxNumPAKs : MOS_BITFIELD_RANGE(16,23);
548 uint32_t m_currFrameType : MOS_BITFIELD_RANGE(24,31);
549 };
550 struct
551 {
552 uint32_t m_value;
553 };
554 } DW5;
555
556 // This offset indicates the byte position of the q_scale_type bit
557 // in the 2nd level batch buffer containing the INSERT_OBJ command
558 // for inserting the picture header data into the bitstream.
559 // This offset includes the 8 bytes of the INSERT command at the
560 // beginning of the buffer.
561 union
562 {
563 struct
564 {
565 uint32_t m_qScaleTypeOffset : MOS_BITFIELD_RANGE(0,15);
566 uint32_t m_vbvDelay : MOS_BITFIELD_RANGE(16,31);
567 };
568 struct
569 {
570 uint32_t m_value;
571 };
572 } DW6;
573
574 // This size is the size of the entire 2nd level batch buffer
575 // containing the INSERT_OBJ command for inserting the
576 // picture header data into the bitstream. It includes the batch buffer end
577 // command at the end of the buffer.
578 union
579 {
580 struct
581 {
582 uint32_t m_picHeaderDataBufferSize :MOS_BITFIELD_RANGE(0,31);
583 };
584 struct
585 {
586 uint32_t m_value;
587 };
588
589 } DW7;
590
591 union
592 {
593 struct
594 {
595 uint32_t m_startGlobalAdjustMult0 : MOS_BITFIELD_RANGE(0,7);
596 uint32_t m_startGlobalAdjustMult1 : MOS_BITFIELD_RANGE(8,15);
597 uint32_t m_startGlobalAdjustMult2 : MOS_BITFIELD_RANGE(16,23);
598 uint32_t m_startGlobalAdjustMult3 : MOS_BITFIELD_RANGE(24,31);
599 };
600 struct
601 {
602 uint32_t m_value;
603 };
604 } DW8;
605
606 union
607 {
608 struct
609 {
610 uint32_t m_startGlobalAdjustMult4 : MOS_BITFIELD_RANGE(0,7);
611 uint32_t m_startGlobalAdjustDiv0 : MOS_BITFIELD_RANGE(8,15);
612 uint32_t m_startGlobalAdjustDiv1 : MOS_BITFIELD_RANGE(16,23);
613 uint32_t m_startGlobalAdjustDiv2 : MOS_BITFIELD_RANGE(24,31);
614 };
615 struct
616 {
617 uint32_t m_value;
618 };
619 } DW9;
620
621 union
622 {
623 struct
624 {
625 uint32_t m_startGlobalAdjustDiv3 : MOS_BITFIELD_RANGE(0,7);
626 uint32_t m_startGlobalAdjustDiv4 : MOS_BITFIELD_RANGE(8,15);
627 uint32_t m_qpThreshold0 : MOS_BITFIELD_RANGE(16,23);
628 uint32_t m_qpThreshold1 : MOS_BITFIELD_RANGE(24,31);
629 };
630 struct
631 {
632 uint32_t m_value;
633 };
634 } DW10;
635
636 union
637 {
638 struct
639 {
640 uint32_t m_qpThreshold2 : MOS_BITFIELD_RANGE(0,7);
641 uint32_t m_qpThreshold3 : MOS_BITFIELD_RANGE(8,15);
642 uint32_t m_gRateRatioThreshold0 : MOS_BITFIELD_RANGE(16,23);
643 uint32_t m_gRateRatioThreshold1 : MOS_BITFIELD_RANGE(24,31);
644 };
645 struct
646 {
647 uint32_t m_value;
648 };
649 } DW11;
650
651 union
652 {
653 struct
654 {
655 uint32_t m_gRateRatioThreshold2 : MOS_BITFIELD_RANGE(0,7);
656 uint32_t m_gRateRatioThreshold3 : MOS_BITFIELD_RANGE(8,15);
657 uint32_t m_gRateRatioThreshold4 : MOS_BITFIELD_RANGE(16,23);
658 uint32_t m_gRateRatioThreshold5 : MOS_BITFIELD_RANGE(24,31);
659 };
660 struct
661 {
662 uint32_t m_value;
663 };
664 } DW12;
665
666 union
667 {
668 struct
669 {
670 uint32_t m_gRateRatioThresholdQP0 : MOS_BITFIELD_RANGE(0,7);
671 uint32_t m_gRateRatioThresholdQP1 : MOS_BITFIELD_RANGE(8,15);
672 uint32_t m_gRateRatioThresholdQP2 : MOS_BITFIELD_RANGE(16,23);
673 uint32_t m_gRateRatioThresholdQP3 : MOS_BITFIELD_RANGE(24,31);
674 };
675 struct
676 {
677 uint32_t m_value;
678 };
679 } DW13;
680
681 union
682 {
683 struct
684 {
685 uint32_t m_gRateRatioThresholdQP4 : MOS_BITFIELD_RANGE(0,7);
686 uint32_t m_gRateRatioThresholdQP5 : MOS_BITFIELD_RANGE(8,15);
687 uint32_t m_gRateRatioThresholdQP6 : MOS_BITFIELD_RANGE(16,23);
688 uint32_t m_forceToSkip : MOS_BITFIELD_RANGE(24,24);
689 uint32_t m_reserved25 : MOS_BITFIELD_RANGE(25,31);
690 };
691 struct
692 {
693 uint32_t m_value;
694 };
695 } DW14;
696
697 union
698 {
699 struct
700 {
701 uint32_t m_extraHeaders : MOS_BITFIELD_RANGE(0,15);
702 uint32_t m_intraDcPrecisionOffset : MOS_BITFIELD_RANGE(16,31);
703 };
704 struct
705 {
706 uint32_t m_value;
707 };
708 } DW15;
709
710 union
711 {
712 struct
713 {
714 uint32_t m_value;
715 };
716 } DW16[16];
717
718 union
719 {
720 struct
721 {
722 uint32_t m_bindingTableIndex : MOS_BITFIELD_RANGE(0,31);
723 };
724 struct
725 {
726 uint32_t m_value;
727 };
728 } DW32[10];
729 }m_curbeData;
730
731 //!
732 //! \brief Constructor
733 //!
734 BrcUpdateCurbe();
735
736 //!
737 //! \brief Destructor
738 //!
~BrcUpdateCurbe()739 ~BrcUpdateCurbe(){};
740
741 static const size_t m_byteSize = sizeof(CurbeData);
742
743 } ;
744
745 //!
746 //! \struct VLCode
747 //! \brief VL code
748 //!
749 struct VLCode{
750 uint32_t m_code;
751 uint32_t m_len;
752 };
753
754 //!
755 //! \struct MediaObjectInlineDataMpeg2
756 //! \brief Media object inline data
757 //!
758 struct MediaObjectInlineDataMpeg2
759 {
760 // DW0
761 union
762 {
763 struct
764 {
765 uint32_t m_mbX : 8; //<! in MB unit
766 uint32_t m_mbY : 8; //<! in MB unit
767 uint32_t m_reserved : 16;
768 };
769 struct
770 {
771 uint32_t m_value;
772 };
773 } DW0;
774
775 // uint32_t 1
776 union
777 {
778 struct
779 {
780 uint32_t m_lastMbInSliceGroup : 8;
781 uint32_t m_firstMbInSliceGroup : 8;
782 uint32_t m_lastMbInSlice : 8;
783 uint32_t m_firstMbInSlice : 8;
784 };
785 struct
786 {
787 uint32_t m_value;
788 };
789 } DW1;
790
791 // uint32_t 2
792 union
793 {
794 struct
795 {
796 uint32_t m_batchBufferEnd : 32;
797 };
798 struct
799 {
800 uint32_t m_value;
801 };
802 } DW2;
803 } ;
804
805 //!
806 //! \struct SliceRecord
807 //! \brief Slice record
808 //!
809 struct SliceRecord
810 {
811 // DW 1
812 union
813 {
814 struct
815 {
816 uint32_t m_lastMbInSliceGroup : 8;
817 uint32_t m_firstMbInSliceGroup : 8;
818 uint32_t m_lastMbInSlice : 8;
819 uint32_t m_firstMbInSlice : 8;
820 };
821 struct
822 {
823 uint32_t m_value;
824 };
825 } DW1;
826
827 // DW 2
828 union
829 {
830 struct
831 {
832 uint32_t m_batchBufferEnd : 32;
833 };
834 struct
835 {
836 uint32_t m_value;
837 };
838 } DW2;
839 } ;
840
841 /* VL codes for macroblock_address_increment ISO/IEC 13818-2, B.1, Table B-1. */
842 static const VLCode mpeg2AddrIncreamentTbl[35] =
843 {
844 { 0x00, 0 }, // forbidden m_value
845 { 0x01, 1 },
846 { 0x03, 3 }, { 0x02, 3 },
847 { 0x03, 4 }, { 0x02, 4 },
848 { 0x03, 5 }, { 0x02, 5 },
849 { 0x07, 7 }, { 0x06, 7 },
850 { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 }, { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 },
851 { 0x17, 10 }, { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 }, { 0x12, 10 },
852 { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 }, { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 }, { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 }, { 0x18, 11 },
853 { 0x08, 11 } // macroblock_escape
854 };
855
856 /* VL codes for macroblock_type ISO/IEC 13818-2, B.2, Tables B-2, B-3, B-4. */
857 static const VLCode mpeg2MbTypeTbl[3][32] =
858 {
859 /* I */
860 {
861 { 0x00, 0 }, { 0x01, 1 }, { 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 { 0x00, 0 }, { 0x01, 2 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
864 { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }
865 },
866 /* P */
867 {
868 { 0x00, 0 }, { 0x03, 5 }, { 0x01, 2 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
869 { 0x01, 3 }, { 0x00, 0 }, { 0x01, 1 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
870 { 0x00, 0 }, { 0x01, 6 }, { 0x01, 5 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 },
871 { 0x00, 0 }, { 0x00, 0 }, { 0x02, 5 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }
872 },
873 /* B */
874 {
875 { 0x00, 0 }, { 0x03, 5 }, { 0x00, 0 }, { 0x00, 0 }, { 0x02, 3 }, { 0x00, 0 }, { 0x03, 3 }, { 0x00, 0 },
876 { 0x02, 4 }, { 0x00, 0 }, { 0x03, 4 }, { 0x00, 0 }, { 0x02, 2 }, { 0x00, 0 }, { 0x03, 2 }, { 0x00, 0 },
877 { 0x00, 0 }, { 0x01, 6 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x02, 6 }, { 0x00, 0 },
878 { 0x00, 0 }, { 0x00, 0 }, { 0x03, 6 }, { 0x00, 0 }, { 0x00, 0 }, { 0x00, 0 }, { 0x02, 5 }, { 0x00, 0 }
879 }
880 };
881
882 /* VL codes for motion_code+16 ISO/IEC 13818-2, B.4, Table B-10. */
883 static const VLCode mpeg2MvVlcTbl[33] =
884 {
885 // negative motion_code
886 { 0x19, 11 }, { 0x1b, 11 }, { 0x1d, 11 }, { 0x1f, 11 }, { 0x21, 11 }, { 0x23, 11 },
887 { 0x13, 10 }, { 0x15, 10 }, { 0x17, 10 },
888 { 0x07, 8 }, { 0x09, 8 }, { 0x0b, 8 },
889 { 0x07, 7 },
890 { 0x03, 5 },
891 { 0x03, 4 },
892 { 0x03, 3 },
893 // zero motion_code
894 { 0x01, 1 },
895 // positive motion_code
896 { 0x02, 3 },
897 { 0x02, 4 },
898 { 0x02, 5 },
899 { 0x06, 7 },
900 { 0x0a, 8 }, { 0x08, 8 }, { 0x06, 8 },
901 { 0x16, 10 }, { 0x14, 10 }, { 0x12, 10 },
902 { 0x22, 11 }, { 0x20, 11 }, { 0x1e, 11 }, { 0x1c, 11 }, { 0x1a, 11 }, { 0x18, 11 }
903 };
904
BrcInitResetCurbe()905 BrcInitResetCurbe::BrcInitResetCurbe()
906 {
907 CODECHAL_ENCODE_FUNCTION_ENTER;
908
909 MOS_ZeroMemory(&m_curbeData, m_byteSize);
910
911 m_curbeData.DW10.m_avbrAccuracy = 30;
912 m_curbeData.DW11.m_avbrConvergence = 150;
913 m_curbeData.DW11.m_minQP = 1;
914 m_curbeData.DW12.m_maxQP = 112;
915 m_curbeData.DW12.m_noSlices = 1;
916 m_curbeData.DW13.m_instantRateThreshold0ForP = 30;
917 m_curbeData.DW13.m_instantRateThreshold1ForP = 50;
918 m_curbeData.DW13.m_instantRateThreshold2ForP = 70;
919 m_curbeData.DW13.m_instantRateThreshold3ForP = 120;
920 m_curbeData.DW14.m_instantRateThreshold0ForB = 25;
921 m_curbeData.DW14.m_instantRateThreshold1ForB = 50;
922 m_curbeData.DW14.m_instantRateThreshold2ForB = 70;
923 m_curbeData.DW14.m_instantRateThreshold3ForB = 120;
924 m_curbeData.DW15.m_instantRateThreshold0ForI = 30;
925 m_curbeData.DW15.m_instantRateThreshold1ForI = 50;
926 m_curbeData.DW15.m_instantRateThreshold2ForI = 90;
927 m_curbeData.DW15.m_instantRateThreshold3ForI = 115;
928 m_curbeData.DW16.m_deviationThreshold0ForPandB = MOS_BITFIELD_VALUE((uint32_t)-45, 8);
929 m_curbeData.DW16.m_deviationThreshold1ForPandB = MOS_BITFIELD_VALUE((uint32_t)-33, 8);
930 m_curbeData.DW16.m_deviationThreshold2ForPandB = MOS_BITFIELD_VALUE((uint32_t)-23, 8);
931 m_curbeData.DW16.m_deviationThreshold3ForPandB = MOS_BITFIELD_VALUE((uint32_t)-15, 8);
932 m_curbeData.DW17.m_deviationThreshold4ForPandB = 15;
933 m_curbeData.DW17.m_deviationThreshold5ForPandB = 23;
934 m_curbeData.DW17.m_deviationThreshold6ForPandB = 35;
935 m_curbeData.DW17.m_deviationThreshold7ForPandB = 45;
936 m_curbeData.DW18.m_deviationThreshold0ForVBR = MOS_BITFIELD_VALUE((uint32_t)-45, 8);
937 m_curbeData.DW18.m_deviationThreshold1ForVBR = MOS_BITFIELD_VALUE((uint32_t)-35, 8);
938 m_curbeData.DW18.m_deviationThreshold2ForVBR = MOS_BITFIELD_VALUE((uint32_t)-25, 8);
939 m_curbeData.DW18.m_deviationThreshold3ForVBR = MOS_BITFIELD_VALUE((uint32_t)-15, 8);
940 m_curbeData.DW19.m_deviationThreshold4ForVBR = 40;
941 m_curbeData.DW19.m_deviationThreshold5ForVBR = 50;
942 m_curbeData.DW19.m_deviationThreshold6ForVBR = 75;
943 m_curbeData.DW19.m_deviationThreshold7ForVBR = 90;
944 m_curbeData.DW20.m_deviationThreshold0ForI = MOS_BITFIELD_VALUE((uint32_t)-40, 8);
945 m_curbeData.DW20.m_deviationThreshold1ForI = MOS_BITFIELD_VALUE((uint32_t)-30, 8);
946 m_curbeData.DW20.m_deviationThreshold2ForI = MOS_BITFIELD_VALUE((uint32_t)-17, 8);
947 m_curbeData.DW20.m_deviationThreshold3ForI = MOS_BITFIELD_VALUE((uint32_t)-10, 8);
948 m_curbeData.DW21.m_deviationThreshold4ForI = 10;
949 m_curbeData.DW21.m_deviationThreshold5ForI = 20;
950 m_curbeData.DW21.m_deviationThreshold6ForI = 33;
951 m_curbeData.DW21.m_deviationThreshold7ForI = 45;
952 m_curbeData.DW25.m_value = 1;
953 }
954
BrcUpdateCurbe()955 BrcUpdateCurbe::BrcUpdateCurbe()
956 {
957 CODECHAL_ENCODE_FUNCTION_ENTER;
958
959 MOS_ZeroMemory(&m_curbeData, m_byteSize);
960
961 m_curbeData.DW3.m_startGAdjFrame0 = 10;
962 m_curbeData.DW3.m_startGAdjFrame1 = 50;
963 m_curbeData.DW4.m_startGAdjFrame2 = 100;
964 m_curbeData.DW4.m_startGAdjFrame3 = 150;
965 m_curbeData.DW7.m_picHeaderDataBufferSize = 0;
966 m_curbeData.DW8.m_startGlobalAdjustMult0 = 1;
967 m_curbeData.DW8.m_startGlobalAdjustMult1 = 1;
968 m_curbeData.DW8.m_startGlobalAdjustMult2 = 3;
969 m_curbeData.DW8.m_startGlobalAdjustMult3 = 2;
970 m_curbeData.DW9.m_startGlobalAdjustMult4 = 1;
971 m_curbeData.DW9.m_startGlobalAdjustDiv0 = 40;
972 m_curbeData.DW9.m_startGlobalAdjustDiv1 = 5;
973 m_curbeData.DW9.m_startGlobalAdjustDiv2 = 5;
974 m_curbeData.DW10.m_startGlobalAdjustDiv3 = 3;
975 m_curbeData.DW10.m_startGlobalAdjustDiv4 = 1;
976 m_curbeData.DW10.m_qpThreshold0 = 7;
977 m_curbeData.DW10.m_qpThreshold1 = 18;
978 m_curbeData.DW11.m_qpThreshold2 = 25;
979 m_curbeData.DW11.m_qpThreshold3 = 37;
980 m_curbeData.DW11.m_gRateRatioThreshold0 = 40;
981 m_curbeData.DW11.m_gRateRatioThreshold1 = 75;
982 m_curbeData.DW12.m_gRateRatioThreshold2 = 97;
983 m_curbeData.DW12.m_gRateRatioThreshold3 = 103;
984 m_curbeData.DW12.m_gRateRatioThreshold4 = 125;
985 m_curbeData.DW12.m_gRateRatioThreshold5 = 160;
986 m_curbeData.DW13.m_gRateRatioThresholdQP0 = MOS_BITFIELD_VALUE((uint32_t)-3, 8);
987 m_curbeData.DW13.m_gRateRatioThresholdQP1 = MOS_BITFIELD_VALUE((uint32_t)-2, 8);
988 m_curbeData.DW13.m_gRateRatioThresholdQP2 = MOS_BITFIELD_VALUE((uint32_t)-1, 8);
989 m_curbeData.DW13.m_gRateRatioThresholdQP3 = 0;
990 m_curbeData.DW14.m_gRateRatioThresholdQP4 = 1;
991 m_curbeData.DW14.m_gRateRatioThresholdQP5 = 2;
992 m_curbeData.DW14.m_gRateRatioThresholdQP6 = 3;
993 m_curbeData.DW14.m_forceToSkip = 1;
994 m_curbeData.DW15.m_value = 0;
995 m_curbeData.DW16[0].m_value = 0x06040200;
996 m_curbeData.DW16[1].m_value = 0x0e0c0a08;
997 m_curbeData.DW16[2].m_value = 0x16141210;
998 m_curbeData.DW16[3].m_value = 0x1e1c1a18;
999 m_curbeData.DW16[4].m_value = 0x26242220;
1000 m_curbeData.DW16[5].m_value = 0x2e2c2a28;
1001 m_curbeData.DW16[6].m_value = 0x36343230;
1002 m_curbeData.DW16[7].m_value = 0x3e3c3a38;
1003 m_curbeData.DW16[8].m_value = 0x03020100;
1004 m_curbeData.DW16[9].m_value = 0x07060504;
1005 m_curbeData.DW16[10].m_value = 0x0e0c0a08;
1006 m_curbeData.DW16[11].m_value = 0x16141210;
1007 m_curbeData.DW16[12].m_value = 0x24201c18;
1008 m_curbeData.DW16[13].m_value = 0x34302c28;
1009 m_curbeData.DW16[14].m_value = 0x50484038;
1010 m_curbeData.DW16[15].m_value = 0x70686058;
1011
1012 for (uint8_t idx = 0; idx < 10 ; idx++)
1013 {
1014 m_curbeData.DW32[idx].m_bindingTableIndex = idx;
1015 }
1016 }
1017
1018 const uint8_t CodechalEncodeMpeg2::m_qpAdjustmentDistThresholdMaxFrameThresholdI[] = {
1019 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x01, 0x02, 0x03, 0x04,
1020 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
1021 0xff, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xfe, 0xff, 0x00, 0x00,
1022 0xfd, 0xfd, 0xff, 0xff, 0x00, 0xfc, 0xfd, 0xfe, 0xff, 0xff,
1023 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x00, 0x04, 0x1e, 0x3c, 0x50,
1024 0x78, 0x8c, 0xc8, 0xff, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x00,
1025 0x00, 0x00, 0x00, 0x00};
1026
1027 const uint8_t CodechalEncodeMpeg2::m_qpAdjustmentDistThresholdMaxFrameThresholdP[] = {
1028 0x01, 0x02, 0x03, 0x04, 0x05, 0x01, 0x01, 0x02, 0x03, 0x04,
1029 0x00, 0x01, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02,
1030 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00,
1031 0xfe, 0xff, 0xff, 0xff, 0x00, 0xfc, 0xfe, 0xff, 0xff, 0x00,
1032 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x04, 0x1e, 0x3c, 0x50,
1033 0x78, 0x8c, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00,
1034 0x00, 0x00, 0x00, 0x00 };
1035
1036 const uint8_t CodechalEncodeMpeg2::m_qpAdjustmentDistThresholdMaxFrameThresholdB[] = {
1037 0x01, 0x01, 0x02, 0x03, 0x04, 0x01, 0x01, 0x01, 0x02, 0x03,
1038 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01,
1039 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
1040 0xfe, 0xff, 0xff, 0xff, 0x00, 0xfd, 0xfe, 0xff, 0xff, 0x01,
1041 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x02, 0x14, 0x28, 0x46,
1042 0x82, 0xa0, 0xc8, 0xff, 0x04, 0x05, 0x06, 0x06, 0x07, 0x00,
1043 0x00, 0x00, 0x00, 0x00 };
1044
1045 const uint8_t CodechalEncodeMpeg2::m_distQpAdjustmentI[] = {
1046 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x00,
1047 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0xff, 0x00,
1048 0x00, 0x00, 0x01, 0x02, 0x02, 0x04, 0x05, 0xff, 0xff, 0x00,
1049 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0xfd, 0xfe, 0xff, 0x00,
1050 0x00, 0x00, 0x01, 0x02, 0x04, 0xfe, 0xfe, 0xff, 0xff, 0x00,
1051 0x00, 0x00, 0x01, 0x03, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0x00,
1052 0x00, 0x00, 0x02, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff,
1053 0x00, 0x01, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
1054 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1055 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1056
1057 const uint8_t CodechalEncodeMpeg2::m_distQpAdjustmentP[] = {
1058 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x00,
1059 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0xff, 0x00,
1060 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0xff, 0xff, 0x00,
1061 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0xfe, 0xff, 0xff, 0x00,
1062 0x00, 0x00, 0x01, 0x01, 0x03, 0xfe, 0xfe, 0xff, 0xff, 0x00,
1063 0x00, 0x00, 0x01, 0x02, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0x00,
1064 0x00, 0x00, 0x02, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff,
1065 0x00, 0x01, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
1066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1068
1069 const uint8_t CodechalEncodeMpeg2::m_distQpAdjustmentB[] = {
1070 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x00,
1071 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x00, 0x00,
1072 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0xff, 0x00, 0x00,
1073 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0xfe, 0xff, 0x00, 0x00,
1074 0x00, 0x00, 0x01, 0x01, 0x02, 0xfe, 0xfe, 0xff, 0x00, 0x00,
1075 0x00, 0x00, 0x01, 0x01, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x00,
1076 0x00, 0x00, 0x01, 0xfc, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0x00,
1077 0x00, 0x00, 0xfb, 0xfc, 0xfd, 0xfe, 0xfe, 0xff, 0xff, 0xff,
1078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1079 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1080
1081 const uint8_t CodechalEncodeMpeg2::m_targetUsageToKernelMode[] = {
1082 encodeNormalMode, encodeNormalMode,
1083 encodeNormalMode, encodeNormalMode,
1084 encodeNormalMode, encodeNormalMode,
1085 encodeNormalMode, encodeNormalMode };
1086
1087 const uint32_t CodechalEncodeMpeg2::m_vmeLutXyP[] = { 0x34262410, 0x46454436 };
1088
1089 const uint32_t CodechalEncodeMpeg2::m_vmeLutXyB[] = { 0x44363410, 0x56555446 };
1090
1091 const uint32_t CodechalEncodeMpeg2::m_vmeSPathP0[] = {
1092 0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x02F1F1F1, 0x1F201111,
1093 0xF1EFFF0C, 0xF01104F1, 0x10FF0A50, 0x000FF1C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1094 };
1095
1096 const uint32_t CodechalEncodeMpeg2::m_vmeSPathP1[] = {
1097 0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0xF1FB06FC, 0x0000D33F, 0x00000000, 0x00000000, 0x00000000,
1098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1099 };
1100
1101 const uint32_t CodechalEncodeMpeg2::m_vmeSPathB0[] = {
1102 0x120FF10F, 0x20E20F1F, 0x201EE2FD, 0x000D02D1, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1103 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1104 };
1105
1106 const uint32_t CodechalEncodeMpeg2::m_vmeSPathB1[] = {
1107 0x120FF10F, 0x20E20F1F, 0x0000E2FD, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1108 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
1109 };
1110
InitMmcState()1111 MOS_STATUS CodechalEncodeMpeg2::InitMmcState()
1112 {
1113 CODECHAL_ENCODE_FUNCTION_ENTER;
1114
1115 #ifdef _MMC_SUPPORTED
1116 m_mmcState = MOS_New(CodechalMmcEncodeMpeg2, m_hwInterface, this);
1117 CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
1118 #endif
1119 return MOS_STATUS_SUCCESS;
1120 }
1121
CodechalEncodeMpeg2(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)1122 CodechalEncodeMpeg2::CodechalEncodeMpeg2(
1123 CodechalHwInterface* hwInterface,
1124 CodechalDebugInterface* debugInterface,
1125 PCODECHAL_STANDARD_INFO standardInfo) :
1126 CodechalEncoderState(hwInterface, debugInterface, standardInfo)
1127 {
1128 CODECHAL_ENCODE_FUNCTION_ENTER;
1129
1130 CODECHAL_ENCODE_ASSERT(hwInterface);
1131 m_hwInterface = hwInterface;
1132 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetOsInterface());
1133 m_osInterface = m_hwInterface->GetOsInterface();
1134 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetMfxInterface());
1135 m_mfxInterface = m_hwInterface->GetMfxInterface();
1136 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetHcpInterface());
1137 m_hcpInterface = m_hwInterface->GetHcpInterface();
1138 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetHucInterface());
1139 m_hucInterface = m_hwInterface->GetHucInterface();
1140 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetVdencInterface());
1141 m_vdencInterface = m_hwInterface->GetVdencInterface();
1142 CODECHAL_ENCODE_ASSERT(m_hwInterface->GetMiInterface());
1143 m_miInterface = m_hwInterface->GetMiInterface();
1144 auto renderInterface = m_hwInterface->GetRenderInterface();
1145 CODECHAL_ENCODE_ASSERT(renderInterface);
1146 m_stateHeapInterface = renderInterface->m_stateHeapInterface;
1147 CODECHAL_ENCODE_ASSERT(m_stateHeapInterface);
1148
1149 MOS_ZeroMemory(&m_picIdx, sizeof(m_picIdx));
1150 MOS_ZeroMemory(&m_refList, sizeof(m_refList));
1151 MOS_ZeroMemory(&m_4xMEMVDataBuffer, sizeof(m_4xMEMVDataBuffer));
1152 MOS_ZeroMemory(&m_batchBufForMEDistBuffer, sizeof(m_batchBufForMEDistBuffer));
1153 MOS_ZeroMemory(&m_mbEncBindingTable, sizeof(m_mbEncBindingTable));
1154 MOS_ZeroMemory(&m_4xMEDistortionBuffer, sizeof(m_4xMEDistortionBuffer));
1155 MOS_ZeroMemory(&m_brcBuffers, sizeof(m_brcBuffers));
1156 MOS_ZeroMemory(&m_mbQpDataSurface, sizeof(m_mbQpDataSurface));
1157
1158 uint8_t i;
1159 for (i = 0; i < CODECHAL_ENCODE_BRC_IDX_NUM; i++)
1160 {
1161 m_brcKernelStates[i] = MHW_KERNEL_STATE();
1162 }
1163 for (i = 0; i < mbEncKernelIdxNum; i++)
1164 {
1165 m_mbEncKernelStates[i] = MHW_KERNEL_STATE();
1166 }
1167
1168 m_interlacedFieldDisabled = true;
1169
1170 // Always true since interlaced field is no longer supported.
1171 m_firstField = true;
1172 m_hwWalker = true;
1173 m_fieldScalingOutputInterleaved = true;
1174 m_hmeSupported = true;
1175 m_kuid = IDR_CODEC_AllMPEG2Enc;
1176
1177 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1178 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1179 MOS_UserFeature_ReadValue_ID(
1180 nullptr,
1181 __MEDIA_USER_FEATURE_VALUE_SINGLE_TASK_PHASE_ENABLE_ID,
1182 &userFeatureData,
1183 m_osInterface->pOsContext);
1184 m_singleTaskPhaseSupported = (userFeatureData.i32Data) ? true : false;
1185
1186 m_hwInterface->GetStateHeapSettings()->dwNumSyncTags = m_numSyncTags;
1187 m_hwInterface->GetStateHeapSettings()->dwDshSize = m_initDshSize;
1188
1189 m_useCmScalingKernel = true;
1190
1191 }
1192
~CodechalEncodeMpeg2()1193 CodechalEncodeMpeg2::~CodechalEncodeMpeg2()
1194 {
1195 MOS_Delete(m_hmeKernel);
1196 }
1197
Initialize(CodechalSetting * codecHalSettings)1198 MOS_STATUS CodechalEncodeMpeg2::Initialize(CodechalSetting * codecHalSettings)
1199 {
1200 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1201
1202 CODECHAL_ENCODE_FUNCTION_ENTER;
1203
1204 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::Initialize(codecHalSettings));
1205
1206 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface);
1207 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hwInterface);
1208 CODECHAL_ENCODE_CHK_NULL_RETURN(m_miInterface);
1209 CODECHAL_ENCODE_CHK_NULL_RETURN(m_stateHeapInterface);
1210
1211 m_frameNumB = 0;
1212
1213 // Offset + Size of MB + size of MV
1214 m_mbCodeStrideInDW = 16;
1215 uint32_t fieldNumMBs = m_picWidthInMb * ((m_picHeightInMb + 1) >> 1);
1216 // 12 DW for MB + 4 DW for MV
1217 m_mbCodeSize = fieldNumMBs * 2 * 16 * sizeof(uint32_t);
1218
1219 #if (_DEBUG || _RELEASE_INTERNAL)
1220 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1221 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1222 MOS_UserFeature_ReadValue_ID(
1223 nullptr,
1224 __MEDIA_USER_FEATURE_VALUE_MPEG2_ENCODE_BRC_DISTORTION_BUFFER_ENABLE_ID,
1225 &userFeatureData,
1226 m_osInterface->pOsContext);
1227 m_brcDistortionBufferSupported = (userFeatureData.i32Data) ? true : false;
1228
1229 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1230 MOS_UserFeature_ReadValue_ID(
1231 nullptr,
1232 __MEDIA_USER_FEATURE_VALUE_MPEG2_SLICE_STATE_ENABLE_ID,
1233 &userFeatureData,
1234 m_osInterface->pOsContext);
1235 m_sliceStateEnable = (userFeatureData.i32Data) ? true : false;
1236
1237 #endif
1238 // Initialize kernel State
1239 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelState());
1240
1241 if (m_singleTaskPhaseSupported)
1242 {
1243 m_maxBtCount = GetMaxBtCount();
1244 }
1245
1246 // Picture Level Commands
1247 m_hwInterface->GetMfxStateCommandsDataSize(
1248 CODECHAL_ENCODE_MODE_MPEG2,
1249 &m_pictureStatesSize,
1250 &m_picturePatchListSize,
1251 0);
1252
1253 // Slice Level Commands (cannot be placed in 2nd level batch)
1254 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1255 CODECHAL_ENCODE_MODE_MPEG2,
1256 &m_sliceStatesSize,
1257 &m_slicePatchListSize,
1258 0);
1259
1260 CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState());
1261
1262 return eStatus;
1263 }
1264
AllocateBuffer(PMOS_RESOURCE buffer,uint32_t bufSize,PCCHAR name)1265 MOS_STATUS CodechalEncodeMpeg2::AllocateBuffer(
1266 PMOS_RESOURCE buffer,
1267 uint32_t bufSize,
1268 PCCHAR name)
1269 {
1270 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1271
1272 CODECHAL_ENCODE_CHK_NULL_RETURN(buffer);
1273
1274 MOS_ALLOC_GFXRES_PARAMS allocParams;
1275 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1276 allocParams.Type = MOS_GFXRES_BUFFER;
1277 allocParams.TileType = MOS_TILE_LINEAR;
1278 allocParams.Format = Format_Buffer;
1279 allocParams.dwBytes = bufSize;
1280 allocParams.pBufName = name;
1281
1282 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
1283 m_osInterface,
1284 &allocParams,
1285 buffer);
1286
1287 if (eStatus != MOS_STATUS_SUCCESS)
1288 {
1289 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
1290 return eStatus;
1291 }
1292
1293 CodechalResLock bufLock(m_osInterface, buffer);
1294 auto data = bufLock.Lock(CodechalResLock::writeOnly);
1295 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1296
1297 MOS_ZeroMemory(data, bufSize);
1298
1299 return eStatus;
1300 }
1301
AllocateBuffer2D(PMOS_SURFACE surface,uint32_t surfWidth,uint32_t surfHeight,PCCHAR name)1302 MOS_STATUS CodechalEncodeMpeg2::AllocateBuffer2D(
1303 PMOS_SURFACE surface,
1304 uint32_t surfWidth,
1305 uint32_t surfHeight,
1306 PCCHAR name)
1307 {
1308 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1309
1310 CODECHAL_ENCODE_CHK_NULL_RETURN(surface);
1311
1312 MOS_ZeroMemory(surface, sizeof(*surface));
1313
1314 surface->TileType = MOS_TILE_LINEAR;
1315 surface->bArraySpacing = true;
1316 surface->Format = Format_Buffer_2D;
1317 surface->dwWidth = MOS_ALIGN_CEIL(surfWidth, 64);
1318 surface->dwHeight = surfHeight;
1319 surface->dwPitch = surface->dwWidth;
1320
1321 MOS_ALLOC_GFXRES_PARAMS AllocParamsForBuffer2D;
1322 MOS_ZeroMemory(&AllocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
1323 AllocParamsForBuffer2D.Type = MOS_GFXRES_2D;
1324 AllocParamsForBuffer2D.TileType = surface->TileType;
1325 AllocParamsForBuffer2D.Format = surface->Format;
1326 AllocParamsForBuffer2D.dwWidth = surface->dwWidth;
1327 AllocParamsForBuffer2D.dwHeight = surface->dwHeight;
1328 AllocParamsForBuffer2D.pBufName = name;
1329
1330 eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
1331 m_osInterface,
1332 &AllocParamsForBuffer2D,
1333 &surface->OsResource);
1334
1335 if (eStatus != MOS_STATUS_SUCCESS)
1336 {
1337 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
1338 return eStatus;
1339 }
1340
1341 surface->dwPitch = (uint32_t)surface->OsResource.pGmmResInfo->GetRenderPitch();
1342
1343 CodechalResLock bufLock(m_osInterface, &surface->OsResource);
1344 auto data = bufLock.Lock(CodechalResLock::writeOnly);
1345 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1346
1347 MOS_ZeroMemory(data, surface->dwPitch * surface->dwHeight);
1348
1349 return eStatus;
1350 }
1351
AllocateBatchBuffer(PMHW_BATCH_BUFFER batchBuffer,uint32_t bufSize,PCCHAR name)1352 MOS_STATUS CodechalEncodeMpeg2::AllocateBatchBuffer(
1353 PMHW_BATCH_BUFFER batchBuffer,
1354 uint32_t bufSize,
1355 PCCHAR name)
1356 {
1357 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1358
1359 CODECHAL_ENCODE_CHK_NULL_RETURN(batchBuffer);
1360
1361 MOS_ZeroMemory(
1362 batchBuffer,
1363 sizeof(MHW_BATCH_BUFFER));
1364
1365 batchBuffer->bSecondLevel = true;
1366
1367 eStatus = Mhw_AllocateBb(
1368 m_osInterface,
1369 batchBuffer,
1370 nullptr,
1371 bufSize);
1372
1373 if (eStatus != MOS_STATUS_SUCCESS)
1374 {
1375 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate %s.", name);
1376 return eStatus;
1377 }
1378
1379 eStatus = Mhw_LockBb(m_osInterface, batchBuffer);
1380
1381 if (eStatus != MOS_STATUS_SUCCESS)
1382 {
1383 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to lock %s.", name);
1384 return eStatus;
1385 }
1386
1387 MOS_ZeroMemory(batchBuffer->pData, bufSize);
1388
1389 eStatus = Mhw_UnlockBb(
1390 m_osInterface,
1391 batchBuffer,
1392 false);
1393
1394 if (eStatus != MOS_STATUS_SUCCESS)
1395 {
1396 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to unlock %s.", name);
1397 return eStatus;
1398 }
1399
1400 return eStatus;
1401 }
1402
AllocateBrcResources()1403 MOS_STATUS CodechalEncodeMpeg2::AllocateBrcResources()
1404 {
1405 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1406
1407 CODECHAL_ENCODE_FUNCTION_ENTER;
1408
1409 // BRC history buffer
1410 uint32_t bufSize = m_brcHistoryBufferSize;
1411 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1412 &m_brcBuffers.resBrcHistoryBuffer,
1413 bufSize,
1414 "BRC History Buffer"));
1415
1416 // PAK Statistics buffer
1417 bufSize = m_brcPakStatisticsSize;
1418 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1419 &m_brcBuffers.resBrcPakStatisticBuffer[0],
1420 bufSize,
1421 "BRC PAK Statistics Buffer"));
1422
1423 // PAK IMG_STATEs buffer
1424 bufSize = BRC_IMG_STATE_SIZE_PER_PASS * m_mfxInterface->GetBrcNumPakPasses();
1425 for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1426 {
1427 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1428 &m_brcBuffers.resBrcImageStatesReadBuffer[i],
1429 bufSize,
1430 "PAK IMG State Read Buffer"));
1431 }
1432
1433 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1434 &m_brcBuffers.resBrcImageStatesWriteBuffer,
1435 bufSize,
1436 "PAK IMG State Write Buffer"));
1437
1438 // Picture header input and output buffers
1439 bufSize = m_brcPicHeaderSurfaceSize;
1440 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1441 &m_brcBuffers.resBrcPicHeaderInputBuffer,
1442 bufSize,
1443 "Picture Header Input Buffer"));
1444 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer(
1445 &m_brcBuffers.resBrcPicHeaderOutputBuffer,
1446 bufSize,
1447 "Picture Header Output Buffer"));
1448
1449 uint32_t surfWidth = m_hwInterface->m_mpeg2BrcConstantSurfaceWidth;
1450 uint32_t surfHeight = m_hwInterface->m_mpeg2BrcConstantSurfaceHeight;
1451 for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1452 {
1453 //BRC Constant Data Surfaces
1454 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1455 &m_brcBuffers.sBrcConstantDataBuffer[i],
1456 surfWidth,
1457 surfHeight,
1458 "BRC Constant Data Buffer"));
1459 }
1460
1461 // BRC Distortion Surface
1462 uint32_t downscaledFieldHeightInMB4x =
1463 (m_downscaledHeightInMb4x + 1) >> 1;
1464 surfWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
1465 surfHeight = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4), 8);
1466 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1467 &m_brcBuffers.sMeBrcDistortionBuffer,
1468 surfWidth,
1469 surfHeight,
1470 "BRC Distortion Surface Buffer"));
1471
1472 // VME batch buffer for distortion surface
1473 for (uint8_t i = 0; i < NUM_ENCODE_BB_TYPE; i++)
1474 {
1475 uint32_t currNumMBs;
1476 if (i == MB_ENC_Frame_BB)
1477 {
1478 currNumMBs = m_downscaledWidthInMb4x * m_downscaledHeightInMb4x;
1479 }
1480 else
1481 {
1482 currNumMBs = m_downscaledWidthInMb4x * downscaledFieldHeightInMB4x;
1483 }
1484
1485 bufSize = m_hwInterface->GetMediaObjectBufferSize(
1486 currNumMBs,
1487 sizeof(MediaObjectInlineDataMpeg2));
1488
1489 AllocateBatchBuffer(&m_batchBufForMEDistBuffer[i], bufSize, "ME Distortion Buffer");
1490 }
1491
1492 return eStatus;
1493 }
1494
AllocateEncResources()1495 MOS_STATUS CodechalEncodeMpeg2::AllocateEncResources()
1496 {
1497 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1498
1499 CODECHAL_ENCODE_FUNCTION_ENTER;
1500
1501 uint32_t downscaledFieldHeightInMB4x = (m_downscaledHeightInMb4x + 1) >> 1;
1502
1503 if (m_hmeSupported)
1504 {
1505 if (m_hmeKernel)
1506 {
1507 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hmeKernel->AllocateResources());
1508 }
1509 else
1510 {
1511 uint32_t bufWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 32), 64); // MediaBlockRW requires pitch multiple of 64 bytes when linear.
1512 uint32_t bufHeight = (m_downscaledHeightInMb4x * 2 * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER);
1513 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1514 &m_4xMEMVDataBuffer,
1515 bufWidth,
1516 bufHeight,
1517 "4xME MV Data Buffer"));
1518
1519 bufWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb4x * 8), 64);
1520 bufHeight = 2 * MOS_ALIGN_CEIL((downscaledFieldHeightInMB4x * 4 * 10), 8);
1521 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBuffer2D(
1522 &m_4xMEDistortionBuffer,
1523 bufWidth,
1524 bufHeight,
1525 "4xME Distortion Buffer"));
1526 }
1527 }
1528
1529 return eStatus;
1530 }
1531
AllocateResources()1532 MOS_STATUS CodechalEncodeMpeg2::AllocateResources()
1533 {
1534 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1535
1536 CODECHAL_ENCODE_FUNCTION_ENTER;
1537
1538 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources());
1539
1540 // Allocate Ref Lists
1541 CodecHalAllocateDataList(
1542 m_refList,
1543 CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);
1544
1545 if (m_encEnabled)
1546 {
1547 eStatus = AllocateEncResources();
1548 if (eStatus != MOS_STATUS_SUCCESS)
1549 {
1550 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate ENC resources.");
1551 return eStatus;
1552 }
1553
1554 eStatus = AllocateBrcResources();
1555 if (eStatus != MOS_STATUS_SUCCESS)
1556 {
1557 CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate BRC resources.");
1558 return eStatus;
1559 }
1560 }
1561
1562 return eStatus;
1563 }
1564
FreeBrcResources()1565 MOS_STATUS CodechalEncodeMpeg2::FreeBrcResources()
1566 {
1567 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1568 CODECHAL_ENCODE_FUNCTION_ENTER;
1569
1570 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcHistoryBuffer))
1571 {
1572 m_osInterface->pfnFreeResource(
1573 m_osInterface,
1574 &m_brcBuffers.resBrcHistoryBuffer);
1575 }
1576
1577 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcPakStatisticBuffer[0]))
1578 {
1579 m_osInterface->pfnFreeResource(
1580 m_osInterface,
1581 &m_brcBuffers.resBrcPakStatisticBuffer[0]);
1582 }
1583
1584 uint32_t i;
1585 for (i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1586 {
1587 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcImageStatesReadBuffer[i]))
1588 {
1589 m_osInterface->pfnFreeResource(
1590 m_osInterface,
1591 &m_brcBuffers.resBrcImageStatesReadBuffer[i]);
1592 }
1593 }
1594
1595 if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcImageStatesWriteBuffer))
1596 {
1597 m_osInterface->pfnFreeResource(
1598 m_osInterface,
1599 &m_brcBuffers.resBrcImageStatesWriteBuffer);
1600 }
1601
1602 for (i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
1603 {
1604 if (!Mos_ResourceIsNull(&m_brcBuffers.sBrcConstantDataBuffer[i].OsResource))
1605 {
1606 m_osInterface->pfnFreeResource(
1607 m_osInterface,
1608 &m_brcBuffers.sBrcConstantDataBuffer[i].OsResource);
1609 }
1610 }
1611
1612 if (!Mos_ResourceIsNull(&m_brcBuffers.sMeBrcDistortionBuffer.OsResource))
1613 {
1614 m_osInterface->pfnFreeResource(
1615 m_osInterface,
1616 &m_brcBuffers.sMeBrcDistortionBuffer.OsResource);
1617 }
1618
1619 if(!Mos_ResourceIsNull(&m_brcBuffers.resBrcPicHeaderInputBuffer))
1620 {
1621 m_osInterface->pfnFreeResource(
1622 m_osInterface,
1623 &m_brcBuffers.resBrcPicHeaderInputBuffer);
1624 }
1625 if(!Mos_ResourceIsNull(&m_brcBuffers.resBrcPicHeaderOutputBuffer))
1626 {
1627 m_osInterface->pfnFreeResource(
1628 m_osInterface,
1629 &m_brcBuffers.resBrcPicHeaderOutputBuffer);
1630 }
1631
1632 for (i = 0; i < NUM_ENCODE_BB_TYPE; i++)
1633 {
1634 if (!Mos_ResourceIsNull(&m_batchBufForMEDistBuffer[i].OsResource))
1635 {
1636 Mhw_FreeBb(m_osInterface, &m_batchBufForMEDistBuffer[i], nullptr);
1637 }
1638 }
1639
1640 return eStatus;
1641 }
1642
FreeEncResources()1643 MOS_STATUS CodechalEncodeMpeg2::FreeEncResources()
1644 {
1645 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1646
1647 CODECHAL_ENCODE_FUNCTION_ENTER;
1648
1649 if (m_hmeSupported)
1650 {
1651 // 4xME ME MV data buffer
1652 if (!Mos_ResourceIsNull(&m_4xMEMVDataBuffer.OsResource))
1653 {
1654 m_osInterface->pfnFreeResource(
1655 m_osInterface,
1656 &m_4xMEMVDataBuffer.OsResource);
1657 }
1658
1659 // 4xME distortion buffer
1660 if (!Mos_ResourceIsNull(&m_4xMEDistortionBuffer.OsResource))
1661 {
1662 m_osInterface->pfnFreeResource(
1663 m_osInterface,
1664 &m_4xMEDistortionBuffer.OsResource);
1665 }
1666 }
1667
1668 return eStatus;
1669
1670 }
1671
FreeResources()1672 void CodechalEncodeMpeg2::FreeResources()
1673 {
1674 CODECHAL_ENCODE_FUNCTION_ENTER;
1675
1676 CodechalEncoderState::FreeResources();
1677
1678 // Release Ref Lists
1679 CodecHalFreeDataList(m_refList, CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2);
1680
1681 if (m_encEnabled)
1682 {
1683 FreeBrcResources();
1684
1685 FreeEncResources();
1686 }
1687 }
1688
CheckProfileAndLevel()1689 MOS_STATUS CodechalEncodeMpeg2::CheckProfileAndLevel()
1690 {
1691 MOS_STATUS eStatus = MOS_STATUS_INVALID_PARAMETER;
1692
1693 CODECHAL_ENCODE_FUNCTION_ENTER;
1694
1695 switch(m_seqParams->m_profile)
1696 {
1697 case highProfile:
1698 case mainProfile:
1699 case simpleProfile:
1700 break;
1701 default:
1702 return eStatus;
1703 break;
1704 }
1705
1706 switch(m_seqParams->m_level)
1707 {
1708 case levelHigh:
1709 case levelHigh1440:
1710 case levelMain:
1711 case levelLow:
1712 case levelHighP:
1713 break;
1714 default:
1715 return eStatus;
1716 break;
1717 }
1718
1719 eStatus = MOS_STATUS_SUCCESS;
1720
1721 return eStatus;
1722 }
1723
SetSequenceStructs()1724 MOS_STATUS CodechalEncodeMpeg2::SetSequenceStructs()
1725 {
1726 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1727
1728 CODECHAL_ENCODE_FUNCTION_ENTER;
1729
1730 m_oriFrameHeight = m_seqParams->m_frameHeight;
1731 m_oriFrameWidth = m_seqParams->m_frameWidth;
1732 if (m_seqParams->m_progressiveSequence)
1733 {
1734 m_picHeightInMb =
1735 (uint16_t)(CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight));
1736 }
1737 else
1738 {
1739 // For interlaced frame, align to 32 pixels.
1740 m_picHeightInMb =
1741 (uint16_t)((CODECHAL_GET_WIDTH_IN_BLOCKS(m_oriFrameHeight, (CODECHAL_MACROBLOCK_WIDTH << 1))) << 1);
1742 }
1743 m_picWidthInMb =
1744 (uint16_t)(CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth));
1745 m_frameWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
1746 m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
1747
1748 // HME Scaling WxH
1749 m_downscaledWidthInMb4x =
1750 CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
1751 m_downscaledHeightInMb4x =
1752 CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
1753 m_downscaledWidth4x =
1754 m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
1755 m_downscaledHeight4x =
1756 m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
1757
1758 MotionEstimationDisableCheck();
1759
1760 m_targetUsage = m_seqParams->m_targetUsage & 0x7;
1761 m_kernelMode = m_targetUsageToKernelMode[m_targetUsage];
1762
1763 CODECHAL_ENCODE_CHK_STATUS_RETURN(CheckProfileAndLevel());
1764
1765 m_brcEnabled = CodecHalIsRateControlBrc(m_seqParams->m_rateControlMethod, CODECHAL_MPEG2);
1766
1767 // Mb Qp data is only enabled for CQP
1768 if (m_brcEnabled)
1769 {
1770 m_mbQpDataEnabled = false;
1771 }
1772
1773 m_brcReset = m_seqParams->m_resetBRC;
1774
1775 m_avbrAccuracy = 30;
1776 m_avbrConvergence = 150;
1777
1778 return eStatus;
1779 }
1780
SetPictureStructs()1781 MOS_STATUS CodechalEncodeMpeg2::SetPictureStructs()
1782 {
1783 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1784
1785 CODECHAL_ENCODE_FUNCTION_ENTER;
1786
1787 if ((m_picParams->m_pictureCodingType < I_TYPE) ||
1788 (m_picParams->m_pictureCodingType > B_TYPE))
1789 {
1790 eStatus = MOS_STATUS_INVALID_PARAMETER;
1791 return eStatus;
1792 }
1793
1794 if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
1795 (!m_picParams->m_useRawPicForRef || m_pakEnabled))
1796 {
1797 eStatus = MOS_STATUS_INVALID_PARAMETER;
1798 return eStatus;
1799 }
1800
1801 // Sync initialize
1802 if ((m_firstFrame) ||
1803 (m_codecFunction == CODECHAL_FUNCTION_ENC) ||
1804 (!m_brcEnabled && m_picParams->m_useRawPicForRef) ||
1805 (!m_brcEnabled && (m_picParams->m_pictureCodingType == I_TYPE)))
1806 {
1807 m_waitForPak = false;
1808 }
1809 else
1810 {
1811 m_waitForPak = true;
1812 }
1813
1814 if (m_codecFunction != CODECHAL_FUNCTION_ENC)
1815 {
1816 m_signalEnc = true;
1817 }
1818 else
1819 {
1820 m_signalEnc = false;
1821 }
1822 m_pictureCodingType = m_picParams->m_pictureCodingType;
1823 m_mbEncForcePictureCodingType = 0;
1824
1825 // f_code checking.
1826 uint32_t fcodeX = CODECHAL_ENCODE_MPEG2_FCODE_X(m_frameWidth);
1827 uint32_t fcodeY = CODECHAL_ENCODE_MPEG2_FCODE_Y(fcodeX);
1828
1829 if (m_pictureCodingType == I_TYPE)
1830 {
1831 if ((m_picParams->m_fcode00 > fcodeX) ||
1832 (m_picParams->m_fcode01 > fcodeY) ||
1833 (m_picParams->m_fcode00 == 0) ||
1834 (m_picParams->m_fcode01 == 0))
1835 {
1836 m_picParams->m_fcode00 = fcodeX;
1837 m_picParams->m_fcode01 = fcodeY;
1838 }
1839 }
1840 else if (m_pictureCodingType == P_TYPE)
1841 {
1842 if ((m_picParams->m_fcode00 > fcodeX) ||
1843 (m_picParams->m_fcode01 > fcodeY) ||
1844 (m_picParams->m_fcode00 == 0) ||
1845 (m_picParams->m_fcode01 == 0))
1846 {
1847 m_picParams->m_fcode00 = fcodeX;
1848 m_picParams->m_fcode01 = fcodeY;
1849 }
1850 }
1851 else // B picture
1852 {
1853 if ((m_picParams->m_fcode00 > fcodeX) ||
1854 (m_picParams->m_fcode01 > fcodeY) ||
1855 (m_picParams->m_fcode10 > fcodeX) ||
1856 (m_picParams->m_fcode11 > fcodeY) ||
1857 (m_picParams->m_fcode00 == 0) ||
1858 (m_picParams->m_fcode01 == 0) ||
1859 (m_picParams->m_fcode10 == 0) ||
1860 (m_picParams->m_fcode11 == 0))
1861 {
1862 m_picParams->m_fcode00 = fcodeX;
1863 m_picParams->m_fcode01 = fcodeY;
1864 m_picParams->m_fcode10 = fcodeX;
1865 m_picParams->m_fcode11 = fcodeY;
1866 }
1867 }
1868
1869 if (m_picParams->m_fieldCodingFlag == 0)
1870 {
1871 m_frameFieldHeight = m_frameHeight;
1872 m_frameFieldHeightInMb = m_picHeightInMb;
1873 m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x;
1874 }
1875 else
1876 {
1877 m_frameFieldHeight = ((m_frameHeight + 1) >> 1);
1878 m_frameFieldHeightInMb = ((m_picHeightInMb + 1) >> 1);
1879 m_downscaledFrameFieldHeightInMb4x = ((m_downscaledHeightInMb4x + 1) >> 1);
1880 }
1881
1882 m_statusReportFeedbackNumber = m_picParams->m_statusReportFeedbackNumber;
1883 m_lastPicInStream = m_picParams->m_lastPicInStream;
1884 m_currOriginalPic = m_picParams->m_currOriginalPic;
1885 m_currReconstructedPic = m_picParams->m_currReconstructedPic;
1886
1887 uint8_t currRefIdx = m_picParams->m_currReconstructedPic.FrameIdx;
1888
1889 ENCODE_CHK_COND_RETURN(currRefIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2, "currRefIdx cannot bigger than 128.");
1890 m_refList[currRefIdx]->sRefRawBuffer = m_rawSurface;
1891 m_refList[currRefIdx]->sRefReconBuffer = m_reconSurface;
1892 m_refList[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer;
1893
1894 if (m_pictureCodingType == I_TYPE)
1895 {
1896 m_picIdx[0].bValid = m_picIdx[1].bValid = 0;
1897 m_refList[currRefIdx]->bUsedAsRef = true;
1898 m_refList[currRefIdx]->ucNumRef = 0;
1899 }
1900 else if (m_pictureCodingType == P_TYPE)
1901 {
1902 if (m_picParams->m_refFrameList[0].PicFlags != PICTURE_INVALID)
1903 {
1904 m_picIdx[0].bValid = 1;
1905 m_picIdx[0].ucPicIdx = m_picParams->m_refFrameList[0].FrameIdx;
1906 }
1907 m_picIdx[1].bValid = 0;
1908 m_refList[currRefIdx]->bUsedAsRef = true;
1909 m_refList[currRefIdx]->RefList[0] = m_picParams->m_refFrameList[0];
1910 m_refList[currRefIdx]->ucNumRef = 1;
1911 }
1912 else// B_TYPE
1913 {
1914 if (m_picParams->m_refFrameList[0].PicFlags != PICTURE_INVALID)
1915 {
1916 m_picIdx[0].bValid = 1;
1917 m_picIdx[0].ucPicIdx = m_picParams->m_refFrameList[0].FrameIdx;
1918 }
1919
1920 if (m_picParams->m_refFrameList[1].PicFlags != PICTURE_INVALID)
1921 {
1922 m_picIdx[1].bValid = 1;
1923 m_picIdx[1].ucPicIdx = m_picParams->m_refFrameList[1].FrameIdx;
1924 }
1925 m_refList[currRefIdx]->bUsedAsRef = false;
1926 }
1927 m_currRefList = m_refList[currRefIdx];
1928
1929 if (m_codecFunction == CODECHAL_FUNCTION_ENC)
1930 {
1931 CODECHAL_ENCODE_CHK_NULL_RETURN(m_encodeParams.presMbCodeSurface);
1932 m_resMbCodeSurface = *(m_encodeParams.presMbCodeSurface);
1933 }
1934 else if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
1935 {
1936 // the actual MbCode/MvData surface to be allocated later
1937 m_trackedBuf->SetAllocationFlag(true);
1938 }
1939
1940 m_hmeEnabled = m_hmeSupported && m_pictureCodingType != I_TYPE;
1941
1942 if (m_brcEnabled)
1943 {
1944 m_numPasses = (uint8_t)(m_mfxInterface->GetBrcNumPakPasses() - 1); // 1 original plus extra to handle BRC
1945 }
1946
1947 // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer
1948 m_gopIsIdrFrameOnly = (m_picParams->m_gopPicSize == 1 && m_picParams->m_gopRefDist == 0);
1949
1950 return eStatus;
1951 }
1952
SetSliceGroups()1953 MOS_STATUS CodechalEncodeMpeg2::SetSliceGroups()
1954 {
1955 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1956
1957 CODECHAL_ENCODE_FUNCTION_ENTER;
1958
1959 uint32_t mbCount = 0;
1960 auto bsBuffer = &m_bsBuffer;
1961 auto slcParams = m_sliceParams;
1962 auto slcData = m_slcData;
1963 PCODEC_ENCODER_SLCDATA slcDataPrevStart = nullptr;
1964
1965 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
1966 {
1967 // Slice width should equal picture width, MBs should be on same row
1968 CODECHAL_ENCODE_CHK_NULL_RETURN(slcData);
1969 CODECHAL_ENCODE_CHK_NULL_RETURN(slcParams);
1970 CODECHAL_ENCODE_ASSERT((slcParams->m_numMbsForSlice % m_picWidthInMb) == 0);
1971 CODECHAL_ENCODE_ASSERT(slcParams->m_numMbsForSlice <= m_picWidthInMb);
1972
1973 if ((slcParams->m_quantiserScaleCode < 1) ||
1974 (slcParams->m_quantiserScaleCode > 31))
1975 {
1976 slcParams->m_quantiserScaleCode = 1;
1977 }
1978
1979 // Determine slice groups
1980 if (slcCount == 0)
1981 {
1982 // First slice
1983 slcDataPrevStart = slcData;
1984 slcData->SliceGroup |= SLICE_GROUP_START;
1985
1986 if (m_codecFunction == (CODECHAL_FUNCTION_ENC | CODECHAL_FUNCTION_PAK))
1987 {
1988 slcData->SliceOffset = bsBuffer->SliceOffset;
1989 // Make slice header uint8_t aligned, all start codes are uint8_t aligned
1990 while (bsBuffer->BitOffset)
1991 {
1992 PutBit(bsBuffer, 0);
1993 }
1994 for (uint32_t i = 0; i < 8; i++)
1995 {
1996 PutBit(bsBuffer, 0);
1997 }
1998
1999 slcData->BitSize = bsBuffer->BitSize =
2000 (uint32_t)((bsBuffer->pCurrent - bsBuffer->SliceOffset - bsBuffer->pBase) * 8 + bsBuffer->BitOffset);
2001 bsBuffer->SliceOffset =
2002 (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase + (bsBuffer->BitOffset != 0)); // start at next byte
2003 }
2004 else
2005 {
2006 slcData->SliceOffset = bsBuffer->SliceOffset;
2007 slcData->BitSize = bsBuffer->BitSize;
2008 }
2009 }
2010 else
2011 {
2012 // Compare with prev slice to see if curr slice is start of new slice group
2013 PCODEC_ENCODER_SLCDATA slcDataPrev = slcData - 1;
2014 CodecEncodeMpeg2SliceParmas *slcParamsPrev = slcParams - 1;
2015
2016 // Start of a new slice group if gap in slices or quantiser_scale_code/IntraSlice changes
2017 uint32_t mbPrevEnd =
2018 (slcParamsPrev->m_firstMbY * m_picWidthInMb) +
2019 slcParamsPrev->m_firstMbX +
2020 slcParamsPrev->m_numMbsForSlice;
2021 uint32_t mbCurrStart = (slcParams->m_firstMbY * m_picWidthInMb) + slcParams->m_firstMbX;
2022
2023 if ((mbPrevEnd != mbCurrStart) ||
2024 (slcParamsPrev->m_quantiserScaleCode != slcParams->m_quantiserScaleCode) ||
2025 (slcParamsPrev->m_intraSlice != slcParams->m_intraSlice))
2026 {
2027 slcDataPrev->SliceGroup |= SLICE_GROUP_END;
2028 slcData->SliceGroup |= SLICE_GROUP_START;
2029
2030 slcDataPrevStart->NextSgMbXCnt = slcParams->m_firstMbX;
2031 slcDataPrevStart->NextSgMbYCnt = slcParams->m_firstMbY;
2032 slcDataPrevStart = slcData;
2033
2034 slcData->SliceOffset = bsBuffer->SliceOffset;
2035 // Make slice header uint8_t aligned, all start codes are uint8_t aligned
2036 while (bsBuffer->BitOffset)
2037 {
2038 PutBit(bsBuffer, 0);
2039 }
2040 for (uint32_t i = 0; i < 8; i++)
2041 {
2042 PutBit(bsBuffer, 0);
2043 }
2044
2045 slcData->BitSize = bsBuffer->BitSize =
2046 (uint32_t)((bsBuffer->pCurrent - bsBuffer->SliceOffset - bsBuffer->pBase) * 8 + bsBuffer->BitOffset);
2047 bsBuffer->SliceOffset =
2048 (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase + (bsBuffer->BitOffset != 0)); // start at next byte
2049 }
2050 }
2051
2052 if (slcCount == (m_numSlices - 1))
2053 {
2054 // Last slice
2055 slcData->SliceGroup |= SLICE_GROUP_END;
2056 slcDataPrevStart->SliceGroup |= SLICE_GROUP_LAST;
2057 slcDataPrevStart->NextSgMbXCnt = 0;
2058 slcDataPrevStart->NextSgMbYCnt = m_frameFieldHeightInMb;
2059 }
2060
2061 slcData->CmdOffset = mbCount * m_mbCodeStrideInDW * sizeof(uint32_t);
2062
2063 mbCount += slcParams->m_numMbsForSlice;
2064 slcParams++;
2065 slcData++;
2066 }
2067
2068 return eStatus;
2069
2070 }
2071
GetCurByteOffset(BSBuffer * bsBuffer)2072 uint32_t CodechalEncodeMpeg2::GetCurByteOffset(BSBuffer* bsBuffer)
2073 {
2074 return (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase);
2075 }
2076
PackDisplaySeqExtension()2077 MOS_STATUS CodechalEncodeMpeg2::PackDisplaySeqExtension()
2078 {
2079 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2080
2081 CODECHAL_ENCODE_FUNCTION_ENTER;
2082
2083 auto bsBuffer = &m_bsBuffer;
2084
2085 // Make start code uint8_t aligned
2086 while (bsBuffer->BitOffset)
2087 {
2088 PutBit(bsBuffer, 0);
2089 }
2090
2091 // extension_start_code
2092 PutBits(bsBuffer, startCodePrefix, 24);
2093 PutBits(bsBuffer, startCodeExtension, 8);
2094
2095 // extension_start_code_identifier
2096 PutBits(bsBuffer, Mpeg2sequenceDisplayExtension, 4);
2097
2098 // video_format
2099 PutBits(bsBuffer, m_vuiParams->m_videoFormat, 3);
2100
2101 // colour_description
2102 PutBit(bsBuffer, m_vuiParams->m_colourDescription);
2103
2104 if (m_vuiParams->m_colourDescription)
2105 {
2106 // colour_primaries
2107 PutBits(bsBuffer, m_vuiParams->m_colourPrimaries, 8);
2108
2109 // transfer_characteristics
2110 PutBits(bsBuffer, m_vuiParams->m_transferCharacteristics, 8);
2111
2112 // matrix_coefficients
2113 PutBits(bsBuffer, m_vuiParams->m_matrixCoefficients, 8);
2114 }
2115
2116 // display_horizontal_size
2117 PutBits(bsBuffer, m_vuiParams->m_displayHorizontalSize, 14);
2118
2119 // marker_bit
2120 PutBit(bsBuffer, 1);
2121
2122 // display_vertical_size
2123 PutBits(bsBuffer, m_vuiParams->m_displayVerticalSize, 14);
2124
2125 return eStatus;
2126
2127 }
2128
PackSeqExtension()2129 MOS_STATUS CodechalEncodeMpeg2::PackSeqExtension()
2130 {
2131 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2132
2133 CODECHAL_ENCODE_FUNCTION_ENTER;
2134
2135 auto bsBuffer = &m_bsBuffer;
2136
2137 // Make start code uint8_t aligned
2138 while (bsBuffer->BitOffset)
2139 {
2140 PutBit(bsBuffer, 0);
2141 }
2142
2143 // extension_start_code
2144 PutBits(bsBuffer, startCodePrefix, 24);
2145 PutBits(bsBuffer, startCodeExtension, 8);
2146
2147 // extension_start_code_identifier
2148 PutBits(bsBuffer, Mpeg2sequenceExtension, 4);
2149
2150 // profile_and_level_indication
2151 PutBits(bsBuffer, ((m_seqParams->m_profile & 0x70) | (m_seqParams->m_level & 0xF)), 8);
2152
2153 // progressive_sequence
2154 PutBit(bsBuffer, m_seqParams->m_progressiveSequence);
2155
2156 // chroma_format
2157 PutBits(bsBuffer, m_seqParams->m_chromaFormat, 2);
2158
2159 // horizontal_size_extension
2160 PutBits(bsBuffer, ((m_seqParams->m_frameWidth >> 12) & 0x3), 2);
2161
2162 // vertical_size_extension
2163 PutBits(bsBuffer, ((m_seqParams->m_frameHeight >> 12) & 0x3), 2);
2164
2165 // bit_rate_extension
2166 PutBits(bsBuffer, ((MOS_ROUNDUP_DIVIDE(m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS, 400)) >> 18) & 0xFFF, 12);
2167
2168 // marker_bit
2169 PutBit(bsBuffer, 1);
2170
2171 // vbv_buffer_size_extension 8 uimsbf
2172 PutBits(bsBuffer, ((m_seqParams->m_vbvBufferSize >> 10) & 0xFF), 8);
2173
2174 // low_delay
2175 PutBit(bsBuffer, m_seqParams->m_lowDelay);
2176
2177 // frame_rate_extension_n
2178 PutBits(bsBuffer, m_seqParams->m_frameRateExtN, 2);
2179
2180 // frame_rate_extension_d
2181 PutBits(bsBuffer, m_seqParams->m_frameRateExtD, 5);
2182
2183 return eStatus;
2184
2185 }
2186
PackSeqHeader()2187 MOS_STATUS CodechalEncodeMpeg2::PackSeqHeader()
2188 {
2189 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2190
2191 CODECHAL_ENCODE_FUNCTION_ENTER;
2192
2193 auto bsBuffer = &m_bsBuffer;
2194
2195 // Make start code uint8_t aligned
2196 while (bsBuffer->BitOffset)
2197 {
2198 PutBit(bsBuffer, 0);
2199 }
2200
2201 // sequence_start_code
2202 PutBits(bsBuffer, startCodePrefix, 24);
2203 PutBits(bsBuffer, startCodeSequenceHeader, 8);
2204
2205 // horizontal_size_value
2206 CODECHAL_ENCODE_ASSERT((m_seqParams->m_frameWidth & 0xFFF) != 0); // Avoid start code emulation
2207 PutBits(bsBuffer, (m_seqParams->m_frameWidth & 0xFFF), 12);
2208
2209 // vertical_size_value
2210 CODECHAL_ENCODE_ASSERT((m_seqParams->m_frameHeight & 0xFFF) != 0); // Avoid start code emulation
2211 PutBits(bsBuffer, (m_seqParams->m_frameHeight & 0xFFF), 12);
2212
2213 // aspect_ratio_information
2214 CODECHAL_ENCODE_ASSERT((m_seqParams->m_aspectRatio > 0) && (m_seqParams->m_aspectRatio < 5));
2215 PutBits(bsBuffer, m_seqParams->m_aspectRatio, 4);
2216
2217 // frame_rate_code
2218 CODECHAL_ENCODE_ASSERT((m_seqParams->m_frameRateCode > 0) & (m_seqParams->m_frameRateCode < 15));
2219 PutBits(bsBuffer, m_seqParams->m_frameRateCode, 4);
2220
2221 // bit_rate_value
2222 if (m_seqParams->m_rateControlMethod == RATECONTROL_VBR)
2223 {
2224 // In Architecture prototype, the bit_rate_value of sequence header is set to m_maxBitRate not the target bit-rate for VBR case.
2225 PutBits(bsBuffer, ((MOS_ROUNDUP_DIVIDE(m_seqParams->m_maxBitRate * CODECHAL_ENCODE_BRC_KBPS, 400)) & 0x3FFFF), 18);
2226 }
2227 else
2228 {
2229 PutBits(bsBuffer, ((MOS_ROUNDUP_DIVIDE(m_seqParams->m_bitrate * CODECHAL_ENCODE_BRC_KBPS, 400)) & 0x3FFFF), 18);
2230 }
2231
2232 // marker_bit
2233 PutBit(bsBuffer, 1);
2234
2235 // vbv_buffer_size_value
2236 PutBits(bsBuffer, (m_seqParams->m_vbvBufferSize & 0x3FF), 10);
2237
2238 // constrained_parameters_flag
2239 PutBit(bsBuffer, 0);
2240
2241 // m_loadIntraQuantiserMatrix
2242 PutBit(bsBuffer, m_qMatrixParams->m_newQmatrix[0]);
2243 if (m_qMatrixParams->m_newQmatrix[0])
2244 {
2245 // m_intraQuantiserMatrix[64]
2246 for (uint8_t i = 0; i < 64; i++)
2247 {
2248 // Already in zig-zag scan order
2249 PutBits(bsBuffer, m_qMatrixParams->m_qmatrix[0][i], 8);
2250 }
2251 }
2252
2253 // m_loadNonIntraQuantiserMatrix
2254 PutBit(bsBuffer, m_qMatrixParams->m_newQmatrix[1]);
2255 if (m_qMatrixParams->m_newQmatrix[1])
2256 {
2257 // m_nonIntraQuantiserMatrix[64]
2258 for (uint8_t i = 0; i < 64; i++)
2259 {
2260 // Already in zig-zag scan order
2261 PutBits(bsBuffer, m_qMatrixParams->m_qmatrix[1][i], 8);
2262 }
2263 }
2264
2265 return eStatus;
2266
2267 }
2268
PackSequenceParams()2269 MOS_STATUS CodechalEncodeMpeg2::PackSequenceParams()
2270 {
2271 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2272
2273 CODECHAL_ENCODE_FUNCTION_ENTER;
2274
2275 // picture header
2276 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackSeqHeader());
2277
2278 // picture coding extension
2279 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackSeqExtension());
2280
2281 // optional sequence display extension (& user data)
2282 if (m_newVuiData)
2283 {
2284 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackDisplaySeqExtension());
2285
2286 m_newVuiData = false;
2287 }
2288
2289 return eStatus;
2290 }
2291
PackPicCodingExtension()2292 MOS_STATUS CodechalEncodeMpeg2::PackPicCodingExtension()
2293 {
2294 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2295
2296 CODECHAL_ENCODE_FUNCTION_ENTER;
2297
2298 auto bsBuffer = &m_bsBuffer;
2299
2300 // All start codes are uint8_t aligned
2301 while (bsBuffer->BitOffset)
2302 {
2303 PutBit(bsBuffer, 0);
2304 }
2305
2306 // extension_start_code
2307 PutBits(bsBuffer, startCodePrefix, 24);
2308 PutBits(bsBuffer, startCodeExtension, 8);
2309
2310 // extension_start_code_identifier
2311 PutBits(bsBuffer, Mpeg2pictureCodingExtension, 4);
2312
2313 // f_codes values 1-9 or 15; 0 or 1-14 are reserved
2314 if ((m_picParams->m_pictureCodingType == I_TYPE) && !m_picParams->m_concealmentMotionVectors)
2315 {
2316 // f_code[0][0], forward horizontal
2317 PutBits(bsBuffer, 0xF, 4);
2318 // f_code[0][1], forward vertical
2319 PutBits(bsBuffer, 0xF, 4);
2320 // f_code[1][0], backward horizontal
2321 PutBits(bsBuffer, 0xF, 4);
2322 // f_code[1][1], backward vertical
2323 PutBits(bsBuffer, 0xF, 4);
2324 }
2325 else
2326 {
2327 // f_code[0][0], forward horizontal
2328 PutBits(bsBuffer, m_picParams->m_fcode00, 4);
2329 // f_code[0][1], forward vertical
2330 PutBits(bsBuffer, m_picParams->m_fcode01, 4);
2331
2332 if ((m_picParams->m_pictureCodingType == I_TYPE) || (m_picParams->m_pictureCodingType == P_TYPE))
2333 {
2334 // f_code[1][0], backward horizontal
2335 PutBits(bsBuffer, 0xF, 4);
2336 // f_code[1][1], backward vertical
2337 PutBits(bsBuffer, 0xF, 4);
2338 }
2339 else
2340 {
2341 // f_code[1][0], backward horizontal
2342 PutBits(bsBuffer, m_picParams->m_fcode10, 4);
2343 // f_code[1][1], backward vertical
2344 PutBits(bsBuffer, m_picParams->m_fcode11, 4);
2345 }
2346 }
2347
2348 // store byte offset of intra_dc_precision
2349 m_intraDcPrecisionOffset = GetCurByteOffset(bsBuffer);
2350 // intra_dc_precision
2351 PutBits(bsBuffer, m_picParams->m_intraDCprecision, 2);
2352
2353 // picture_structure
2354 PutBits(bsBuffer, (!m_picParams->m_fieldCodingFlag) ? 3 : ((m_picParams->m_interleavedFieldBFF) ? 2 : 1), 2);
2355
2356 bool progressiveSequence = m_seqParams->m_progressiveSequence & 0x1;
2357 bool actual_tff = (!m_picParams->m_fieldCodingFlag && !progressiveSequence) || (m_picParams->m_repeatFirstField != 0);
2358
2359 // top_field_first
2360 PutBit(bsBuffer, (actual_tff ) ? (!m_picParams->m_interleavedFieldBFF) : 0);
2361 bool progressive = true;
2362 if (m_picParams->m_fieldCodingFlag || m_picParams->m_fieldFrameCodingFlag)
2363 {
2364 progressive = false;
2365 }
2366
2367 // frame_pred_frame_dct
2368 if (progressive)
2369 {
2370 PutBit(bsBuffer, 1);
2371 }
2372 else if (m_picParams->m_fieldCodingFlag)
2373 {
2374 PutBit(bsBuffer, 0);
2375 }
2376 else
2377 {
2378 PutBit(bsBuffer, m_picParams->m_framePredFrameDCT);
2379 }
2380
2381 // concealment_motion_vectors
2382 PutBit(bsBuffer, m_picParams->m_concealmentMotionVectors);
2383
2384 // Store the byte offset of the q_scale_type
2385 m_qScaleTypeByteOffse = GetCurByteOffset(bsBuffer);
2386 // q_scale_type
2387 PutBit(bsBuffer, m_picParams->m_qscaleType);
2388
2389 // intra_vlc_format
2390 PutBit(bsBuffer, m_picParams->m_intraVlcFormat);
2391
2392 // alternate_scan
2393 PutBit(bsBuffer, m_picParams->m_alternateScan);
2394
2395 // repeat_first_field
2396 PutBit(bsBuffer, (!m_picParams->m_fieldCodingFlag) ? m_picParams->m_repeatFirstField : 0);
2397
2398 // chroma_420_type
2399 PutBit(bsBuffer, progressive);
2400
2401 // progressive_frame
2402 PutBit(bsBuffer, progressive);
2403
2404 // composite_display_flag
2405 PutBit(bsBuffer, m_picParams->m_compositeDisplayFlag);
2406
2407 if (m_picParams->m_compositeDisplayFlag)
2408 {
2409 // v_axis
2410 PutBit(bsBuffer, m_picParams->m_vaxis);
2411 // field_sequence
2412 PutBits(bsBuffer, m_picParams->m_fieldSequence, 3);
2413 // sub_carrier
2414 PutBit(bsBuffer, m_picParams->m_subCarrier);
2415 // burst_amplitude
2416 PutBits(bsBuffer, m_picParams->m_burstAmplitude, 7);
2417 // sub_carrier_phase
2418 PutBits(bsBuffer, m_picParams->m_subCarrierPhase, 8);
2419 }
2420
2421 return eStatus;
2422 }
2423
PackPicUserData()2424 MOS_STATUS CodechalEncodeMpeg2::PackPicUserData()
2425 {
2426 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2427
2428 CODECHAL_ENCODE_FUNCTION_ENTER;
2429
2430 auto userDataListHead = (CodecEncodeMpeg2UserDataList *)m_encodeParams.pMpeg2UserDataListHead;
2431 CODECHAL_ENCODE_CHK_NULL_RETURN(userDataListHead);
2432
2433 auto bsBuffer = &m_bsBuffer;
2434
2435 for (auto p = userDataListHead; p; p = p->m_nextItem)
2436 {
2437 auto userData = (uint8_t*)p->m_userData;
2438
2439 while (bsBuffer->BitOffset)
2440 {
2441 PutBit(bsBuffer, 0);
2442 }
2443
2444 for(unsigned int i = 0; i < p->m_userDataSize; ++i)
2445 {
2446 PutBits(bsBuffer, (uint32_t) (userData[i]), 8);
2447 }
2448 }
2449
2450 return eStatus;
2451 }
2452
PackPicHeader()2453 MOS_STATUS CodechalEncodeMpeg2::PackPicHeader()
2454 {
2455 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2456
2457 CODECHAL_ENCODE_FUNCTION_ENTER;
2458
2459 auto bsBuffer = &m_bsBuffer;
2460
2461 // All start codes are uint8_t aligned
2462 while (bsBuffer->BitOffset)
2463 {
2464 PutBit(bsBuffer, 0);
2465 }
2466
2467 // picture_start_code
2468 PutBits(bsBuffer, startCodePrefix, 24);
2469 PutBits(bsBuffer, startCodePicture, 8);
2470
2471 // temporal_reference
2472 PutBits(bsBuffer, m_picParams->m_temporalReference, 10);
2473
2474 // picture_coding_type
2475 PutBits(bsBuffer, m_picParams->m_pictureCodingType, 3);
2476
2477 // Store the byte offset of the q_scale_type
2478 m_vbvDelayOffset = GetCurByteOffset(bsBuffer);
2479 // vbv_delay
2480 PutBits(bsBuffer, m_picParams->m_vbvDelay, 16);
2481
2482 if ((m_picParams->m_pictureCodingType == P_TYPE) || (m_picParams->m_pictureCodingType == B_TYPE))
2483 {
2484 // full_pel_forward_vector, '0'
2485 PutBit(bsBuffer, 0);
2486 // forward_f_code, '111'
2487 PutBits(bsBuffer, 0x7, 3);
2488 }
2489
2490 if (m_picParams->m_pictureCodingType == B_TYPE)
2491 {
2492 // full_pel_backward_vector, '0'
2493 PutBit(bsBuffer, 0);
2494 // backward_f_code '111'
2495 PutBits(bsBuffer, 0x7, 3);
2496 }
2497
2498 // extra_bit_picture, '0'
2499 PutBit(bsBuffer, 0);
2500
2501 return eStatus;
2502
2503 }
2504
PackGroupOfPicHeader()2505 MOS_STATUS CodechalEncodeMpeg2::PackGroupOfPicHeader()
2506 {
2507 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2508
2509 CODECHAL_ENCODE_FUNCTION_ENTER;
2510
2511 auto bsBuffer = &m_bsBuffer;
2512
2513 // All start codes are uint8_t aligned
2514 while (bsBuffer->BitOffset)
2515 {
2516 PutBit(bsBuffer, 0);
2517 }
2518
2519 // group_start_code
2520 PutBits(bsBuffer, startCodePrefix, 24);
2521 PutBits(bsBuffer, startCodeGroupStart, 8);
2522
2523 // time_code, 25 bits total
2524 // drop_flag
2525 PutBit(bsBuffer, ((m_picParams->m_timeCode >> 24) & 1));
2526 // hour
2527 PutBits(bsBuffer, ((m_picParams->m_timeCode >> 19) & 0x1F), 5);
2528 // minute
2529 PutBits(bsBuffer, ((m_picParams->m_timeCode >> 13) & 0x3F), 6);
2530 // marker_bit
2531 PutBit(bsBuffer, 1);
2532 // sec
2533 PutBits(bsBuffer, ((m_picParams->m_timeCode >> 6) & 0x3F), 6);
2534 // frame
2535 PutBits(bsBuffer, ((m_picParams->m_timeCode) & 0x3F), 6);
2536
2537 // closed_gop
2538 PutBit(bsBuffer, m_picParams->m_gopOptFlag & 1);
2539 // broken_link, used in editing
2540 PutBit(bsBuffer, 0);
2541
2542 return eStatus;
2543
2544 }
2545
PackPictureParams()2546 MOS_STATUS CodechalEncodeMpeg2::PackPictureParams()
2547 {
2548 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2549
2550 CODECHAL_ENCODE_FUNCTION_ENTER;
2551
2552 // optional GOP header (& user data)
2553 if (m_picParams->m_newGop)
2554 {
2555 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackGroupOfPicHeader());
2556 }
2557
2558 // picture header
2559 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPicHeader());
2560
2561 // picture coding extension
2562 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPicCodingExtension());
2563
2564 // user data
2565 if(m_encodeParams.pMpeg2UserDataListHead)
2566 {
2567 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPicUserData());
2568 }
2569
2570 return eStatus;
2571 }
2572
PackPictureHeader()2573 MOS_STATUS CodechalEncodeMpeg2::PackPictureHeader()
2574 {
2575 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2576
2577 CODECHAL_ENCODE_FUNCTION_ENTER;
2578
2579 auto bsBuffer = &m_bsBuffer;
2580
2581 *(bsBuffer->pBase) = 0; // init first byte to 0
2582 bsBuffer->pCurrent = bsBuffer->pBase;
2583 bsBuffer->SliceOffset = 0;
2584 bsBuffer->BitOffset = 0;
2585 bsBuffer->BitSize = 0;
2586
2587 // If this is a new sequence, write the seq set
2588 if (m_newSeq)
2589 {
2590 // Pack SPS
2591 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackSequenceParams());
2592 }
2593
2594 // Pack PPS
2595 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPictureParams());
2596
2597 // HW will insert next slice start code, but need to byte align for HW
2598 while (bsBuffer->BitOffset)
2599 {
2600 PutBit(bsBuffer, 0);
2601 }
2602 bsBuffer->BitSize = (uint32_t)(bsBuffer->pCurrent - bsBuffer->SliceOffset - bsBuffer->pBase) * 8 + bsBuffer->BitOffset;
2603
2604 return eStatus;
2605 }
2606
InitializePicture(const EncoderParams & params)2607 MOS_STATUS CodechalEncodeMpeg2::InitializePicture(const EncoderParams& params)
2608 {
2609 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2610
2611 CODECHAL_ENCODE_FUNCTION_ENTER;
2612
2613 m_seqParams = (CodecEncodeMpeg2SequenceParams *)(params.pSeqParams);
2614 m_vuiParams = (CodecEncodeMpeg2VuiParams *)(params.pVuiParams);
2615 m_picParams = (CodecEncodeMpeg2PictureParams *)(params.pPicParams);
2616 m_sliceParams = (CodecEncodeMpeg2SliceParmas *)(params.pSliceParams);
2617 m_qMatrixParams = (CodecEncodeMpeg2QmatixParams *)(params.pIQMatrixBuffer);
2618
2619 CODECHAL_ENCODE_CHK_NULL_RETURN(m_seqParams);
2620 CODECHAL_ENCODE_CHK_NULL_RETURN(m_vuiParams);
2621 CODECHAL_ENCODE_CHK_NULL_RETURN(m_picParams);
2622 CODECHAL_ENCODE_CHK_NULL_RETURN(m_sliceParams);
2623 CODECHAL_ENCODE_CHK_NULL_RETURN(m_qMatrixParams);
2624
2625 // Mb Qp data
2626 m_mbQpDataEnabled = params.bMbQpDataEnabled;
2627 if (m_mbQpDataEnabled)
2628 {
2629 m_mbQpDataSurface = *(params.psMbQpDataSurface);
2630 }
2631 m_skipFrameFlag = m_picParams->m_skipFrameFlag;
2632
2633 m_verticalLineStride = CODECHAL_VLINESTRIDE_FRAME;
2634 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
2635 m_mbcodeBottomFieldOffset = 0;
2636 m_mvBottomFieldOffset = 0;
2637 m_scaledBottomFieldOffset = 0;
2638 m_scaled16xBottomFieldOffset = 0;
2639
2640 if (m_newSeq)
2641 {
2642 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
2643 }
2644
2645 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
2646
2647 // 4x downscaled surface needed by MbEnc IDist (for BRC) kernel or HME kernel
2648 m_scalingEnabled = (m_hmeSupported || m_brcEnabled);
2649
2650 if (CodecHal_PictureIsField(m_currOriginalPic))
2651 {
2652 m_verticalLineStride = CODECHAL_VLINESTRIDE_FIELD;
2653 m_frameHeight = m_frameFieldHeightInMb * 2 * 16;
2654 m_picHeightInMb = (uint16_t)(m_frameHeight / 16);
2655 if (CodecHal_PictureIsBottomField(m_currOriginalPic))
2656 {
2657 m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_BOT_FIELD;
2658 m_mbcodeBottomFieldOffset = m_frameFieldHeightInMb * m_picWidthInMb * 64;
2659 m_mvBottomFieldOffset = MOS_ALIGN_CEIL(m_frameFieldHeightInMb * m_picWidthInMb * (32 * 4), 0x1000);
2660 }
2661 }
2662
2663 if (m_pictureCodingType == B_TYPE)
2664 {
2665 m_frameNumB += 1;
2666 }
2667 else
2668 {
2669 m_frameNumB = 0;
2670 }
2671
2672 if (m_pakEnabled)
2673 {
2674 CODECHAL_ENCODE_CHK_STATUS_RETURN(PackPictureHeader());
2675
2676 if (m_brcEnabled)
2677 {
2678 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
2679 uint32_t dwPicHeaderDataStartOffset,dwPicHeaderDataBufferSize;
2680
2681 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
2682 pakInsertObjectParams.pBsBuffer = &m_bsBuffer;
2683 pakInsertObjectParams.pdwMpeg2PicHeaderDataStartOffset = &dwPicHeaderDataStartOffset;
2684 pakInsertObjectParams.pdwMpeg2PicHeaderTotalBufferSize = &dwPicHeaderDataBufferSize;
2685
2686 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfcMpeg2PakInsertBrcBuffer(
2687 &m_brcBuffers.resBrcPicHeaderInputBuffer,
2688 &pakInsertObjectParams));
2689
2690 // The q_scale_type offset is relative to the beginning of the picture header buffer.
2691 // Since it starts off with the INSERT command, include its size in the offset for the
2692 // q_scale_type. Do the same for the vbv_delay offset.
2693 m_picHeaderDataBufferSize = dwPicHeaderDataBufferSize;
2694 m_qScaleTypeByteOffse += dwPicHeaderDataStartOffset;
2695 m_vbvDelayOffset += dwPicHeaderDataStartOffset;
2696 m_intraDcPrecisionOffset += dwPicHeaderDataStartOffset;
2697 }
2698
2699 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceGroups());
2700 }
2701
2702 CODECHAL_DEBUG_TOOL(
2703 m_debugInterface->m_currPic = m_picParams->m_currOriginalPic;
2704 m_debugInterface->m_bufferDumpFrameNum = m_storeData;
2705 m_debugInterface->m_frameType = m_pictureCodingType;
2706
2707 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpVuiParams(
2708 m_vuiParams));
2709
2710 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams(
2711 m_picParams));
2712
2713 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
2714 m_seqParams));
2715
2716 CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSliceParams(
2717 m_sliceParams));)
2718
2719 if (m_currReconstructedPic.FrameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
2720 {
2721 return MOS_STATUS_INVALID_PARAMETER;
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.dwPitch * 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 (64), but pitch can be greater.
3780 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
3781 data,
3782 m_frameThresholdArraySize,
3783 maxFrameThresholdArray,
3784 m_frameThresholdArraySize));
3785
3786 data += brcConstantDataBuffer.dwPitch; // advance next row in 2D using pitch
3787
3788 for (uint32_t i = 0; i < m_distQpAdjustmentArraySize; i += m_brcConstantSurfaceWidth, data += brcConstantDataBuffer.dwPitch)
3789 {
3790 uint32_t copySize; // to write <=64 bytes per row
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,
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 PMOS_RESOURCE globalGpuContextSyncTagBuffer = nullptr;
4438 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
4439 m_osInterface,
4440 globalGpuContextSyncTagBuffer));
4441 CODECHAL_ENCODE_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer);
4442
4443 uint32_t statusTag = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
4444 MHW_MI_STORE_DATA_PARAMS params;
4445 params.pOsResource = globalGpuContextSyncTagBuffer;
4446 params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
4447 params.dwValue = (statusTag > 0)? (statusTag - 1) : 0;
4448 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, ¶ms));
4449 }
4450
4451 CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4452
4453 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
4454
4455 // Ref surface
4456 surfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID;
4457 surfaceParams.psSurface = &m_reconSurface;
4458 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
4459 // Src surface
4460 surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID;
4461 surfaceParams.psSurface = m_rawSurfaceToPak;
4462 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
4463
4464 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
4465
4466 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
4467
4468 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
4469
4470 if (m_brcEnabled)
4471 {
4472 MHW_BATCH_BUFFER batchBuffer;
4473 MOS_ZeroMemory(&batchBuffer, sizeof(batchBuffer));
4474 batchBuffer.OsResource = m_brcBuffers.resBrcImageStatesWriteBuffer;
4475 batchBuffer.dwOffset = m_currPass * BRC_IMG_STATE_SIZE_PER_PASS;
4476 batchBuffer.bSecondLevel = true;
4477
4478 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
4479 &cmdBuffer,
4480 &batchBuffer));
4481 }
4482 else
4483 {
4484 auto picStateCmdStart = cmdBuffer.pCmdPtr;
4485 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxMpeg2PicCmd(&cmdBuffer, &mpeg2PicState));
4486
4487 CODECHAL_DEBUG_TOOL(
4488 auto picStateCmdEnd = cmdBuffer.pCmdPtr;
4489 uint32_t picStateCmdSize = ((uint32_t)(picStateCmdEnd - picStateCmdStart))*sizeof(uint32_t);
4490 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpData(
4491 (void *)picStateCmdStart,
4492 picStateCmdSize,
4493 CodechalDbgAttr::attrPicParams,
4494 "PicState")));
4495 }
4496
4497 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams));
4498
4499 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams));
4500
4501 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4502
4503 return eStatus;
4504
4505 }
4506
SendSliceParams(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_SLICE_STATE params)4507 MOS_STATUS CodechalEncodeMpeg2::SendSliceParams(
4508 PMOS_COMMAND_BUFFER cmdBuffer,
4509 PMHW_VDBOX_MPEG2_SLICE_STATE params)
4510 {
4511 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4512
4513 CODECHAL_ENCODE_FUNCTION_ENTER;
4514
4515 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4516 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
4517 CODECHAL_ENCODE_CHK_NULL_RETURN(params->presDataBuffer);
4518 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pBsBuffer);
4519 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSlcData);
4520
4521 if (params->pSlcData->SliceGroup & SLICE_GROUP_START)
4522 {
4523 // add Mpeg2 Slice group commands
4524 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfcMpeg2SliceGroupCmd(cmdBuffer, params));
4525 MHW_BATCH_BUFFER secondLevelBatchBuffer;
4526 if (params->bBrcEnabled && params->dwSliceIndex == 0)
4527 {
4528 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
4529 secondLevelBatchBuffer.OsResource = *(params->presPicHeaderBBSurf);
4530 secondLevelBatchBuffer.dwOffset = 0;
4531 secondLevelBatchBuffer.bSecondLevel = true;
4532 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
4533 }
4534 else
4535 {
4536 // Insert pre-slice headers
4537 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
4538 MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
4539 pakInsertObjectParams.bLastHeader = true;
4540 pakInsertObjectParams.pBsBuffer = params->pBsBuffer;
4541 pakInsertObjectParams.dwBitSize = params->dwLength;
4542 pakInsertObjectParams.dwOffset = params->dwOffset;
4543
4544 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(cmdBuffer, nullptr, &pakInsertObjectParams));
4545 }
4546
4547 // Insert Batch Buffer Start command to send Mpeg2_PAK_OBJ data for MBs in this slice
4548 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
4549 secondLevelBatchBuffer.OsResource = *params->presDataBuffer;
4550 secondLevelBatchBuffer.dwOffset = params->dwDataBufferOffset;
4551 secondLevelBatchBuffer.bSecondLevel = true;
4552
4553 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(cmdBuffer, &secondLevelBatchBuffer));
4554 }
4555
4556 return eStatus;
4557 }
4558
ExecuteSliceLevel()4559 MOS_STATUS CodechalEncodeMpeg2::ExecuteSliceLevel()
4560 {
4561 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4562
4563 CODECHAL_ENCODE_FUNCTION_ENTER;
4564
4565 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);
4566
4567 auto cpInterface = m_hwInterface->GetCpInterface();
4568
4569 MOS_COMMAND_BUFFER cmdBuffer;
4570 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4571
4572 if (m_osInterface->osCpInterface->IsCpEnabled())
4573 {
4574 MHW_CP_SLICE_INFO_PARAMS sliceInfoParam;
4575 sliceInfoParam.bLastPass = (m_currPass == m_numPasses) ? true : false;
4576 CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->SetMfxProtectionState(m_mfxInterface->IsDecodeInUse(), &cmdBuffer, nullptr, &sliceInfoParam));
4577
4578 CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->UpdateParams(false));
4579 }
4580
4581 MHW_VDBOX_MPEG2_SLICE_STATE sliceState;
4582 MOS_ZeroMemory(&sliceState, sizeof(sliceState));
4583 sliceState.presDataBuffer = &m_resMbCodeSurface;
4584 sliceState.pMpeg2PicIdx = &(m_picIdx[0]);
4585 sliceState.ppMpeg2RefList = &(m_refList[0]);
4586 sliceState.pEncodeMpeg2SeqParams = m_seqParams;
4587 sliceState.pEncodeMpeg2PicParams = m_picParams;
4588 sliceState.pEncodeMpeg2SliceParams = m_sliceParams;
4589 sliceState.pBsBuffer = &m_bsBuffer;
4590 sliceState.bBrcEnabled = m_brcEnabled;
4591 if (m_seqParams->m_forcePanicModeControl == 1) {
4592 sliceState.bRCPanicEnable = !m_seqParams->m_panicModeDisable;
4593 } else {
4594 sliceState.bRCPanicEnable = m_panicEnable;
4595 }
4596 sliceState.presPicHeaderBBSurf = &m_brcBuffers.resBrcPicHeaderOutputBuffer;
4597
4598 for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
4599 {
4600 //we should not need to call pfnPackSliceHeader this it's done by hw
4601 PCODEC_ENCODER_SLCDATA slcData = m_slcData;
4602 CODECHAL_ENCODE_CHK_NULL_RETURN(slcData);
4603 sliceState.dwDataBufferOffset =
4604 m_slcData[slcCount].CmdOffset + m_mbcodeBottomFieldOffset;
4605 sliceState.dwOffset = slcData[slcCount].SliceOffset;
4606 sliceState.dwLength = slcData[slcCount].BitSize;
4607 sliceState.dwSliceIndex = slcCount;
4608 sliceState.bFirstPass = true;
4609 sliceState.bLastPass = false;
4610 sliceState.pSlcData = &slcData[slcCount];
4611 sliceState.bFirstPass = (m_currPass == 0);
4612 sliceState.bLastPass = (m_currPass == m_numPasses);
4613
4614 CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSliceParams(&cmdBuffer, &sliceState));
4615 }
4616
4617 // Insert end of stream if set
4618 if (m_lastPicInStream)
4619 {
4620 MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
4621 MOS_ZeroMemory(&pakInsertObjectParams,sizeof(pakInsertObjectParams));
4622 pakInsertObjectParams.bLastPicInStream = true;
4623 if (m_codecFunction == CODECHAL_FUNCTION_ENC_PAK)
4624 {
4625 pakInsertObjectParams.bSetLastPicInStreamData = true;
4626 pakInsertObjectParams.dwBitSize = 32; // use dwBitSize for SrcDataEndingBitInclusion
4627 pakInsertObjectParams.dwLastPicInStreamData = (uint32_t)((1 << 16) | startCodeSequenceEnd << 24);
4628 }
4629 else
4630 {
4631 pakInsertObjectParams.bSetLastPicInStreamData = false;
4632 pakInsertObjectParams.dwBitSize = 8; // use dwBitSize for SrcDataEndingBitInclusion
4633 pakInsertObjectParams.dwLastPicInStreamData = 0;
4634 }
4635 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr, &pakInsertObjectParams));
4636 }
4637
4638 CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer));
4639
4640 // BRC PAK statistics different for each pass
4641 if (m_brcEnabled)
4642 {
4643 uint32_t frameOffset =
4644 (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
4645 m_encodeStatusBuf.dwNumPassesOffset + // Num passes offset
4646 sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource
4647
4648 EncodeReadBrcPakStatsParams readBrcPakStatsParams;
4649 readBrcPakStatsParams.pHwInterface = m_hwInterface;
4650 readBrcPakStatsParams.presBrcPakStatisticBuffer = &m_brcBuffers.resBrcPakStatisticBuffer[0];
4651 readBrcPakStatsParams.presStatusBuffer = &m_encodeStatusBuf.resStatusBuffer;
4652 readBrcPakStatsParams.dwStatusBufNumPassesOffset = frameOffset;
4653 readBrcPakStatsParams.ucPass = m_currPass;
4654 readBrcPakStatsParams.VideoContext = m_videoContext;
4655
4656 CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadBrcPakStatistics(
4657 &cmdBuffer,
4658 &readBrcPakStatsParams));
4659 }
4660
4661 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(
4662 &cmdBuffer,
4663 CODECHAL_NUM_MEDIA_STATES));
4664
4665 if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
4666 {
4667 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
4668 &cmdBuffer,
4669 nullptr));
4670 }
4671
4672 std::string Pak_pass = "PAK_PASS[" + std::to_string(static_cast<uint32_t>(m_currPass))+"]";
4673 CODECHAL_DEBUG_TOOL(
4674 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
4675 &cmdBuffer,
4676 CODECHAL_NUM_MEDIA_STATES,
4677 Pak_pass.c_str()));
4678
4679 //CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
4680 // m_debugInterface,
4681 // &cmdBuffer));
4682 )
4683
4684 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4685
4686 MOS_SYNC_PARAMS syncParams;
4687 if ((m_currPass == 0) &&
4688 !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
4689 {
4690 syncParams = g_cInitSyncParams;
4691 syncParams.GpuContext = m_videoContext;
4692 syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;
4693
4694 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4695 }
4696
4697 if (!m_singleTaskPhaseSupported ||
4698 m_lastTaskInPhase)
4699 {
4700 CODECHAL_ENCODE_CHK_STATUS_RETURN(SubmitCommandBuffer(&cmdBuffer, m_videoContextUsesNullHw));
4701
4702 CODECHAL_DEBUG_TOOL(
4703 if (m_mmcState)
4704 {
4705 m_mmcState->UpdateUserFeatureKey(&m_reconSurface);
4706 }
4707 )
4708
4709 if ((m_currPass == m_numPasses) &&
4710 m_signalEnc &&
4711 !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
4712 {
4713 // Check if the signal obj count exceeds max m_value
4714 if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED))
4715 {
4716 syncParams = g_cInitSyncParams;
4717 syncParams.GpuContext = m_renderContext;
4718 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4719
4720 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4721 m_semaphoreObjCount--;
4722 }
4723
4724 // signal semaphore
4725 syncParams = g_cInitSyncParams;
4726 syncParams.GpuContext = m_videoContext;
4727 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4728
4729 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
4730 m_semaphoreObjCount++;
4731 }
4732 }
4733
4734 // Reset parameters for next PAK execution
4735 if (m_currPass == m_numPasses)
4736 {
4737 m_newPpsHeader = 0;
4738 m_newSeqHeader = 0;
4739 }
4740
4741 return eStatus;
4742 }
4743
PackSkippedMB(uint32_t mbIncrement)4744 MOS_STATUS CodechalEncodeMpeg2::PackSkippedMB(uint32_t mbIncrement)
4745 {
4746 CODECHAL_ENCODE_FUNCTION_ENTER;
4747
4748 auto bsBuffer = &m_bsBuffer;
4749 //macroblock_escap: The macroblock_escap`e is a fixed bit-string "0000 0001 000" which is used
4750 //when the difference between macroblock_address and previous_macroblock_address is greater than 33
4751 while(mbIncrement > 33)
4752 {
4753 PutBits(bsBuffer,0x08,11);
4754 mbIncrement -= 33;
4755 }
4756 // macroblock_address_increment: This is a variable length coded integer
4757 //which indicates the difference between macroblock_address and previous_macroblock_address
4758 PutBits(bsBuffer, mpeg2AddrIncreamentTbl[mbIncrement].m_code, mpeg2AddrIncreamentTbl[mbIncrement].m_len);
4759 // macroblock_modes()
4760 //macroblock_type: Variable length coded indicator which indicates the method of coding and
4761 //content of the macroblock according to the Tables B-2 through B-8 in spec ISO 13818-2,
4762 //for skip mb, we should choose "MC, NotCoded" for P frame which means there are no quant, backward mv, mb pattern ...
4763 //choose "Bwd,Not Coded" for B frame
4764 if(m_pictureCodingType == P_TYPE)
4765 {
4766 PutBits(bsBuffer, mpeg2MbTypeTbl[1][8].m_code, mpeg2MbTypeTbl[1][8].m_len);
4767 }
4768 else if(m_pictureCodingType == B_TYPE)
4769 {
4770 PutBits(bsBuffer, mpeg2MbTypeTbl[2][4].m_code, mpeg2MbTypeTbl[2][4].m_len);
4771 }
4772 // frame_motion_type This is a two bit code indicating the macroblock prediction, 0b10 -- frame-based
4773 // 0b01 --field based 0b11---Dual-Prime
4774 // attention: currently, mpeg2 encode only support frame encoding and field frame encoding , so Picture_Struct should be 3
4775 if(m_picParams->m_framePredFrameDCT == 0)
4776 {
4777 PutBits(bsBuffer, 2, 2);
4778 }
4779 // motion_vectors // motion_vector ( 0, 0 ) //
4780 // set the MV to zero for skip MB.
4781 PutBits(bsBuffer, mpeg2MvVlcTbl[16 + 0].m_code, mpeg2MvVlcTbl[16 + 0].m_len);
4782 PutBits(bsBuffer, mpeg2MvVlcTbl[16 + 0].m_code, mpeg2MvVlcTbl[16 + 0].m_len);
4783
4784 return MOS_STATUS_SUCCESS;
4785 }
PackSkipSliceData()4786 MOS_STATUS CodechalEncodeMpeg2::PackSkipSliceData()
4787 {
4788 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4789
4790 CODECHAL_ENCODE_FUNCTION_ENTER;
4791
4792 auto slcParams = m_sliceParams;
4793 auto bsBuffer = &m_bsBuffer;
4794
4795 while (bsBuffer->BitOffset)
4796 {
4797 PutBits(bsBuffer, 0, 1);
4798 }
4799
4800 for (uint32_t slcCount = 0; slcCount < m_numSlices; slcCount++)
4801 {
4802 //slice start code
4803 PutBits(bsBuffer,0x000001,24);
4804 PutBits(bsBuffer,slcParams->m_firstMbY + 1,8);
4805 // quantiser_scale_code
4806 PutBits(bsBuffer,slcParams->m_quantiserScaleCode, 5);
4807 // intra_slice_flag
4808 PutBits(bsBuffer, 1, 1);
4809 // intra_slice
4810 PutBits(bsBuffer, slcParams->m_intraSlice, 1);
4811 // reserved_bits
4812 PutBits(bsBuffer, 0, 7);
4813 // extra_bit_slice
4814 PutBits(bsBuffer, 0, 1);
4815
4816 PackSkippedMB(1);
4817 PackSkippedMB(slcParams->m_numMbsForSlice - 1);
4818 while (bsBuffer->BitOffset)
4819 {
4820 PutBits(bsBuffer, 0, 1);
4821 }
4822 slcParams++;
4823 }
4824
4825 return eStatus;
4826 }
4827
EncodeCopySkipFrame()4828 MOS_STATUS CodechalEncodeMpeg2::EncodeCopySkipFrame()
4829 {
4830 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4831
4832 CODECHAL_ENCODE_FUNCTION_ENTER;
4833
4834 PackSkipSliceData();
4835
4836 CodechalResLock bufLock(m_osInterface, &m_resBitstreamBuffer);
4837 auto data = bufLock.Lock(CodechalResLock::writeOnly);;
4838 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
4839
4840 auto bsBuffer = &m_bsBuffer;
4841 auto bsSize = (uint32_t)(bsBuffer->pCurrent - bsBuffer->pBase);
4842
4843 //copy skipped frame
4844 MOS_SecureMemcpy(data, bsSize, bsBuffer->pBase, bsSize);
4845 //unlock bitstream buffer
4846 m_osInterface->pfnUnlockResource( m_osInterface, &m_resBitstreamBuffer );
4847
4848 //get cmd buffer
4849 MOS_COMMAND_BUFFER cmdBuffer;
4850 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4851 //start status report
4852 CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4853
4854 //fill status report
4855 auto encodeStatus = (EncodeStatus*)(m_encodeStatusBuf.pEncodeStatus +
4856 m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize);
4857 encodeStatus->dwMFCBitstreamByteCountPerFrame = bsSize;
4858 encodeStatus->dwHeaderBytesInserted = 0; // set dwHeaderBytesInserted to 0
4859
4860 //end status report
4861 CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4862
4863 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4864
4865 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw));
4866
4867 return eStatus;
4868 }
4869
SendMbEncSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,bool mbEncIFrameDistEnabled)4870 MOS_STATUS CodechalEncodeMpeg2::SendMbEncSurfaces(
4871 PMOS_COMMAND_BUFFER cmdBuffer,
4872 bool mbEncIFrameDistEnabled)
4873 {
4874 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4875
4876 CODECHAL_ENCODE_FUNCTION_ENTER;
4877
4878 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4879
4880 PMHW_KERNEL_STATE kernelState;
4881 if (mbEncIFrameDistEnabled)
4882 {
4883 kernelState = &m_brcKernelStates[CODECHAL_ENCODE_BRC_IDX_IFRAMEDIST];
4884 }
4885 else
4886 {
4887 // wPictureCodingType: I_TYPE = 1, P_TYPE = 2, B_TYPE = 3
4888 // KernelStates are I: 0, P: 1, B: 2
4889 // m_mbEncKernelStates: I: m_mbEncKernelStates[0], P: m_mbEncKernelStates[1], B: m_mbEncKernelStates[2]
4890 uint32_t krnStateIdx = m_pictureCodingType - 1;
4891
4892 if (m_mbEncForcePictureCodingType)
4893 {
4894 krnStateIdx = m_mbEncForcePictureCodingType - 1;
4895 }
4896
4897 kernelState = &m_mbEncKernelStates[krnStateIdx];
4898 }
4899
4900 auto presMbCodeBuffer = &m_refList[m_currReconstructedPic.FrameIdx]->resRefMbCodeBuffer;
4901 auto presPrevMbCodeBuffer = &m_refList[m_prevMBCodeIdx]->resRefMbCodeBuffer;
4902
4903 // Caution: if PAFF supports added, need to make sure each field get correct surface pointer
4904 // PAK Obj command buffer
4905 uint32_t pakSize = (uint32_t)m_picWidthInMb * m_frameFieldHeightInMb * 16 * 4; // 12 DW for MB + 4 DW for MV
4906 CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
4907
4908 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4909 surfaceCodecParams.presBuffer = presMbCodeBuffer;
4910 surfaceCodecParams.dwSize = pakSize;
4911 surfaceCodecParams.dwOffset = (uint32_t)m_mbcodeBottomFieldOffset;
4912 surfaceCodecParams.dwCacheabilityControl =
4913 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value;
4914 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncPakObj;
4915 surfaceCodecParams.bRenderTarget = true;
4916 surfaceCodecParams.bIsWritable = true;
4917 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4918 m_hwInterface,
4919 cmdBuffer,
4920 &surfaceCodecParams,
4921 kernelState));
4922
4923 // Prev PAK Obj command buffer
4924 pakSize = (uint32_t)m_picWidthInMb * m_frameFieldHeightInMb * 16 * 4; // 12 DW for MB + 4 DW for MV
4925
4926 // verify if the current frame is not the first frame
4927 if (!Mos_ResourceIsNull(presPrevMbCodeBuffer) &&
4928 !m_firstFrame)
4929 {
4930 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4931 surfaceCodecParams.presBuffer = presPrevMbCodeBuffer;
4932 surfaceCodecParams.dwSize = pakSize;
4933 surfaceCodecParams.dwOffset = (uint32_t)m_mbcodeBottomFieldOffset;
4934 surfaceCodecParams.dwCacheabilityControl =
4935 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_PAK_OBJECT_ENCODE].Value;
4936 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncPakObjPrev;
4937 surfaceCodecParams.bRenderTarget = true;
4938 surfaceCodecParams.bIsWritable = true;
4939 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4940 m_hwInterface,
4941 cmdBuffer,
4942 &surfaceCodecParams,
4943 kernelState));
4944 }
4945 auto currPicSurface = mbEncIFrameDistEnabled ? m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER) : m_rawSurfaceToEnc;
4946
4947 // Current Picture Y
4948 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4949 surfaceCodecParams.bIs2DSurface = true;
4950 surfaceCodecParams.psSurface = currPicSurface;
4951 surfaceCodecParams.dwCacheabilityControl =
4952 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
4953 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncCurrentY;
4954 surfaceCodecParams.dwVerticalLineStride = m_verticalLineStride;
4955 surfaceCodecParams.dwVerticalLineStrideOffset = m_verticalLineStrideOffset;
4956
4957 #ifdef _MMC_SUPPORTED
4958 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4959 #endif
4960 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4961 m_hwInterface,
4962 cmdBuffer,
4963 &surfaceCodecParams,
4964 kernelState));
4965
4966 bool currBottomField = CodecHal_PictureIsBottomField(m_currOriginalPic) ? 1 : 0;
4967 uint8_t vDirection = (CodecHal_PictureIsFrame(m_currOriginalPic)) ? CODECHAL_VDIRECTION_FRAME :
4968 (currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD;
4969
4970 // Current Picture
4971 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
4972 surfaceCodecParams.bUseAdvState = true;
4973 surfaceCodecParams.psSurface = currPicSurface;
4974 surfaceCodecParams.dwCacheabilityControl =
4975 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
4976 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncCurrentPic;
4977 surfaceCodecParams.ucVDirection = vDirection;
4978
4979 #ifdef _MMC_SUPPORTED
4980 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
4981 #endif
4982 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
4983 m_hwInterface,
4984 cmdBuffer,
4985 &surfaceCodecParams,
4986 kernelState));
4987
4988 uint8_t picIdx0 = CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2;
4989 uint8_t picIdx1 = CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2;
4990 bool refL0BottomField = false;
4991 bool refL1BottomField = false;
4992
4993 if (m_picIdx[0].bValid)
4994 {
4995 picIdx0 = m_picIdx[0].ucPicIdx;
4996 refL0BottomField = (CodecHal_PictureIsBottomField(m_currOriginalPic)) ? 1 : 0;
4997 }
4998
4999 if (m_picIdx[1].bValid)
5000 {
5001 picIdx1 = m_picIdx[1].ucPicIdx;
5002 refL1BottomField = (CodecHal_PictureIsBottomField(m_currOriginalPic)) ? 1 : 0;
5003 }
5004
5005 // forward reference
5006 if (picIdx0 < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
5007 {
5008 if (m_verticalLineStride == CODECHAL_VLINESTRIDE_FIELD)
5009 {
5010 vDirection = (refL0BottomField ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
5011 }
5012
5013 // Picture Y
5014 CodecHalGetResourceInfo(m_osInterface, &m_refList[picIdx0]->sRefBuffer);
5015
5016 // Picture Y VME
5017 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5018 surfaceCodecParams.bUseAdvState = true;
5019 surfaceCodecParams.psSurface = &m_refList[picIdx0]->sRefBuffer;
5020 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncForwardPic;
5021 surfaceCodecParams.ucVDirection = vDirection;
5022 surfaceCodecParams.dwCacheabilityControl =
5023 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
5024
5025 #ifdef _MMC_SUPPORTED
5026 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5027 #endif
5028 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5029 m_hwInterface,
5030 cmdBuffer,
5031 &surfaceCodecParams,
5032 kernelState));
5033 }
5034
5035 // backward reference
5036 if (picIdx1 < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
5037 {
5038 if (m_verticalLineStride == CODECHAL_VLINESTRIDE_FIELD)
5039 {
5040 vDirection = (refL1BottomField ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
5041 }
5042
5043 CodecHalGetResourceInfo(m_osInterface, &m_refList[picIdx1]->sRefBuffer);
5044
5045 // Picture Y VME
5046 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5047 surfaceCodecParams.bUseAdvState = true;
5048 surfaceCodecParams.psSurface = &m_refList[picIdx1]->sRefBuffer;
5049 surfaceCodecParams.dwCacheabilityControl =
5050 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
5051 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncBackwardPic;
5052 surfaceCodecParams.ucVDirection = vDirection;
5053
5054 #ifdef _MMC_SUPPORTED
5055 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5056 #endif
5057 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5058 m_hwInterface,
5059 cmdBuffer,
5060 &surfaceCodecParams,
5061 kernelState));
5062 }
5063
5064 // Interlace Frame
5065 if ((CodecHal_PictureIsFrame(m_picParams->m_currOriginalPic)) &&
5066 (m_picParams->m_fieldCodingFlag || m_picParams->m_fieldFrameCodingFlag))
5067 {
5068 // Current Picture Interlace
5069 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5070 surfaceCodecParams.bUseAdvState = true;
5071 surfaceCodecParams.psSurface = currPicSurface;
5072 surfaceCodecParams.dwCacheabilityControl =
5073 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
5074 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncInterlaceFrameCurrentPic;
5075 surfaceCodecParams.ucVDirection = vDirection;
5076
5077 #ifdef _MMC_SUPPORTED
5078 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5079 #endif
5080 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5081 m_hwInterface,
5082 cmdBuffer,
5083 &surfaceCodecParams,
5084 kernelState));
5085
5086 if (picIdx1 < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
5087 {
5088 // Picture Y VME
5089 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5090 surfaceCodecParams.bUseAdvState = true;
5091 surfaceCodecParams.psSurface = &m_refList[picIdx1]->sRefBuffer;
5092 surfaceCodecParams.dwCacheabilityControl =
5093 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
5094 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncInterlaceFrameBackwardPic;
5095 surfaceCodecParams.ucVDirection = vDirection;
5096
5097 #ifdef _MMC_SUPPORTED
5098 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mmcState->SetSurfaceParams(&surfaceCodecParams));
5099 #endif
5100 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5101 m_hwInterface,
5102 cmdBuffer,
5103 &surfaceCodecParams,
5104 kernelState));
5105 }
5106 }
5107
5108 // BRC distortion data buffer for I frame
5109 if (mbEncIFrameDistEnabled)
5110 {
5111 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5112 surfaceCodecParams.bIs2DSurface = true;
5113 surfaceCodecParams.bMediaBlockRW = true;
5114 surfaceCodecParams.psSurface = &m_brcBuffers.sMeBrcDistortionBuffer;
5115 surfaceCodecParams.dwOffset = m_brcBuffers.dwMeBrcDistortionBottomFieldOffset;
5116 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncBrcDistortionSurface;
5117 surfaceCodecParams.bRenderTarget = true;
5118 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5119 m_hwInterface,
5120 cmdBuffer,
5121 &surfaceCodecParams,
5122 kernelState));
5123 }
5124
5125 // MB-control surface for MB level QP, SkipEnable and NonSkipEnable
5126 if (m_mbQpDataEnabled)
5127 {
5128 MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
5129 surfaceCodecParams.bIs2DSurface = true;
5130 surfaceCodecParams.bMediaBlockRW = true;
5131 surfaceCodecParams.psSurface = &m_mbQpDataSurface;
5132 surfaceCodecParams.dwCacheabilityControl =
5133 m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MB_QP_CODEC].Value;
5134 surfaceCodecParams.dwBindingTableOffset = m_mbEncBindingTable.m_mbEncMbControl;
5135 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
5136 m_hwInterface,
5137 cmdBuffer,
5138 &surfaceCodecParams,
5139 kernelState));
5140 }
5141
5142 return eStatus;
5143 }
5144
SendPrologWithFrameTracking(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTracking,MHW_MI_MMIOREGISTERS * mmioRegister)5145 MOS_STATUS CodechalEncodeMpeg2::SendPrologWithFrameTracking(
5146 PMOS_COMMAND_BUFFER cmdBuffer,
5147 bool frameTracking,
5148 MHW_MI_MMIOREGISTERS *mmioRegister)
5149 {
5150 return CodechalEncoderState::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister);
5151 }
5152
UpdateSSDSliceCount()5153 void CodechalEncodeMpeg2::UpdateSSDSliceCount()
5154 {
5155 m_setRequestedEUSlices = (m_brcEnabled &&
5156 m_sliceStateEnable &&
5157 (m_frameHeight * m_frameWidth) >= m_hwInterface->m_mpeg2SSDResolutionThreshold) ? true : false;
5158
5159 m_hwInterface->m_numRequestedEuSlices = (m_setRequestedEUSlices) ?
5160 m_sliceShutdownRequestState : m_sliceShutdownDefaultState;
5161 }
5162
AddMediaVfeCmd(PMOS_COMMAND_BUFFER cmdBuffer,SendKernelCmdsParams * params)5163 MOS_STATUS CodechalEncodeMpeg2::AddMediaVfeCmd(
5164 PMOS_COMMAND_BUFFER cmdBuffer,
5165 SendKernelCmdsParams *params)
5166 {
5167 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
5168
5169 MHW_VFE_PARAMS vfeParams = {};
5170 vfeParams.pKernelState = params->pKernelState;
5171 vfeParams.eVfeSliceDisable = MHW_VFE_SLICE_ALL;
5172 vfeParams.dwMaximumNumberofThreads = m_encodeVfeMaxThreads;
5173
5174 if (!m_useHwScoreboard)
5175 {
5176 vfeParams.Scoreboard.ScoreboardMask = 0;
5177 }
5178 else
5179 {
5180 vfeParams.Scoreboard.ScoreboardEnable = true;
5181 vfeParams.Scoreboard.ScoreboardType = m_hwScoreboardType;
5182 vfeParams.Scoreboard.ScoreboardMask = 0xFF;
5183
5184 // Scoreboard 0
5185 vfeParams.Scoreboard.ScoreboardDelta[0].x = 0xF;
5186 vfeParams.Scoreboard.ScoreboardDelta[0].y = 0;
5187
5188 // Scoreboard 1
5189 vfeParams.Scoreboard.ScoreboardDelta[1].x = 0;
5190 vfeParams.Scoreboard.ScoreboardDelta[1].y = 0xF;
5191
5192 // Scoreboard 2
5193 vfeParams.Scoreboard.ScoreboardDelta[2].x = 0xE;
5194 vfeParams.Scoreboard.ScoreboardDelta[2].y = 0;
5195 }
5196
5197 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaVfeCmd(cmdBuffer, &vfeParams));
5198
5199 return MOS_STATUS_SUCCESS;
5200 }
5201
5202 #if USE_CODECHAL_DEBUG_TOOL
DumpSeqParams(CodecEncodeMpeg2SequenceParams * seqParams)5203 MOS_STATUS CodechalEncodeMpeg2::DumpSeqParams(
5204 CodecEncodeMpeg2SequenceParams *seqParams)
5205 {
5206 CODECHAL_DEBUG_FUNCTION_ENTER;
5207
5208 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
5209 {
5210 return MOS_STATUS_SUCCESS;
5211 }
5212
5213 CODECHAL_DEBUG_CHK_NULL(seqParams);
5214
5215 std::ostringstream oss;
5216 oss.setf(std::ios::showbase | std::ios::uppercase);
5217
5218 oss << "m_frameWidth: " << +seqParams->m_frameWidth << std::endl;
5219 oss << "m_frameHeight: " << +seqParams->m_frameHeight << std::endl;
5220 oss << "m_profile: " << +seqParams->m_profile << std::endl;
5221 oss << "m_profile: " << +seqParams->m_level << std::endl;
5222 oss << "m_chromaFormat: " << +seqParams->m_chromaFormat << std::endl;
5223 oss << "m_targetUsage: " << +seqParams->m_targetUsage << std::endl;
5224 oss << "m_aratioFrate: " << +seqParams->m_aratioFrate << std::endl;
5225 oss << "m_aspectRatio: " << +seqParams->m_aspectRatio << std::endl;
5226 oss << "m_frameRateCode: " << +seqParams->m_frameRateCode << std::endl;
5227 oss << "m_frameRateExtN: " << +seqParams->m_frameRateExtN << std::endl;
5228 oss << "m_frameRateExtD: " << +seqParams->m_frameRateExtD << std::endl;
5229 oss << "m_bitrate: " << +seqParams->m_bitrate << std::endl;
5230 oss << "m_vbvBufferSize: " << +seqParams->m_vbvBufferSize << std::endl;
5231 oss << "m_progressiveSequence: " << +seqParams->m_progressiveSequence << std::endl;
5232 oss << "m_lowDelay: " << +seqParams->m_lowDelay << std::endl;
5233 oss << "m_resetBRC: " << +seqParams->m_resetBRC << std::endl;
5234 oss << "m_noAcceleratorSPSInsertion: " << +seqParams->m_noAcceleratorSPSInsertion << std::endl;
5235 oss << "m_reserved0: " << +seqParams->m_reserved0 << std::endl;
5236 oss << "m_rateControlMethod: " << +seqParams->m_rateControlMethod << std::endl;
5237 oss << "m_reserved1: " << +seqParams->m_reserved1 << std::endl;
5238 oss << "m_maxBitRate: " << +seqParams->m_maxBitRate << std::endl;
5239 oss << "m_minBitRate: " << +seqParams->m_minBitRate << std::endl;
5240 oss << "m_userMaxFrameSize: " << +seqParams->m_userMaxFrameSize << std::endl;
5241 oss << "m_initVBVBufferFullnessInBit: " << +seqParams->m_initVBVBufferFullnessInBit << std::endl;
5242
5243 const char *fileName = m_debugInterface->CreateFileName(
5244 "_DDIEnc",
5245 CodechalDbgBufferType::bufSeqParams,
5246 CodechalDbgExtType::txt);
5247
5248 std::ofstream ofs(fileName, std::ios::out);
5249 ofs << oss.str();
5250 ofs.close();
5251 return MOS_STATUS_SUCCESS;
5252 }
5253
DumpPicParams(CodecEncodeMpeg2PictureParams * picParams)5254 MOS_STATUS CodechalEncodeMpeg2::DumpPicParams(
5255 CodecEncodeMpeg2PictureParams *picParams)
5256 {
5257 CODECHAL_DEBUG_FUNCTION_ENTER;
5258
5259 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
5260 {
5261 return MOS_STATUS_SUCCESS;
5262 }
5263
5264 CODECHAL_DEBUG_CHK_NULL(picParams);
5265
5266 std::ostringstream oss;
5267 oss.setf(std::ios::showbase | std::ios::uppercase);
5268
5269 oss << "m_currOriginalPic: " << +picParams->m_currOriginalPic.FrameIdx << std::endl;
5270 oss << "m_currReconstructedPic: " << +picParams->m_currReconstructedPic.FrameIdx << std::endl;
5271 oss << "m_pictureCodingType: " << +picParams->m_pictureCodingType << std::endl;
5272 oss << "m_fieldCodingFlag: " << +picParams->m_fieldCodingFlag << std::endl;
5273 oss << "m_fieldFrameCodingFlag: " << +picParams->m_fieldFrameCodingFlag << std::endl;
5274 oss << "m_interleavedFieldBFF: " << +picParams->m_interleavedFieldBFF << std::endl;
5275 oss << "m_progressiveField: " << +picParams->m_progressiveField << std::endl;
5276 oss << "m_numSlice: " << +picParams->m_numSlice << std::endl;
5277 oss << "m_picBackwardPrediction: " << +picParams->m_picBackwardPrediction << std::endl;
5278 oss << "m_bidirectionalAveragingMode: " << +picParams->m_bidirectionalAveragingMode << std::endl;
5279 oss << "m_pic4MVallowed: " << +picParams->m_pic4MVallowed << std::endl;
5280 oss << "m_refFrameList: " << +picParams->m_refFrameList[0].FrameIdx << " " << +picParams->m_refFrameList[1].FrameIdx << std::endl;
5281 oss << "m_useRawPicForRef: " << +picParams->m_useRawPicForRef << std::endl;
5282 oss << "m_statusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl;
5283 oss << "m_alternateScan: " << +picParams->m_alternateScan << std::endl;
5284 oss << "m_intraVlcFormat: " << +picParams->m_intraVlcFormat << std::endl;
5285 oss << "m_qscaleType: " << +picParams->m_qscaleType << std::endl;
5286 oss << "m_concealmentMotionVectors: " << +picParams->m_concealmentMotionVectors << std::endl;
5287 oss << "m_framePredFrameDCT: " << +picParams->m_framePredFrameDCT << std::endl;
5288 oss << "m_disableMismatchControl: " << +picParams->m_disableMismatchControl << std::endl;
5289 oss << "m_intraDCprecision: " << +picParams->m_intraDCprecision << std::endl;
5290 oss << "m_fcode00: " << +picParams->m_fcode00 << std::endl;
5291 oss << "m_fcode01: " << +picParams->m_fcode01 << std::endl;
5292 oss << "m_fcode10: " << +picParams->m_fcode10 << std::endl;
5293 oss << "m_fcode11: " << +picParams->m_fcode11 << std::endl;
5294 oss << "m_lastPicInStream: " << +picParams->m_lastPicInStream << std::endl;
5295 oss << "m_newGop: " << +picParams->m_newGop << std::endl;
5296 oss << "m_gopPicSize: " << +picParams->m_gopPicSize << std::endl;
5297 oss << "m_gopRefDist: " << +picParams->m_gopRefDist << std::endl;
5298 oss << "m_gopOptFlag: " << +picParams->m_gopOptFlag << std::endl;
5299 oss << "m_timeCode: " << +picParams->m_timeCode << std::endl;
5300 oss << "m_temporalReference: " << +picParams->m_temporalReference << std::endl;
5301 oss << "m_vbvDelay: " << +picParams->m_vbvDelay << std::endl;
5302 oss << "m_repeatFirstField: " << +picParams->m_repeatFirstField << std::endl;
5303 oss << "m_compositeDisplayFlag: " << +picParams->m_compositeDisplayFlag << std::endl;
5304 oss << "m_vaxis: " << +picParams->m_vaxis << std::endl;
5305 oss << "m_fieldSequence: " << +picParams->m_fieldSequence << std::endl;
5306 oss << "m_subCarrier: " << +picParams->m_subCarrier << std::endl;
5307 oss << "m_burstAmplitude: " << +picParams->m_burstAmplitude << std::endl;
5308 oss << "m_subCarrierPhase: " << +picParams->m_subCarrierPhase << std::endl;
5309
5310 const char *fileName = m_debugInterface->CreateFileName(
5311 "_DDIEnc",
5312 CodechalDbgBufferType::bufPicParams,
5313 CodechalDbgExtType::txt);
5314
5315 std::ofstream ofs(fileName, std::ios::out);
5316 ofs << oss.str();
5317 ofs.close();
5318 return MOS_STATUS_SUCCESS;
5319 }
5320
DumpSliceParams(CodecEncodeMpeg2SliceParmas * sliceParams)5321 MOS_STATUS CodechalEncodeMpeg2::DumpSliceParams(
5322 CodecEncodeMpeg2SliceParmas *sliceParams)
5323 {
5324 CODECHAL_DEBUG_FUNCTION_ENTER;
5325
5326 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
5327 {
5328 return MOS_STATUS_SUCCESS;
5329 }
5330
5331 CODECHAL_DEBUG_CHK_NULL(sliceParams);
5332
5333 std::ostringstream oss;
5334 oss.setf(std::ios::showbase | std::ios::uppercase);
5335
5336 oss << "m_numMbsForSlice: " << +sliceParams->m_numMbsForSlice << std::endl;
5337 oss << "m_firstMbX: " << +sliceParams->m_firstMbX << std::endl;
5338 oss << "m_firstMbY: " << +sliceParams->m_firstMbY << std::endl;
5339 oss << "m_intraSlice: " << +sliceParams->m_intraSlice << std::endl;
5340 oss << "m_quantiserScaleCode: " << +sliceParams->m_quantiserScaleCode << std::endl;
5341
5342 const char *fileName = m_debugInterface->CreateFileName(
5343 "_DDIEnc",
5344 CodechalDbgBufferType::bufSlcParams,
5345 CodechalDbgExtType::txt);
5346
5347 std::ofstream ofs(fileName, std::ios::out);
5348 ofs << oss.str();
5349 ofs.close();
5350
5351 return MOS_STATUS_SUCCESS;
5352 }
5353
DumpVuiParams(CodecEncodeMpeg2VuiParams * vuiParams)5354 MOS_STATUS CodechalEncodeMpeg2::DumpVuiParams(
5355 CodecEncodeMpeg2VuiParams *vuiParams)
5356 {
5357 CODECHAL_DEBUG_FUNCTION_ENTER;
5358 CODECHAL_DEBUG_CHK_NULL(vuiParams);
5359
5360 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrVuiParams))
5361 {
5362 return MOS_STATUS_SUCCESS;
5363 }
5364
5365 std::ostringstream oss;
5366 oss.setf(std::ios::showbase | std::ios::uppercase);
5367
5368 oss << "m_videoFormat: " << +vuiParams->m_videoFormat << std::endl;
5369 oss << "m_colourDescription: " << +vuiParams->m_colourDescription << std::endl;
5370 oss << "m_colourPrimaries: " << +vuiParams->m_colourPrimaries << std::endl;
5371 oss << "m_transferCharacteristics: " << +vuiParams->m_transferCharacteristics << std::endl;
5372 oss << "m_matrixCoefficients: " << +vuiParams->m_matrixCoefficients << std::endl;
5373 oss << "m_displayHorizontalSize: " << +vuiParams->m_displayHorizontalSize << std::endl;
5374 oss << "m_displayVerticalSize: " << +vuiParams->m_displayVerticalSize << std::endl;
5375
5376 const char *fileName = m_debugInterface->CreateFileName(
5377 "_DDIEnc",
5378 CodechalDbgBufferType::bufVuiParams,
5379 CodechalDbgExtType::txt);
5380
5381 std::ofstream ofs(fileName, std::ios::out);
5382 ofs << oss.str();
5383 ofs.close();
5384 return MOS_STATUS_SUCCESS;
5385 }
5386 #endif
5387
5388 /**************************************************************************
5389 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 6
5390 * 26 degree walking pattern
5391 * 0 1 2 3 4
5392 * -----------------------
5393 * 0 | 0 1 2 4 6
5394 * 1 | 3 5 7 9 11
5395 * 2 | 8 10 12 14 16
5396 * 3 | 13 15 17 19 21
5397 * 4 | 18 20 22 24 26
5398 * 5 | 23 25 27 28 29
5399 ***************************************************************************/
MBWalker(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5400 void CodechalEncodeMpeg2::MBWalker(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5401 {
5402 uint16_t i, j;
5403 uint16_t numMBs = picWidthInMB * picHeightInMB;
5404 uint16_t curX = 0, curY = 0, wflenX, wflenY;
5405 uint16_t wfstart = 0, wflen;
5406 uint16_t walkX, walkY;
5407
5408 wflenY = picHeightInMB - 1;
5409 for (i = 0; i < numMBs; i++)
5410 {
5411 // Get current region length
5412 wflenX = curX / 2;
5413 wflen = (wflenX < wflenY) ? wflenX : wflenY;
5414
5415 mbmap[wfstart] = curY * picWidthInMB + curX;
5416
5417 if (wfstart == (numMBs - 1))
5418 break;
5419
5420 walkX = curX - 2;
5421 walkY = curY + 1;
5422 for (j = 0; j < wflen; j++)
5423 {
5424 mbmap[wfstart + j + 1] = walkY * picWidthInMB + walkX;
5425 walkX -= 2;
5426 walkY++;
5427 }
5428
5429 // Start new region
5430 if (curX == (picWidthInMB - 1))
5431 {
5432 // Right picture boundary reached, adjustment required
5433 curX--;
5434 curY++;
5435 wflenY--;
5436 }
5437 else
5438 {
5439 curX++;
5440 }
5441 wfstart += (wflen + 1);
5442 }
5443 }
5444
5445 /**************************************************************************
5446 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 6
5447 * 45 degree pattern
5448 * 0 1 2 3 4
5449 * -----------------------
5450 * 0 | 0 1 3 6 10
5451 * 1 | 2 4 7 11 15
5452 * 2 | 5 8 12 16 20
5453 * 3 | 9 13 17 21 24
5454 * 4 | 14 18 22 25 27
5455 * 5 | 19 23 26 28 29
5456 ***************************************************************************/
MBWalker45Degree(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5457 void CodechalEncodeMpeg2::MBWalker45Degree(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5458 {
5459 uint16_t i, j;
5460 uint16_t numMBs = picWidthInMB * picHeightInMB;
5461 uint16_t curX = 0, curY = 0, wflenX, wflenY;
5462 uint16_t wfstart = 0, wflen;
5463 uint16_t walkX, walkY;
5464
5465 wflenY = picHeightInMB - 1;
5466 for (i = 0; i < numMBs; i++)
5467 {
5468 // Get current region length
5469 wflenX = curX;
5470 wflen = (wflenX < wflenY) ? wflenX : wflenY;
5471
5472 mbmap[wfstart] = curY * picWidthInMB + curX;
5473
5474 if (wfstart == (numMBs - 1))
5475 break;
5476
5477 walkX = curX - 1;
5478 walkY = curY + 1;
5479 for (j = 0; j < wflen; j++)
5480 {
5481 mbmap[wfstart + j + 1] = walkY * picWidthInMB + walkX;
5482 walkX -= 1;
5483 walkY++;
5484 }
5485
5486 // Start new region
5487 if (curX == (picWidthInMB - 1))
5488 {
5489 // Right picture boundary reached, adjustment required
5490 curY++;
5491 wflenY--;
5492 }
5493 else
5494 {
5495 curX++;
5496 }
5497 wfstart += (wflen + 1);
5498 }
5499 }
5500
5501 /**************************************************************************
5502 * MB sequence in a MBAFF picture with WidthInMB = 5 & HeightInMB = 6
5503 * 26 degree walking pattern
5504 * 0 1 2 3 4
5505 * -----------------------
5506 * 0 | 0 2 4 8 12
5507 * 1 | 1 3 6 10 15
5508 * 2 | 5 9 13 18 22
5509 * 3 | 7 11 16 20 24
5510 * 4 | 14 19 23 26 28
5511 * 5 | 17 21 25 27 29
5512 ***************************************************************************/
MBWalkerMBAFF(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5513 void CodechalEncodeMpeg2::MBWalkerMBAFF(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5514 {
5515 uint16_t i, j, k;
5516 uint16_t numMBs = picWidthInMB * picHeightInMB;
5517 uint16_t curX = 0, curY = 0, wflenX, wflenY;
5518 uint16_t wfstart = 0, wflen;
5519 uint16_t walkX, walkY;
5520
5521 wflenY = picHeightInMB / 2 - 1;
5522 for (i = 0; i < numMBs; i++)
5523 {
5524 // Get current region length
5525 wflenX = curX / 2;
5526 wflen = (wflenX < wflenY) ? wflenX : wflenY;
5527
5528 mbmap[wfstart] = curY * picWidthInMB + curX * 2;
5529 mbmap[wfstart + wflen + 1] = mbmap[wfstart] + 1;
5530
5531 if ((wfstart + wflen + 1) == (numMBs - 1))
5532 break;
5533
5534 walkX = curX - 2;
5535 walkY = curY + 2;
5536 for (j = 0; j < wflen; j++)
5537 {
5538 k = wfstart + j + 1;
5539 mbmap[k] = walkY * picWidthInMB + walkX * 2;
5540 mbmap[k + wflen + 1] = mbmap[k] + 1;
5541 walkX -= 2;
5542 walkY += 2;
5543 }
5544
5545 // Start new region
5546 if (curX == (picWidthInMB - 1))
5547 {
5548 // Right picture boundary reached, adjustment required
5549 curX--;
5550 curY += 2;
5551 wflenY--;
5552 }
5553 else
5554 {
5555 curX++;
5556 }
5557 wfstart += ((wflen + 1) * 2);
5558 }
5559 }
5560
5561 /**************************************************************************
5562 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 5
5563 * Raster scan pattern
5564 * 0 1 2 3 4
5565 * -----------------------
5566 * 0 | 0 1 2 3 4
5567 * 1 | 5 6 7 8 9
5568 * 2 | 10 11 12 13 14
5569 * 3 | 15 16 17 18 19
5570 * 4 | 20 21 22 23 24
5571 ***************************************************************************/
MBWalkerRasterScan(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5572 void CodechalEncodeMpeg2::MBWalkerRasterScan(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5573 {
5574 uint32_t i;
5575 uint32_t numMBs = picWidthInMB * picHeightInMB;
5576
5577 for (i = 0; i < numMBs; i++)
5578 {
5579 mbmap[i] = (uint16_t)i;
5580 }
5581 }
5582
5583 /**************************************************************************
5584 * MB sequence in a non-MBAFF picture with WidthInMB = 5 & HeightInMB = 5
5585 * Vertical scan pattern
5586 * 0 1 2 3 4
5587 * -----------------------
5588 * 0 | 0 5 10 15 20
5589 * 1 | 1 6 11 16 21
5590 * 2 | 2 7 12 17 22
5591 * 3 | 3 8 13 18 23
5592 * 4 | 4 9 14 19 24
5593 ***************************************************************************/
MBWalkerVerticalScan(uint16_t picWidthInMB,uint16_t picHeightInMB,uint16_t * mbmap)5594 void CodechalEncodeMpeg2::MBWalkerVerticalScan(uint16_t picWidthInMB, uint16_t picHeightInMB, uint16_t *mbmap)
5595 {
5596 uint32_t i, j, k;
5597
5598 for (i = 0, k = 0; i < picWidthInMB; i++)
5599 {
5600 for (j = 0; j < picHeightInMB; j++)
5601 {
5602 mbmap[k++] = (uint16_t)(i + j * picWidthInMB);
5603 }
5604 }
5605 }
5606