History

B-frame decoding support for Main and High Profile with two test cases.

xiaotianshi2 committed 8 years ago

Commit 657d2171 parent e3e838355 files · +17936 −13825Browse files

Showing the changes to codec/decoder/plus/src/welsDecoderExt.cpp (1 of 55 files). Show all

Unified · Split

codec/decoder/plus/src/welsDecoderExt.cpp+1009−860
@@ -1,860 +1,1009 @@
1/*!1/*!
2 * \copy2 * \copy
3 * Copyright (c) 2009-2013, Cisco Systems3 * Copyright (c) 2009-2013, Cisco Systems
4 * All rights reserved.4 * All rights reserved.
5 *5 *
6 * Redistribution and use in source and binary forms, with or without6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions7 * modification, are permitted provided that the following conditions
8 * are met:8 * are met:
9 *9 *
10 * * Redistributions of source code must retain the above copyright10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.11 * notice, this list of conditions and the following disclaimer.
12 *12 *
13 * * Redistributions in binary form must reproduce the above copyright13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the15 * the documentation and/or other materials provided with the
16 * distribution.16 * distribution.
17 *17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.29 * POSSIBILITY OF SUCH DAMAGE.
30 *30 *
31 *31 *
32 * welsDecoderExt.cpp32 * welsDecoderExt.cpp
33 *33 *
34 * Abstract34 * Abstract
35 * Cisco OpenH264 decoder extension utilization35 * Cisco OpenH264 decoder extension utilization
36 *36 *
37 * History37 * History
38 * 3/12/2009 Created38 * 3/12/2009 Created
39 *39 *
40 *40 *
41 ************************************************************************/41 ************************************************************************/
42//#include <assert.h>42//#include <assert.h>
43#include "welsDecoderExt.h"43#include "welsDecoderExt.h"
44#include "welsCodecTrace.h"44#include "welsCodecTrace.h"
45#include "codec_def.h"45#include "codec_def.h"
46#include "typedefs.h"46#include "typedefs.h"
47#include "memory_align.h"47#include "memory_align.h"
48#include "utils.h"48#include "utils.h"
49#include "version.h"49#include "version.h"
50 50
51//#include "macros.h"51//#include "macros.h"
52#include "decoder.h"52#include "decoder.h"
53#include "decoder_core.h"53#include "decoder_core.h"
54#include "error_concealment.h"54#include "error_concealment.h"
55 55
56#include "measure_time.h"56#include "measure_time.h"
57extern "C" {57extern "C" {
58#include "decoder_core.h"58#include "decoder_core.h"
59#include "manage_dec_ref.h"59#include "manage_dec_ref.h"
60}60}
61#include "error_code.h"61#include "error_code.h"
62#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms62#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms
63#include <time.h>63#include <time.h>
64#if defined(_WIN32) /*&& defined(_DEBUG)*/64#if defined(_WIN32) /*&& defined(_DEBUG)*/
65 65
66#include <windows.h>66#include <windows.h>
67#include <stdio.h>67#include <stdio.h>
68#include <stdarg.h>68#include <stdarg.h>
69#include <sys/types.h>69#include <sys/types.h>
70#else70#else
71#include <sys/time.h>71#include <sys/time.h>
72#endif72#endif
73 73
74namespace WelsDec {74#define _PICTURE_REORDERING_ 1
75 75
76//////////////////////////////////////////////////////////////////////76namespace WelsDec {
77// Construction/Destruction77
78//////////////////////////////////////////////////////////////////////78//////////////////////////////////////////////////////////////////////
79 79// Construction/Destruction
80/***************************************************************************80//////////////////////////////////////////////////////////////////////
81* Description:81
82* class CWelsDecoder constructor function, do initialization and82/***************************************************************************
83* alloc memory required83* Description:
84*84* class CWelsDecoder constructor function, do initialization and
85* Input parameters: none85* alloc memory required
86*86*
87* return: none87* Input parameters: none
88***************************************************************************/88*
89CWelsDecoder::CWelsDecoder (void)89* return: none
90 : m_pDecContext (NULL),90***************************************************************************/
91 m_pWelsTrace (NULL) {91CWelsDecoder::CWelsDecoder (void)
92#ifdef OUTPUT_BIT_STREAM92 : m_pDecContext (NULL),
93 char chFileName[1024] = { 0 }; //for .26493 m_pWelsTrace (NULL),
94 int iBufUsed = 0;94 m_iPictInfoIndex (0),
95 int iBufLeft = 1023;95 m_iMinPOC (-1),
96 int iCurUsed;96 m_iNumOfPicts (0),
97 97 m_iLastGOPRemainPicts (0),
98 char chFileNameSize[1024] = { 0 }; //for .len98 m_LastWrittenPOC (0) {
99 int iBufUsedSize = 0;99#ifdef OUTPUT_BIT_STREAM
100 int iBufLeftSize = 1023;100 char chFileName[1024] = { 0 }; //for .264
101 int iCurUsedSize;101 int iBufUsed = 0;
102#endif//OUTPUT_BIT_STREAM102 int iBufLeft = 1023;
103 103 int iCurUsed;
104 104
105 m_pWelsTrace = new welsCodecTrace();105 char chFileNameSize[1024] = { 0 }; //for .len
106 if (m_pWelsTrace != NULL) {106 int iBufUsedSize = 0;
107 m_pWelsTrace->SetCodecInstance (this);107 int iBufLeftSize = 1023;
108 m_pWelsTrace->SetTraceLevel (WELS_LOG_ERROR);108 int iCurUsedSize;
109 109#endif//OUTPUT_BIT_STREAM
110 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");110
111 }111
112 112 m_pWelsTrace = new welsCodecTrace();
113#ifdef OUTPUT_BIT_STREAM113 if (m_pWelsTrace != NULL) {
114 SWelsTime sCurTime;114 m_pWelsTrace->SetCodecInstance (this);
115 115 m_pWelsTrace->SetTraceLevel (WELS_LOG_ERROR);
116 WelsGetTimeOfDay (&sCurTime);116
117 117 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");
118 iCurUsed = WelsSnprintf (chFileName, iBufLeft, "bs_0x%p_", (void*)this);118 }
119 iCurUsedSize = WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void*)this);119
120 120 for (int32_t i = 0; i < 10; ++i) {
121 iBufUsed += iCurUsed;121 m_sPictInfoList[i].bLastGOP = false;
122 iBufLeft -= iCurUsed;122 m_sPictInfoList[i].iPOC = -1;
123 if (iBufLeft > 0) {123 }
124 iCurUsed = WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);124
125 iBufUsed += iCurUsed;125#ifdef OUTPUT_BIT_STREAM
126 iBufLeft -= iCurUsed;126 SWelsTime sCurTime;
127 }127
128 128 WelsGetTimeOfDay (&sCurTime);
129 iBufUsedSize += iCurUsedSize;129
130 iBufLeftSize -= iCurUsedSize;130 iCurUsed = WelsSnprintf (chFileName, iBufLeft, "bs_0x%p_", (void*)this);
131 if (iBufLeftSize > 0) {131 iCurUsedSize = WelsSnprintf (chFileNameSize, iBufLeftSize, "size_0x%p_", (void*)this);
132 iCurUsedSize = WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);132
133 iBufUsedSize += iCurUsedSize;133 iBufUsed += iCurUsed;
134 iBufLeftSize -= iCurUsedSize;134 iBufLeft -= iCurUsed;
135 }135 if (iBufLeft > 0) {
136 136 iCurUsed = WelsStrftime (&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
137 if (iBufLeft > 0) {137 iBufUsed += iCurUsed;
138 iCurUsed = WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillisecond (&sCurTime));138 iBufLeft -= iCurUsed;
139 iBufUsed += iCurUsed;139 }
140 iBufLeft -= iCurUsed;140
141 }141 iBufUsedSize += iCurUsedSize;
142 142 iBufLeftSize -= iCurUsedSize;
143 if (iBufLeftSize > 0) {143 if (iBufLeftSize > 0) {
144 iCurUsedSize = WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",144 iCurUsedSize = WelsStrftime (&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
145 WelsGetMillisecond (&sCurTime));145 iBufUsedSize += iCurUsedSize;
146 iBufUsedSize += iCurUsedSize;146 iBufLeftSize -= iCurUsedSize;
147 iBufLeftSize -= iCurUsedSize;147 }
148 }148
149 149 if (iBufLeft > 0) {
150 150 iCurUsed = WelsSnprintf (&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillisecond (&sCurTime));
151 m_pFBS = WelsFopen (chFileName, "wb");151 iBufUsed += iCurUsed;
152 m_pFBSSize = WelsFopen (chFileNameSize, "wb");152 iBufLeft -= iCurUsed;
153#endif//OUTPUT_BIT_STREAM153 }
154 154
155}155 if (iBufLeftSize > 0) {
156 156 iCurUsedSize = WelsSnprintf (&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len",
157/***************************************************************************157 WelsGetMillisecond (&sCurTime));
158* Description:158 iBufUsedSize += iCurUsedSize;
159* class CWelsDecoder destructor function, destroy allocced memory159 iBufLeftSize -= iCurUsedSize;
160*160 }
161* Input parameters: none161
162*162
163* return: none163 m_pFBS = WelsFopen (chFileName, "wb");
164***************************************************************************/164 m_pFBSSize = WelsFopen (chFileNameSize, "wb");
165CWelsDecoder::~CWelsDecoder() {165#endif//OUTPUT_BIT_STREAM
166 if (m_pWelsTrace != NULL) {166}
167 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");167
168 }168/***************************************************************************
169 169* Description:
170 UninitDecoder();170* class CWelsDecoder destructor function, destroy allocced memory
171 171*
172#ifdef OUTPUT_BIT_STREAM172* Input parameters: none
173 if (m_pFBS) {173*
174 WelsFclose (m_pFBS);174* return: none
175 m_pFBS = NULL;175***************************************************************************/
176 }176CWelsDecoder::~CWelsDecoder() {
177 if (m_pFBSSize) {177 if (m_pWelsTrace != NULL) {
178 WelsFclose (m_pFBSSize);178 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
179 m_pFBSSize = NULL;179 }
180 }180
181#endif//OUTPUT_BIT_STREAM181 UninitDecoder();
182 182
183 if (m_pWelsTrace != NULL) {183#ifdef OUTPUT_BIT_STREAM
184 delete m_pWelsTrace;184 if (m_pFBS) {
185 m_pWelsTrace = NULL;185 WelsFclose (m_pFBS);
186 }186 m_pFBS = NULL;
187}187 }
188 188 if (m_pFBSSize) {
189long CWelsDecoder::Initialize (const SDecodingParam* pParam) {189 WelsFclose (m_pFBSSize);
190 int iRet = ERR_NONE;190 m_pFBSSize = NULL;
191 if (m_pWelsTrace == NULL) {191 }
192 return cmMallocMemeError;192#endif//OUTPUT_BIT_STREAM
193 }193
194 194 if (m_pWelsTrace != NULL) {
195 if (pParam == NULL) {195 delete m_pWelsTrace;
196 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsDecoder::Initialize(), invalid input argument.");196 m_pWelsTrace = NULL;
197 return cmInitParaError;197 }
198 }198}
199 199
200 // H.264 decoder initialization,including memory allocation,then open it ready to decode200long CWelsDecoder::Initialize (const SDecodingParam* pParam) {
201 iRet = InitDecoder (pParam);201 int iRet = ERR_NONE;
202 if (iRet)202 if (m_pWelsTrace == NULL) {
203 return iRet;203 return cmMallocMemeError;
204 204 }
205 return cmResultSuccess;205
206}206 if (pParam == NULL) {
207 207 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsDecoder::Initialize(), invalid input argument.");
208long CWelsDecoder::Uninitialize() {208 return cmInitParaError;
209 UninitDecoder();209 }
210 210
211 return ERR_NONE;211 // H.264 decoder initialization,including memory allocation,then open it ready to decode
212}212 iRet = InitDecoder (pParam);
213 213 if (iRet)
214void CWelsDecoder::UninitDecoder (void) {214 return iRet;
215 if (NULL == m_pDecContext)215
216 return;216 return cmResultSuccess;
217 217}
218 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoder(), openh264 codec version = %s.",218
219 VERSION_NUMBER);219long CWelsDecoder::Uninitialize() {
220 220 UninitDecoder();
221 WelsEndDecoder (m_pDecContext);221
222 222 return ERR_NONE;
223 if (m_pDecContext->pMemAlign != NULL) {223}
224 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,224
225 "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",225void CWelsDecoder::UninitDecoder (void) {
226 m_pDecContext->pMemAlign->WelsGetMemoryUsage());226 if (NULL == m_pDecContext)
227 delete m_pDecContext->pMemAlign;227 return;
228 m_pDecContext->pMemAlign = NULL;228
229 }229 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::UninitDecoder(), openh264 codec version = %s.",
230 230 VERSION_NUMBER);
231 if (NULL != m_pDecContext) {231
232 WelsFree (m_pDecContext, "m_pDecContext");232 WelsEndDecoder (m_pDecContext);
233 233
234 m_pDecContext = NULL;234 if (m_pDecContext->pMemAlign != NULL) {
235 }235 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
236 236 "CWelsDecoder::UninitDecoder(), verify memory usage (%d bytes) after free..",
237}237 m_pDecContext->pMemAlign->WelsGetMemoryUsage());
238 238 delete m_pDecContext->pMemAlign;
239// the return value of this function is not suitable, it need report failure info to upper layer.239 m_pDecContext->pMemAlign = NULL;
240int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) {240 }
241 241
242 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,242 if (NULL != m_pDecContext) {
243 "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",243 WelsFree (m_pDecContext, "m_pDecContext");
244 VERSION_NUMBER, (int32_t)pParam->bParseOnly);244
245 245 m_pDecContext = NULL;
246 //reset decoder context246 }
247 if (m_pDecContext) //free247}
248 UninitDecoder();248
249 m_pDecContext = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");249// the return value of this function is not suitable, it need report failure info to upper layer.
250 if (NULL == m_pDecContext)250int32_t CWelsDecoder::InitDecoder (const SDecodingParam* pParam) {
251 return cmMallocMemeError;251
252 int32_t iCacheLineSize = 16; // on chip cache line size in byte252 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
253 m_pDecContext->pMemAlign = new CMemoryAlign (iCacheLineSize);253 "CWelsDecoder::init_decoder(), openh264 codec version = %s, ParseOnly = %d",
254 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pMemAlign), UninitDecoder())254 VERSION_NUMBER, (int32_t)pParam->bParseOnly);
255 255
256 //fill in default value into context256 //reset decoder context
257 WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);257 if (m_pDecContext) //free
258 258 UninitDecoder();
259 //check param and update decoder context259 m_pDecContext = (PWelsDecoderContext)WelsMallocz (sizeof (SWelsDecoderContext), "m_pDecContext");
260 m_pDecContext->pParam = (SDecodingParam*) m_pDecContext->pMemAlign->WelsMallocz (sizeof (SDecodingParam),260 if (NULL == m_pDecContext)
261 "SDecodingParam");261 return cmMallocMemeError;
262 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pParam), UninitDecoder());262 int32_t iCacheLineSize = 16; // on chip cache line size in byte
263 int32_t iRet = DecoderConfigParam (m_pDecContext, pParam);263 m_pDecContext->pMemAlign = new CMemoryAlign (iCacheLineSize);
264 WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);264 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pMemAlign), UninitDecoder())
265 265
266 //init decoder266 //fill in default value into context
267 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx),267 WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
268 UninitDecoder())268
269 269 //check param and update decoder context
270 return cmResultSuccess;270 m_pDecContext->pParam = (SDecodingParam*)m_pDecContext->pMemAlign->WelsMallocz (sizeof (SDecodingParam),
271}271 "SDecodingParam");
272 272 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, (NULL == m_pDecContext->pParam), UninitDecoder());
273int32_t CWelsDecoder::ResetDecoder() {273 int32_t iRet = DecoderConfigParam (m_pDecContext, pParam);
274 // TBC: need to be modified when context and trace point are null274 WELS_VERIFY_RETURN_IFNEQ (iRet, cmResultSuccess);
275 if (m_pDecContext != NULL && m_pWelsTrace != NULL) {275
276 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",276 //init decoder
277 m_pDecContext->iErrorCode);277 WELS_VERIFY_RETURN_PROC_IF (cmMallocMemeError, WelsInitDecoder (m_pDecContext, &m_pWelsTrace->m_sLogCtx),
278 SDecodingParam sPrevParam;278 UninitDecoder())
279 memcpy (&sPrevParam, m_pDecContext->pParam, sizeof (SDecodingParam));279
280 280 return cmResultSuccess;
281 WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoder (&sPrevParam), UninitDecoder());281}
282 } else if (m_pWelsTrace != NULL) {282
283 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");283int32_t CWelsDecoder::ResetDecoder() {
284 }284 // TBC: need to be modified when context and trace point are null
285 return ERR_INFO_UNINIT;285 if (m_pDecContext != NULL && m_pWelsTrace != NULL) {
286}286 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "ResetDecoder(), context error code is %d",
287 287 m_pDecContext->iErrorCode);
288/*288 SDecodingParam sPrevParam;
289 * Set Option289 memcpy (&sPrevParam, m_pDecContext->pParam, sizeof (SDecodingParam));
290 */290
291long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {291 WELS_VERIFY_RETURN_PROC_IF (cmInitParaError, InitDecoder (&sPrevParam), UninitDecoder());
292 int iVal = 0;292 } else if (m_pWelsTrace != NULL) {
293 293 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
294 if (m_pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&294 }
295 eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)295 return ERR_INFO_UNINIT;
296 return dsInitialOptExpected;296}
297 if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded297
298 if (pOption == NULL)298/*
299 return cmInitParaError;299 * Set Option
300 300 */
301 iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag301long CWelsDecoder::SetOption (DECODER_OPTION eOptID, void* pOption) {
302 302 int iVal = 0;
303 m_pDecContext->bEndOfStreamFlag = iVal ? true : false;303
304 304 if (m_pDecContext == NULL && eOptID != DECODER_OPTION_TRACE_LEVEL &&
305 return cmResultSuccess;305 eOptID != DECODER_OPTION_TRACE_CALLBACK && eOptID != DECODER_OPTION_TRACE_CALLBACK_CONTEXT)
306 } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status306 return dsInitialOptExpected;
307 if (pOption == NULL)307 if (eOptID == DECODER_OPTION_END_OF_STREAM) { // Indicate bit-stream of the final frame to be decoded
308 return cmInitParaError;308 if (pOption == NULL)
309 309 return cmInitParaError;
310 iVal = * ((int*)pOption); // int value for error concealment idc310
311 iVal = WELS_CLIP3 (iVal, (int32_t) ERROR_CON_DISABLE, (int32_t) ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);311 iVal = * ((int*)pOption); // boolean value for whether enabled End Of Stream flag
312 if ((m_pDecContext->pParam->bParseOnly) && (iVal != (int32_t) ERROR_CON_DISABLE)) {312
313 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,313 m_pDecContext->bEndOfStreamFlag = iVal ? true : false;
314 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);314
315 return cmInitParaError;315 return cmResultSuccess;
316 }316 } else if (eOptID == DECODER_OPTION_ERROR_CON_IDC) { // Indicate error concealment status
317 317 if (pOption == NULL)
318 m_pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC) iVal;318 return cmInitParaError;
319 InitErrorCon (m_pDecContext);319
320 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,320 iVal = * ((int*)pOption); // int value for error concealment idc
321 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);321 iVal = WELS_CLIP3 (iVal, (int32_t)ERROR_CON_DISABLE, (int32_t)ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE);
322 322 if ((m_pDecContext->pParam->bParseOnly) && (iVal != (int32_t)ERROR_CON_DISABLE)) {
323 return cmResultSuccess;323 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
324 } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {324 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d not allowd for parse only!.", iVal);
325 if (m_pWelsTrace) {325 return cmInitParaError;
326 uint32_t level = * ((uint32_t*)pOption);326 }
327 m_pWelsTrace->SetTraceLevel (level);327
328 }328 m_pDecContext->pParam->eEcActiveIdc = (ERROR_CON_IDC)iVal;
329 return cmResultSuccess;329 InitErrorCon (m_pDecContext);
330 } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {330 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
331 if (m_pWelsTrace) {331 "CWelsDecoder::SetOption for ERROR_CON_IDC = %d.", iVal);
332 WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);332
333 m_pWelsTrace->SetTraceCallback (callback);333 return cmResultSuccess;
334 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,334 } else if (eOptID == DECODER_OPTION_TRACE_LEVEL) {
335 "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",335 if (m_pWelsTrace) {
336 callback);336 uint32_t level = * ((uint32_t*)pOption);
337 }337 m_pWelsTrace->SetTraceLevel (level);
338 return cmResultSuccess;338 }
339 } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {339 return cmResultSuccess;
340 if (m_pWelsTrace) {340 } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK) {
341 void* ctx = * ((void**)pOption);341 if (m_pWelsTrace) {
342 m_pWelsTrace->SetTraceCallbackContext (ctx);342 WelsTraceCallback callback = * ((WelsTraceCallback*)pOption);
343 }343 m_pWelsTrace->SetTraceCallback (callback);
344 return cmResultSuccess;344 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
345 } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {345 "CWelsDecoder::SetOption():DECODER_OPTION_TRACE_CALLBACK callback = %p.",
346 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,346 callback);
347 "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");347 }
348 return cmInitParaError;348 return cmResultSuccess;
349 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {349 } else if (eOptID == DECODER_OPTION_TRACE_CALLBACK_CONTEXT) {
350 if (pOption) {350 if (m_pWelsTrace) {
351 m_pDecContext->sDecoderStatistics.iStatisticsLogInterval = (* ((unsigned int*)pOption));351 void* ctx = * ((void**)pOption);
352 return cmResultSuccess;352 m_pWelsTrace->SetTraceCallbackContext (ctx);
353 }353 }
354 } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {354 return cmResultSuccess;
355 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,355 } else if (eOptID == DECODER_OPTION_GET_STATISTICS) {
356 "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");356 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
357 return cmInitParaError;357 "CWelsDecoder::SetOption():DECODER_OPTION_GET_STATISTICS: this option is get-only!");
358 }358 return cmInitParaError;
359 return cmInitParaError;359 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
360}360 if (pOption) {
361 361 m_pDecContext->sDecoderStatistics.iStatisticsLogInterval = (* ((unsigned int*)pOption));
362/*362 return cmResultSuccess;
363 * Get Option363 }
364 */364 } else if (eOptID == DECODER_OPTION_GET_SAR_INFO) {
365long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {365 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
366 int iVal = 0;366 "CWelsDecoder::SetOption():DECODER_OPTION_GET_SAR_INFO: this option is get-only!");
367 367 return cmInitParaError;
368 if (m_pDecContext == NULL)368 }
369 return cmInitExpected;369 return cmInitParaError;
370 370}
371 if (pOption == NULL)371
372 return cmInitParaError;372/*
373 373 * Get Option
374 if (DECODER_OPTION_END_OF_STREAM == eOptID) {374 */
375 iVal = m_pDecContext->bEndOfStreamFlag;375long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
376 * ((int*)pOption) = iVal;376 int iVal = 0;
377 return cmResultSuccess;377
378 }378 if (m_pDecContext == NULL)
379#ifdef LONG_TERM_REF379 return cmInitExpected;
380 else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {380
381 iVal = m_pDecContext->uiCurIdrPicId;381 if (pOption == NULL)
382 * ((int*)pOption) = iVal;382 return cmInitParaError;
383 return cmResultSuccess;383
384 } else if (DECODER_OPTION_FRAME_NUM == eOptID) {384 if (DECODER_OPTION_END_OF_STREAM == eOptID) {
385 iVal = m_pDecContext->iFrameNum;385 iVal = m_pDecContext->bEndOfStreamFlag;
386 * ((int*)pOption) = iVal;386 * ((int*)pOption) = iVal;
387 return cmResultSuccess;387 return cmResultSuccess;
388 } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {388 }
389 iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;389#ifdef LONG_TERM_REF
390 * ((int*)pOption) = iVal;390 else if (DECODER_OPTION_IDR_PIC_ID == eOptID) {
391 return cmResultSuccess;391 iVal = m_pDecContext->uiCurIdrPicId;
392 } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {392 * ((int*)pOption) = iVal;
393 iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;393 return cmResultSuccess;
394 * ((int*)pOption) = iVal;394 } else if (DECODER_OPTION_FRAME_NUM == eOptID) {
395 return cmResultSuccess;395 iVal = m_pDecContext->iFrameNum;
396 }396 * ((int*)pOption) = iVal;
397#endif397 return cmResultSuccess;
398 else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU398 } else if (DECODER_OPTION_LTR_MARKING_FLAG == eOptID) {
399 iVal = m_pDecContext->iFeedbackVclNalInAu;399 iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;
400 * ((int*)pOption) = iVal;400 * ((int*)pOption) = iVal;
401 return cmResultSuccess;401 return cmResultSuccess;
402 } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID402 } else if (DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID) {
403 iVal = m_pDecContext->iFeedbackTidInAu;403 iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;
404 * ((int*)pOption) = iVal;404 * ((int*)pOption) = iVal;
405 return cmResultSuccess;405 return cmResultSuccess;
406 } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {406 }
407 iVal = m_pDecContext->iFeedbackNalRefIdc;407#endif
408 if (iVal > 0)408 else if (DECODER_OPTION_VCL_NAL == eOptID) { //feedback whether or not have VCL NAL in current AU
409 iVal = 1;409 iVal = m_pDecContext->iFeedbackVclNalInAu;
410 * ((int*)pOption) = iVal;410 * ((int*)pOption) = iVal;
411 return cmResultSuccess;411 return cmResultSuccess;
412 } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {412 } else if (DECODER_OPTION_TEMPORAL_ID == eOptID) { //if have VCL NAL in current AU, then feedback the temporal ID
413 iVal = (int) m_pDecContext->pParam->eEcActiveIdc;413 iVal = m_pDecContext->iFeedbackTidInAu;
414 * ((int*)pOption) = iVal;414 * ((int*)pOption) = iVal;
415 return cmResultSuccess;415 return cmResultSuccess;
416 } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging416 } else if (DECODER_OPTION_IS_REF_PIC == eOptID) {
417 SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));417 iVal = m_pDecContext->iFeedbackNalRefIdc;
418 418 if (iVal > 0)
419 memcpy (pDecoderStatistics, &m_pDecContext->sDecoderStatistics, sizeof (SDecoderStatistics));419 iVal = 1;
420 420 * ((int*)pOption) = iVal;
421 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount != 0) { //not original status421 return cmResultSuccess;
422 pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /422 } else if (DECODER_OPTION_ERROR_CON_IDC == eOptID) {
423 (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount);423 iVal = (int)m_pDecContext->pParam->eEcActiveIdc;
424 pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /424 * ((int*)pOption) = iVal;
425 (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum +425 return cmResultSuccess;
426 m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum);426 } else if (DECODER_OPTION_GET_STATISTICS == eOptID) { // get decoder statistics info for real time debugging
427 }427 SDecoderStatistics* pDecoderStatistics = (static_cast<SDecoderStatistics*> (pOption));
428 return cmResultSuccess;428
429 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {429 memcpy (pDecoderStatistics, &m_pDecContext->sDecoderStatistics, sizeof (SDecoderStatistics));
430 if (pOption) {430
431 iVal = m_pDecContext->sDecoderStatistics.iStatisticsLogInterval;431 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount != 0) { //not original status
432 * ((unsigned int*)pOption) = iVal;432 pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
433 return cmResultSuccess;433 (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount);
434 }434 pDecoderStatistics->fActualAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
435 } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI435 (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount + m_pDecContext->sDecoderStatistics.uiFreezingIDRNum +
436 PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));436 m_pDecContext->sDecoderStatistics.uiFreezingNonIDRNum);
437 memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));437 }
438 if (!m_pDecContext->pSps) {438 return cmResultSuccess;
439 return cmInitExpected;439 } else if (eOptID == DECODER_OPTION_STATISTICS_LOG_INTERVAL) {
440 } else {440 if (pOption) {
441 pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;441 iVal = m_pDecContext->sDecoderStatistics.iStatisticsLogInterval;
442 pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;442 * ((unsigned int*)pOption) = iVal;
443 pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;443 return cmResultSuccess;
444 return cmResultSuccess;444 }
445 }445 } else if (DECODER_OPTION_GET_SAR_INFO == eOptID) { //get decoder SAR info in VUI
446 } else if (DECODER_OPTION_PROFILE == eOptID) {446 PVuiSarInfo pVuiSarInfo = (static_cast<PVuiSarInfo> (pOption));
447 if (!m_pDecContext->pSps) {447 memset (pVuiSarInfo, 0, sizeof (SVuiSarInfo));
448 return cmInitExpected;448 if (!m_pDecContext->pSps) {
449 }449 return cmInitExpected;
450 iVal = (int) m_pDecContext->pSps->uiProfileIdc;450 } else {
451 * ((int*)pOption) = iVal;451 pVuiSarInfo->uiSarWidth = m_pDecContext->pSps->sVui.uiSarWidth;
452 return cmResultSuccess;452 pVuiSarInfo->uiSarHeight = m_pDecContext->pSps->sVui.uiSarHeight;
453 } else if (DECODER_OPTION_LEVEL == eOptID) {453 pVuiSarInfo->bOverscanAppropriateFlag = m_pDecContext->pSps->sVui.bOverscanAppropriateFlag;
454 if (!m_pDecContext->pSps) {454 return cmResultSuccess;
455 return cmInitExpected;455 }
456 }456 } else if (DECODER_OPTION_PROFILE == eOptID) {
457 iVal = (int) m_pDecContext->pSps->uiLevelIdc;457 if (!m_pDecContext->pSps) {
458 * ((int*)pOption) = iVal;458 return cmInitExpected;
459 return cmResultSuccess;459 }
460 }460 iVal = (int)m_pDecContext->pSps->uiProfileIdc;
461 461 * ((int*)pOption) = iVal;
462 return cmInitParaError;462 return cmResultSuccess;
463}463 } else if (DECODER_OPTION_LEVEL == eOptID) {
464 464 if (!m_pDecContext->pSps) {
465DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc,465 return cmInitExpected;
466 const int kiSrcLen,466 }
467 unsigned char** ppDst,467 iVal = (int)m_pDecContext->pSps->uiLevelIdc;
468 SBufferInfo* pDstInfo) {468 * ((int*)pOption) = iVal;
469 int iRet;469 return cmResultSuccess;
470 //SBufferInfo sTmpBufferInfo;470 } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
471 //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};471 if (m_pDecContext->pSps && m_pDecContext->pSps->uiProfileIdc != 66 && m_pDecContext->pPps->bEntropyCodingModeFlag) {
472 472 * ((int*)pOption) = m_iNumOfPicts > 0 ? m_iNumOfPicts : 0;
473 iRet = (int) DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);473 }
474 //memcpy (&sTmpBufferInfo, pDstInfo, sizeof (SBufferInfo));474 return cmResultSuccess;
475 //ppTmpDst[0] = ppDst[0];475 }
476 //ppTmpDst[1] = ppDst[1];476
477 //ppTmpDst[2] = ppDst[2];477 return cmInitParaError;
478 iRet |= DecodeFrame2 (NULL, 0, ppDst, pDstInfo);478}
479 //if ((pDstInfo->iBufferStatus == 0) && (sTmpBufferInfo.iBufferStatus == 1)) {479
480 //memcpy (pDstInfo, &sTmpBufferInfo, sizeof (SBufferInfo));480DECODING_STATE CWelsDecoder::DecodeFrameNoDelay (const unsigned char* kpSrc,
481 //ppDst[0] = ppTmpDst[0];481 const int kiSrcLen,
482 //ppDst[1] = ppTmpDst[1];482 unsigned char** ppDst,
483 //ppDst[2] = ppTmpDst[2];483 SBufferInfo* pDstInfo) {
484 //}484 int iRet;
485 485 //SBufferInfo sTmpBufferInfo;
486 return (DECODING_STATE) iRet;486 //unsigned char* ppTmpDst[3] = {NULL, NULL, NULL};
487}487 iRet = (int)DecodeFrame2 (kpSrc, kiSrcLen, ppDst, pDstInfo);
488 488 //memcpy (&sTmpBufferInfo, pDstInfo, sizeof (SBufferInfo));
489DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,489 //ppTmpDst[0] = ppDst[0];
490 const int kiSrcLen,490 //ppTmpDst[1] = ppDst[1];
491 unsigned char** ppDst,491 //ppTmpDst[2] = ppDst[2];
492 SBufferInfo* pDstInfo) {492 iRet |= DecodeFrame2 (NULL, 0, ppDst, pDstInfo);
493 if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {493 //if ((pDstInfo->iBufferStatus == 0) && (sTmpBufferInfo.iBufferStatus == 1)) {
494 if (m_pWelsTrace != NULL) {494 //memcpy (pDstInfo, &sTmpBufferInfo, sizeof (SBufferInfo));
495 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");495 //ppDst[0] = ppTmpDst[0];
496 }496 //ppDst[1] = ppTmpDst[1];
497 return dsInitialOptExpected;497 //ppDst[2] = ppTmpDst[2];
498 }498 //}
499 499 return (DECODING_STATE)iRet;
500 if (m_pDecContext->pParam->bParseOnly) {500}
501 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");501
502 m_pDecContext->iErrorCode |= dsInvalidArgument;502DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
503 return dsInvalidArgument;503 const int kiSrcLen,
504 }504 unsigned char** ppDst,
505 if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {505 SBufferInfo* pDstInfo) {
506 if (ResetDecoder())506 if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
507 return dsOutOfMemory;507 if (m_pWelsTrace != NULL) {
508 508 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeFrame2 without Initialize.\n");
509 return dsErrorFree;509 }
510 }510 return dsInitialOptExpected;
511 if (kiSrcLen > 0 && kpSrc != NULL) {511 }
512#ifdef OUTPUT_BIT_STREAM512
513 if (m_pFBS) {513 if (m_pDecContext->pParam->bParseOnly) {
514 WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);514 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be false for this API calling! \n");
515 WelsFflush (m_pFBS);515 m_pDecContext->iErrorCode |= dsInvalidArgument;
516 }516 return dsInvalidArgument;
517 if (m_pFBSSize) {517 }
518 WelsFwrite (&kiSrcLen, sizeof (int), 1, m_pFBSSize);518 if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
519 WelsFflush (m_pFBSSize);519 if (ResetDecoder())
520 }520 return dsOutOfMemory;
521#endif//OUTPUT_BIT_STREAM521
522 m_pDecContext->bEndOfStreamFlag = false;522 return dsErrorFree;
523 } else {523 }
524 //For application MODE, the error detection should be added for safe.524 if (kiSrcLen > 0 && kpSrc != NULL) {
525 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.525#ifdef OUTPUT_BIT_STREAM
526 m_pDecContext->bEndOfStreamFlag = true;526 if (m_pFBS) {
527 m_pDecContext->bInstantDecFlag = true;527 WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
528 }528 WelsFflush (m_pFBS);
529 529 }
530 int64_t iStart, iEnd;530 if (m_pFBSSize) {
531 iStart = WelsTime();531 WelsFwrite (&kiSrcLen, sizeof (int), 1, m_pFBSSize);
532 ppDst[0] = ppDst[1] = ppDst[2] = NULL;532 WelsFflush (m_pFBSSize);
533 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.533 }
534 m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize534#endif//OUTPUT_BIT_STREAM
535 unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;535 m_pDecContext->bEndOfStreamFlag = false;
536 memset (pDstInfo, 0, sizeof (SBufferInfo));536 } else {
537 pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;537 //For application MODE, the error detection should be added for safe.
538#ifdef LONG_TERM_REF538 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
539 m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR539 m_pDecContext->bEndOfStreamFlag = true;
540 m_pDecContext->bCurAuContainLtrMarkSeFlag = false;540 m_pDecContext->bInstantDecFlag = true;
541 m_pDecContext->iFrameNumOfAuMarkedLtr = 0;541 }
542 m_pDecContext->iFrameNum = -1; //initialize542
543#endif543 int64_t iStart, iEnd;
544 544 iStart = WelsTime();
545 m_pDecContext->iFeedbackTidInAu = -1; //initialize545
546 m_pDecContext->iFeedbackNalRefIdc = -1; //initialize546 ppDst[0] = ppDst[1] = ppDst[2] = NULL;
547 if (pDstInfo) {547 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
548 pDstInfo->uiOutYuvTimeStamp = 0;548 m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
549 m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;549 unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
550 } else {550 memset (pDstInfo, 0, sizeof (SBufferInfo));
551 m_pDecContext->uiTimeStamp = 0;551 pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
552 }552#ifdef LONG_TERM_REF
553 WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,553 m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
554 pDstInfo, NULL); //iErrorCode has been modified in this function554 m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
555 m_pDecContext->bInstantDecFlag = false; //reset no-delay flag555 m_pDecContext->iFrameNumOfAuMarkedLtr = 0;
556 if (m_pDecContext->iErrorCode) {556 m_pDecContext->iFrameNum = -1; //initialize
557 EWelsNalUnitType eNalType =557#endif
558 NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently558
559 559 m_pDecContext->iFeedbackTidInAu = -1; //initialize
560 eNalType = m_pDecContext->sCurNalHead.eNalUnitType;560 m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
561 561 if (pDstInfo) {
562 if (m_pDecContext->iErrorCode & dsOutOfMemory) {562 pDstInfo->uiOutYuvTimeStamp = 0;
563 if (ResetDecoder())563 m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
564 return dsOutOfMemory;564 } else {
565 565 m_pDecContext->uiTimeStamp = 0;
566 return dsErrorFree;566 }
567 }567 WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
568 //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.568 pDstInfo, NULL); //iErrorCode has been modified in this function
569 if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||569 m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
570 (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {570 if (m_pDecContext->iErrorCode) {
571 if (m_pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {571 EWelsNalUnitType eNalType =
572#ifdef LONG_TERM_REF572 NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
573 m_pDecContext->bParamSetsLostFlag = true;573
574#else574 eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
575 m_pDecContext->bReferenceLostAtT0Flag = true;575
576#endif576 if (m_pDecContext->iErrorCode & dsOutOfMemory) {
577 }577 if (ResetDecoder())
578 }578 return dsOutOfMemory;
579 579
580 if (m_pDecContext->bPrintFrameErrorTraceFlag) {580 return dsErrorFree;
581 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",581 }
582 m_pDecContext->iErrorCode);582 //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
583 m_pDecContext->bPrintFrameErrorTraceFlag = false;583 if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
584 } else {584 (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {
585 m_pDecContext->iIgnoredErrorInfoPacketCount ++;585 if (m_pDecContext->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
586 if (m_pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {586#ifdef LONG_TERM_REF
587 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");587 m_pDecContext->bParamSetsLostFlag = true;
588 m_pDecContext->iIgnoredErrorInfoPacketCount = 0;588#else
589 }589 m_pDecContext->bReferenceLostAtT0Flag = true;
590 }590#endif
591 if ((m_pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {591 }
592 //TODO after dec status updated592 }
593 m_pDecContext->iErrorCode |= dsDataErrorConcealed;593
594 594 if (m_pDecContext->bPrintFrameErrorTraceFlag) {
595 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;595 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n",
596 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t596 m_pDecContext->iErrorCode);
597 ResetDecStatNums (&m_pDecContext->sDecoderStatistics);597 m_pDecContext->bPrintFrameErrorTraceFlag = false;
598 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;598 } else {
599 }599 m_pDecContext->iIgnoredErrorInfoPacketCount++;
600 int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;600 if (m_pDecContext->iIgnoredErrorInfoPacketCount == INT_MAX) {
601 m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?601 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING, "continuous error reached INT_MAX! Restart as 0.");
602 (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((602 m_pDecContext->iIgnoredErrorInfoPacketCount = 0;
603 m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((603 }
604 iMbConcealedNum * 100) / m_pDecContext->iMbNum));604 }
605 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?605 if ((m_pDecContext->pParam->eEcActiveIdc != ERROR_CON_DISABLE) && (pDstInfo->iBufferStatus == 1)) {
606 (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((606 //TODO after dec status updated
607 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((607 m_pDecContext->iErrorCode |= dsDataErrorConcealed;
608 m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));608
609 m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);609 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
610 m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :610 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
611 m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;611 ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
612 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :612 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
613 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;613 }
614 }614 int32_t iMbConcealedNum = m_pDecContext->iMbEcedNum + m_pDecContext->iMbEcedPropNum;
615 iEnd = WelsTime();615 m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->iMbNum == 0 ?
616 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;616 (m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
617 617 m_pDecContext->sDecoderStatistics.uiAvgEcRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
618 OutputStatisticsLog (m_pDecContext->sDecoderStatistics);618 iMbConcealedNum * 100) / m_pDecContext->iMbNum));
619 619 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->iMbNum == 0 ?
620 return (DECODING_STATE) m_pDecContext->iErrorCode;620 (m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) : ((
621 }621 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio * m_pDecContext->sDecoderStatistics.uiEcFrameNum) + ((
622 // else Error free, the current codec works well622 m_pDecContext->iMbEcedPropNum * 100) / m_pDecContext->iMbNum));
623 623 m_pDecContext->sDecoderStatistics.uiEcFrameNum += (iMbConcealedNum == 0 ? 0 : 1);
624 if (pDstInfo->iBufferStatus == 1) {624 m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
625 625 m_pDecContext->sDecoderStatistics.uiAvgEcRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
626 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;626 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio = m_pDecContext->sDecoderStatistics.uiEcFrameNum == 0 ? 0 :
627 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t627 m_pDecContext->sDecoderStatistics.uiAvgEcPropRatio / m_pDecContext->sDecoderStatistics.uiEcFrameNum;
628 ResetDecStatNums (&m_pDecContext->sDecoderStatistics);628 }
629 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;629 iEnd = WelsTime();
630 }630 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
631 631
632 OutputStatisticsLog (m_pDecContext->sDecoderStatistics);632 OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
633 }633
634 iEnd = WelsTime();634#ifdef _PICTURE_REORDERING_
635 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;635 ReorderPicturesInDisplay (ppDst, pDstInfo);
636 636#endif
637 637
638 638 return (DECODING_STATE)m_pDecContext->iErrorCode;
639 return dsErrorFree;639 }
640}640 // else Error free, the current codec works well
641 641
642void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) {642 if (pDstInfo->iBufferStatus == 1) {
643 if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0)643
644 && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {644 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
645 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,645 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
646 "DecoderStatistics: uiWidth=%d, uiHeight=%d, fAverageFrameSpeedInMs=%.1f, fActualAverageFrameSpeedInMs=%.1f, \646 ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
647 uiDecodedFrameCount=%d, uiResolutionChangeTimes=%d, uiIDRCorrectNum=%d, \647 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
648 uiAvgEcRatio=%d, uiAvgEcPropRatio=%d, uiEcIDRNum=%d, uiEcFrameNum=%d, \648 }
649 uiIDRLostNum=%d, uiFreezingIDRNum=%d, uiFreezingNonIDRNum=%d, iAvgLumaQp=%d, \649
650 iSpsReportErrorNum=%d, iSubSpsReportErrorNum=%d, iPpsReportErrorNum=%d, iSpsNoExistNalNum=%d, iSubSpsNoExistNalNum=%d, iPpsNoExistNalNum=%d, \650 OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
651 uiProfile=%d, uiLevel=%d, \651 }
652 iCurrentActiveSpsId=%d, iCurrentActivePpsId=%d,",652 iEnd = WelsTime();
653 sDecoderStatistics.uiWidth,653 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
654 sDecoderStatistics.uiHeight,654
655 sDecoderStatistics.fAverageFrameSpeedInMs,655#ifdef _PICTURE_REORDERING_
656 sDecoderStatistics.fActualAverageFrameSpeedInMs,656 ReorderPicturesInDisplay (ppDst, pDstInfo);
657 657#endif
658 sDecoderStatistics.uiDecodedFrameCount,658 return dsErrorFree;
659 sDecoderStatistics.uiResolutionChangeTimes,659}
660 sDecoderStatistics.uiIDRCorrectNum,660
661 661DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
662 sDecoderStatistics.uiAvgEcRatio,662 SBufferInfo* pDstInfo) {
663 sDecoderStatistics.uiAvgEcPropRatio,663 if (m_pDecContext->bEndOfStreamFlag && m_iNumOfPicts > 0) {
664 sDecoderStatistics.uiEcIDRNum,664 m_iMinPOC = -1;
665 sDecoderStatistics.uiEcFrameNum,665 for (int32_t i = 0; i < 10; ++i) {
666 666 if (m_iMinPOC == -1 && m_sPictInfoList[i].iPOC >= 0) {
667 sDecoderStatistics.uiIDRLostNum,667 m_iMinPOC = m_sPictInfoList[i].iPOC;
668 sDecoderStatistics.uiFreezingIDRNum,668 m_iPictInfoIndex = i;
669 sDecoderStatistics.uiFreezingNonIDRNum,669 }
670 sDecoderStatistics.iAvgLumaQp,670 if (m_sPictInfoList[i].iPOC >= 0 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
671 671 m_iMinPOC = m_sPictInfoList[i].iPOC;
672 sDecoderStatistics.iSpsReportErrorNum,672 m_iPictInfoIndex = i;
673 sDecoderStatistics.iSubSpsReportErrorNum,673 }
674 sDecoderStatistics.iPpsReportErrorNum,674 }
675 sDecoderStatistics.iSpsNoExistNalNum,675 }
676 sDecoderStatistics.iSubSpsNoExistNalNum,676 if (m_iMinPOC >= 0) {
677 sDecoderStatistics.iPpsNoExistNalNum,677 m_LastWrittenPOC = m_iMinPOC;
678 678#if defined (_DEBUG)
679 sDecoderStatistics.uiProfile,679#ifdef _MOTION_VECTOR_DUMP_
680 sDecoderStatistics.uiLevel,680 fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
681 681#endif
682 sDecoderStatistics.iCurrentActiveSpsId,682#endif
683 sDecoderStatistics.iCurrentActivePpsId);683 memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
684 }684 ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
685}685 ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
686 686 ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
687DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,687 m_sPictInfoList[m_iPictInfoIndex].iPOC = -1;
688 const int kiSrcLen,688 m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
689 SParserBsInfo* pDstInfo) {689 m_iMinPOC = -1;
690 if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {690 --m_iNumOfPicts;
691 if (m_pWelsTrace != NULL) {691 }
692 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");692 return dsErrorFree;
693 }693}
694 return dsInitialOptExpected;694
695 }695void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) {
696 696 if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0)
697 if (!m_pDecContext->pParam->bParseOnly) {697 && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {
698 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");698 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
699 m_pDecContext->iErrorCode |= dsInvalidArgument;699 "DecoderStatistics: uiWidth=%d, uiHeight=%d, fAverageFrameSpeedInMs=%.1f, fActualAverageFrameSpeedInMs=%.1f, \
700 return dsInvalidArgument;700 uiDecodedFrameCount=%d, uiResolutionChangeTimes=%d, uiIDRCorrectNum=%d, \
701 }701 uiAvgEcRatio=%d, uiAvgEcPropRatio=%d, uiEcIDRNum=%d, uiEcFrameNum=%d, \
702 int64_t iEnd, iStart = WelsTime();702 uiIDRLostNum=%d, uiFreezingIDRNum=%d, uiFreezingNonIDRNum=%d, iAvgLumaQp=%d, \
703 if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {703 iSpsReportErrorNum=%d, iSubSpsReportErrorNum=%d, iPpsReportErrorNum=%d, iSpsNoExistNalNum=%d, iSubSpsNoExistNalNum=%d, iPpsNoExistNalNum=%d, \
704 if (ResetDecoder())704 uiProfile=%d, uiLevel=%d, \
705 return dsOutOfMemory;705 iCurrentActiveSpsId=%d, iCurrentActivePpsId=%d,",
706 706 sDecoderStatistics.uiWidth,
707 return dsErrorFree;707 sDecoderStatistics.uiHeight,
708 }708 sDecoderStatistics.fAverageFrameSpeedInMs,
709 if (kiSrcLen > 0 && kpSrc != NULL) {709 sDecoderStatistics.fActualAverageFrameSpeedInMs,
710#ifdef OUTPUT_BITSTREAM710
711 if (m_pFBS) {711 sDecoderStatistics.uiDecodedFrameCount,
712 WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);712 sDecoderStatistics.uiResolutionChangeTimes,
713 WelsFflush (m_pFBS);713 sDecoderStatistics.uiIDRCorrectNum,
714 }714
715#endif//OUTPUT_BIT_STREAM715 sDecoderStatistics.uiAvgEcRatio,
716 m_pDecContext->bEndOfStreamFlag = false;716 sDecoderStatistics.uiAvgEcPropRatio,
717 } else {717 sDecoderStatistics.uiEcIDRNum,
718 //For application MODE, the error detection should be added for safe.718 sDecoderStatistics.uiEcFrameNum,
719 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.719
720 m_pDecContext->bEndOfStreamFlag = true;720 sDecoderStatistics.uiIDRLostNum,
721 m_pDecContext->bInstantDecFlag = true;721 sDecoderStatistics.uiFreezingIDRNum,
722 }722 sDecoderStatistics.uiFreezingNonIDRNum,
723 723 sDecoderStatistics.iAvgLumaQp,
724 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.724
725 m_pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.725 sDecoderStatistics.iSpsReportErrorNum,
726 m_pDecContext->iFeedbackNalRefIdc = -1; //initialize726 sDecoderStatistics.iSubSpsReportErrorNum,
727 if (!m_pDecContext->bFramePending) { //frame complete727 sDecoderStatistics.iPpsReportErrorNum,
728 m_pDecContext->pParserBsInfo->iNalNum = 0;728 sDecoderStatistics.iSpsNoExistNalNum,
729 memset (m_pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);729 sDecoderStatistics.iSubSpsNoExistNalNum,
730 }730 sDecoderStatistics.iPpsNoExistNalNum,
731 pDstInfo->iNalNum = 0;731
732 pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;732 sDecoderStatistics.uiProfile,
733 if (pDstInfo) {733 sDecoderStatistics.uiLevel,
734 m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;734
735 pDstInfo->uiOutBsTimeStamp = 0;735 sDecoderStatistics.iCurrentActiveSpsId,
736 } else {736 sDecoderStatistics.iCurrentActivePpsId);
737 m_pDecContext->uiTimeStamp = 0;737 }
738 }738}
739 WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);739
740 if (m_pDecContext->iErrorCode & dsOutOfMemory) {740DECODING_STATE CWelsDecoder::ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo) {
741 if (ResetDecoder())741 if (pDstInfo->iBufferStatus == 1 && m_pDecContext->pSps->uiProfileIdc != 66
742 return dsOutOfMemory;742 && m_pDecContext->pPps->bEntropyCodingModeFlag) {
743 return dsErrorFree;743 if (m_pDecContext->pSliceHeader->iPicOrderCntLsb == 0) {
744 }744 if (m_iNumOfPicts > 0) {
745 745 m_iLastGOPRemainPicts = m_iNumOfPicts;
746 if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {746 for (int32_t i = 0; i < 10; ++i) {
747 memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));747 if (m_sPictInfoList[i].iPOC >= 0) {
748 748 m_sPictInfoList[i].bLastGOP = true;
749 if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count749 }
750 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;750 }
751 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t751 }
752 ResetDecStatNums (&m_pDecContext->sDecoderStatistics);752 }
753 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;753 for (int32_t i = 0; i < 10; ++i) {
754 }754 if (m_sPictInfoList[i].iPOC == -1) {
755 }755 memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
756 }756 m_sPictInfoList[i].pData[0] = ppDst[0];
757 757 m_sPictInfoList[i].pData[1] = ppDst[1];
758 m_pDecContext->bInstantDecFlag = false; //reset no-delay flag758 m_sPictInfoList[i].pData[2] = ppDst[2];
759 759 m_sPictInfoList[i].iPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
760 if (m_pDecContext->iErrorCode && m_pDecContext->bPrintFrameErrorTraceFlag) {760 m_sPictInfoList[i].iFrameNum = m_pDecContext->pSliceHeader->iFrameNum;
761 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);761 m_sPictInfoList[i].bLastGOP = false;
762 m_pDecContext->bPrintFrameErrorTraceFlag = false;762 pDstInfo->iBufferStatus = 0;
763 }763 ++m_iNumOfPicts;
764 iEnd = WelsTime();764 break;
765 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;765 }
766 766 }
767 return (DECODING_STATE) m_pDecContext->iErrorCode;767 if (m_iLastGOPRemainPicts > 0) {
768}768 m_iMinPOC = -1;
769 769 for (int32_t i = 0; i < 10; ++i) {
770DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,770 if (m_iMinPOC == -1 && m_sPictInfoList[i].iPOC >= 0 && m_sPictInfoList[i].bLastGOP) {
771 const int kiSrcLen,771 m_iMinPOC = m_sPictInfoList[i].iPOC;
772 unsigned char** ppDst,772 m_iPictInfoIndex = i;
773 int* pStride,773 }
774 int& iWidth,774 if (m_sPictInfoList[i].iPOC >= 0 && m_sPictInfoList[i].iPOC < m_iMinPOC && m_sPictInfoList[i].bLastGOP) {
775 int& iHeight) {775 m_iMinPOC = m_sPictInfoList[i].iPOC;
776 DECODING_STATE eDecState = dsErrorFree;776 m_iPictInfoIndex = i;
777 SBufferInfo DstInfo;777 }
778 778 }
779 memset (&DstInfo, 0, sizeof (SBufferInfo));779 m_LastWrittenPOC = m_iMinPOC;
780 DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0];780#if defined (_DEBUG)
781 DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1];781#ifdef _MOTION_VECTOR_DUMP_
782 DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;782 fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
783 DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;783#endif
784 784#endif
785 eDecState = DecodeFrame2 (kpSrc, kiSrcLen, ppDst, &DstInfo);785 memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
786 if (eDecState == dsErrorFree) {786 ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
787 pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];787 ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
788 pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];788 ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
789 iWidth = DstInfo.UsrData.sSystemBuffer.iWidth;789 m_sPictInfoList[m_iPictInfoIndex].iPOC = -1;
790 iHeight = DstInfo.UsrData.sSystemBuffer.iHeight;790 m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
791 }791 m_iMinPOC = -1;
792 792 --m_iNumOfPicts;
793 return eDecState;793 --m_iLastGOPRemainPicts;
794}794 if (m_iLastGOPRemainPicts == 0) {
795 795 m_LastWrittenPOC = 0;
796DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc,796 }
797 const int kiSrcLen,797 return dsErrorFree;
798 unsigned char* pDst,798 }
799 int iDstStride,799 if (m_iNumOfPicts > 0) {
800 int& iDstLen,800 m_iMinPOC = -1;
801 int& iWidth,801 for (int32_t i = 0; i < 10; ++i) {
802 int& iHeight,802 if (m_iMinPOC == -1 && m_sPictInfoList[i].iPOC >= 0) {
803 int& iColorFormat) {803 m_iMinPOC = m_sPictInfoList[i].iPOC;
804 DECODING_STATE state = dsErrorFree;804 m_iPictInfoIndex = i;
805 805 }
806 return state;806 if (m_sPictInfoList[i].iPOC >= 0 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
807}807 m_iMinPOC = m_sPictInfoList[i].iPOC;
808 808 m_iPictInfoIndex = i;
809 809 }
810} // namespace WelsDec810 }
811 811 }
812 812 if (m_iMinPOC >= 0) {
813using namespace WelsDec;813 if (m_iMinPOC - m_LastWrittenPOC <= 1 || m_iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
814/*814 m_LastWrittenPOC = m_iMinPOC;
815* WelsGetDecoderCapability815#if defined (_DEBUG)
816* @return: DecCapability information816#ifdef _MOTION_VECTOR_DUMP_
817*/817 fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
818int WelsGetDecoderCapability (SDecoderCapability* pDecCapability) {818#endif
819 memset (pDecCapability, 0, sizeof (SDecoderCapability));819#endif
820 pDecCapability->iProfileIdc = 66; //Baseline820 memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
821 pDecCapability->iProfileIop = 0xE0; //11100000b821 ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
822 pDecCapability->iLevelIdc = 32; //level_idc = 3.2822 ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
823 pDecCapability->iMaxMbps = 216000; //from level_idc = 3.2823 ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
824 pDecCapability->iMaxFs = 5120; //from level_idc = 3.2824 m_sPictInfoList[m_iPictInfoIndex].iPOC = -1;
825 pDecCapability->iMaxCpb = 20000; //from level_idc = 3.2825 m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
826 pDecCapability->iMaxDpb = 20480; //from level_idc = 3.2826 m_iMinPOC = -1;
827 pDecCapability->iMaxBr = 20000; //from level_idc = 3.2827 --m_iNumOfPicts;
828 pDecCapability->bRedPicCap = 0; //not support redundant pic828 return dsErrorFree;
829 829 }
830 return ERR_NONE;830 }
831}831 }
832/* WINAPI is indeed in prefix due to sync to application layer callings!! */832
833 833 return dsErrorFree;
834/*834}
835* WelsCreateDecoder835
836* @return: success in return 0, otherwise failed.836DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
837*/837 const int kiSrcLen,
838long WelsCreateDecoder (ISVCDecoder** ppDecoder) {838 SParserBsInfo* pDstInfo) {
839 839 if (m_pDecContext == NULL || m_pDecContext->pParam == NULL) {
840 if (NULL == ppDecoder) {840 if (m_pWelsTrace != NULL) {
841 return ERR_INVALID_PARAMETERS;841 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "Call DecodeParser without Initialize.\n");
842 }842 }
843 843 return dsInitialOptExpected;
844 *ppDecoder = new CWelsDecoder();844 }
845 845
846 if (NULL == *ppDecoder) {846 if (!m_pDecContext->pParam->bParseOnly) {
847 return ERR_MALLOC_FAILED;847 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "bParseOnly should be true for this API calling! \n");
848 }848 m_pDecContext->iErrorCode |= dsInvalidArgument;
849 849 return dsInvalidArgument;
850 return ERR_NONE;850 }
851}851 int64_t iEnd, iStart = WelsTime();
852 852 if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
853/*853 if (ResetDecoder())
854* WelsDestroyDecoder854 return dsOutOfMemory;
855*/855
856void WelsDestroyDecoder (ISVCDecoder* pDecoder) {856 return dsErrorFree;
857 if (NULL != pDecoder) {857 }
858 delete (CWelsDecoder*)pDecoder;858 if (kiSrcLen > 0 && kpSrc != NULL) {
859 }859#ifdef OUTPUT_BITSTREAM
860}860 if (m_pFBS) {
861 WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS);
862 WelsFflush (m_pFBS);
863 }
864#endif//OUTPUT_BIT_STREAM
865 m_pDecContext->bEndOfStreamFlag = false;
866 } else {
867 //For application MODE, the error detection should be added for safe.
868 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
869 m_pDecContext->bEndOfStreamFlag = true;
870 m_pDecContext->bInstantDecFlag = true;
871 }
872
873 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
874 m_pDecContext->pParam->eEcActiveIdc = ERROR_CON_DISABLE; //add protection to disable EC here.
875 m_pDecContext->iFeedbackNalRefIdc = -1; //initialize
876 if (!m_pDecContext->bFramePending) { //frame complete
877 m_pDecContext->pParserBsInfo->iNalNum = 0;
878 memset (m_pDecContext->pParserBsInfo->pNalLenInByte, 0, MAX_NAL_UNITS_IN_LAYER);
879 }
880 pDstInfo->iNalNum = 0;
881 pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
882 if (pDstInfo) {
883 m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
884 pDstInfo->uiOutBsTimeStamp = 0;
885 } else {
886 m_pDecContext->uiTimeStamp = 0;
887 }
888 WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
889 if (m_pDecContext->iErrorCode & dsOutOfMemory) {
890 if (ResetDecoder())
891 return dsOutOfMemory;
892 return dsErrorFree;
893 }
894
895 if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {
896 memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
897
898 if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
899 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
900 if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
901 ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
902 m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
903 }
904 }
905 }
906
907 m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
908
909 if (m_pDecContext->iErrorCode && m_pDecContext->bPrintFrameErrorTraceFlag) {
910 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);
911 m_pDecContext->bPrintFrameErrorTraceFlag = false;
912 }
913 iEnd = WelsTime();
914 m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
915
916 return (DECODING_STATE) m_pDecContext->iErrorCode;
917}
918
919DECODING_STATE CWelsDecoder::DecodeFrame (const unsigned char* kpSrc,
920 const int kiSrcLen,
921 unsigned char** ppDst,
922 int* pStride,
923 int& iWidth,
924 int& iHeight) {
925 DECODING_STATE eDecState = dsErrorFree;
926 SBufferInfo DstInfo;
927
928 memset (&DstInfo, 0, sizeof (SBufferInfo));
929 DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0];
930 DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1];
931 DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;
932 DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;
933
934 eDecState = DecodeFrame2 (kpSrc, kiSrcLen, ppDst, &DstInfo);
935 if (eDecState == dsErrorFree) {
936 pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];
937 pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];
938 iWidth = DstInfo.UsrData.sSystemBuffer.iWidth;
939 iHeight = DstInfo.UsrData.sSystemBuffer.iHeight;
940 }
941
942 return eDecState;
943}
944
945DECODING_STATE CWelsDecoder::DecodeFrameEx (const unsigned char* kpSrc,
946 const int kiSrcLen,
947 unsigned char* pDst,
948 int iDstStride,
949 int& iDstLen,
950 int& iWidth,
951 int& iHeight,
952 int& iColorFormat) {
953 DECODING_STATE state = dsErrorFree;
954
955 return state;
956}
957
958
959} // namespace WelsDec
960
961
962using namespace WelsDec;
963/*
964* WelsGetDecoderCapability
965* @return: DecCapability information
966*/
967int WelsGetDecoderCapability (SDecoderCapability* pDecCapability) {
968 memset (pDecCapability, 0, sizeof (SDecoderCapability));
969 pDecCapability->iProfileIdc = 66; //Baseline
970 pDecCapability->iProfileIop = 0xE0; //11100000b
971 pDecCapability->iLevelIdc = 32; //level_idc = 3.2
972 pDecCapability->iMaxMbps = 216000; //from level_idc = 3.2
973 pDecCapability->iMaxFs = 5120; //from level_idc = 3.2
974 pDecCapability->iMaxCpb = 20000; //from level_idc = 3.2
975 pDecCapability->iMaxDpb = 20480; //from level_idc = 3.2
976 pDecCapability->iMaxBr = 20000; //from level_idc = 3.2
977 pDecCapability->bRedPicCap = 0; //not support redundant pic
978
979 return ERR_NONE;
980}
981/* WINAPI is indeed in prefix due to sync to application layer callings!! */
982
983/*
984* WelsCreateDecoder
985* @return: success in return 0, otherwise failed.
986*/
987long WelsCreateDecoder (ISVCDecoder** ppDecoder) {
988
989 if (NULL == ppDecoder) {
990 return ERR_INVALID_PARAMETERS;
991 }
992
993 *ppDecoder = new CWelsDecoder();
994
995 if (NULL == *ppDecoder) {
996 return ERR_MALLOC_FAILED;
997 }
998
999 return ERR_NONE;
1000}
1001
1002/*
1003* WelsDestroyDecoder
1004*/
1005void WelsDestroyDecoder (ISVCDecoder* pDecoder) {
1006 if (NULL != pDecoder) {
1007 delete (CWelsDecoder*)pDecoder;
1008 }
1009}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t