History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

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

Unified · Split

codec/decoder/plus/src/welsDecoderExt.cpp+532−0
@@ -0,0 +1,532 @@
1/*!
2 * \copy
3 * Copyright (c) 2009-2013, Cisco Systems
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *
32 * welsDecoderExt.cpp
33 *
34 * Abstract
35 * Cisco OpenH264 decoder extension utilization
36 *
37 * History
38 * 3/12/2009 Created
39 *
40 *
41 ************************************************************************/
42//#include <assert.h>
43#include "welsDecoderExt.h"
44#include "welsCodecTrace.h"
45#include "codec_def.h"
46#include "typedefs.h"
47#include "mem_align.h"
48#include "utils.h"
49
50//#include "macros.h"
51#include "decoder.h"
52
53extern "C" {
54#include "decoder_core.h"
55#include "manage_dec_ref.h"
56}
57#include "error_code.h"
58#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms
59#include <time.h>
60#if defined(WIN32) /*&& defined(_DEBUG)*/
61
62#include <windows.h>
63#include <stdio.h>
64#include <stdarg.h>
65#include <sys/types.h>
66#include <sys/timeb.h>
67#else
68#include <sys/time.h>
69#endif
70
71namespace WelsDec {
72
73//////////////////////////////////////////////////////////////////////
74// Construction/Destruction
75//////////////////////////////////////////////////////////////////////
76
77/***************************************************************************
78* Description:
79* class CWelsDecoder constructor function, do initialization and
80* alloc memory required
81*
82* Input parameters: none
83*
84* return: none
85/***************************************************************************/
86CWelsDecoder::CWelsDecoder(void_t)
87: m_pDecContext( NULL ),
88 m_pTrace( NULL )
89{
90#ifdef OUTPUT_BIT_STREAM
91 str_t chFileName[1024] = { 0 }; //for .264
92 int iBufUsed = 0;
93 int iBufLeft = 1023;
94
95 str_t chFileNameSize[1024] = { 0 }; //for .len
96 int iBufUsedSize = 0;
97 int iBufLeftSize = 1023;
98#endif//OUTPUT_BIT_STREAM
99
100 m_pTrace = CreateWelsTrace(Wels_Trace_Type);
101
102 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO,"CWelsDecoder::CWelsDecoder() entry");
103
104
105#ifdef OUTPUT_BIT_STREAM
106 SWelsTime sCurTime;
107
108 WelsGetTimeOfDay(&sCurTime);
109
110 iBufUsed += WelsSnprintf(chFileName, iBufLeft, "bs_0x%p_", (void_t*)this);
111 iBufUsedSize += WelsSnprintf(chFileNameSize, iBufLeftSize, "size_0x%p_", (void_t*)this);
112
113 iBufLeft -= iBufUsed;
114 if ( iBufLeft > iBufUsed )
115 {
116 iBufUsed += WelsStrftime(&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime);
117 iBufLeft -= iBufUsed;
118 }
119
120 iBufLeftSize -= iBufUsedSize;
121 if ( iBufLeftSize> iBufUsedSize )
122 {
123 iBufUsedSize += WelsStrftime(&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime);
124 iBufLeftSize -= iBufUsedSize;
125 }
126
127 if ( iBufLeft > iBufUsed )
128 {
129 iBufUsed += WelsSnprintf(&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillsecond(&sCurTime));
130 iBufLeft -= iBufUsed;
131 }
132
133 if ( iBufLeftSize > iBufUsedSize )
134 {
135 iBufUsedSize += WelsSnprintf(&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len", WelsGetMillsecond(&sCurTime));
136 iBufLeftSize -= iBufUsedSize;
137 }
138
139
140 m_pFBS = WelsFopen(chFileName, "wb");
141 m_pFBSSize = WelsFopen(chFileNameSize, "wb");
142#endif//OUTPUT_BIT_STREAM
143
144}
145
146/***************************************************************************
147* Description:
148* class CWelsDecoder destructor function, destroy allocced memory
149*
150* Input parameters: none
151*
152* return: none
153/***************************************************************************/
154CWelsDecoder::~CWelsDecoder()
155{
156 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()");
157
158 UninitDecoder();
159
160#ifdef OUTPUT_BIT_STREAM
161 if ( m_pFBS )
162 {
163 WelsFclose( m_pFBS );
164 m_pFBS = NULL;
165 }
166 if ( m_pFBSSize )
167 {
168 WelsFclose( m_pFBSSize );
169 m_pFBSSize = NULL;
170 }
171#endif//OUTPUT_BIT_STREAM
172
173 if( NULL != m_pTrace ){
174 delete m_pTrace;
175 m_pTrace = NULL;
176 }
177}
178
179long CWelsDecoder::Initialize(void_t* pParam, const INIT_TYPE keInitType)
180{
181 if ( pParam == NULL || keInitType != INIT_TYPE_PARAMETER_BASED ){
182 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::Initialize(), invalid input argument.");
183 return cmInitParaError;
184 }
185
186 // H.264 decoder initialization,including memory allocation,then open it ready to decode
187 InitDecoder();
188
189 DecoderConfigParam( m_pDecContext, pParam );
190
191 return cmResultSuccess;
192}
193
194long CWelsDecoder::Unintialize()
195{
196 UninitDecoder();
197
198 return ERR_NONE;
199}
200
201void_t CWelsDecoder::UninitDecoder( void_t )
202{
203 if ( NULL == m_pDecContext )
204 return;
205
206 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "into CWelsDecoder::uninit_decoder()..");
207
208 WelsEndDecoder( m_pDecContext );
209
210 if ( NULL != m_pDecContext )
211 {
212 WelsFree( m_pDecContext, "m_pDecContext" );
213
214 m_pDecContext = NULL;
215 }
216
217 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "left CWelsDecoder::uninit_decoder()..");
218}
219
220// the return value of this function is not suitable, it need report failure info to upper layer.
221void_t CWelsDecoder::InitDecoder( void_t )
222{
223 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::init_decoder()..");
224
225 m_pDecContext = (PWelsDecoderContext)WelsMalloc( sizeof(SWelsDecoderContext), "m_pDecContext" );
226
227 WelsInitDecoder( m_pDecContext, m_pTrace, IWelsTrace::WelsTrace );
228
229 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::init_decoder().. left");
230}
231
232/*
233 * Set Option
234 */
235long CWelsDecoder::SetOption(DECODER_OPTION eOptID, void_t* pOption)
236{
237 int iVal = 0;
238
239 if ( m_pDecContext == NULL )
240 return dsInitialOptExpected;
241
242 if ( eOptID == DECODER_OPTION_DATAFORMAT ) // Set color space of decoding output frame
243 {
244 if ( pOption == NULL )
245 return cmInitParaError;
246
247 iVal = *((int*)pOption); // is_rgb
248
249 return DecoderSetCsp( m_pDecContext, iVal );
250 }
251 else if ( eOptID == DECODER_OPTION_END_OF_STREAM ) // Indicate bit-stream of the final frame to be decoded
252 {
253 if ( pOption == NULL )
254 return cmInitParaError;
255
256 iVal = *((int*)pOption); // boolean value for whether enabled End Of Stream flag
257
258 m_pDecContext->bEndOfStreamFlag = iVal ? true : false;
259
260 return cmResultSuccess;
261 }
262 else if ( eOptID == DECODER_OPTION_MODE)
263 {
264 if ( pOption == NULL )
265 return cmInitParaError;
266
267 iVal = *((int *)pOption);
268
269 m_pDecContext->iSetMode = iVal;
270 if(iVal == SW_MODE)
271 {
272 m_pDecContext->iDecoderOutputProperty = BUFFER_HOST;
273 }
274 else
275 {
276#if !defined(__APPLE__)
277 m_pDecContext->iDecoderOutputProperty = BUFFER_DEVICE;
278#else
279 m_pDecContext->iDecoderOutputProperty = BUFFER_HOST;//BUFFER_HOST;//BUFFER_DEVICE;
280#endif
281
282 }
283
284 return cmResultSuccess;
285 }
286 else if ( eOptID == DECODER_OPTION_OUTPUT_PROPERTY)
287 {
288 if ( pOption == NULL)
289 return cmInitParaError;
290
291 iVal = *((int *)pOption);
292 if( m_pDecContext->iSetMode != SW_MODE)
293 m_pDecContext->iDecoderOutputProperty = iVal;
294 }
295
296
297 return cmInitParaError;
298}
299
300/*
301 * Get Option
302 */
303long CWelsDecoder::GetOption(DECODER_OPTION eOptID, void_t* pOption)
304{
305 int iVal = 0;
306
307 if ( m_pDecContext == NULL )
308 return cmInitExpected;
309
310 if ( pOption == NULL )
311 return cmInitParaError;
312
313 if ( DECODER_OPTION_DATAFORMAT == eOptID ){
314 iVal = m_pDecContext->iOutputColorFormat;
315 *((int*)pOption) = iVal;
316 return cmResultSuccess;
317 }
318 else if ( DECODER_OPTION_END_OF_STREAM == eOptID ){
319 iVal = m_pDecContext->bEndOfStreamFlag;
320 *((int*)pOption) = iVal;
321 return cmResultSuccess;
322 }
323#ifdef LONG_TERM_REF
324 else if ( DECODER_OPTION_IDR_PIC_ID == eOptID ){
325 iVal = m_pDecContext->uiCurIdrPicId;
326 *((int*)pOption) = iVal;
327 return cmResultSuccess;
328 }
329 else if ( DECODER_OPTION_FRAME_NUM == eOptID)
330 {
331 iVal = m_pDecContext->iFrameNum;
332 *((int*)pOption) = iVal;
333 return cmResultSuccess;
334 }
335 else if ( DECODER_OPTION_LTR_MARKING_FLAG == eOptID )
336 {
337 iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag;
338 *((int*)pOption) = iVal;
339 return cmResultSuccess;
340 }
341 else if ( DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID )
342 {
343 iVal = m_pDecContext->iFrameNumOfAuMarkedLtr;
344 *((int*)pOption) = iVal;
345 return cmResultSuccess;
346 }
347#endif
348 else if ( DECODER_OPTION_VCL_NAL == eOptID ) //feedback whether or not have VCL NAL in current AU
349 {
350 iVal = m_pDecContext->iFeedbackVclNalInAu;
351 *((int*)pOption) = iVal;
352 return cmResultSuccess;
353 }
354 else if ( DECODER_OPTION_TEMPORAL_ID == eOptID ) //if have VCL NAL in current AU, then feedback the temporal ID
355 {
356 iVal = m_pDecContext->iFeedbackTidInAu;
357 *((int*)pOption) = iVal;
358 return cmResultSuccess;
359 }
360 else if ( DECODER_OPTION_MODE == eOptID )
361 {
362 if ( pOption == NULL )
363 return cmInitParaError;
364
365 iVal = m_pDecContext->iSetMode;
366
367 *((int *)pOption) = iVal;
368 return cmResultSuccess;
369 }
370 else if ( DECODER_OPTION_DEVICE_INFO == eOptID )
371 {
372 if ( pOption == NULL )
373 return cmInitParaError;
374
375 return cmResultSuccess;
376 }
377
378 return cmInitParaError;
379}
380
381DECODING_STATE CWelsDecoder::DecodeFrame( const unsigned char* kpSrc,
382 const int kiSrcLen,
383 void_t ** ppDst,
384 SBufferInfo* pDstInfo)
385{
386 if ( kiSrcLen > 0 && kpSrc != NULL )
387 {
388#ifdef OUTPUT_BIT_STREAM
389 if ( m_pFBS )
390 {
391 WelsFwrite( kpSrc, sizeof(unsigned char), kiSrcLen, m_pFBS );
392 WelsFflush( m_pFBS );
393 }
394 if ( m_pFBSSize )
395 {
396 WelsFwrite( &kiSrcLen, sizeof(int), 1, m_pFBSSize );
397 WelsFflush( m_pFBSSize );
398 }
399#endif//OUTPUT_BIT_STREAM
400 m_pDecContext->bEndOfStreamFlag = false;
401 }
402 else
403 { //For application MODE, the error detection should be added for safe.
404 //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
405 m_pDecContext->bEndOfStreamFlag = true;
406 }
407
408 ppDst[0] = ppDst[1] = ppDst[2] = NULL;
409 m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
410 m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
411 memset(pDstInfo,0,sizeof(SBufferInfo));
412 pDstInfo->eBufferProperty = (EBufferProperty)m_pDecContext->iDecoderOutputProperty;
413
414#ifdef LONG_TERM_REF
415 m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
416 m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
417 m_pDecContext->iFrameNumOfAuMarkedLtr = 0;
418 m_pDecContext->iFrameNum = -1; //initialize
419#endif
420
421 m_pDecContext->iFeedbackTidInAu = -1; //initialize
422
423 WelsDecodeBs( m_pDecContext, kpSrc, kiSrcLen, (unsigned char**)ppDst, pDstInfo); //iErrorCode has been modified in this function
424
425 pDstInfo->eWorkMode = (EDecodeMode)m_pDecContext->iDecoderMode;
426
427 if ( m_pDecContext->iErrorCode )
428 {
429 ENalUnitType eNalType = NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
430
431 eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
432
433 //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
434 if ( (IS_PARAM_SETS_NALS(eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
435 (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType) )
436 {
437#ifdef LONG_TERM_REF
438 m_pDecContext->bParamSetsLostFlag = true;
439#else
440 m_pDecContext->bReferenceLostAtT0Flag = true;
441#endif
442 ResetParameterSetsState( m_pDecContext ); //initial SPS&PPS ready flag
443 }
444
445 IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);
446 return (DECODING_STATE)m_pDecContext->iErrorCode;
447 }
448
449 return dsErrorFree;
450}
451
452DECODING_STATE CWelsDecoder::DecodeFrame( const unsigned char* kpSrc,
453 const int kiSrcLen,
454 unsigned char** ppDst,
455 int* pStride,
456 int& iWidth,
457 int& iHeight )
458{
459 DECODING_STATE eDecState = dsErrorFree;
460 SBufferInfo DstInfo;
461
462 memset(&DstInfo, 0, sizeof(SBufferInfo));
463 DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0];
464 DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1];
465 DstInfo.UsrData.sSystemBuffer.iWidth = iWidth;
466 DstInfo.UsrData.sSystemBuffer.iHeight = iHeight;
467 DstInfo.eBufferProperty = BUFFER_HOST;
468
469 eDecState = DecodeFrame(kpSrc, kiSrcLen, (void_t **)ppDst, &DstInfo);
470 if (eDecState == dsErrorFree)
471 {
472 pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0];
473 pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1];
474 iWidth = DstInfo.UsrData.sSystemBuffer.iWidth;
475 iHeight = DstInfo.UsrData.sSystemBuffer.iHeight;
476 }
477
478 return eDecState;
479}
480
481DECODING_STATE CWelsDecoder::DecodeFrameEx(const unsigned char * kpSrc,
482 const int kiSrcLen,
483 unsigned char * pDst,
484 int iDstStride,
485 int & iDstLen,
486 int & iWidth,
487 int & iHeight,
488 int & iColorFormat )
489{
490 DECODING_STATE state = dsErrorFree;
491
492 return state;
493}
494
495
496} // namespace WelsDec
497
498
499using namespace WelsDec;
500
501/* WINAPI is indeed in prefix due to sync to application layer callings!! */
502
503/*
504* CreateDecoder
505* @return: success in return 0, otherwise failed.
506*/
507long CreateDecoder( ISVCDecoder** ppDecoder )
508{
509
510 if ( NULL == ppDecoder ){
511 return ERR_INVALID_PARAMETERS;
512 }
513
514 *ppDecoder = new CWelsDecoder();
515
516 if ( NULL == *ppDecoder ){
517 return ERR_MALLOC_FAILED;
518 }
519
520 return ERR_NONE;
521}
522
523/*
524* DestroyDecoder
525*/
526void_t DestroyDecoder( ISVCDecoder* pDecoder )
527{
528 if ( NULL != pDecoder ){
529 delete (CWelsDecoder *)pDecoder;
530 pDecoder = NULL;
531 }
532}

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