History

Pretty printed the C++ code with astyle

Ethan Hugg committed 12 years ago

Commit ff6b6691 parent 063709c225 files · +48457 −51954Browse files

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

Unified · Split

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

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