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+
53+extern "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+
71+namespace 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+/***************************************************************************/
86+CWelsDecoder::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+/***************************************************************************/
154+CWelsDecoder::~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+
179+long 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+
194+long CWelsDecoder::Unintialize()
195+{
196+ UninitDecoder();
197+
198+ return ERR_NONE;
199+}
200+
201+void_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.
221+void_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+ */
235+long 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+ */
303+long 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+
381+DECODING_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+
452+DECODING_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+
481+DECODING_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+
499+using 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+*/
507+long 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+*/
526+void_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