1 /*
2 * Copyright (c) 2021, 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     encode_jpeg_packet.h
24 //! \brief    Defines the interface to adapt to JPEG pipeline
25 //!
26 
27 #ifndef __ENCODE_JPEG_PACKET_H__
28 #define __ENCODE_JPEG_PACKET_H__
29 
30 #include "media_cmd_packet.h"
31 #include "encode_jpeg_pipeline.h"
32 #include "encode_jpeg_basic_feature.h"
33 #include "encode_jpeg_packer_feature.h"
34 #include "encode_status_report.h"
35 #include "mhw_vdbox_mfx_itf.h"
36 #include "mhw_mi_itf.h"
37 
38 namespace encode
39 {
40 struct EncodeJpegHuffTable
41 {
42     uint32_t m_tableClass;  //!< table class
43     uint32_t m_tableID;     //!< table ID
44     //This is the max size possible for these arrays, for DC table the actual occupied bits will be lesser
45     // For AC table we need one extra byte to store 00, denoting end of huffman values
46     uint8_t  m_huffSize[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL + 1];  //!< Huffman size, occupies 1 byte in HW command
47     uint16_t m_huffCode[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL + 1];  //!< Huffman code, occupies 2 bytes in HW command
48 };
49 
50 struct EncodeJpegHuffTableParams
51 {
52     uint32_t    HuffTableID;
53     uint8_t     pDCCodeLength[JPEG_NUM_HUFF_TABLE_DC_HUFFVAL]; // 12 values of 1 byte each
54     uint16_t    pDCCodeValues[JPEG_NUM_HUFF_TABLE_DC_HUFFVAL]; // 12 values of 2 bytes each
55     uint8_t     pACCodeLength[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL]; // 162 values of 1 byte each
56     uint16_t    pACCodeValues[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL]; // 162 values of 2 bytes each
57 };
58 
59 class JpegPkt : public CmdPacket, public MediaStatusReportObserver, public mhw::vdbox::mfx::Itf::ParSetting, public mhw::mi::Itf::ParSetting
60 {
61 public:
62 
63     JpegPkt(MediaPipeline *pipeline, MediaTask *task, CodechalHwInterfaceNext *hwInterface);
64 
~JpegPkt()65     virtual ~JpegPkt() {}
66 
67     //!
68     //! \brief  Initialize the media packet, allocate required resources
69     //! \return MOS_STATUS
70     //!         MOS_STATUS_SUCCESS if success, else fail reason
71     //!
72     virtual MOS_STATUS Init() override;
73 
74     //!
75     //! \brief  Prepare interal parameters, should be invoked for each frame
76     //! \return MOS_STATUS
77     //!         MOS_STATUS_SUCCESS if success, else fail reason
78     //!
79     virtual MOS_STATUS Prepare() override;
80 
81     //!
82     //! \brief  Destroy the media packet and release the resources
83     //! \return MOS_STATUS
84     //!         MOS_STATUS_SUCCESS if success, else fail reason
85     //!
86     virtual MOS_STATUS Destroy() override;
87 
88     //!
89     //! \brief  Add the command sequence into the commandBuffer and
90     //!         and return to the caller task
91     //! \param  [in] commandBuffer
92     //!         Pointer to the command buffer which is allocated by caller
93     //! \return MOS_STATUS
94     //!         MOS_STATUS_SUCCESS if success, else fail reason
95     //!
96     virtual MOS_STATUS Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t packetPhase = otherPacket) override;
97 
98     //!
99     //! \brief  One frame is completed
100     //! \param  [in] mfxStatus
101     //!         pointer to status buffer which for MFX
102     //! \param  [in] rcsStatus
103     //!         pointer to status buffer which for RCS
104     //! \param  [in, out] statusReport
105     //!         pointer of EncoderStatusReport
106     //! \return MOS_STATUS
107     //!         MOS_STATUS_SUCCESS if success, else fail reason
108     //!
109     virtual MOS_STATUS Completed(void *mfxStatus, void *rcsStatus, void *statusReport) override;
110 
111     //!
112     //! \brief  Calculate Command Size
113     //!
114     //! \param  [in, out] commandBufferSize
115     //!         requested size
116     //! \param  [in, out] requestedPatchListSize
117     //!         requested size
118     //! \return MOS_STATUS
119     //!         status
120     //!
121     virtual MOS_STATUS CalculateCommandSize(
122         uint32_t &commandBufferSize,
123         uint32_t &requestedPatchListSize) override;
124 
125     //!
126     //! \brief    Calculate Mfx Commands Size
127     //!
128     //! \return   MOS_STATUS
129     //!           MOS_STATUS_SUCCESS if success
130     //!
131     virtual MOS_STATUS CalculateMfxCommandsSize();
132 
133     MOS_STATUS GetMfxPrimitiveCommandsDataSize(
134         uint32_t *commandsSize,
135         uint32_t *patchListSize);
136 
137     MOS_STATUS GetMfxStateCommandsDataSize(
138         uint32_t *commandsSize,
139         uint32_t *patchListSize);
140 
141     MmioRegistersMfx *SelectVdboxAndGetMmioRegister(
142         MHW_VDBOX_NODE_IND  index,
143         PMOS_COMMAND_BUFFER pCmdBuffer);
144 
145     //!
146     //! \brief    Read Image status for status report
147     //! \param    vdboxIndex
148     //!           [in] the vdbox index
149     //! \param    params
150     //!           [in] the parameters for Image status read
151     //! \param    cmdBuffer
152     //!           [in, out] the command buffer
153     //! \return   MOS_STATUS
154     //!           MOS_STATUS_SUCCESS if success, else fail reason
155     //!
156     MOS_STATUS ReadImageStatus(
157         const EncodeStatusReadParams &params,
158         PMOS_COMMAND_BUFFER           cmdBuffer);
159 
160 protected:
161 
162     //!
163     //! \brief    Add command to read Mfc status
164     //!
165     //! \param    [in, out] cmdBuffer
166     //!           Command buffer
167     //!
168     //! \return   MOS_STATUS
169     //!           MOS_STATUS_SUCCESS if success, else fail reason
170     //!
171     MOS_STATUS ReadMfcStatus(MOS_COMMAND_BUFFER &cmdBuffer);
172 
173     //!
174     //! \brief    Add picture-level MFX commands to command buffer
175     //!
176     //! \param    [in, out] cmdBuffer
177     //!           Reference to the command buffer
178     //!
179     //! \return   MOS_STATUS
180     //!           MOS_STATUS_SUCCESS if success, else fail reason
181     //!
182     MOS_STATUS AddPictureMfxCommands(MOS_COMMAND_BUFFER &cmdBuffer);
183 
184     virtual MOS_STATUS EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer) override;
185 
186     MOS_STATUS SendPrologCmds(MOS_COMMAND_BUFFER &cmdBuffer);
187 
188     MOS_STATUS StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer) override;
189 
190     MOS_STATUS PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER &cmdBuffer);
191 
192     MOS_STATUS PatchSliceLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase);
193 
194     void SetPerfTag(uint16_t type, uint16_t mode, uint16_t picCodingType);
195 
196     //!
197     //! \brief  Calculate Command Buffer Size
198     //!
199     //! \return uint32_t
200     //!         Command buffer size calculated
201     //!
202     virtual uint32_t CalculateCommandBufferSize();
203 
204     //!
205     //! \brief  Calculate Patch List Size
206     //!
207     //! \return uint32_t
208     //!         Patchlist size calculated
209     //!
210     virtual uint32_t CalculatePatchListSize();
211 
212     //!
213     //! \brief    Map Huffman value index, implemented based on table K.5 in JPEG spec.
214     //!
215     //! \param    [in] huffValIndex
216     //!           Huffman Value Index
217     //!
218     //! \return   The mapped index
219     //!
220     uint8_t MapHuffValIndex(uint8_t huffValIndex);
221 
222     //!
223     //! \brief    Generate table of Huffman code sizes, implemented based on Flowchart in figure C.1 in JPEG spec
224     //!
225     //! \param    [in] bits
226     //!           Contains the number of codes of each size
227     //! \param    [out] huffSize
228     //!           Huffman Size table
229     //! \param    [out] lastK
230     //!           Index of the last entry in the table
231     //!
232     //! \return   MOS_STATUS
233     //!           MOS_STATUS_SUCCESS if success, else fail reason
234     //!
235     MOS_STATUS GenerateSizeTable(
236         uint8_t  bits[],
237         uint8_t  huffSize[],
238         uint8_t &lastK);
239 
240     //!
241     //! \brief    Generate table of Huffman codes, implemented based on Flowchart in figure C.2 in JPEG spec
242     //!
243     //! \param    [in] huffSize
244     //!           Huffman Size table
245     //! \param    [out] huffCode
246     //!           Huffman Code table
247     //!
248     //! \return   MOS_STATUS
249     //!           MOS_STATUS_SUCCESS if success, else fail reason
250     //!
251     MOS_STATUS GenerateCodeTable(
252         uint8_t  huffSize[],
253         uint16_t huffCode[]);
254 
255     //!
256     //! \brief    Generate Huffman codes in symbol value order, implemented based on Flowchart in figure C.3 in JPEG spec
257     //!
258     //! \param    [in] huffVal
259     //!           Huffman Value table
260     //! \param    [in, out] huffSize
261     //!           Huffman Size table
262     //! \param    [in, out] huffCode
263     //!           Huffman Code table
264     //! \param    [in] lastK
265     //!           Index of the last entry in the table
266     //!
267     //! \return   MOS_STATUS
268     //!           MOS_STATUS_SUCCESS if success, else fail reason
269     //!
270     MOS_STATUS OrderCodes(
271         uint8_t  huffVal[],
272         uint8_t  huffSize[],
273         uint16_t huffCode[],
274         uint8_t  lastK);
275 
276     //!
277     //! \brief    Convert Huffman data to table, including 3 steps: Step 1 - Generate size table, Step2 - Generate code table, Step 3 - Order codes.
278     //!
279     //! \param    [in] huffmanData
280     //!           Huffman Data
281     //! \param    [out] huffmanTable
282     //!           Huffman table
283     //!
284     //! \return   MOS_STATUS
285     //!           MOS_STATUS_SUCCESS if success, else fail reason
286     //!
287     MOS_STATUS ConvertHuffDataToTable(
288         CodecEncodeJpegHuffData huffmanData,
289         EncodeJpegHuffTable *huffmanTable);
290 
291     //!
292     //! \brief    Add SOI
293     //!
294     //! \param    [out] cmdBuffer
295     //!           Command Buffer for submit
296     //!
297     //! \return   MOS_STATUS
298     //!           MOS_STATUS_SUCCESS if success, else fail reason
299     //!
300     MOS_STATUS AddSOI(PMOS_COMMAND_BUFFER cmdBuffer) const;
301 
302     //!
303     //! \brief    Add Application Data
304     //!
305     //! \param    [out] cmdBuffer
306     //!           Command Buffer for submit
307     //!
308     //! \return   MOS_STATUS
309     //!           MOS_STATUS_SUCCESS if success, else fail reason
310     //!
311     MOS_STATUS AddApplicationData(PMOS_COMMAND_BUFFER cmdBuffer) const;
312 
313     //!
314     //! \brief    Add Quant Tables
315     //!
316     //! \param    [out] cmdBuffer
317     //!           Command Buffer for submit
318     //! \param    [in] useSingleDefaultQuantTable
319     //!           if use single default quant talbe
320     //!
321     //! \return   MOS_STATUS
322     //!           MOS_STATUS_SUCCESS if success, else fail reason
323     //!
324     MOS_STATUS AddQuantTable(PMOS_COMMAND_BUFFER cmdBuffer, bool useSingleDefaultQuantTable) const;
325 
326     //!
327     //! \brief    Add Header for frame
328     //!
329     //! \param    [out] cmdBuffer
330     //!           Command Buffer for submit
331     //! \param    [in] useSingleDefaultQuantTable
332     //!           if use single default quant talbe
333     //!
334     //! \return   MOS_STATUS
335     //!           MOS_STATUS_SUCCESS if success, else fail reason
336     //!
337     MOS_STATUS AddFrameHeader(PMOS_COMMAND_BUFFER cmdBuffer, bool useSingleDefaultQuantTable) const;
338 
339     //!
340     //! \brief    Add Huffman Table
341     //!
342     //! \param    [out] cmdBuffer
343     //!           Command Buffer for submit
344     //! \param    [in] tblInd
345     //!           index of Huffman table
346     //!
347     //! \return   MOS_STATUS
348     //!           MOS_STATUS_SUCCESS if success, else fail reason
349     //!
350     MOS_STATUS AddHuffmanTable(PMOS_COMMAND_BUFFER cmdBuffer, uint32_t tblInd) const;
351 
352     //!
353     //! \brief    Add Restart interval
354     //!
355     //! \param    [out] cmdBuffer
356     //!           Command Buffer for submit
357     //!
358     //! \return   MOS_STATUS
359     //!           MOS_STATUS_SUCCESS if success, else fail reason
360     //!
361     MOS_STATUS AddRestartInterval(PMOS_COMMAND_BUFFER cmdBuffer) const;
362 
363     //!
364     //! \brief    Add Scan header
365     //!
366     //! \param    [out] cmdBuffer
367     //!           Command Buffer for submit
368     //!
369     //! \return   MOS_STATUS
370     //!           MOS_STATUS_SUCCESS if success, else fail reason
371     //!
372     MOS_STATUS AddScanHeader(PMOS_COMMAND_BUFFER cmdBuffer) const;
373 
374     MOS_STATUS InitMissedQuantTables();
375 
376     MOS_STATUS InitQuantMatrix();
377 
378     //!
379     //! \brief  set MFC_JPEG_HUFF_TABLE - Convert encoded huffman table to actual table for HW
380     //!         We need a different params struct for JPEG Encode Huffman table because JPEG decode huffman table has Bits and codes,
381     //!         whereas JPEG encode huffman table has huffman code lengths and values
382     //!
383     //! \return MOS_STATUS
384     //!
385     MOS_STATUS InitHuffTable();
386 
387     MOS_STATUS AddAllCmds_MFX_FQM_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
388 
389     MOS_STATUS AddAllCmds_MFC_JPEG_HUFF_TABLE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const;
390 
391     MOS_STATUS AddAllCmds_MFX_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const;
392 
393     MHW_SETPAR_DECL_HDR(MI_STORE_REGISTER_MEM);
394 
395 #if USE_CODECHAL_DEBUG_TOOL
396     //! \brief    Dump the output resources in status report callback function
397     //!
398     //! \param    [in] encodeStatusMfx
399     //!           Pointer to encoder status for vdbox
400     //! \param    [in] statusReportData
401     //!           Pointer to encoder status report data
402     //!
403     //! \return   MOS_STATUS
404     //!           MOS_STATUS_SUCCESS if success, else fail reason
405     //!
406     MOS_STATUS DumpResources(
407         EncodeStatusMfx *       encodeStatusMfx,
408         EncodeStatusReportData *statusReportData);
409 
410     MOS_STATUS DumpHuffmanTable(
411         CodecEncodeJpegHuffmanDataArray *huffmanTable);
412 
413     MOS_STATUS DumpPicParams(
414         CodecEncodeJpegPictureParams *picParams);
415 
416     MOS_STATUS DumpScanParams(
417         CodecEncodeJpegScanHeader *scanParams);
418 
419     MOS_STATUS DumpQuantTables(
420         CodecEncodeJpegQuantTable *quantTable);
421 
422 #endif
423 
424     JpegPipeline             *m_pipeline       = nullptr;
425 
426     // Interfaces
427     CodechalHwInterfaceNext     *m_hwInterface    = nullptr;
428     JpegBasicFeature        *m_basicFeature   = nullptr;
429     JpegPackerFeature       *m_jpgPkrFeature  = nullptr;
430     MediaFeatureManager     *m_featureManager = nullptr;
431     EncodeMemComp           *m_mmcState       = nullptr;
432     EncodeCp                *m_encodecp       = nullptr;
433     CodechalDebugInterface  *m_debugInterface = nullptr;
434 
435     std::shared_ptr<mhw::vdbox::mfx::Itf>   m_mfxItf   = nullptr;
436 
437     // Parameters passed from application
438     CodecEncodeJpegPictureParams        *m_jpegPicParams    = nullptr;  //!< Pointer to picture parameter
439     CodecEncodeJpegScanHeader           *m_jpegScanParams   = nullptr;  //!< Pointer to slice parameter
440     CodecEncodeJpegQuantTable           *m_jpegQuantTables  = nullptr;
441     CodecEncodeJpegHuffmanDataArray     *m_jpegHuffmanTable = nullptr;  //!< Pointer to IQWidght ScaleLists
442     void                                *m_applicationData  = nullptr;  //!< Pointer to Application data
443 
444     // Patch List
445     bool m_usePatchList                = 0;  //!< Use Ptach List or not
446 
447     // CMD buffer sizes
448     uint32_t m_pictureStatesSize       = 0;  //!< Picture states size
449     uint32_t m_picturePatchListSize    = 0;  //!< Picture patch list size
450     uint32_t m_sliceStatesSize         = 0;  //!< Slice states size
451     uint32_t m_slicePatchListSize      = 0;  //!< Slice patch list size
452 
453     uint32_t m_numHuffBuffers          = 0;
454     uint32_t m_numQuantTables          = 0;
455 
456     bool     m_repeatHuffTable         = false;
457 
458     PMOS_RESOURCE m_pResource                      = nullptr;
459     uint32_t      m_dwOffset                       = 0;
460     uint32_t      m_dwValue                        = 0;
461 
462     CodecJpegQuantMatrix      m_jpegQuantMatrix                                = {};
463     EncodeJpegHuffTableParams m_huffTableParams[JPEG_MAX_NUM_HUFF_TABLE_INDEX] = {};
464 
465     MHW_VDBOX_NODE_IND m_vdboxIndex    = MHW_VDBOX_NODE_1;  //!< Index of VDBOX
466 
467 MEDIA_CLASS_DEFINE_END(encode__JpegPkt)
468 };
469 
470 }  // namespace encode
471 
472 #endif  // !__ENCODE_JPEG_PACKET_H__
473