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_input_bitstream.cpp
25 //! \brief    Defines the common interface for decode jpeg input bitstream
26 //!
27 #include "decode_jpeg_input_bitstream.h"
28 #include "decode_pipeline.h"
29 
30 namespace decode
31 {
DecodeJpegInputBitstream(DecodePipeline * pipeline,MediaTask * task,uint8_t numVdbox)32 DecodeJpegInputBitstream::DecodeJpegInputBitstream(DecodePipeline* pipeline, MediaTask* task, uint8_t numVdbox)
33     : DecodeInputBitstream(pipeline, task, numVdbox)
34 {
35 }
36 
Init(CodechalSetting & settings)37 MOS_STATUS DecodeJpegInputBitstream::Init(CodechalSetting &settings)
38 {
39     DecodeInputBitstream::Init(settings);
40 
41     m_jpegBasicFeature = dynamic_cast<JpegBasicFeature *>(m_basicFeature);
42     DECODE_CHK_NULL(m_jpegBasicFeature);
43     return MOS_STATUS_SUCCESS;
44 }
45 
IsComplete()46 bool DecodeJpegInputBitstream::IsComplete()
47 {
48     return m_completeBitStream && m_completeJpegScan;
49 }
50 
Append(const CodechalDecodeParams & decodeParams)51 MOS_STATUS DecodeJpegInputBitstream::Append(const CodechalDecodeParams &decodeParams)
52 {
53     bool firstExecuteCall  = (decodeParams.m_executeCallIndex == 0);
54     auto numScans          = m_jpegBasicFeature->m_jpegScanParams->NumScans;
55     auto totalScans        = m_jpegBasicFeature->m_jpegPicParams->m_totalScans;
56     uint32_t maxBufferSize = MOS_ALIGN_CEIL(m_jpegBasicFeature->m_jpegPicParams->m_frameWidth * m_jpegBasicFeature->m_jpegPicParams->m_frameHeight * 3, 64);
57     uint32_t segmentSize   = decodeParams.m_dataSize;
58     if (firstExecuteCall)
59     {
60         auto headerSize = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[numScans - 1].DataOffset +
61                           m_jpegBasicFeature->m_jpegScanParams->ScanHeader[numScans - 1].DataLength;
62 
63         if (numScans >= totalScans && segmentSize >= headerSize)  // Bitstream complete and scan complete
64         {
65             m_completeBitStream = true;
66             m_completeJpegScan  = true;
67         }
68         else if (numScans < totalScans && segmentSize > headerSize)  // Bitstream complete and scan incomplete
69         {
70             m_completeBitStream = true;
71             m_completeJpegScan  = false;
72         }
73         else if (numScans >= totalScans && segmentSize < headerSize)  //Bitstream incomplete and scan complete, should catenate bitstream
74         {
75             m_completeBitStream = false;
76             m_completeJpegScan  = true;
77             m_requiredSize      = maxBufferSize;
78 
79             //Allocate Buffer
80             DECODE_CHK_STATUS(AllocateCatenatedBuffer());
81             m_basicFeature->m_resDataBuffer = *m_catenatedBuffer;
82             m_basicFeature->m_dataOffset    = 0;
83             DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(m_pipeline, hucCopyPacketId), true, 0, 0));
84             AddNewSegment(*(decodeParams.m_dataBuffer), decodeParams.m_dataOffset, decodeParams.m_dataSize);
85         }
86         else
87         {
88             return MOS_STATUS_INVALID_PARAMETER;
89         }
90 
91     }
92     else
93     {
94         if (m_completeBitStream)// Bitstream complete and scan incomplete, wait scan complete
95         {
96             m_completeJpegScan = (numScans >= totalScans);
97         }
98         else//Bitstream incomplete and scan complete, should catenate bitstream
99         {
100             if (m_segmentsTotalSize + segmentSize > m_requiredSize)
101             {
102                 DECODE_ASSERTMESSAGE("Bitstream size exceeds allocated buffer size!");
103                 return MOS_STATUS_INVALID_PARAMETER;
104             }
105             DECODE_CHK_STATUS(ActivatePacket(DecodePacketId(m_pipeline, hucCopyPacketId), true, 0, 0));
106             AddNewSegment(*(decodeParams.m_dataBuffer), decodeParams.m_dataOffset, decodeParams.m_dataSize);
107 
108             uint32_t totalSize = m_jpegBasicFeature->m_jpegScanParams->ScanHeader[totalScans - 1].DataOffset +
109                                  m_jpegBasicFeature->m_jpegScanParams->ScanHeader[totalScans - 1].DataLength;
110             if (m_segmentsTotalSize + segmentSize >= totalSize)
111             {
112                 m_completeBitStream = true;
113             }
114         }
115     }
116     m_segmentsTotalSize += MOS_ALIGN_CEIL(segmentSize, MHW_CACHELINE_SIZE);
117     return MOS_STATUS_SUCCESS;
118 }
119 
120 
121 }  // namespace decode
122 
123