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 //!
24 //! \file     decode_jpeg_basic_features.cpp
25 //! \brief    Defines the common interface for decode jpeg basic feature
26 //!
27 #include "decode_jpeg_basic_feature.h"
28 #include "decode_utils.h"
29 #include "decode_allocator.h"
30 #include "decode_resource_array.h"
31 
32 namespace decode
33 {
~JpegBasicFeature()34 JpegBasicFeature::~JpegBasicFeature()
35 {
36 }
37 
Init(void * setting)38 MOS_STATUS JpegBasicFeature::Init(void *setting)
39 {
40     DECODE_FUNC_CALL();
41 
42     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
43     DECODE_CHK_STATUS(DecodeBasicFeature::Init(setting));
44 
45     return MOS_STATUS_SUCCESS;
46 }
47 
Update(void * params)48 MOS_STATUS JpegBasicFeature::Update(void *params)
49 {
50     DECODE_FUNC_CALL();
51 
52     PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
53 
54     DECODE_CHK_NULL(params);
55     DECODE_CHK_STATUS(DecodeBasicFeature::Update(params));
56 
57     CodechalDecodeParams *decodeParams = (CodechalDecodeParams *)params;
58 
59     m_jpegPicParams    = (CodecDecodeJpegPicParams *)decodeParams->m_picParams;
60     m_jpegPicParams    = (CodecDecodeJpegPicParams *)decodeParams->m_picParams;
61     m_jpegQMatrix      = (CodecJpegQuantMatrix *)decodeParams->m_iqMatrixBuffer;
62     m_jpegHuffmanTable = (PCODECHAL_DECODE_JPEG_HUFFMAN_TABLE)decodeParams->m_huffmanTable;
63     m_jpegScanParams   = (CodecDecodeJpegScanParameter *)decodeParams->m_sliceParams;
64     DECODE_CHK_NULL(m_jpegPicParams);
65 
66     GetRenderTargetFormat(&m_destSurface.Format);
67 
68     DECODE_CHK_STATUS(CheckSupportedFormat(
69         &m_destSurface.Format));
70 
71     uint32_t totalDataLength;
72 
73     totalDataLength = m_jpegScanParams->ScanHeader[m_jpegScanParams->NumScans - 1].DataOffset +
74                       m_jpegScanParams->ScanHeader[m_jpegScanParams->NumScans - 1].DataLength;
75 
76     //update m_datasize
77     DECODE_CHK_STATUS(SetRequiredBitstreamSize(totalDataLength));
78 
79     DECODE_CHK_STATUS(SetPictureStructs());
80 
81     return MOS_STATUS_SUCCESS;
82 }
83 
GetRenderTargetFormat(PMOS_FORMAT format)84 void JpegBasicFeature::GetRenderTargetFormat(PMOS_FORMAT format)
85 {
86     if (*format == Format_420O || *format == Format_AYUV)
87     {
88         if (m_osInterface != nullptr)
89         {
90             *format = m_osInterface->pfnOsFmtToMosFmt((MOS_OS_FORMAT)m_jpegPicParams->m_renderTargetFormat);
91         }
92     }
93 }
94 
CheckSupportedFormat(PMOS_FORMAT format)95 MOS_STATUS JpegBasicFeature::CheckSupportedFormat(PMOS_FORMAT format)
96 {
97     DECODE_FUNC_CALL();
98 
99     //No support for RGBP/BGRP channel swap or YUV/RGB conversion!
100     switch (*format)
101     {
102     case Format_BGRP:
103         if (m_jpegPicParams->m_chromaType == jpegRGB ||
104             m_jpegPicParams->m_chromaType == jpegYUV444)
105         {
106             return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
107         }
108         break;
109     case Format_RGBP:
110         if (m_jpegPicParams->m_chromaType == jpegYUV444)
111         {
112             return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
113         }
114         break;
115     case Format_Y416:
116     case Format_AYUV:
117     case Format_AUYV:
118     case Format_Y410:
119         if (m_jpegPicParams->m_chromaType == jpegRGB ||
120             m_jpegPicParams->m_chromaType == jpegBGR)
121         {
122             return MOS_STATUS_PLATFORM_NOT_SUPPORTED;
123         }
124         break;
125     default:
126         break;
127     }
128 
129     return MOS_STATUS_SUCCESS;
130 }
131 
SetRequiredBitstreamSize(uint32_t requiredSize)132 MOS_STATUS JpegBasicFeature::SetRequiredBitstreamSize(uint32_t requiredSize)
133 {
134     DECODE_FUNC_CALL();
135 
136     if (requiredSize > m_dataSize)
137     {
138         m_dataOffset = 0;
139         m_dataSize   = MOS_ALIGN_CEIL(requiredSize, MHW_CACHELINE_SIZE);
140     }
141 
142     DECODE_NORMALMESSAGE("Estimate bitstream size in this Frame: %u", requiredSize);
143     return MOS_STATUS_SUCCESS;
144 }
145 
SetPictureStructs()146 MOS_STATUS JpegBasicFeature::SetPictureStructs()
147 {
148     DECODE_FUNC_CALL();
149     uint32_t widthAlign  = 0;
150     uint32_t heightAlign = 0;
151 
152     // Overwriting surface width and height of destination surface, so it comes from Picture Parameters struct
153     if (!m_jpegPicParams->m_interleavedData)
154     {
155         widthAlign  = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
156         heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
157     }
158     else
159     {
160         switch (m_jpegPicParams->m_chromaType)
161         {
162         case jpegYUV400:
163         case jpegYUV444:
164         case jpegRGB:
165         case jpegBGR:
166             widthAlign  = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
167             heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
168             break;
169         case jpegYUV422V2Y:
170             widthAlign  = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
171             heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
172             break;
173         case jpegYUV422H2Y:
174             widthAlign  = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
175             heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
176             break;
177         case jpegYUV411:
178             widthAlign  = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X4);
179             heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE);
180             break;
181         default:  // YUV422H_4Y, YUV422V_4Y & YUV420
182             widthAlign  = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameWidth, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
183             heightAlign = MOS_ALIGN_CEIL(m_jpegPicParams->m_frameHeight, CODECHAL_DECODE_JPEG_BLOCK_ALIGN_SIZE_X2);
184             break;
185         }
186     }
187 
188     if ((m_jpegPicParams->m_rotation == jpegRotation90) || (m_jpegPicParams->m_rotation == jpegRotation270))
189     {
190         // Interchanging picture width and height for 90/270 degree rotation
191         m_destSurface.dwWidth  = heightAlign;
192         m_destSurface.dwHeight = widthAlign;
193     }
194     else
195     {
196         m_destSurface.dwWidth  = widthAlign;
197         m_destSurface.dwHeight = heightAlign;
198     }
199 
200     return MOS_STATUS_SUCCESS;
201 }
202 }  // namespace decode
203