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
64namespace WelsSVCEnc {
65
66void WelsLogDefault( void *pCtx, const int32_t kiLevel, const str_t *kpFmtStr, va_list argv );
67void WelsLogNil( void *pCtx, const int32_t kiLevel, const str_t *kpFmtStr, va_list argv );
68
69real32_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
78PWelsLogCallbackFunc wlog = WelsLogDefault;
79#else
80PWelsLogCallbackFunc wlog = WelsLogNil;
81#endif
82
83iWelsLogLevel g_iLevelLog = WELS_LOG_DEFAULT; // default log iLevel
84int32_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 */
95static 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 */
139void 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}
329void 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*/
346void 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 */
391void 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 */
424int32_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 */
440void WelsSetLogCallback( PWelsLogCallbackFunc _log )
441{
442 wlog = _log;
443}
444
445void WelsLogCall(void *pCtx, int32_t iLevel, const str_t *kpFmt, va_list vl)
446{
447 wlog(pCtx, iLevel, kpFmt, vl);
448}
449
450void 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 */
482real32_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