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