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
56namespace WelsSVCEnc {
57
58/*
59 * CWelsH264SVCEncoder class implementation
60 */
61CWelsH264SVCEncoder::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
227CWelsH264SVCEncoder::~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
264void 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 */
293int 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
364int 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 */
519int32_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
566int32_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 */
602int 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
628int 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 */
750int 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 */
771int 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************************************************************************/
790int 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
1048int 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
1111void 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
1229using namespace WelsSVCEnc;
1230
1231int32_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
1246void 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