History

Initial Commit

Ethan Hugg committed 12 years ago

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

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

Unified · Split

codec/encoder/plus/src/welsEncoderExt.cpp+1255−0
@@ -0,0 +1,1255 @@
1+/*!
2+ * \copy
3+ * Copyright (c) 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+
33+#include <assert.h>
34+#include "welsEncoderExt.h"
35+#include "welsCodecTrace.h"
36+#include "typedefs.h"
37+#include "wels_const.h"
38+#include "utils.h"
39+#include "macros.h"
40+
41+#include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms
42+#include "ref_list_mgr_svc.h"
43+
44+#include <time.h>
45+#if defined(WIN32) /*&& defined(_DEBUG)*/
46+
47+#include <windows.h>
48+#include <stdio.h>
49+#include <stdarg.h>
50+#include <sys/types.h>
51+#include <sys/timeb.h>
52+#else
53+#include <sys/time.h>
54+#endif
55+
56+namespace WelsSVCEnc {
57+
58+/*
59+ * CWelsH264SVCEncoder class implementation
60+ */
61+CWelsH264SVCEncoder::CWelsH264SVCEncoder()
62+: m_pEncContext ( NULL ),
63+#if defined(WIN32)||defined(_MACH_PLATFORM)||defined(__GNUC__)
64+ m_pWelsTrace ( NULL ),
65+#endif
66+ m_pSrcPicList ( NULL ),
67+ m_iSrcListSize ( 0 ),
68+ m_iMaxPicWidth ( 0 ),
69+ m_iMaxPicHeight ( 0 ),
70+ m_iCspInternal ( 0 ),
71+ m_bInitialFlag ( FALSE )
72+{
73+#ifdef REC_FRAME_COUNT
74+ int32_t m_uiCountFrameNum = 0;
75+#endif//REC_FRAME_COUNT
76+
77+#ifdef OUTPUT_BIT_STREAM
78+ str_t strStreamFileName[1024] = { 0 }; //for .264
79+ int32_t iBufferUsed = 0;
80+ int32_t iBufferLeft = 1023;
81+
82+ str_t strLenFileName[1024] = { 0 }; //for .len
83+ int32_t iBufferUsedSize = 0;
84+ int32_t iBufferLeftSize = 1023;
85+#endif//OUTPUT_BIT_STREAM
86+
87+#ifdef OUTPUT_BIT_STREAM
88+ time_t tTime;
89+
90+#if defined( WIN32 )
91+#if defined(_MSC_VER)
92+#if _MSC_VER>=1500
93+ struct tm tTimeNow;
94+#else
95+ struct tm *tTimeNow;
96+#endif//_MSC_VER>=1500
97+#endif//_MSC_VER
98+ struct _timeb tTimeb;
99+
100+ time(&tTime);
101+#if defined(_MSC_VER)
102+#if _MSC_VER>=1500
103+ LOCALTIME(&tTimeNow, &tTime);
104+#else
105+ tTimeNow = LOCALTIME(&tTime);
106+ if ( NULL == tTimeNow )
107+ return;
108+#endif//_MSC_VER>=1500
109+#endif//_MSC_VER
110+ FTIME(&tTimeb);
111+#elif defined( __GNUC__ )
112+ struct tm* tTimeNow;
113+ struct timeval tTimev;
114+ time(&tTime);
115+ tTimeNow = (struct tm *)localtime(&tTime);
116+ gettimeofday(&tTimev,NULL);
117+#endif//WIN32
118+
119+#ifdef WIN32
120+#if defined(_MSC_VER)
121+#if _MSC_VER>=1500
122+ iBufferUsed += SNPRINTF(strStreamFileName, iBufferLeft, iBufferLeft, "enc_bs_0x%p_", (void*)this);
123+ iBufferUsedSize += SNPRINTF(strLenFileName, iBufferLeftSize, iBufferLeftSize, "enc_size_0x%p_", (void*)this);
124+#else
125+ iBufferUsed += SNPRINTF(strStreamFileName, iBufferLeft, "enc_bs_0x%p_", (void*)this);
126+ iBufferUsedSize += SNPRINTF(strLenFileName, iBufferLeftSize, "enc_size_0x%p_", (void*)this);
127+#endif//_MSC_VER>=1500
128+#endif//_MSC_VER
129+#else
130+ iBufferUsed += SNPRINTF(strStreamFileName, iBufferLeft, "/tmp/enc_bs_0x%p_", (void*)this);
131+ iBufferUsedSize += SNPRINTF(strLenFileName, iBufferLeftSize, "/tmp/enc_size_0x%p", (void*)this);
132+#endif//WIN32
133+
134+
135+ iBufferLeft -= iBufferUsed;
136+ if ( iBufferLeft > iBufferUsed )
137+ {
138+#if defined(_GNUC__)
139+ iBufferUsed += strftime(&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S", tTimeNow);
140+#else
141+#if defined(_MSC_VER)
142+ iBufferUsed += strftime(&strStreamFileName[iBufferUsed], iBufferLeft, "%y%m%d%H%M%S",
143+#if _MSC_VER>=1500
144+ &tTimeNow
145+#else
146+ tTimeNow
147+#endif//_MSC_VER>=1500
148+ );
149+#endif//_MSC_VER
150+#endif//__GNUC__
151+ iBufferLeft -= iBufferUsed;
152+ }
153+
154+ iBufferLeftSize -= iBufferUsedSize;
155+ if ( iBufferLeftSize> iBufferUsedSize )
156+ {
157+#if defined(_GNUC__)
158+ iBufferUsedSize += strftime(&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S", tTimeNow);
159+#else
160+#if defined(_MSC_VER)
161+ iBufferUsedSize += strftime(&strLenFileName[iBufferUsedSize], iBufferLeftSize, "%y%m%d%H%M%S",
162+#if _MSC_VER>=1500
163+ &tTimeNow
164+#else
165+ tTimeNow
166+#endif//_MSC_VER>=1500
167+ );
168+#endif//_MSC_VER
169+#endif//__GNUC__
170+ iBufferLeftSize -= iBufferUsedSize;
171+ }
172+
173+ if ( iBufferLeft > iBufferUsed )
174+ {
175+#ifdef WIN32
176+#if defined(_MSC_VER)
177+#if _MSC_VER>=1500
178+ iBufferUsed += SNPRINTF(&strStreamFileName[iBufferUsed], iBufferLeft, iBufferLeft, ".%03.3u.264", tTimeb.millitm);
179+#else
180+ iBufferUsed += SNPRINTF(&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimeb.millitm);
181+#endif//_MSC_VER>=1500
182+#endif//_MSC_VER
183+#else
184+ iBufferUsed += SNPRINTF(&strStreamFileName[iBufferUsed], iBufferLeft, ".%03.3u.264", tTimev.tv_usec/1000);
185+#endif//WIN32
186+ iBufferLeft -= iBufferUsed;
187+ }
188+
189+ if ( iBufferLeftSize > iBufferUsedSize )
190+ {
191+#ifdef WIN32
192+#if defined(_MSC_VER)
193+#if _MSC_VER>=1500
194+ iBufferUsedSize += SNPRINTF(&strLenFileName[iBufferUsedSize], iBufferLeftSize, iBufferLeftSize, ".%03.3u.len", tTimeb.millitm);
195+#else
196+ iBufferUsedSize += SNPRINTF(&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimeb.millitm);
197+#endif//_MSC_VER>=1500
198+#endif//_MSC_VER
199+#else
200+ iBufferUsedSize += SNPRINTF(&strLenFileName[iBufferUsedSize], iBufferLeftSize, ".%03.3u.len", tTimev.tv_usec/1000);
201+#endif//WIN32
202+ iBufferLeftSize -= iBufferUsedSize;
203+ }
204+
205+#if defined(__GNUC__)
206+ m_pFileBs = FOPEN(strStreamFileName, "wb");
207+ m_pFileBsSize = FOPEN(strLenFileName, "wb");
208+#else
209+#if defined(_MSC_VER)
210+#if _MSC_VER>=1500
211+ FOPEN(&m_pFileBs, strStreamFileName, "wb");
212+ FOPEN(&m_pFileBsSize, strLenFileName, "wb");
213+#else
214+ m_pFileBs = FOPEN(strStreamFileName, "wb");
215+ m_pFileBsSize = FOPEN(strLenFileName, "wb");
216+#endif//_MSC_VER>=1500
217+#endif//_MSC_VER
218+#endif//__GNUC__
219+
220+ m_bSwitch = FALSE;
221+ m_iSwitchTimes = 0;
222+#endif//OUTPUT_BIT_STREAM
223+
224+ InitEncoder();
225+}
226+
227+CWelsH264SVCEncoder::~CWelsH264SVCEncoder()
228+{
229+ WelsLog(NULL, WELS_LOG_INFO, "CWelsH264SVCEncoder::~CWelsH264SVCEncoder()\n");
230+#if defined(WIN32)||defined(_MACH_PLATFORM)||defined(__GNUC__)
231+
232+ if ( m_pWelsTrace != NULL )
233+ {
234+ delete m_pWelsTrace;
235+ m_pWelsTrace = NULL;
236+ }
237+#endif
238+#ifdef REC_FRAME_COUNT
239+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::~CWelsH264SVCEncoder(), m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
240+#endif
241+
242+#ifdef REC_FRAME_COUNT
243+ m_uiCountFrameNum = 0;
244+#endif//REC_FRAME_COUNT
245+
246+#ifdef OUTPUT_BIT_STREAM
247+ if ( m_pFileBs )
248+ {
249+ fclose( m_pFileBs );
250+ m_pFileBs = NULL;
251+ }
252+ if ( m_pFileBsSize )
253+ {
254+ fclose( m_pFileBsSize );
255+ m_pFileBsSize = NULL;
256+ }
257+ m_bSwitch = FALSE;
258+ m_iSwitchTimes = 0;
259+#endif//OUTPUT_BIT_STREAM
260+
261+ Unintialize();
262+}
263+
264+void CWelsH264SVCEncoder::InitEncoder( void )
265+{
266+#if defined(WIN32)||defined(_MACH_PLATFORM)||defined(__GNUC__)
267+
268+#ifdef REC_FRAME_COUNT
269+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::InitEncoder, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
270+#endif
271+
272+ m_pWelsTrace = new welsCodecTrace();
273+ if ( m_pWelsTrace != NULL )
274+ {
275+ const int32_t iWelsTraceExistingFlag = m_pWelsTrace->WelsTraceModuleIsExist();
276+ if ( iWelsTraceExistingFlag )
277+ {
278+ m_pWelsTrace->SetTraceLevel( WELS_LOG_DEFAULT );
279+ WelsSetLogCallback( welsCodecTrace::CODEC_TRACE );
280+ }
281+ }
282+
283+ // initialization
284+ WelsSetLogLevel( WELS_LOG_DEFAULT ); // no output, WELS_LOG_QUIET
285+#endif
286+}
287+
288+/* Interfaces override from ISVCEncoder */
289+
290+/*
291+ * SVC Encoder Initialization
292+ */
293+int CWelsH264SVCEncoder::Initialize(SVCEncodingParam* argv, const INIT_TYPE iInitType)
294+{
295+ if ( INIT_TYPE_PARAMETER_BASED != iInitType || NULL == argv )
296+ {
297+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iInitType= %d, argv= 0x%p\n", iInitType, (void *)argv);
298+ return cmInitParaError;
299+ }
300+
301+ if ( m_bInitialFlag )
302+ {
303+ WelsLog(m_pEncContext, WELS_LOG_WARNING, "CWelsH264SVCEncoder::Initialize(), reinitialize, m_bInitialFlag= %d\n", m_bInitialFlag);
304+ Unintialize();
305+ }
306+
307+ SVCEncodingParam sEncodingParam;
308+ SWelsSvcCodingParam sConfig( true );
309+
310+ memcpy(&sEncodingParam, argv, sizeof(SVCEncodingParam)); // confirmed_safe_unsafe_usage
311+
312+#ifdef REC_FRAME_COUNT
313+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::Initialize, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
314+ WelsLog( m_pEncContext, WELS_LOG_INFO, "coding_param->iPicWidth= %d;coding_param->iPicHeight= %d;coding_param->iTargetBitrate= %d;coding_param->iRCMode= %d;coding_param->iTemporalLayerNum= %d;coding_param->iSpatialLayerNum= %d;coding_param->fFrameRate= %.6ff;coding_param->iInputCsp= %d;coding_param->iKeyPicCodingMode= %d;coding_param->uiIntraPeriod= %d;coding_param->bEnableSpsPpsIdAddition = %d;coding_param->bPrefixNalAddingCtrl = %d;coding_param->bEnableDenoise= %d;coding_param->bEnableBackgroundDetection= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableCropPic= %d;coding_param->bEnableLongTermReference= %d;coding_param->iLtrMarkPeriod= %d;\n",
315+ sEncodingParam.iPicWidth,
316+ sEncodingParam.iPicHeight,
317+ sEncodingParam.iTargetBitrate,
318+ sEncodingParam.iRCMode,
319+ sEncodingParam.iTemporalLayerNum,
320+ sEncodingParam.iSpatialLayerNum,
321+ sEncodingParam.fFrameRate,
322+ sEncodingParam.iInputCsp,
323+ sEncodingParam.iKeyPicCodingMode,
324+ sEncodingParam.iIntraPeriod,
325+ sEncodingParam.bEnableSpsPpsIdAddition,
326+ sEncodingParam.bPrefixNalAddingCtrl,
327+ sEncodingParam.bEnableDenoise,
328+ sEncodingParam.bEnableBackgroundDetection,
329+ sEncodingParam.bEnableAdaptiveQuant,
330+ sEncodingParam.bEnableCropPic,
331+ sEncodingParam.bEnableLongTermReference,
332+ sEncodingParam.iLtrMarkPeriod);
333+ int32_t i = 0;
334+ while (i < sEncodingParam.iSpatialLayerNum) {
335+ SSpatialLayerConfig *spatial_cfg = &sEncodingParam.sSpatialLayers[i];
336+ WelsLog( m_pEncContext, WELS_LOG_INFO, "coding_param->sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iQualityLayerNum= %d; .iSpatialBitrate= %d; .iCgsSnrRefined= %d; .iInterSpatialLayerPredFlag= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.uiSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\n",
337+ i, spatial_cfg->iVideoWidth,
338+ spatial_cfg->iVideoHeight,
339+ spatial_cfg->fFrameRate,
340+ spatial_cfg->iQualityLayerNum,
341+ spatial_cfg->iSpatialBitrate,
342+ spatial_cfg->iCgsSnrRefined,
343+ spatial_cfg->iInterSpatialLayerPredFlag,
344+ spatial_cfg->sSliceCfg.uiSliceMode,
345+ spatial_cfg->sSliceCfg.sSliceArgument.uiSliceNum,
346+ spatial_cfg->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
347+ );
348+ ++ i;
349+ }
350+#endif//REC_FRAME_COUNT
351+
352+ // Convert SVCEncodingParam into WelsSVCParamConfig here..
353+ if ( sConfig.ParamTranscode( sEncodingParam, true ) ){
354+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), parameter_translation failed.\n");
355+ Unintialize();
356+ return cmInitParaError;
357+ }
358+
359+ m_iSrcListSize = 1;
360+
361+ return Initialize((void *)&sConfig, INIT_TYPE_CONFIG_BASED);
362+}
363+
364+int CWelsH264SVCEncoder::Initialize(void * argv, const INIT_TYPE iInitType)
365+{
366+ if ( INIT_TYPE_CONFIG_BASED != iInitType || NULL == argv )
367+ {
368+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iInitType= %d, argv= 0x%p.\n", iInitType, (void *)argv);
369+ return cmInitParaError;
370+ }
371+
372+ if ( m_bInitialFlag )
373+ {
374+ WelsLog(m_pEncContext, WELS_LOG_WARNING, "CWelsH264SVCEncoder::Initialize(), reinitialize, m_bInitialFlag= %d.\n", m_bInitialFlag);
375+ Unintialize();
376+ }
377+
378+ SWelsSvcCodingParam *pCfg = static_cast<SWelsSvcCodingParam*>(argv);
379+
380+ const int32_t iColorspace = pCfg->iInputCsp;
381+ if ( 0 == iColorspace )
382+ {
383+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iInputCsp= %d.\n", iColorspace);
384+ Unintialize();
385+ return cmInitParaError;
386+ }
387+
388+ // Check valid parameters
389+ const int32_t iNumOfLayers = pCfg->iNumDependencyLayer;
390+ if ( iNumOfLayers < 1 || iNumOfLayers > MAX_DEPENDENCY_LAYER ){
391+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iNumDependencyLayer= %d, valid at range of [1, %d].\n", iNumOfLayers, MAX_DEPENDENCY_LAYER);
392+ Unintialize();
393+ return cmInitParaError;
394+ }
395+ if ( pCfg->iNumTemporalLayer < 1 )
396+ pCfg->iNumTemporalLayer = 1;
397+ if ( pCfg->iNumTemporalLayer > MAX_TEMPORAL_LEVEL ){
398+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid iNumTemporalLayer= %d, valid at range of [1, %d].\n", pCfg->iNumTemporalLayer, MAX_TEMPORAL_LEVEL);
399+ Unintialize();
400+ return cmInitParaError;
401+ }
402+
403+ // assert( cfg.uiGopSize >= 1 && ( cfg.uiIntraPeriod && (cfg.uiIntraPeriod % cfg.uiGopSize) == 0) );
404+
405+ if ( pCfg->uiGopSize < 1 || pCfg->uiGopSize > MAX_GOP_SIZE ){
406+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid uiGopSize= %d, valid at range of [1, %d].\n", pCfg->uiGopSize, MAX_GOP_SIZE);
407+ Unintialize();
408+ return cmInitParaError;
409+ }
410+
411+ if ( !WELS_POWER2_IF(pCfg->uiGopSize) ){
412+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid uiGopSize= %d, valid at range of [1, %d] and yield to power of 2.\n", pCfg->uiGopSize, MAX_GOP_SIZE);
413+ Unintialize();
414+ return cmInitParaError;
415+ }
416+
417+ if ( pCfg->uiIntraPeriod && pCfg->uiIntraPeriod < pCfg->uiGopSize )
418+ {
419+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid uiIntraPeriod= %d, valid in case it equals to 0 for unlimited intra period or exceeds specified uiGopSize= %d.\n", pCfg->uiIntraPeriod, pCfg->uiGopSize);
420+ Unintialize();
421+ return cmInitParaError;
422+ }
423+
424+ if ( ( pCfg->uiIntraPeriod && (pCfg->uiIntraPeriod & (pCfg->uiGopSize-1)) != 0) )
425+ {
426+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), invalid uiIntraPeriod= %d, valid in case it equals to 0 for unlimited intra period or exceeds specified uiGopSize= %d also multiple of it.\n", pCfg->uiIntraPeriod, pCfg->uiGopSize);
427+ Unintialize();
428+ return cmInitParaError;
429+ }
430+
431+ // Fine tune num_ref_num
432+ if (pCfg->bEnableLongTermReference){
433+ pCfg->iLTRRefNum = LONG_TERM_REF_NUM;
434+ }else{
435+ pCfg->iLTRRefNum = 0;
436+ }
437+ pCfg->iNumRefFrame = ((pCfg->uiGopSize>>1)>1)?((pCfg->uiGopSize>>1)+pCfg->iLTRRefNum):(MIN_REF_PIC_COUNT+pCfg->iLTRRefNum);
438+
439+ pCfg->iNumRefFrame = WELS_CLIP3(pCfg->iNumRefFrame, MIN_REF_PIC_COUNT, MAX_REFERENCE_PICTURE_COUNT_NUM);
440+
441+ if (pCfg->uiLtrMarkPeriod == 0)
442+ {
443+ pCfg->uiLtrMarkPeriod = 30;
444+ }
445+
446+ const int32_t kiDecStages = WELS_LOG2( pCfg->uiGopSize );
447+ pCfg->iInputCsp = iColorspace;
448+ pCfg->iNumTemporalLayer = (int8_t)(1 + kiDecStages);
449+ pCfg->iLoopFilterAlphaC0Offset = WELS_CLIP3( pCfg->iLoopFilterAlphaC0Offset, -6, 6 );
450+ pCfg->iLoopFilterBetaOffset = WELS_CLIP3( pCfg->iLoopFilterBetaOffset, -6, 6 );
451+
452+// m_pSrcPicList = (SSourcePicture **)WelsMalloc( pCfg->iNumDependencyLayer * sizeof(SSourcePicture *), "m_pSrcPicList" );
453+ // prefer use new/delete pair due encoder intialization stage not start yet for CacheLineSize not detection here (16 or 64 not matched)
454+ m_pSrcPicList = new SSourcePicture* [iNumOfLayers];
455+
456+ if ( NULL == m_pSrcPicList ){
457+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), pOut of memory due m_pSrcPicList memory request.\n");
458+ Unintialize();
459+ return cmMallocMemeError;
460+ }
461+
462+ // decide property list size between INIT_TYPE_PARAMETER_BASED/INIT_TYPE_CONFIG_BASED
463+ m_iMaxPicWidth = pCfg->iActualPicWidth;
464+ m_iMaxPicHeight = pCfg->iActualPicHeight;
465+ m_iSrcListSize = iNumOfLayers;
466+
467+ for (int32_t i = 0; i < m_iSrcListSize; ++ i)
468+ {
469+// m_pSrcPicList[i] = (SSourcePicture *)WelsMalloc( sizeof(SSourcePicture), "m_pSrcPicList[]" );
470+ // prefer use new/delete pair due encoder intialization stage not start yet for CacheLineSize not detection here (16 or 64 not matched)
471+ m_pSrcPicList[i] = new SSourcePicture;
472+
473+ if ( NULL == m_pSrcPicList[i] )
474+ {
475+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), pOut of memory due m_pSrcPicList[%d] memory request.\n", i);
476+ Unintialize();
477+ m_iSrcListSize = 0;
478+ return cmMallocMemeError;
479+ }
480+ InitPic( m_pSrcPicList[i], iColorspace, m_iMaxPicWidth, m_iMaxPicHeight );
481+ }
482+
483+#if defined(OUTPUT_BIT_STREAM) || defined(ENABLE_TRACE_FILE)
484+ str_t fpath[MAX_FNAME_LEN] = {0};
485+#if defined(__GNUC__)
486+ SNPRINTF(fpath, MAX_FNAME_LEN, "/tmp/"); // confirmed_safe_unsafe_usage
487+
488+#else//__GNUC__
489+
490+#if defined (_MSC_VER)
491+#if _MSC_VER>=1500
492+ SNPRINTF(fpath, MAX_FNAME_LEN, MAX_FNAME_LEN, ".\\" ); // confirmed_safe_unsafe_usage
493+#else
494+ SNPRINTF(fpath, MAX_FNAME_LEN, ".\\" ); // confirmed_safe_unsafe_usage
495+#endif//_MSC_VER>=1500
496+#endif//_MSC_VER
497+#endif //__GNUC__
498+
499+ strcpy(pCfg->sTracePath, fpath); // confirmed_safe_unsafe_usage
500+
501+#endif //#if defined(OUTPUT_BIT_STREAM) || defined(ENABLE_TRACE_FILE)
502+
503+ if ( WelsInitEncoderExt( &m_pEncContext, pCfg ) )
504+ {
505+ WelsLog(m_pEncContext, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.\n");
506+ Unintialize();
507+ return cmInitParaError;
508+ }
509+
510+ m_iCspInternal = iColorspace;
511+ m_bInitialFlag = TRUE;
512+
513+ return cmResultSuccess;
514+}
515+
516+/*
517+ * SVC Encoder Uninitialization
518+ */
519+int32_t CWelsH264SVCEncoder::Unintialize()
520+{
521+ if ( !m_bInitialFlag )
522+ {
523+ return 0;
524+ }
525+
526+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::Unintialize()..\n" );
527+
528+#ifdef REC_FRAME_COUNT
529+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::Unintialize, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
530+#endif//REC_FRAME_COUNT
531+
532+ if ( NULL != m_pEncContext )
533+ {
534+ if ( NULL != m_pSrcPicList )
535+ {
536+ for (int32_t i = 0; i < m_iSrcListSize; i++)
537+ {
538+ SSourcePicture *pic = m_pSrcPicList[i];
539+ if ( NULL != pic )
540+ {
541+// WelsFree( pic, "m_pSrcPicList[]" );
542+ // prefer use new/delete pair due encoder intialization stage not start yet for CacheLineSize not detection here (16 or 64 not matched)
543+ delete pic;
544+
545+ pic = NULL;
546+ }
547+ }
548+// WelsFree( m_pSrcPicList, "m_pSrcPicList" );
549+ // prefer use new/delete pair due encoder intialization stage not start yet for CacheLineSize not detection here (16 or 64 not matched)
550+ delete [] m_pSrcPicList;
551+
552+ m_pSrcPicList = NULL;
553+ m_iSrcListSize= 0;
554+ }
555+
556+ WelsUninitEncoderExt( &m_pEncContext );
557+ m_pEncContext = NULL;
558+ }
559+
560+ m_bInitialFlag = FALSE;
561+
562+ return 0;
563+}
564+
565+
566+int32_t CWelsH264SVCEncoder::RawData2SrcPic(const uint8_t * pSrc)
567+{
568+ assert( m_iSrcListSize > 0 );
569+
570+ int32_t y_length = m_iMaxPicWidth * m_iMaxPicHeight;
571+ m_pSrcPicList[0]->pData[0] = const_cast<uint8_t*>(pSrc);
572+
573+ switch(m_iCspInternal & (~videoFormatVFlip))
574+ {
575+ case videoFormatYVYU:
576+ case videoFormatUYVY:
577+ case videoFormatYUY2:
578+ case videoFormatRGB:
579+ case videoFormatBGR:
580+ case videoFormatBGRA:
581+ case videoFormatRGBA:
582+ case videoFormatARGB:
583+ case videoFormatABGR:
584+ m_pSrcPicList[0]->pData[1] = m_pSrcPicList[0]->pData[2] = NULL;
585+ break;
586+ case videoFormatI420:
587+ case videoFormatYV12:
588+ m_pSrcPicList[0]->pData[1] = m_pSrcPicList[0]->pData[0] + y_length;
589+ m_pSrcPicList[0]->pData[2] = m_pSrcPicList[0]->pData[1] + ( y_length >> 2 );
590+ break;
591+ default:
592+ return 1;
593+ }
594+
595+ return 0;
596+}
597+
598+
599+/*
600+ * SVC core encoding
601+ */
602+int CWelsH264SVCEncoder::EncodeFrame(const unsigned char* pSrc, SFrameBSInfo* pBsInfo)
603+{
604+ if ( !(pSrc && m_pEncContext && m_bInitialFlag) )
605+ {
606+ return videoFrameTypeInvalid;
607+ }
608+
609+ int32_t uiFrameType = videoFrameTypeInvalid;
610+
611+ if( RawData2SrcPic((uint8_t *)pSrc) == 0 ){
612+ uiFrameType = EncodeFrame(const_cast<const SSourcePicture**>(m_pSrcPicList), 1, pBsInfo);
613+ }
614+
615+#ifdef REC_FRAME_COUNT
616+ ++ m_uiCountFrameNum;
617+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::EncodeFrame(), m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
618+#endif//REC_FRAME_COUNT
619+
620+#ifdef DUMP_SRC_PICTURE
621+ DumpSrcPicture(pSrc);
622+#endif // DUMP_SRC_PICTURE
623+
624+ return uiFrameType;
625+}
626+
627+
628+int CWelsH264SVCEncoder::EncodeFrame(const SSourcePicture ** pSrcPicList, int nSrcPicNum, SFrameBSInfo * pBsInfo)
629+{
630+ if ( !(pSrcPicList && m_pEncContext && m_bInitialFlag) )
631+ {
632+ return videoFrameTypeInvalid;
633+ }
634+
635+ int32_t iFrameTypeReturned = 0;
636+ int32_t iFrameType = videoFrameTypeInvalid;
637+
638+ if (nSrcPicNum > 0)
639+ {
640+ iFrameTypeReturned = WelsEncoderEncodeExt( m_pEncContext, pBsInfo, pSrcPicList, nSrcPicNum);
641+ }
642+ else
643+ {
644+ assert ( 0 );
645+ return videoFrameTypeInvalid;
646+ }
647+
648+ switch( iFrameTypeReturned )
649+ {
650+ case WELS_FRAME_TYPE_P:
651+ iFrameType = videoFrameTypeP;
652+ break;
653+ case WELS_FRAME_TYPE_IDR:
654+ iFrameType = videoFrameTypeIDR;
655+ break;
656+ case WELS_FRAME_TYPE_SKIP:
657+ iFrameType = videoFrameTypeSkip;
658+ break;
659+ case WELS_FRAME_TYPE_I:
660+ iFrameType = videoFrameTypeI;
661+ break;
662+ case WELS_FRAME_TYPE_AUTO:
663+ case WELS_FRAME_TYPE_B: // not support B pictures
664+ iFrameType = videoFrameTypeInvalid;
665+ break;
666+ default:
667+ break;
668+ }
669+
670+
671+
672+ ///////////////////for test
673+#ifdef OUTPUT_BIT_STREAM
674+ if ( iFrameType != videoFrameTypeInvalid && iFrameType != videoFrameTypeSkip )
675+ {
676+ SLayerBSInfo* pLayer = NULL;
677+ int32_t i = 0, j = 0, iCurLayerBits = 0, total_bits = 0;
678+
679+ if ( m_bSwitch )
680+ {
681+ if ( m_pFileBs )
682+ {
683+ fclose( m_pFileBs );
684+ m_pFileBs = NULL;
685+ }
686+ if ( m_pFileBsSize )
687+ {
688+ fclose( m_pFileBsSize );
689+ m_pFileBsSize = NULL;
690+ }
691+ str_t strStreamFileName[128] = {0};
692+#if defined(__GNUC__)
693+
694+ int32_t iLen = SNPRINTF(strStreamFileName, 128, "%sadj%d_w%d.264", m_pEncContext->sTracePath, m_iSwitchTimes, m_pEncContext->pSvcParam->iActualPicWidth);
695+ m_pFileBs = FOPEN( strStreamFileName, "wb" );
696+ SNPRINTF(strStreamFileName, 128, "%sadj%d_w%d_size.iLen", m_pEncContext->sTracePath, m_iSwitchTimes, m_pEncContext->pSvcParam->iActualPicWidth);
697+ m_pFileBsSize = FOPEN( strStreamFileName, "wb");
698+
699+#else//__GNUC__
700+
701+#if defined (_MSC_VER)
702+#if _MSC_VER>=1500
703+ int32_t iLen = SNPRINTF(strStreamFileName, 128, 128, "adj%d_w%d.264", m_iSwitchTimes, m_pEncContext->pSvcParam->iActualPicWidth);
704+ FOPEN( &m_pFileBs, strStreamFileName, "wb" );
705+ SNPRINTF(strStreamFileName, 128, 128, "adj%d_w%d_size.iLen", m_iSwitchTimes, m_pEncContext->pSvcParam->iActualPicWidth);
706+ FOPEN( &m_pFileBsSize, strStreamFileName, "wb");
707+#else
708+ int32_t iLen = SNPRINTF(strStreamFileName, 128, "adj%d_w%d.264", m_iSwitchTimes, m_pEncContext->pSvcParam->iActualPicWidth);
709+ m_pFileBs = FOPEN( strStreamFileName, "wb" );
710+ SNPRINTF(strStreamFileName, 128, "adj%d_w%d_size.iLen", m_iSwitchTimes, m_pEncContext->pSvcParam->iActualPicWidth);
711+ m_pFileBsSize = FOPEN( strStreamFileName, "wb");
712+#endif//_MSC_VER>=1500
713+#endif//_MSC_VER
714+
715+
716+#endif//__GNUC__
717+
718+ m_bSwitch = FALSE;
719+ }
720+
721+ for ( i = 0; i < pBsInfo->iLayerNum; i++ )
722+ {
723+ pLayer = &pBsInfo->sLayerInfo[i];
724+
725+ iCurLayerBits = 0;
726+ for ( j = 0; j < pLayer->iNalCount; j++ )
727+ {
728+ iCurLayerBits += pLayer->iNalLengthInByte[j];
729+ }
730+ total_bits += iCurLayerBits;
731+ if ( m_pFileBs != NULL )
732+ fwrite( pLayer->pBsBuf, 1, iCurLayerBits, m_pFileBs );
733+ }
734+
735+ if ( m_pFileBsSize != NULL )
736+ fwrite( &total_bits, sizeof(int32_t), 1, m_pFileBsSize );
737+ }
738+#endif //OUTPUT_BIT_STREAM
739+#ifdef DUMP_SRC_PICTURE
740+ DumpSrcPicture(pSrcPicList[0]->pData[0]);
741+#endif // DUMP_SRC_PICTURE
742+
743+ return iFrameType;
744+
745+}
746+
747+/*
748+ * return: 0 - success; otherwise - failed;
749+ */
750+int CWelsH264SVCEncoder::PauseFrame(const unsigned char* kpSrc, SFrameBSInfo* pBsInfo)
751+{
752+ int32_t iReturn = 1;
753+
754+ ForceIntraFrame(true);
755+
756+ if( EncodeFrame(kpSrc, pBsInfo) != videoFrameTypeInvalid ){
757+ iReturn = 0;
758+ }
759+
760+ // to avoid pause frame bitstream and
761+ // normal bitstream use different video channel.
762+ ForceIntraFrame(true);
763+
764+ return (int)iReturn;
765+}
766+
767+
768+/*
769+ * Force key frame
770+ */
771+int CWelsH264SVCEncoder::ForceIntraFrame(bool bIDR)
772+{
773+ if ( !(m_pEncContext && m_bInitialFlag) )
774+ {
775+ return 1;
776+ }
777+
778+#ifdef REC_FRAME_COUNT
779+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", bIDR, m_uiCountFrameNum, m_iCspInternal );
780+#endif//REC_FRAME_COUNT
781+
782+ ForceCodingIDR( m_pEncContext );
783+
784+ return 0;
785+}
786+
787+/************************************************************************
788+* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
789+************************************************************************/
790+int CWelsH264SVCEncoder::SetOption(ENCODER_OPTION eOptionId, void* pOption)
791+{
792+ if ( NULL == pOption ){
793+ return cmInitParaError;
794+ }
795+
796+ if ( NULL == m_pEncContext || FALSE == m_bInitialFlag ){
797+ return cmInitExpected;
798+ }
799+
800+ switch( eOptionId ) {
801+ case ENCODER_OPTION_INTER_SPATIAL_PRED: // Inter spatial layer prediction flag
802+ {
803+ WelsLog( m_pEncContext, WELS_LOG_INFO, "ENCODER_OPTION_INTER_SPATIAL_PRED, this feature not supported at present.\n" );
804+ }
805+ break;
806+ case ENCODER_OPTION_DATAFORMAT: // Input color space
807+ {
808+ int32_t iValue = *((int32_t*)pOption);
809+ int32_t iColorspace = iValue;
810+ if ( iColorspace == 0 ){
811+ return cmInitParaError;
812+ }
813+
814+#ifdef REC_FRAME_COUNT
815+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_DATAFORMAT, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x, iValue= %d\n", m_uiCountFrameNum, m_iCspInternal, iValue );
816+#endif//REC_FRAME_COUNT
817+
818+
819+ int32_t iPicIdx = m_iSrcListSize -1;
820+ while ( iPicIdx >= 0 )
821+ {
822+ if ( m_pSrcPicList[iPicIdx] == NULL )
823+ {
824+ -- iPicIdx;
825+ if (iPicIdx < 0) return cmInitParaError;
826+ continue;
827+ }
828+
829+ if ( m_pSrcPicList[iPicIdx]->iColorFormat == iColorspace )
830+ {
831+ -- iPicIdx;
832+ continue;
833+ }
834+
835+ InitPic( m_pSrcPicList[iPicIdx], iColorspace, m_iMaxPicWidth, m_iMaxPicHeight );
836+ }
837+ m_iCspInternal = iColorspace;
838+#ifdef REC_FRAME_COUNT
839+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_DATAFORMAT, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
840+#endif//REC_FRAME_COUNT
841+ }
842+ break;
843+ case ENCODER_OPTION_IDR_INTERVAL: // IDR Interval
844+ {
845+ int32_t iValue = *((int32_t*)pOption);
846+#ifdef REC_FRAME_COUNT
847+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_IDR_INTERVAL, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x, iValue= %d\n", m_uiCountFrameNum, m_iCspInternal, iValue );
848+#endif//REC_FRAME_COUNT
849+
850+ if ( iValue < -1 || iValue == 0 )
851+ iValue = 1;
852+ if ( iValue == (int32_t)m_pEncContext->pSvcParam->uiIntraPeriod ){
853+ return cmResultSuccess;
854+ }
855+
856+
857+ m_pEncContext->pSvcParam->uiIntraPeriod = (uint32_t)iValue;
858+ }
859+ break;
860+ case ENCODER_OPTION_SVC_ENCODE_PARAM: // SVC Encoding Parameter
861+ {
862+ SVCEncodingParam sEncodingParam;
863+ SWelsSvcCodingParam sConfig( true );
864+ int32_t iInputColorspace = 0;
865+ int32_t iTargetWidth = 0;
866+ int32_t iTargetHeight= 0;
867+
868+ memcpy(&sEncodingParam, pOption, sizeof(SVCEncodingParam)); // confirmed_safe_unsafe_usage
869+ WelsLog( m_pEncContext, WELS_LOG_INFO, "ENCODER_OPTION_SVC_ENCODE_PARAM, sEncodingParam.iInputCsp= 0x%x\n", sEncodingParam.iInputCsp );
870+ WelsLog( m_pEncContext, WELS_LOG_INFO, "coding_param->iPicWidth= %d;coding_param->iPicHeight= %d;coding_param->iTargetBitrate= %d;coding_param->iRCMode= %d;coding_param->iPaddingFlag= %d;coding_param->iTemporalLayerNum= %d;coding_param->iSpatialLayerNum= %d;coding_param->fFrameRate= %.6ff;coding_param->iInputCsp= %d;coding_param->iKeyPicCodingMode= %d;coding_param->uiIntraPeriod= %d;coding_param->bEnableSpsPpsIdAddition = %d;coding_param->bPrefixNalAddingCtrl = %d;coding_param->bEnableDenoise= %d;coding_param->bEnableBackgroundDetection= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableCropPic= %d;coding_param->bEnableLongTermReference= %d;coding_param->iLtrMarkPeriod= %d;\n",
871+ sEncodingParam.iPicWidth,
872+ sEncodingParam.iPicHeight,
873+ sEncodingParam.iTargetBitrate,
874+ sEncodingParam.iRCMode,
875+ sEncodingParam.iPaddingFlag,
876+ sEncodingParam.iTemporalLayerNum,
877+ sEncodingParam.iSpatialLayerNum,
878+ sEncodingParam.fFrameRate,
879+ sEncodingParam.iInputCsp,
880+ sEncodingParam.iKeyPicCodingMode,
881+ sEncodingParam.iIntraPeriod,
882+ sEncodingParam.bEnableSpsPpsIdAddition,
883+ sEncodingParam.bPrefixNalAddingCtrl,
884+ sEncodingParam.bEnableDenoise,
885+ sEncodingParam.bEnableBackgroundDetection,
886+ sEncodingParam.bEnableAdaptiveQuant,
887+ sEncodingParam.bEnableCropPic,
888+ sEncodingParam.bEnableLongTermReference,
889+ sEncodingParam.iLtrMarkPeriod);
890+ int32_t i = 0;
891+ while (i < sEncodingParam.iSpatialLayerNum)
892+ {
893+ SSpatialLayerConfig *pSpatialCfg = &sEncodingParam.sSpatialLayers[i];
894+ WelsLog( m_pEncContext, WELS_LOG_INFO, "coding_param->sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iQualityLayerNum= %d; .iSpatialBitrate= %d; .iCgsSnrRefined= %d; .iInterSpatialLayerPredFlag= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.iSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\n",
895+ i, pSpatialCfg->iVideoWidth,
896+ pSpatialCfg->iVideoHeight,
897+ pSpatialCfg->fFrameRate,
898+ pSpatialCfg->iQualityLayerNum,
899+ pSpatialCfg->iSpatialBitrate,
900+ pSpatialCfg->iCgsSnrRefined,
901+ pSpatialCfg->iInterSpatialLayerPredFlag,
902+ pSpatialCfg->sSliceCfg.uiSliceMode,
903+ pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceNum,
904+ pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
905+ );
906+ ++ i;
907+ }
908+#ifdef OUTPUT_BIT_STREAM
909+ if ( sEncodingParam.sSpatialLayers[sEncodingParam.iSpatialLayerNum-1].iVideoWidth != m_pEncContext->pSvcParam->sDependencyLayers[m_pEncContext->pSvcParam->iNumDependencyLayer-1].iFrameWidth )
910+ {
911+ ++ m_iSwitchTimes;
912+ m_bSwitch = TRUE;
913+ }
914+#endif//OUTPUT_BIT_STREAM
915+ if ( sEncodingParam.iSpatialLayerNum < 1 || sEncodingParam.iSpatialLayerNum > MAX_SPATIAL_LAYER_NUM ) // verify number of spatial layer
916+ {
917+ return cmInitParaError;
918+ }
919+
920+ iInputColorspace = sEncodingParam.iInputCsp;
921+ if ( sConfig.ParamTranscode( sEncodingParam, true ) )
922+ {
923+ return cmInitParaError;
924+ }
925+ if ( sConfig.iNumDependencyLayer < 1 )
926+ {
927+ return cmInitParaError;
928+ }
929+ iTargetWidth = sConfig.iActualPicWidth;
930+ iTargetHeight = sConfig.iActualPicHeight;
931+ if ( m_pSrcPicList[0] == NULL )
932+ {
933+ return cmInitParaError;
934+ }
935+ if ( m_iCspInternal != iInputColorspace || m_iMaxPicWidth != iTargetWidth || m_iMaxPicHeight != iTargetHeight ){ // for color space due to changed
936+ InitPic( m_pSrcPicList[0], iInputColorspace, iTargetWidth, iTargetHeight );
937+ m_iMaxPicWidth = iTargetWidth;
938+ m_iMaxPicHeight = iTargetHeight;
939+ m_iCspInternal = iInputColorspace;
940+ }
941+#ifdef REC_FRAME_COUNT
942+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
943+#endif//REC_FRAME_COUNT
944+
945+ /* New configuration available here */
946+ sConfig.iInputCsp = m_iCspInternal; // I420 in default designed for presentation in encoder used internal
947+ sConfig.DetermineTemporalSettings();
948+
949+ /* Check every field whether there is new request for memory block changed or else, Oct. 24, 2008 */
950+ WelsEncoderParamAdjust( &m_pEncContext, &sConfig );
951+ }
952+ break;
953+ case ENCODER_OPTION_FRAME_RATE: // Maximal input frame rate
954+ {
955+ float iValue = *((float*)pOption);
956+#ifdef REC_FRAME_COUNT
957+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_FRAME_RATE, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x, iValue= %d\n", m_uiCountFrameNum, m_iCspInternal, iValue );
958+#endif//REC_FRAME_COUNT
959+ m_pEncContext->pSvcParam->fMaxFrameRate = iValue;
960+
961+ }
962+ break;
963+ case ENCODER_OPTION_iBitRate: // Target bit-rate
964+ {
965+ int32_t iValue = *((int32_t*)pOption);
966+#ifdef REC_FRAME_COUNT
967+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_iBitRate, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x, iValue= %d\n", m_uiCountFrameNum, m_iCspInternal, iValue );
968+#endif//REC_FRAME_COUNT
969+ m_pEncContext->pSvcParam->iTargetBitrate = iValue;
970+
971+ }
972+ break;
973+ case ENCODER_OPTION_RC_MODE: // 0:quality mode;1:bit-rate mode
974+ {
975+ int32_t iValue = *((int32_t*)pOption);
976+ m_pEncContext->pSvcParam->iRCMode = iValue;
977+ }
978+ break;
979+ case ENCODER_PADDING_PADDING: // 0:disable padding;1:padding
980+ {
981+ int32_t iValue = *((int32_t*)pOption);
982+ m_pEncContext->pSvcParam->iPaddingFlag = iValue;
983+ }
984+ break;
985+ case ENCODER_LTR_RECOVERY_REQUEST:
986+ {
987+ SLTRRecoverRequest* pLTR_Recover_Request = (SLTRRecoverRequest*)(pOption);
988+ FilterLTRRecoveryRequest(m_pEncContext,pLTR_Recover_Request);
989+ }
990+ break;
991+ case ENCODER_LTR_MARKING_FEEDBACK:
992+ {
993+ SLTRMarkingFeedback* fb = (SLTRMarkingFeedback*)(pOption);
994+ FilterLTRMarkingFeedback(m_pEncContext,fb);
995+ }
996+ break;
997+ case ENCOCER_LTR_MARKING_PERIOD:
998+ {
999+ uint32_t iValue = *((uint32_t*)(pOption));
1000+ m_pEncContext->pSvcParam->uiLtrMarkPeriod = iValue;
1001+ }
1002+ break;
1003+ case ENCODER_OPTION_LTR:
1004+ {
1005+ uint32_t iValue = *((uint32_t*)(pOption));
1006+ m_pEncContext->pSvcParam->bEnableLongTermReference = iValue?true:false;
1007+ WelsLog(m_pEncContext,WELS_LOG_WARNING," CWelsH264SVCEncoder::SetOption enable LTR = %d",m_pEncContext->pSvcParam->bEnableLongTermReference);
1008+ }
1009+ break;
1010+ case ENCODER_OPTION_ENABLE_SSEI:
1011+ {
1012+ bool_t iValue = *((bool_t*)pOption);
1013+ m_pEncContext->pSvcParam->bEnableSSEI = iValue;
1014+ WelsLog( m_pEncContext, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable SSEI = %d \n", m_pEncContext->pSvcParam->bEnableSSEI );
1015+ }
1016+ break;
1017+ case ENCODER_OPTION_ENABLE_PREFIX_NAL_ADDING:
1018+ {
1019+ bool_t iValue = *((bool_t*)pOption);
1020+ m_pEncContext->pSvcParam->bPrefixNalAddingCtrl = iValue;
1021+ WelsLog( m_pEncContext, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption bPrefixNalAddingCtrl = %d \n", m_pEncContext->pSvcParam->bPrefixNalAddingCtrl );
1022+ }
1023+ break;
1024+ case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION:
1025+ {
1026+ bool_t iValue = *((bool_t*)pOption);
1027+
1028+ m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition = iValue;
1029+ WelsLog( m_pEncContext, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable SPS/PPS ID = %d \n", m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition );
1030+ }
1031+ break;
1032+ case ENCODER_OPTION_CURRENT_PATH:
1033+ {
1034+ if (m_pEncContext->pSvcParam != NULL)
1035+ {
1036+ str_t * path = static_cast<str_t *>(pOption);
1037+ m_pEncContext->pSvcParam->pCurPath = path;
1038+ }
1039+ }
1040+ break;
1041+ default:
1042+ return cmInitParaError;
1043+ }
1044+
1045+ return 0;
1046+}
1047+
1048+int CWelsH264SVCEncoder::GetOption(ENCODER_OPTION eOptionId, void* pOption)
1049+{
1050+ if ( NULL == pOption ){
1051+ return cmInitParaError;
1052+ }
1053+ if ( NULL == m_pEncContext || FALSE == m_bInitialFlag ){
1054+ return cmInitExpected;
1055+ }
1056+
1057+ switch( eOptionId ) {
1058+ case ENCODER_OPTION_INTER_SPATIAL_PRED: // Inter spatial layer prediction flag
1059+ {
1060+ WelsLog( m_pEncContext, WELS_LOG_INFO, "ENCODER_OPTION_INTER_SPATIAL_PRED, this feature not supported at present.\n" );
1061+ }
1062+ break;
1063+ case ENCODER_OPTION_DATAFORMAT: // Input color space
1064+ {
1065+#ifdef REC_FRAME_COUNT
1066+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_DATAFORMAT, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
1067+#endif//REC_FRAME_COUNT
1068+
1069+ *((int32_t*)pOption) = m_iCspInternal;
1070+ }
1071+ break;
1072+ case ENCODER_OPTION_IDR_INTERVAL: // IDR Interval
1073+ {
1074+#ifdef REC_FRAME_COUNT
1075+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_IDR_INTERVAL, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
1076+#endif//REC_FRAME_COUNT
1077+ *((int32_t*)pOption) = m_pEncContext->pSvcParam->uiIntraPeriod;
1078+ }
1079+ break;
1080+ case ENCODER_OPTION_SVC_ENCODE_PARAM: // SVC Encoding Parameter
1081+ {
1082+#ifdef REC_FRAME_COUNT
1083+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_SVC_ENCODE_PARAM, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
1084+#endif//REC_FRAME_COUNT
1085+ memcpy( pOption, m_pEncContext->pSvcParam, sizeof(SWelsSvcCodingParam) ); // confirmed_safe_unsafe_usage
1086+ }
1087+ break;
1088+ case ENCODER_OPTION_FRAME_RATE: // Maximal input frame rate
1089+ {
1090+#ifdef REC_FRAME_COUNT
1091+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_FRAME_RATE, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
1092+#endif//REC_FRAME_COUNT
1093+ *((float*)pOption) = m_pEncContext->pSvcParam->fMaxFrameRate;
1094+ }
1095+ break;
1096+ case ENCODER_OPTION_iBitRate: // Target bit-rate
1097+ {
1098+#ifdef REC_FRAME_COUNT
1099+ WelsLog( m_pEncContext, WELS_LOG_INFO, "CWelsH264SVCEncoder::GetOption():ENCODER_OPTION_iBitRate, m_uiCountFrameNum= %d, m_iCspInternal= 0x%x\n", m_uiCountFrameNum, m_iCspInternal );
1100+#endif//REC_FRAME_COUNT
1101+ *((int32_t*)pOption) = m_pEncContext->pSvcParam->iTargetBitrate;
1102+ }
1103+ break;
1104+ default:
1105+ return cmInitParaError;
1106+ }
1107+
1108+ return 0;
1109+}
1110+
1111+void CWelsH264SVCEncoder::DumpSrcPicture(const uint8_t *pSrc)
1112+{
1113+#ifdef DUMP_SRC_PICTURE
1114+ FILE *pFile = NULL;
1115+ str_t strFileName[256] = {0};
1116+ const int32_t iDataLength = m_iMaxPicWidth * m_iMaxPicHeight;
1117+
1118+#if defined(__GNUC__)
1119+ STRNCPY(strFileName, 256, "/tmp/pic_in_", STRNLEN("/tmp/pic_in_", 255)); // confirmed_safe_unsafe_usage
1120+#else
1121+ STRNCPY(strFileName, 256, "d:\\incoming\\mosaic_st\\pic_in_", STRNLEN("d:\\incoming\\mosaic_st\\pic_in_", 255)); // confirmed_safe_unsafe_usage
1122+#endif//__GNUC__
1123+
1124+ if ( m_iMaxPicWidth == 640 )
1125+ {
1126+ STRCAT(strFileName, 256, "360p."); // confirmed_safe_unsafe_usage
1127+ }
1128+ else if ( m_iMaxPicWidth == 320 )
1129+ {
1130+ STRCAT(strFileName, 256, "180p."); // confirmed_safe_unsafe_usage
1131+ }
1132+ else if ( m_iMaxPicWidth == 160 )
1133+ {
1134+ STRCAT(strFileName, 256, "90p."); // confirmed_safe_unsafe_usage
1135+ }
1136+
1137+ switch( m_iCspInternal) {
1138+ case videoFormatI420:
1139+ case videoFormatYV12:
1140+ STRCAT(strFileName, 256, "yuv"); // confirmed_safe_unsafe_usage
1141+#if defined(__GNUC__)
1142+ pFile = FOPEN(strFileName, "ab+");
1143+#else
1144+#if defined(_MSC_VER)
1145+#if _MSC_VER>=1500
1146+ FOPEN(&pFile, strFileName, "ab+");
1147+#else
1148+ pFile = FOPEN(strFileName, "ab+");
1149+#endif//_MSC_VER>=1500
1150+#endif//_MSC_VER
1151+#endif//__GNUC__
1152+ // WelsLog( m_pEncContext, WELS_LOG_INFO, "WELS_CSP_I420, m_iCspInternal= 0x%x\n", m_iCspInternal);
1153+ if (NULL != pFile)
1154+ {
1155+ fwrite( pSrc, sizeof(uint8_t), (iDataLength * 3)>>1, pFile );
1156+ fflush( pFile );
1157+ fclose(pFile);
1158+ }
1159+ break;
1160+ case videoFormatRGB:
1161+ STRCAT(strFileName, 256, "rgb"); // confirmed_safe_unsafe_usage
1162+#if defined(__GNUC__)
1163+ pFile = FOPEN(strFileName, "ab+");
1164+#else
1165+#if defined(_MSC_VER)
1166+#if _MSC_VER>=1500
1167+ FOPEN(&pFile, strFileName, "ab+");
1168+#else
1169+ pFile = FOPEN(strFileName, "ab+");
1170+#endif//_MSC_VER>=1500
1171+#endif//_MSC_VER
1172+#endif//__GNUC__
1173+ if ( NULL != pFile )
1174+ {
1175+ fwrite( pSrc, sizeof(uint8_t), iDataLength * 3, pFile );
1176+ fflush( pFile );
1177+ fclose( pFile );
1178+ }
1179+ case videoFormatBGR:
1180+ STRCAT(strFileName, 256, "bgr"); // confirmed_safe_unsafe_usage
1181+#if defined(__GNUC__)
1182+ pFile = FOPEN(strFileName, "ab+");
1183+#else
1184+#if defined(_MSC_VER)
1185+#if _MSC_VER>=1500
1186+ FOPEN(&pFile, strFileName, "ab+");
1187+#else
1188+ pFile = FOPEN(strFileName, "ab+");
1189+#endif//_MSC_VER>=1500
1190+#endif//_MSC_VER
1191+#endif//__GNUC__
1192+ // WelsLog( m_pEncContext, WELS_LOG_INFO, "WELS_CSP_BGR, m_iCspInternal= 0x%x\n", m_iCspInternal);
1193+ if ( NULL != pFile )
1194+ {
1195+ fwrite( pSrc, sizeof(uint8_t), iDataLength * 3, pFile );
1196+ fflush( pFile );
1197+ fclose( pFile );
1198+ }
1199+ break;
1200+ case videoFormatYUY2:
1201+ STRCAT(strFileName, 256, "yuy2"); // confirmed_safe_unsafe_usage
1202+#if defined(__GNUC__)
1203+ pFile = FOPEN(strFileName, "ab+");
1204+#else
1205+#if defined(_MSC_VER)
1206+#if _MSC_VER>=1500
1207+ FOPEN(&pFile, strFileName, "ab+");
1208+#else
1209+ pFile = FOPEN(strFileName, "ab+");
1210+#endif//_MSC_VER>=1500
1211+#endif//_MSC_VER
1212+#endif//__GNUC__
1213+ if ( NULL != pFile )
1214+ {
1215+ fwrite( pSrc, sizeof(uint8_t), (CALC_BI_STRIDE(m_iMaxPicWidth, 16)) * m_iMaxPicHeight, pFile );
1216+ fflush( pFile );
1217+ fclose( pFile );
1218+ }
1219+ break;
1220+ default:
1221+ WelsLog( m_pEncContext, WELS_LOG_INFO, "Exclusive case, m_iCspInternal= 0x%x\n", m_iCspInternal);
1222+ break;
1223+ }
1224+#endif//DUMP_SRC_PICTURE
1225+ return;
1226+}
1227+}
1228+
1229+using namespace WelsSVCEnc;
1230+
1231+int32_t CreateSVCEncoder(ISVCEncoder** ppEncoder)
1232+{
1233+ assert( ppEncoder );
1234+
1235+ if ( NULL == ppEncoder )
1236+ return 1;
1237+
1238+ if( ( *ppEncoder = new CWelsH264SVCEncoder() ) != NULL )
1239+ {
1240+ return 0;
1241+ }
1242+
1243+ return 1;
1244+}
1245+
1246+void DestroySVCEncoder(ISVCEncoder* pEncoder)
1247+{
1248+ CWelsH264SVCEncoder *pSVCEncoder = (CWelsH264SVCEncoder*)pEncoder;
1249+
1250+ if( pSVCEncoder ){
1251+ delete pSVCEncoder;
1252+ pSVCEncoder = NULL;
1253+ }
1254+}
1255+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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