1 /*
2 * Copyright (c) 2018-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_vp9_pipeline.h
24 //! \brief    Defines the interface for vp9 encode pipeline
25 //!
26 
27 #include "encode_vp9_pipeline.h"
28 #include "encode_utils.h"
29 
30 namespace encode
31 {
Vp9Pipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)32 Vp9Pipeline::Vp9Pipeline(
33     CodechalHwInterfaceNext *   hwInterface,
34     CodechalDebugInterface *debugInterface)
35     : EncodePipeline(hwInterface, debugInterface)
36 {
37 }
38 
Initialize(void * settings)39 MOS_STATUS Vp9Pipeline::Initialize(void *settings)
40 {
41     ENCODE_FUNC_CALL();
42     ENCODE_CHK_STATUS_RETURN(InitUserSetting(m_userSettingPtr));
43     ENCODE_CHK_STATUS_RETURN(EncodePipeline::Initialize(settings));
44 
45     return MOS_STATUS_SUCCESS;
46 }
47 
Uninitialize()48 MOS_STATUS Vp9Pipeline::Uninitialize()
49 {
50     ENCODE_FUNC_CALL();
51     return EncodePipeline::Uninitialize();
52 }
53 
ReportUserSettingValue(const std::string & valueName,const MediaUserSetting::Value & value,const MediaUserSetting::Group & group)54 MOS_STATUS Vp9Pipeline::ReportUserSettingValue(const std::string &valueName,
55     const MediaUserSetting::Value &                               value,
56     const MediaUserSetting::Group &                               group)
57 {
58     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
59 
60 #if (_DEBUG || _RELEASE_INTERNAL)
61     eStatus = ReportUserSettingForDebug(
62         m_userSettingPtr,
63         valueName,
64         value,
65         group);
66 
67     if (eStatus != MOS_STATUS_SUCCESS)
68     {
69         // Print out an error message in non-release builds. Do not report an error: execution can continue.
70         ENCODE_NORMALMESSAGE("Failed to write an user feature key value. Status: ", eStatus);
71         eStatus = MOS_STATUS_SUCCESS;
72     }
73 #endif
74 
75     return eStatus;
76 }
77 
DeclareUserSettingKeyValue(const std::string & valueName,const MediaUserSetting::Group & group,const MediaUserSetting::Value & defaultValue,bool isReportKey)78 MOS_STATUS Vp9Pipeline::DeclareUserSettingKeyValue(const std::string &valueName,
79     const MediaUserSetting::Group &                                   group,
80     const MediaUserSetting::Value &                                   defaultValue,
81     bool                                                              isReportKey)
82 {
83     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
84 
85 #if (_DEBUG || _RELEASE_INTERNAL)
86     eStatus = DeclareUserSettingKeyForDebug(
87         m_userSettingPtr,
88         valueName,
89         group,
90         defaultValue,
91         isReportKey);
92 
93     if (eStatus != MOS_STATUS_SUCCESS)
94     {
95         // Print out an error message in non-release builds. Do not report an error: execution can continue.
96         if (eStatus != MOS_STATUS_FILE_EXISTS)
97         {
98             ENCODE_NORMALMESSAGE("Failed to declare an user feature key value. Status: ", eStatus);
99         }
100         eStatus = MOS_STATUS_SUCCESS;
101     }
102 #endif
103 
104     return eStatus;
105 }
106 
UserFeatureReport()107 MOS_STATUS Vp9Pipeline::UserFeatureReport()
108 {
109     ENCODE_FUNC_CALL();
110     ENCODE_CHK_STATUS_RETURN(EncodePipeline::UserFeatureReport());
111 #if (_DEBUG || _RELEASE_INTERNAL)
112     ENCODE_CHK_STATUS_RETURN(
113         ReportUserSettingValue(__MEDIA_USER_FEATURE_VALUE_SIM_IN_USE,
114             m_osInterface->bSimIsActive,
115             MediaUserSetting::Group::Device));
116 #endif
117     return MOS_STATUS_SUCCESS;
118 }
119 
Prepare(void * params)120 MOS_STATUS Vp9Pipeline::Prepare(void *params)
121 {
122     ENCODE_FUNC_CALL();
123 
124     ENCODE_CHK_STATUS_RETURN(EncodePipeline::Prepare(params));
125 
126     auto basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(Vp9FeatureIDs::basicFeature));
127     ENCODE_CHK_NULL_RETURN(basicFeature);
128 
129     CODECHAL_DEBUG_TOOL(
130         m_debugInterface->m_currPic            = basicFeature->m_currOriginalPic;
131         m_debugInterface->m_bufferDumpFrameNum = basicFeature->m_frameNum + 1;  // +1 for debug purpose with legacy
132         m_debugInterface->m_frameType          = basicFeature->m_pictureCodingType;
133 
134         if (basicFeature->m_newSeq) {
135             ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
136                 basicFeature->m_vp9SeqParams));
137         }
138 
139         ENCODE_CHK_STATUS_RETURN(DumpPicParams(
140             basicFeature->m_vp9PicParams));
141 
142         ENCODE_CHK_STATUS_RETURN(DumpSegmentParams(
143             basicFeature->m_vp9SegmentParams));)
144 
145     return MOS_STATUS_SUCCESS;
146 }
147 
CreateBufferTracker()148 MOS_STATUS Vp9Pipeline::CreateBufferTracker()
149 {
150     return MOS_STATUS_SUCCESS;
151 }
152 
CreateStatusReport()153 MOS_STATUS Vp9Pipeline::CreateStatusReport()
154 {
155     return MOS_STATUS_SUCCESS;
156 }
157 
158 #if USE_CODECHAL_DEBUG_TOOL
DumpSegmentParams(const CODEC_VP9_ENCODE_SEGMENT_PARAMS * segmentParams)159 MOS_STATUS Vp9Pipeline::DumpSegmentParams(
160     const CODEC_VP9_ENCODE_SEGMENT_PARAMS *segmentParams)
161 {
162     ENCODE_FUNC_CALL();
163     ENCODE_CHK_NULL_RETURN(m_debugInterface);
164 
165     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSegmentParams))
166     {
167         return MOS_STATUS_SUCCESS;
168     }
169     CODECHAL_DEBUG_CHK_NULL(segmentParams);
170 
171     std::ostringstream oss;
172     oss.setf(std::ios::showbase | std::ios::uppercase);
173 
174     for (uint8_t i = 0; i < 8; ++i)
175     {
176         oss << "Segment_id = "              << std::dec << +i << std::endl;
177         oss << "SegmentReferenceEnabled = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled << std::endl;
178         oss << "SegmentReference = "        << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReference << std::endl;
179         oss << "SegmentSkipped = "          << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped << std::endl;
180         oss << "SegmentLFLevelDelta = "     << std::dec << +segmentParams->SegData[i].SegmentLFLevelDelta << std::endl;
181         oss << "SegmentQIndexDelta = "      << std::dec << +segmentParams->SegData[i].SegmentQIndexDelta << std::endl;
182     }
183 
184     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
185     {
186         if (!m_debugInterface->m_ddiFileName.empty())
187         {
188             std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
189             ofs << "SegmentParamFileParamFile"
190                 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
191             ofs.close();
192         }
193     }
194 
195     const char *fileName = m_debugInterface->CreateFileName(
196         "_DDIEnc",
197         CodechalDbgBufferType::bufSegmentParams,
198         CodechalDbgExtType::txt);
199 
200     std::ofstream ofs(fileName, std::ios::out);
201     ofs << oss.str();
202     ofs.close();
203 
204     return MOS_STATUS_SUCCESS;
205 }
206 
DumpSeqParams(const CODEC_VP9_ENCODE_SEQUENCE_PARAMS * seqParams)207 MOS_STATUS Vp9Pipeline::DumpSeqParams(
208     const CODEC_VP9_ENCODE_SEQUENCE_PARAMS *seqParams)
209 {
210     ENCODE_FUNC_CALL();
211     ENCODE_CHK_NULL_RETURN(m_debugInterface);
212 
213     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
214     {
215         return MOS_STATUS_SUCCESS;
216     }
217 
218     CODECHAL_DEBUG_CHK_NULL(seqParams);
219 
220     std::ostringstream oss;
221     oss.setf(std::ios::showbase | std::ios::uppercase);
222 
223     oss << "# DDI Parameters:"    << std::endl;
224     oss << "MaxFrameWidth = "     << std::dec << +seqParams->wMaxFrameWidth << std::endl;
225     oss << "MaxFrameHeight = "    << std::dec << +seqParams->wMaxFrameHeight << std::endl;
226     oss << "GopPicSize = "        << std::dec << +seqParams->GopPicSize << std::endl;
227     oss << "TargetUsage = "       << std::dec << +seqParams->TargetUsage << std::endl;
228     oss << "RateControlMethod = " << std::dec << +seqParams->RateControlMethod << std::endl;
229 
230     for (uint8_t i = 0; i < 8; i++)
231     {
232         oss << "TargetBitRate[" << +i << "] = " << std::dec << +seqParams->TargetBitRate[i] << std::endl;
233     }
234     oss << "MaxBitRate = "                        << std::dec << +seqParams->MaxBitRate << std::endl;
235     oss << "MinBitRate = "                        << std::dec << +seqParams->MinBitRate << std::endl;
236     oss << "InitVBVBufferFullnessInBit = "        << std::dec << +seqParams->InitVBVBufferFullnessInBit << std::endl;
237     oss << "VBVBufferSizeInBit = "                << std::dec << +seqParams->VBVBufferSizeInBit << std::endl;
238     oss << "OptimalVBVBufferLevelInBit = "        << std::dec << +seqParams->OptimalVBVBufferLevelInBit << std::endl;
239     oss << "UpperVBVBufferLevelThresholdInBit = " << std::dec << +seqParams->UpperVBVBufferLevelThresholdInBit << std::endl;
240     oss << "LowerVBVBufferLevelThresholdInBit = " << std::dec << +seqParams->LowerVBVBufferLevelThresholdInBit << std::endl;
241     oss << "DisplayFormatSwizzle = "              << std::dec << +seqParams->SeqFlags.fields.DisplayFormatSwizzle << std::endl;
242     // begining of union/struct
243     oss << "# bResetBRC = "                       << std::dec << +seqParams->SeqFlags.fields.bResetBRC << std::endl;
244     oss << "# bNoFrameHeaderInsertion = "         << std::dec << +seqParams->SeqFlags.fields.bNoFrameHeaderInsertion << std::endl;
245     // Next 5 fields not currently implemented.  nullptr output
246     oss << "# UseRawReconRef = "                  << std::dec << +seqParams->SeqFlags.fields.bUseRawReconRef << std::endl;
247     oss << "# MBBRC = "                           << std::dec << +seqParams->SeqFlags.fields.MBBRC << std::endl;
248     oss << "EnableDynamicScaling = "              << std::dec << +seqParams->SeqFlags.fields.EnableDynamicScaling << std::endl;
249     oss << "SourceFormat = "                      << std::dec << +seqParams->SeqFlags.fields.SourceFormat << std::endl;
250     oss << "SourceBitDepth = "                    << std::dec << +seqParams->SeqFlags.fields.SourceBitDepth << std::endl;
251     oss << "EncodedFormat = "                     << std::dec << +seqParams->SeqFlags.fields.EncodedFormat << std::endl;
252     oss << "EncodedBitDepth = "                   << std::dec << +seqParams->SeqFlags.fields.EncodedBitDepth << std::endl;
253     oss << "DisplayFormatSwizzle = "              << std::dec << +seqParams->SeqFlags.fields.DisplayFormatSwizzle << std::endl;
254     // end of union/struct
255 
256     oss << "UserMaxFrameSize = " << std::dec << +seqParams->UserMaxFrameSize << std::endl;
257     for (uint8_t i = 0; i < 8; i++)
258     {
259         oss << "FrameRateNumerator[" << +i << "] = "   << std::dec << +seqParams->FrameRate[i].uiNumerator << std::endl;
260         oss << "FrameRateDenominator[" << +i << "] = " << std::dec << +seqParams->FrameRate[i].uiDenominator << std::endl;
261     }
262 
263     oss << "NumTemporalLayersMinus1 = " << std::dec << +seqParams->NumTemporalLayersMinus1 << std::endl;
264 
265     const char *fileName = m_debugInterface->CreateFileName(
266         "_DDIEnc",
267         CodechalDbgBufferType::bufSeqParams,
268         CodechalDbgExtType::txt);
269 
270     std::ofstream ofs(fileName, std::ios::out);
271     ofs << oss.str();
272     ofs.close();
273 
274     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
275     {
276         if (!m_debugInterface->m_ddiFileName.empty())
277         {
278             std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
279             ofs << "SeqParamFile"
280                 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
281             ofs.close();
282         }
283     }
284 
285     return MOS_STATUS_SUCCESS;
286 }
287 
DumpPicParams(const CODEC_VP9_ENCODE_PIC_PARAMS * picParams)288 MOS_STATUS Vp9Pipeline::DumpPicParams(
289     const CODEC_VP9_ENCODE_PIC_PARAMS *picParams)
290 {
291     ENCODE_FUNC_CALL();
292     ENCODE_CHK_NULL_RETURN(m_debugInterface);
293 
294     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
295     {
296         return MOS_STATUS_SUCCESS;
297     }
298 
299     CODECHAL_DEBUG_CHK_NULL(picParams);
300 
301     std::ostringstream oss;
302     oss.setf(std::ios::showbase | std::ios::uppercase);
303 
304     oss << "# DDI Parameters:"       << std::endl;
305     oss << "SrcFrameHeightMinus1 = " << std::dec << +picParams->SrcFrameHeightMinus1 << std::endl;
306     oss << "SrcFrameWidthMinus1 = "  << std::dec << +picParams->SrcFrameWidthMinus1 << std::endl;
307     oss << "CurrOriginalPic = "      << std::dec << +picParams->CurrOriginalPic.FrameIdx << std::endl;
308     oss << "CurrReconstructedPic = " << std::dec << +picParams->CurrReconstructedPic.FrameIdx << std::endl;
309 
310     for (uint16_t i = 0; i < CODEC_VP9_NUM_REF_FRAMES; ++i)
311     {
312         oss << "RefFrameList[" << +i << "] = " << std::dec << +picParams->RefFrameList[i].FrameIdx << std::endl;
313     }
314     oss << "frame_type = "                   << std::dec << +picParams->PicFlags.fields.frame_type << std::endl;
315     oss << "show_frame = "                   << std::dec << +picParams->PicFlags.fields.show_frame << std::endl;
316     oss << "error_resilient_mode = "         << std::dec << +picParams->PicFlags.fields.error_resilient_mode << std::endl;
317     oss << "intra_only = "                   << std::dec << +picParams->PicFlags.fields.intra_only << std::endl;
318     oss << "allow_high_precision_mv = "      << std::dec << +picParams->PicFlags.fields.allow_high_precision_mv << std::endl;
319     oss << "mcomp_filter_type = "            << std::dec << +picParams->PicFlags.fields.mcomp_filter_type << std::endl;
320     oss << "frame_parallel_decoding_mode = " << std::dec << +picParams->PicFlags.fields.frame_parallel_decoding_mode << std::endl;
321     oss << "segmentation_enabled = "         << std::dec << +picParams->PicFlags.fields.segmentation_enabled << std::endl;
322     oss << "segmentation_temporal_update = " << std::dec << +picParams->PicFlags.fields.segmentation_temporal_update << std::endl;
323     oss << "segmentation_update_map = "      << std::dec << +picParams->PicFlags.fields.segmentation_update_map << std::endl;
324     oss << "reset_frame_context = "          << std::dec << +picParams->PicFlags.fields.reset_frame_context << std::endl;
325     oss << "refresh_frame_context = "        << std::dec << +picParams->PicFlags.fields.refresh_frame_context << std::endl;
326     oss << "frame_context_idx = "            << std::dec << +picParams->PicFlags.fields.frame_context_idx << std::endl;
327     oss << "LosslessFlag = "                 << std::dec << +picParams->PicFlags.fields.LosslessFlag << std::endl;
328     oss << "comp_prediction_mode = "         << std::dec << +picParams->PicFlags.fields.comp_prediction_mode << std::endl;
329     oss << "super_frame = "                  << std::dec << +picParams->PicFlags.fields.super_frame << std::endl;
330     oss << "seg_id_block_size = "            << std::dec << +picParams->PicFlags.fields.seg_id_block_size << std::endl;
331     oss << "seg_update_data = "              << std::dec << +picParams->PicFlags.fields.seg_update_data << std::endl;
332     oss << "LastRefIdx = "                   << std::dec << +picParams->RefFlags.fields.LastRefIdx << std::endl;
333     oss << "LastRefSignBias = "              << std::dec << +picParams->RefFlags.fields.LastRefSignBias << std::endl;
334     oss << "GoldenRefIdx = "                 << std::dec << +picParams->RefFlags.fields.GoldenRefIdx << std::endl;
335     oss << "GoldenRefSignBias = "            << std::dec << +picParams->RefFlags.fields.GoldenRefSignBias << std::endl;
336     oss << "AltRefIdx = "                    << std::dec << +picParams->RefFlags.fields.AltRefIdx << std::endl;
337     oss << "AltRefSignBias = "               << std::dec << +picParams->RefFlags.fields.AltRefSignBias << std::endl;
338     oss << "ref_frame_ctrl_l0 = "            << std::dec << +picParams->RefFlags.fields.ref_frame_ctrl_l0 << std::endl;
339     oss << "ref_frame_ctrl_l1 = "            << std::dec << +picParams->RefFlags.fields.ref_frame_ctrl_l1 << std::endl;
340     oss << "refresh_frame_flags = "          << std::dec << +picParams->RefFlags.fields.refresh_frame_flags << std::endl;
341     oss << "LumaACQIndex = "                 << std::dec << +picParams->LumaACQIndex << std::endl;
342     oss << "LumaDCQIndexDelta = "            << std::dec << +picParams->LumaDCQIndexDelta << std::endl;
343     oss << "ChromaACQIndexDelta = "          << std::dec << +picParams->ChromaACQIndexDelta << std::endl;
344     oss << "ChromaDCQIndexDelta = "          << std::dec << +picParams->ChromaDCQIndexDelta << std::endl;
345     oss << "filter_level = "                 << std::dec << +picParams->filter_level << std::endl;
346     oss << "sharpness_level = "              << std::dec << +picParams->sharpness_level << std::endl;
347 
348     for (uint8_t i = 0; i < 4; ++i)
349     {
350         oss << "LFRefDelta[" << +i << "] = " << std::dec << +picParams->LFRefDelta[i] << std::endl;
351     }
352 
353     for (uint8_t i = 0; i < 2; ++i)
354     {
355         oss << "LFModeDelta[" << +i << "] = " << std::dec << +picParams->LFModeDelta[i] << std::endl;
356     }
357 
358     oss << "BitOffsetForLFRefDelta = "         << std::dec << +picParams->BitOffsetForLFRefDelta << std::endl;
359     oss << "BitOffsetForLFModeDelta = "        << std::dec << +picParams->BitOffsetForLFModeDelta << std::endl;
360     oss << "BitOffsetForLFLevel = "            << std::dec << +picParams->BitOffsetForLFLevel << std::endl;
361     oss << "BitOffsetForQIndex = "             << std::dec << +picParams->BitOffsetForQIndex << std::endl;
362     oss << "BitOffsetForFirstPartitionSize = " << std::dec << +picParams->BitOffsetForFirstPartitionSize << std::endl;
363     oss << "BitOffsetForSegmentation = "       << std::dec << +picParams->BitOffsetForSegmentation << std::endl;
364     oss << "BitSizeForSegmentation = "         << std::dec << +picParams->BitSizeForSegmentation << std::endl;
365     oss << "log2_tile_rows = "                 << std::dec << +picParams->log2_tile_rows << std::endl;
366     oss << "log2_tile_columns = "              << std::dec << +picParams->log2_tile_columns << std::endl;
367     oss << "temporal_id = "                    << std::dec << +picParams->temporal_id << std::endl;
368     oss << "StatusReportFeedbackNumber = "     << std::dec << +picParams->StatusReportFeedbackNumber << std::endl;
369     oss << "SkipFrameFlag = "                  << std::dec << +picParams->SkipFrameFlag << std::endl;
370     oss << "NumSkipFrames = "                  << std::dec << +picParams->NumSkipFrames << std::endl;
371     oss << "SizeSkipFrames = "                 << std::dec << +picParams->SizeSkipFrames << std::endl;
372 
373     const char *fileName = m_debugInterface->CreateFileName(
374         "_DDIEnc",
375         CodechalDbgBufferType::bufPicParams,
376         CodechalDbgExtType::txt);
377 
378     std::ofstream ofs(fileName, std::ios::out);
379     ofs << oss.str();
380     ofs.close();
381 
382     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
383     {
384         if (!m_debugInterface->m_ddiFileName.empty())
385         {
386             std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
387             ofs << "PicNum"
388                 << " = " << m_debugInterface->m_bufferDumpFrameNum << std::endl;
389             ofs << "PicParamFile"
390                 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
391             ofs.close();
392         }
393     }
394 
395     return MOS_STATUS_SUCCESS;
396 }
397 #endif
398 
399 }  // namespace encode