History

Initial Commit

Ethan Hugg committed 12 years ago

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

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

Unified · Split

codec/encoder/core/src/utils.cpp+513−0
@@ -0,0 +1,513 @@
1+/*!
2+ * \copy
3+ * Copyright (c) 2009-2013, Cisco Systems
4+ * All rights reserved.
5+ *
6+ * Redistribution and use in source and binary forms, with or without
7+ * modification, are permitted provided that the following conditions
8+ * are met:
9+ *
10+ * * Redistributions of source code must retain the above copyright
11+ * notice, this list of conditions and the following disclaimer.
12+ *
13+ * * Redistributions in binary form must reproduce the above copyright
14+ * notice, this list of conditions and the following disclaimer in
15+ * the documentation and/or other materials provided with the
16+ * distribution.
17+ *
18+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+ * POSSIBILITY OF SUCH DAMAGE.
30+ *
31+ *
32+ * \file utils.c
33+ *
34+ * \brief common tool/function utilization
35+ *
36+ * \date 03/10/2009 Created
37+ *
38+ *************************************************************************************
39+ */
40+#include <string.h>
41+#include <stdlib.h>
42+#include <assert.h>
43+#include <math.h>
44+#include <time.h>
45+#if defined(WIN32)
46+#include <windows.h>
47+#include <sys/types.h>
48+#include <sys/timeb.h>
49+#else
50+#include <sys/time.h>
51+#endif
52+
53+#include "utils.h"
54+#include "macros.h"
55+#include "wels_const.h"
56+#include "property.h"
57+#include "cpu_core.h"
58+#include "encoder_context.h"
59+#include "as264_common.h"
60+#include "property.h"
61+#include "crt_util_safe_x.h" // Safe CRT routines like utils for cross platforms
62+
63+
64+namespace WelsSVCEnc {
65+
66+void WelsLogDefault( void *pCtx, const int32_t kiLevel, const str_t *kpFmtStr, va_list argv );
67+void WelsLogNil( void *pCtx, const int32_t kiLevel, const str_t *kpFmtStr, va_list argv );
68+
69+real32_t WelsCalcPsnr( const void *kpTarPic,
70+ const int32_t kiTarStride,
71+ const void *kpRefPic,
72+ const int32_t kiRefStride,
73+ const int32_t kiWidth,
74+ const int32_t kiHeight );
75+
76+// to fill default routines
77+#ifdef ENABLE_TRACE_FILE
78+PWelsLogCallbackFunc wlog = WelsLogDefault;
79+#else
80+PWelsLogCallbackFunc wlog = WelsLogNil;
81+#endif
82+
83+iWelsLogLevel g_iLevelLog = WELS_LOG_DEFAULT; // default log iLevel
84+int32_t g_iSizeLogBuf = 1024; // pBuffer size for each log output
85+
86+/*
87+ * Log output routines
88+ */
89+
90+/*!
91+ * \brief get log tag
92+ * \param kiLevel log iLevel
93+ * \return tag of log iLevel
94+ */
95+static inline str_t *GetLogTag( const int32_t kiLevel, int32_t *pBit )
96+{
97+ int32_t iShift = 0;
98+ int32_t iVal = 0;
99+ bool_t bFound = false;
100+
101+ if ( kiLevel <= 0 || kiLevel > (1 << (WELS_LOG_LEVEL_COUNT-1)) || NULL == pBit )
102+ return NULL;
103+
104+ for(;;)
105+ {
106+ if ( iShift >= WELS_LOG_LEVEL_COUNT )
107+ break;
108+ iVal = (1 << iShift);
109+ if ( iVal == kiLevel )
110+ {
111+ bFound = true;
112+ break;
113+ }
114+ ++ iShift;
115+ }
116+
117+ if ( bFound )
118+ {
119+ *pBit = iShift;
120+ return (str_t *)g_sWelsLogTags[iShift];
121+ }
122+ return NULL;
123+}
124+
125+/*!
126+ *************************************************************************************
127+ * \brief System trace log output in Wels
128+ *
129+ * \param pCtx instance pointer
130+ * \param kiLevel log iLevel ( WELS_LOG_QUIET, ERROR, WARNING, INFO, DEBUG )
131+ * \param kpFmtStr formated string to mount
132+ * \param argv pData string argument
133+ *
134+ * \return NONE
135+ *
136+ * \note N/A
137+ *************************************************************************************
138+ */
139+void WelsLogDefault( void *pCtx, const int32_t kiLevel, const str_t *kpFmtStr, va_list argv )
140+{
141+ sWelsEncCtx *pEncCtx = (sWelsEncCtx *)pCtx;
142+ iWelsLogLevel iVal = (kiLevel & g_iLevelLog);
143+
144+ if ( 0 == iVal || NULL == pEncCtx ) // such iLevel not enabled
145+ {
146+ return;
147+ }
148+ else
149+ {
150+ str_t pBuf[WELS_LOG_BUF_SIZE+1] = {0};
151+ const int32_t kiBufSize = sizeof(pBuf) / sizeof(pBuf[0]) - 1;
152+ int32_t iCurUsed = 0;
153+ int32_t iBufUsed = 0;
154+ int32_t iBufLeft = kiBufSize - iBufUsed;
155+
156+ if ( pEncCtx ){
157+ time_t l_time;
158+#if defined(WIN32)
159+#if defined(_MSC_VER)
160+#if _MSC_VER >= 1500
161+ struct tm t_now;
162+#else//VC6
163+ struct tm* t_now;
164+#endif//_MSC_VER >= 1500
165+#endif//_MSC_VER
166+#else//__GNUC__
167+ struct tm* t_now;
168+#endif//WIN32
169+
170+#if defined( WIN32 )
171+ struct _timeb tb;
172+
173+ time(&l_time);
174+#ifdef _MSC_VER
175+#if _MSC_VER >= 1500
176+ LOCALTIME(&t_now, &l_time);
177+#else
178+ t_now = LOCALTIME(&l_time);
179+ if ( NULL == t_now )
180+ {
181+ return;
182+ }
183+#endif//_MSC_VER >= 1500
184+#endif//_MSC_VER
185+ FTIME(&tb);
186+#elif defined( __GNUC__ )
187+ struct timeval tv;
188+ time(&l_time);
189+ t_now = (struct tm *)LOCALTIME(&l_time);
190+ gettimeofday(&tv,NULL);
191+#endif//WIN32
192+ if (iBufLeft > 0){
193+#ifdef _MSC_VER
194+#if _MSC_VER >= 1500
195+ iCurUsed = SNPRINTF( &pBuf[iBufUsed], iBufLeft, iBufLeft, "[0x%p @ ", pEncCtx ); // confirmed_safe_unsafe_usage
196+#else
197+ iCurUsed = SNPRINTF( &pBuf[iBufUsed], iBufLeft, "[0x%p @ ", pEncCtx ); // confirmed_safe_unsafe_usage
198+#endif//_MSC_VER >= 1500
199+#endif//_MSC_VER
200+ if (iCurUsed >= 0){
201+ iBufUsed += iCurUsed;
202+ iBufLeft -= iCurUsed;
203+ }
204+ }
205+ else{
206+ return;
207+ }
208+
209+ if ( iBufLeft > 0 ){
210+ iCurUsed = GetCodeName( &pBuf[iBufUsed], iBufLeft );
211+ if ( iCurUsed > 0 ){
212+ iBufUsed += iCurUsed;
213+ iBufLeft -= iCurUsed;
214+ }
215+ pBuf[iBufUsed] = ' ';
216+ ++ iBufUsed;
217+ -- iBufLeft;
218+
219+ iCurUsed = GetLibName( &pBuf[iBufUsed], iBufLeft );
220+ if ( iCurUsed > 0 ){
221+ iBufUsed += iCurUsed;
222+ iBufLeft -= iCurUsed;
223+ }
224+ pBuf[iBufUsed] = ' ';
225+ ++ iBufUsed;
226+ -- iBufLeft;
227+
228+ pBuf[iBufUsed] = 'v';
229+ ++ iBufUsed;
230+ -- iBufLeft;
231+ iCurUsed = GetVerNum( &pBuf[iBufUsed], iBufLeft );
232+ if ( iCurUsed > 0 ){
233+ iBufUsed += iCurUsed;
234+ iBufLeft -= iCurUsed;
235+ }
236+ pBuf[iBufUsed] = ' ';
237+ ++ iBufUsed;
238+ -- iBufLeft;
239+ }
240+
241+ if (iBufLeft > 0){
242+#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1500)
243+ iCurUsed = strftime(&pBuf[iBufUsed], iBufLeft, "%y-%m-%d %H:%M:%S", &t_now);
244+#else
245+ iCurUsed = strftime(&pBuf[iBufUsed], iBufLeft, "%y-%m-%d %H:%M:%S", t_now);
246+#endif//WIN32..
247+ if (iCurUsed > 0){
248+ iBufUsed += iCurUsed;
249+ iBufLeft -= iCurUsed;
250+ }
251+ }
252+ else{
253+ return;
254+ }
255+
256+ if (iBufLeft > 0){
257+#if defined (WIN32)
258+#ifdef _MSC_VER
259+#if _MSC_VER >= 1500
260+ iCurUsed = SNPRINTF(&pBuf[iBufUsed], iBufLeft, iBufLeft, ".%03.3u]: ", tb.millitm); // confirmed_safe_unsafe_usage
261+#else
262+ iCurUsed = SNPRINTF(&pBuf[iBufUsed], iBufLeft, ".%3.3u]: ", tb.millitm); // confirmed_safe_unsafe_usage
263+#endif//_MSC_VER >= 1500
264+#endif//_MSC_VER
265+#elif defined (__GNUC__)
266+ iCurUsed = SNPRINTF(&pBuf[iBufUsed], iBufLeft, ".%3.3u]: ", tv.tv_usec/1000); // confirmed_safe_unsafe_usage
267+#endif//WIN32
268+ if (iCurUsed >= 0){
269+ iBufUsed += iCurUsed;
270+ iBufLeft -= iCurUsed;
271+ }
272+ }
273+ else{
274+ return;
275+ }
276+ }
277+
278+ // fixed stack corruption issue on vs2008
279+ if ( iBufLeft > 0 ){
280+ int32_t i_shift = 0;
281+ str_t *pStr = NULL;
282+ pStr = GetLogTag( kiLevel, &i_shift );
283+ if ( NULL != pCtx){
284+ int32_t iLenTag = STRNLEN( pStr, 8 ); // confirmed_safe_unsafe_usage
285+ STRCAT( &pBuf[iBufUsed], iBufLeft, pStr ); // confirmed_safe_unsafe_usage
286+ iBufUsed += iLenTag;
287+ pBuf[iBufUsed] = ' ';
288+ iBufUsed++;
289+ ++iLenTag;
290+ iBufLeft -= iLenTag;
291+ }
292+ }
293+ if (iBufLeft > 0){
294+#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1500)
295+ int32_t len = 0;
296+ len = _vscprintf( kpFmtStr, argv ) // _vscprintf doesn't count
297+ + 1; // terminating '\0'
298+ iCurUsed = VSPRINTF(&pBuf[iBufUsed], len, kpFmtStr, argv); // confirmed_safe_unsafe_usage
299+#else
300+ iCurUsed = VSPRINTF(&pBuf[iBufUsed], kpFmtStr, argv); // confirmed_safe_unsafe_usage
301+#endif//WIN32..
302+ if (iCurUsed > 0){
303+ iBufUsed += iCurUsed;
304+ iBufLeft -= iCurUsed;
305+ }
306+ }
307+#ifdef ENABLE_TRACE_FILE
308+ if (NULL != pEncCtx && NULL != pEncCtx->pFileLog){
309+ if ( pEncCtx->uiSizeLog > MAX_TRACE_LOG_SIZE){
310+ if (0 == fseek(pEncCtx->pFileLog, 0L, SEEK_SET))
311+ pEncCtx->uiSizeLog = 0;
312+ }
313+ if ( iBufUsed > 0 && iBufUsed < WELS_LOG_BUF_SIZE )
314+ {
315+ iCurUsed = fwrite(pBuf, 1, iBufUsed, pEncCtx->pFileLog);
316+ fflush( pEncCtx->pFileLog );
317+ if ( iCurUsed == iBufUsed )
318+ pEncCtx->uiSizeLog += iBufUsed;
319+ }
320+ }
321+ else{
322+#if defined(WIN32) && defined(_DEBUG)
323+ OutputDebugStringA(pBuf);
324+#endif
325+ }
326+#endif//ENABLE_TRACE_FILE
327+ }
328+}
329+void WelsLogNil( void *pCtx, const int32_t kiLevel, const str_t *kpFmtStr, va_list argv )
330+{
331+ // NULL implementation
332+}
333+
334+/*!
335+*************************************************************************************
336+* \brief reopen log file when finish setting current path
337+*
338+* \param pCtx context pCtx
339+* \param pCurPath current path string
340+*
341+* \return NONE
342+*
343+* \note N/A
344+*************************************************************************************
345+*/
346+void WelsReopenTraceFile( void *pCtx, str_t *pCurPath )
347+{
348+#ifdef ENABLE_TRACE_FILE
349+ sWelsEncCtx *pEncCtx = (sWelsEncCtx *)pCtx;
350+ if (wlog == WelsLogDefault)
351+ {
352+ str_t strTraceFile[MAX_FNAME_LEN] = {0};
353+ int32_t len = 0;
354+ if (pEncCtx->pFileLog != NULL)
355+ {
356+ fclose(pEncCtx->pFileLog);
357+ pEncCtx->pFileLog = NULL;
358+ }
359+ pEncCtx->uiSizeLog = 0;
360+ len = STRNLEN( pCurPath, MAX_FNAME_LEN-1 ); // confirmed_safe_unsafe_usage
361+ if (len >= MAX_FNAME_LEN)
362+ return;
363+ STRNCPY(strTraceFile, MAX_FNAME_LEN, pCurPath, len); // confirmed_safe_unsafe_usage
364+#ifdef __GNUC__
365+ STRCAT(strTraceFile, MAX_FNAME_LEN-len, "/wels_encoder_trace.txt"); // confirmed_safe_unsafe_usage
366+ pEncCtx->pFileLog = FOPEN(strTraceFile, "wt+"); // confirmed_safe_unsafe_usage
367+#elif WIN32
368+ STRCAT(strTraceFile, MAX_FNAME_LEN-len, "\\wels_encoder_trace.txt");// confirmed_safe_unsafe_usage
369+#if _MSC_VER >= 1500
370+ FOPEN(&pEncCtx->pFileLog, strTraceFile, "wt+"); // confirmed_safe_unsafe_usage
371+#else
372+ pEncCtx->pFileLog = FOPEN(strTraceFile, "wt+"); // confirmed_safe_unsafe_usage
373+#endif//_MSC_VER>=1500
374+#else
375+#endif//__GNUC__
376+ }
377+#endif//ENABLE_TRACE_FILE
378+}
379+
380+/*!
381+ *************************************************************************************
382+ * \brief set log iLevel from external call
383+ *
384+ * \param iLevel iLevel of log
385+ *
386+ * \return NONE
387+ *
388+ * \note can be able to control log iLevel dynamically
389+ *************************************************************************************
390+ */
391+void WelsSetLogLevel( const int32_t kiLevel )
392+{
393+ iWelsLogLevel iVal = 0;
394+ if ( kiLevel & WELS_LOG_ERROR )
395+ {
396+ iVal |= WELS_LOG_ERROR;
397+ }
398+ if ( kiLevel & WELS_LOG_WARNING )
399+ {
400+ iVal |= WELS_LOG_WARNING;
401+ }
402+ if ( kiLevel & WELS_LOG_INFO )
403+ {
404+ iVal |= WELS_LOG_INFO;
405+ }
406+ if ( kiLevel & WELS_LOG_DEBUG )
407+ {
408+ iVal |= WELS_LOG_DEBUG;
409+ }
410+ g_iLevelLog = iVal;
411+}
412+
413+/*!
414+ *************************************************************************************
415+ * \brief get log iLevel from external call
416+ *
417+ * \param N/A
418+ *
419+ * \return current iLevel of log used in codec internal
420+ *
421+ * \note can be able to get log iLevel of internal codec applicable
422+ *************************************************************************************
423+ */
424+int32_t WelsGetLogLevel( void )
425+{
426+ return g_iLevelLog;
427+}
428+
429+/*!
430+ *************************************************************************************
431+ * \brief set log callback from external call
432+ *
433+ * \param _log log function routine
434+ *
435+ * \return NONE
436+ *
437+ * \note N/A
438+ *************************************************************************************
439+ */
440+void WelsSetLogCallback( PWelsLogCallbackFunc _log )
441+{
442+ wlog = _log;
443+}
444+
445+void WelsLogCall(void *pCtx, int32_t iLevel, const str_t *kpFmt, va_list vl)
446+{
447+ wlog(pCtx, iLevel, kpFmt, vl);
448+}
449+
450+void WelsLog(void *pCtx, int32_t iLevel, const str_t *kpFmt, ...)
451+{
452+ va_list vl;
453+ va_start(vl, kpFmt);
454+ WelsLogCall(pCtx, iLevel, kpFmt, vl);
455+ va_end(vl);
456+}
457+
458+#ifndef CALC_PSNR
459+#define CONST_FACTOR_PSNR (10.0 / log(10.0)) // for good computation
460+#define CALC_PSNR(w, h, s) ((real32_t)(CONST_FACTOR_PSNR * log( 65025.0 * w * h / iSqe )))
461+#endif//CALC_PSNR
462+
463+/*
464+ * PSNR calculation routines
465+ */
466+/*!
467+ *************************************************************************************
468+ * \brief PSNR calculation utilization in Wels
469+ *
470+ * \param pTarPic target picture to be calculated in Picture pData format
471+ * \param iTarStride stride of target picture pData pBuffer
472+ * \param pRefPic base referencing picture samples
473+ * \param iRefStride stride of reference picture pData pBuffer
474+ * \param iWidth picture iWidth in pixel
475+ * \param iHeight picture iHeight in pixel
476+ *
477+ * \return actual PSNR result;
478+ *
479+ * \note N/A
480+ *************************************************************************************
481+ */
482+real32_t WelsCalcPsnr( const void *kpTarPic,
483+ const int32_t kiTarStride,
484+ const void *kpRefPic,
485+ const int32_t kiRefStride,
486+ const int32_t kiWidth,
487+ const int32_t kiHeight )
488+{
489+ int64_t iSqe = 0;
490+ int32_t x, y;
491+ uint8_t *pTar = (uint8_t *)kpTarPic;
492+ uint8_t *pRef = (uint8_t *)kpRefPic;
493+
494+ if ( NULL == pTar || NULL == pRef )
495+ return (-1.0f);
496+
497+ for ( y = 0; y < kiHeight; ++ y ) // OPTable !!
498+ {
499+ for ( x = 0; x < kiWidth; ++ x )
500+ {
501+ const int32_t kiT = pTar[y*kiTarStride+x] - pRef[y*kiRefStride+x];
502+ iSqe += kiT * kiT;
503+ }
504+ }
505+ if ( 0 == iSqe )
506+ {
507+ return (99.99f);
508+ }
509+ return CALC_PSNR( kiWidth, kiHeight, iSqe );
510+}
511+
512+
513+}

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