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