| @@ -0,0 +1,532 @@ |
| | 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 | * welsDecoderExt.cpp |
| | 33 | * |
| | 34 | * Abstract |
| | 35 | * Cisco OpenH264 decoder extension utilization |
| | 36 | * |
| | 37 | * History |
| | 38 | * 3/12/2009 Created |
| | 39 | * |
| | 40 | * |
| | 41 | ************************************************************************/ |
| | 42 | //#include <assert.h> |
| | 43 | #include "welsDecoderExt.h" |
| | 44 | #include "welsCodecTrace.h" |
| | 45 | #include "codec_def.h" |
| | 46 | #include "typedefs.h" |
| | 47 | #include "mem_align.h" |
| | 48 | #include "utils.h" |
| | 49 | |
| | 50 | //#include "macros.h" |
| | 51 | #include "decoder.h" |
| | 52 | |
| | 53 | extern "C" { |
| | 54 | #include "decoder_core.h" |
| | 55 | #include "manage_dec_ref.h" |
| | 56 | } |
| | 57 | #include "error_code.h" |
| | 58 | #include "crt_util_safe_x.h" // Safe CRT routines like util for cross platforms |
| | 59 | #include <time.h> |
| | 60 | #if defined(WIN32) /*&& defined(_DEBUG)*/ |
| | 61 | |
| | 62 | #include <windows.h> |
| | 63 | #include <stdio.h> |
| | 64 | #include <stdarg.h> |
| | 65 | #include <sys/types.h> |
| | 66 | #include <sys/timeb.h> |
| | 67 | #else |
| | 68 | #include <sys/time.h> |
| | 69 | #endif |
| | 70 | |
| | 71 | namespace WelsDec { |
| | 72 | |
| | 73 | ////////////////////////////////////////////////////////////////////// |
| | 74 | // Construction/Destruction |
| | 75 | ////////////////////////////////////////////////////////////////////// |
| | 76 | |
| | 77 | /*************************************************************************** |
| | 78 | * Description: |
| | 79 | * class CWelsDecoder constructor function, do initialization and |
| | 80 | * alloc memory required |
| | 81 | * |
| | 82 | * Input parameters: none |
| | 83 | * |
| | 84 | * return: none |
| | 85 | /***************************************************************************/ |
| | 86 | CWelsDecoder::CWelsDecoder(void_t) |
| | 87 | : m_pDecContext( NULL ), |
| | 88 | m_pTrace( NULL ) |
| | 89 | { |
| | 90 | #ifdef OUTPUT_BIT_STREAM |
| | 91 | str_t chFileName[1024] = { 0 }; //for .264 |
| | 92 | int iBufUsed = 0; |
| | 93 | int iBufLeft = 1023; |
| | 94 | |
| | 95 | str_t chFileNameSize[1024] = { 0 }; //for .len |
| | 96 | int iBufUsedSize = 0; |
| | 97 | int iBufLeftSize = 1023; |
| | 98 | #endif//OUTPUT_BIT_STREAM |
| | 99 | |
| | 100 | m_pTrace = CreateWelsTrace(Wels_Trace_Type); |
| | 101 | |
| | 102 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO,"CWelsDecoder::CWelsDecoder() entry"); |
| | 103 | |
| | 104 | |
| | 105 | #ifdef OUTPUT_BIT_STREAM |
| | 106 | SWelsTime sCurTime; |
| | 107 | |
| | 108 | WelsGetTimeOfDay(&sCurTime); |
| | 109 | |
| | 110 | iBufUsed += WelsSnprintf(chFileName, iBufLeft, "bs_0x%p_", (void_t*)this); |
| | 111 | iBufUsedSize += WelsSnprintf(chFileNameSize, iBufLeftSize, "size_0x%p_", (void_t*)this); |
| | 112 | |
| | 113 | iBufLeft -= iBufUsed; |
| | 114 | if ( iBufLeft > iBufUsed ) |
| | 115 | { |
| | 116 | iBufUsed += WelsStrftime(&chFileName[iBufUsed], iBufLeft, "%y%m%d%H%M%S", &sCurTime); |
| | 117 | iBufLeft -= iBufUsed; |
| | 118 | } |
| | 119 | |
| | 120 | iBufLeftSize -= iBufUsedSize; |
| | 121 | if ( iBufLeftSize> iBufUsedSize ) |
| | 122 | { |
| | 123 | iBufUsedSize += WelsStrftime(&chFileNameSize[iBufUsedSize], iBufLeftSize, "%y%m%d%H%M%S", &sCurTime); |
| | 124 | iBufLeftSize -= iBufUsedSize; |
| | 125 | } |
| | 126 | |
| | 127 | if ( iBufLeft > iBufUsed ) |
| | 128 | { |
| | 129 | iBufUsed += WelsSnprintf(&chFileName[iBufUsed], iBufLeft, ".%03.3u.264", WelsGetMillsecond(&sCurTime)); |
| | 130 | iBufLeft -= iBufUsed; |
| | 131 | } |
| | 132 | |
| | 133 | if ( iBufLeftSize > iBufUsedSize ) |
| | 134 | { |
| | 135 | iBufUsedSize += WelsSnprintf(&chFileNameSize[iBufUsedSize], iBufLeftSize, ".%03.3u.len", WelsGetMillsecond(&sCurTime)); |
| | 136 | iBufLeftSize -= iBufUsedSize; |
| | 137 | } |
| | 138 | |
| | 139 | |
| | 140 | m_pFBS = WelsFopen(chFileName, "wb"); |
| | 141 | m_pFBSSize = WelsFopen(chFileNameSize, "wb"); |
| | 142 | #endif//OUTPUT_BIT_STREAM |
| | 143 | |
| | 144 | } |
| | 145 | |
| | 146 | /*************************************************************************** |
| | 147 | * Description: |
| | 148 | * class CWelsDecoder destructor function, destroy allocced memory |
| | 149 | * |
| | 150 | * Input parameters: none |
| | 151 | * |
| | 152 | * return: none |
| | 153 | /***************************************************************************/ |
| | 154 | CWelsDecoder::~CWelsDecoder() |
| | 155 | { |
| | 156 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::~CWelsDecoder()"); |
| | 157 | |
| | 158 | UninitDecoder(); |
| | 159 | |
| | 160 | #ifdef OUTPUT_BIT_STREAM |
| | 161 | if ( m_pFBS ) |
| | 162 | { |
| | 163 | WelsFclose( m_pFBS ); |
| | 164 | m_pFBS = NULL; |
| | 165 | } |
| | 166 | if ( m_pFBSSize ) |
| | 167 | { |
| | 168 | WelsFclose( m_pFBSSize ); |
| | 169 | m_pFBSSize = NULL; |
| | 170 | } |
| | 171 | #endif//OUTPUT_BIT_STREAM |
| | 172 | |
| | 173 | if( NULL != m_pTrace ){ |
| | 174 | delete m_pTrace; |
| | 175 | m_pTrace = NULL; |
| | 176 | } |
| | 177 | } |
| | 178 | |
| | 179 | long CWelsDecoder::Initialize(void_t* pParam, const INIT_TYPE keInitType) |
| | 180 | { |
| | 181 | if ( pParam == NULL || keInitType != INIT_TYPE_PARAMETER_BASED ){ |
| | 182 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::Initialize(), invalid input argument."); |
| | 183 | return cmInitParaError; |
| | 184 | } |
| | 185 | |
| | 186 | // H.264 decoder initialization,including memory allocation,then open it ready to decode |
| | 187 | InitDecoder(); |
| | 188 | |
| | 189 | DecoderConfigParam( m_pDecContext, pParam ); |
| | 190 | |
| | 191 | return cmResultSuccess; |
| | 192 | } |
| | 193 | |
| | 194 | long CWelsDecoder::Unintialize() |
| | 195 | { |
| | 196 | UninitDecoder(); |
| | 197 | |
| | 198 | return ERR_NONE; |
| | 199 | } |
| | 200 | |
| | 201 | void_t CWelsDecoder::UninitDecoder( void_t ) |
| | 202 | { |
| | 203 | if ( NULL == m_pDecContext ) |
| | 204 | return; |
| | 205 | |
| | 206 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "into CWelsDecoder::uninit_decoder().."); |
| | 207 | |
| | 208 | WelsEndDecoder( m_pDecContext ); |
| | 209 | |
| | 210 | if ( NULL != m_pDecContext ) |
| | 211 | { |
| | 212 | WelsFree( m_pDecContext, "m_pDecContext" ); |
| | 213 | |
| | 214 | m_pDecContext = NULL; |
| | 215 | } |
| | 216 | |
| | 217 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "left CWelsDecoder::uninit_decoder().."); |
| | 218 | } |
| | 219 | |
| | 220 | // the return value of this function is not suitable, it need report failure info to upper layer. |
| | 221 | void_t CWelsDecoder::InitDecoder( void_t ) |
| | 222 | { |
| | 223 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::init_decoder().."); |
| | 224 | |
| | 225 | m_pDecContext = (PWelsDecoderContext)WelsMalloc( sizeof(SWelsDecoderContext), "m_pDecContext" ); |
| | 226 | |
| | 227 | WelsInitDecoder( m_pDecContext, m_pTrace, IWelsTrace::WelsTrace ); |
| | 228 | |
| | 229 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "CWelsDecoder::init_decoder().. left"); |
| | 230 | } |
| | 231 | |
| | 232 | /* |
| | 233 | * Set Option |
| | 234 | */ |
| | 235 | long CWelsDecoder::SetOption(DECODER_OPTION eOptID, void_t* pOption) |
| | 236 | { |
| | 237 | int iVal = 0; |
| | 238 | |
| | 239 | if ( m_pDecContext == NULL ) |
| | 240 | return dsInitialOptExpected; |
| | 241 | |
| | 242 | if ( eOptID == DECODER_OPTION_DATAFORMAT ) // Set color space of decoding output frame |
| | 243 | { |
| | 244 | if ( pOption == NULL ) |
| | 245 | return cmInitParaError; |
| | 246 | |
| | 247 | iVal = *((int*)pOption); // is_rgb |
| | 248 | |
| | 249 | return DecoderSetCsp( m_pDecContext, iVal ); |
| | 250 | } |
| | 251 | else if ( eOptID == DECODER_OPTION_END_OF_STREAM ) // Indicate bit-stream of the final frame to be decoded |
| | 252 | { |
| | 253 | if ( pOption == NULL ) |
| | 254 | return cmInitParaError; |
| | 255 | |
| | 256 | iVal = *((int*)pOption); // boolean value for whether enabled End Of Stream flag |
| | 257 | |
| | 258 | m_pDecContext->bEndOfStreamFlag = iVal ? true : false; |
| | 259 | |
| | 260 | return cmResultSuccess; |
| | 261 | } |
| | 262 | else if ( eOptID == DECODER_OPTION_MODE) |
| | 263 | { |
| | 264 | if ( pOption == NULL ) |
| | 265 | return cmInitParaError; |
| | 266 | |
| | 267 | iVal = *((int *)pOption); |
| | 268 | |
| | 269 | m_pDecContext->iSetMode = iVal; |
| | 270 | if(iVal == SW_MODE) |
| | 271 | { |
| | 272 | m_pDecContext->iDecoderOutputProperty = BUFFER_HOST; |
| | 273 | } |
| | 274 | else |
| | 275 | { |
| | 276 | #if !defined(__APPLE__) |
| | 277 | m_pDecContext->iDecoderOutputProperty = BUFFER_DEVICE; |
| | 278 | #else |
| | 279 | m_pDecContext->iDecoderOutputProperty = BUFFER_HOST;//BUFFER_HOST;//BUFFER_DEVICE; |
| | 280 | #endif |
| | 281 | |
| | 282 | } |
| | 283 | |
| | 284 | return cmResultSuccess; |
| | 285 | } |
| | 286 | else if ( eOptID == DECODER_OPTION_OUTPUT_PROPERTY) |
| | 287 | { |
| | 288 | if ( pOption == NULL) |
| | 289 | return cmInitParaError; |
| | 290 | |
| | 291 | iVal = *((int *)pOption); |
| | 292 | if( m_pDecContext->iSetMode != SW_MODE) |
| | 293 | m_pDecContext->iDecoderOutputProperty = iVal; |
| | 294 | } |
| | 295 | |
| | 296 | |
| | 297 | return cmInitParaError; |
| | 298 | } |
| | 299 | |
| | 300 | /* |
| | 301 | * Get Option |
| | 302 | */ |
| | 303 | long CWelsDecoder::GetOption(DECODER_OPTION eOptID, void_t* pOption) |
| | 304 | { |
| | 305 | int iVal = 0; |
| | 306 | |
| | 307 | if ( m_pDecContext == NULL ) |
| | 308 | return cmInitExpected; |
| | 309 | |
| | 310 | if ( pOption == NULL ) |
| | 311 | return cmInitParaError; |
| | 312 | |
| | 313 | if ( DECODER_OPTION_DATAFORMAT == eOptID ){ |
| | 314 | iVal = m_pDecContext->iOutputColorFormat; |
| | 315 | *((int*)pOption) = iVal; |
| | 316 | return cmResultSuccess; |
| | 317 | } |
| | 318 | else if ( DECODER_OPTION_END_OF_STREAM == eOptID ){ |
| | 319 | iVal = m_pDecContext->bEndOfStreamFlag; |
| | 320 | *((int*)pOption) = iVal; |
| | 321 | return cmResultSuccess; |
| | 322 | } |
| | 323 | #ifdef LONG_TERM_REF |
| | 324 | else if ( DECODER_OPTION_IDR_PIC_ID == eOptID ){ |
| | 325 | iVal = m_pDecContext->uiCurIdrPicId; |
| | 326 | *((int*)pOption) = iVal; |
| | 327 | return cmResultSuccess; |
| | 328 | } |
| | 329 | else if ( DECODER_OPTION_FRAME_NUM == eOptID) |
| | 330 | { |
| | 331 | iVal = m_pDecContext->iFrameNum; |
| | 332 | *((int*)pOption) = iVal; |
| | 333 | return cmResultSuccess; |
| | 334 | } |
| | 335 | else if ( DECODER_OPTION_LTR_MARKING_FLAG == eOptID ) |
| | 336 | { |
| | 337 | iVal = m_pDecContext->bCurAuContainLtrMarkSeFlag; |
| | 338 | *((int*)pOption) = iVal; |
| | 339 | return cmResultSuccess; |
| | 340 | } |
| | 341 | else if ( DECODER_OPTION_LTR_MARKED_FRAME_NUM == eOptID ) |
| | 342 | { |
| | 343 | iVal = m_pDecContext->iFrameNumOfAuMarkedLtr; |
| | 344 | *((int*)pOption) = iVal; |
| | 345 | return cmResultSuccess; |
| | 346 | } |
| | 347 | #endif |
| | 348 | else if ( DECODER_OPTION_VCL_NAL == eOptID ) //feedback whether or not have VCL NAL in current AU |
| | 349 | { |
| | 350 | iVal = m_pDecContext->iFeedbackVclNalInAu; |
| | 351 | *((int*)pOption) = iVal; |
| | 352 | return cmResultSuccess; |
| | 353 | } |
| | 354 | else if ( DECODER_OPTION_TEMPORAL_ID == eOptID ) //if have VCL NAL in current AU, then feedback the temporal ID |
| | 355 | { |
| | 356 | iVal = m_pDecContext->iFeedbackTidInAu; |
| | 357 | *((int*)pOption) = iVal; |
| | 358 | return cmResultSuccess; |
| | 359 | } |
| | 360 | else if ( DECODER_OPTION_MODE == eOptID ) |
| | 361 | { |
| | 362 | if ( pOption == NULL ) |
| | 363 | return cmInitParaError; |
| | 364 | |
| | 365 | iVal = m_pDecContext->iSetMode; |
| | 366 | |
| | 367 | *((int *)pOption) = iVal; |
| | 368 | return cmResultSuccess; |
| | 369 | } |
| | 370 | else if ( DECODER_OPTION_DEVICE_INFO == eOptID ) |
| | 371 | { |
| | 372 | if ( pOption == NULL ) |
| | 373 | return cmInitParaError; |
| | 374 | |
| | 375 | return cmResultSuccess; |
| | 376 | } |
| | 377 | |
| | 378 | return cmInitParaError; |
| | 379 | } |
| | 380 | |
| | 381 | DECODING_STATE CWelsDecoder::DecodeFrame( const unsigned char* kpSrc, |
| | 382 | const int kiSrcLen, |
| | 383 | void_t ** ppDst, |
| | 384 | SBufferInfo* pDstInfo) |
| | 385 | { |
| | 386 | if ( kiSrcLen > 0 && kpSrc != NULL ) |
| | 387 | { |
| | 388 | #ifdef OUTPUT_BIT_STREAM |
| | 389 | if ( m_pFBS ) |
| | 390 | { |
| | 391 | WelsFwrite( kpSrc, sizeof(unsigned char), kiSrcLen, m_pFBS ); |
| | 392 | WelsFflush( m_pFBS ); |
| | 393 | } |
| | 394 | if ( m_pFBSSize ) |
| | 395 | { |
| | 396 | WelsFwrite( &kiSrcLen, sizeof(int), 1, m_pFBSSize ); |
| | 397 | WelsFflush( m_pFBSSize ); |
| | 398 | } |
| | 399 | #endif//OUTPUT_BIT_STREAM |
| | 400 | m_pDecContext->bEndOfStreamFlag = false; |
| | 401 | } |
| | 402 | else |
| | 403 | { //For application MODE, the error detection should be added for safe. |
| | 404 | //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL. |
| | 405 | m_pDecContext->bEndOfStreamFlag = true; |
| | 406 | } |
| | 407 | |
| | 408 | ppDst[0] = ppDst[1] = ppDst[2] = NULL; |
| | 409 | m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding. |
| | 410 | m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize |
| | 411 | memset(pDstInfo,0,sizeof(SBufferInfo)); |
| | 412 | pDstInfo->eBufferProperty = (EBufferProperty)m_pDecContext->iDecoderOutputProperty; |
| | 413 | |
| | 414 | #ifdef LONG_TERM_REF |
| | 415 | m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR |
| | 416 | m_pDecContext->bCurAuContainLtrMarkSeFlag = false; |
| | 417 | m_pDecContext->iFrameNumOfAuMarkedLtr = 0; |
| | 418 | m_pDecContext->iFrameNum = -1; //initialize |
| | 419 | #endif |
| | 420 | |
| | 421 | m_pDecContext->iFeedbackTidInAu = -1; //initialize |
| | 422 | |
| | 423 | WelsDecodeBs( m_pDecContext, kpSrc, kiSrcLen, (unsigned char**)ppDst, pDstInfo); //iErrorCode has been modified in this function |
| | 424 | |
| | 425 | pDstInfo->eWorkMode = (EDecodeMode)m_pDecContext->iDecoderMode; |
| | 426 | |
| | 427 | if ( m_pDecContext->iErrorCode ) |
| | 428 | { |
| | 429 | ENalUnitType eNalType = NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently |
| | 430 | |
| | 431 | eNalType = m_pDecContext->sCurNalHead.eNalUnitType; |
| | 432 | |
| | 433 | //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss. |
| | 434 | if ( (IS_PARAM_SETS_NALS(eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) || |
| | 435 | (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType) ) |
| | 436 | { |
| | 437 | #ifdef LONG_TERM_REF |
| | 438 | m_pDecContext->bParamSetsLostFlag = true; |
| | 439 | #else |
| | 440 | m_pDecContext->bReferenceLostAtT0Flag = true; |
| | 441 | #endif |
| | 442 | ResetParameterSetsState( m_pDecContext ); //initial SPS&PPS ready flag |
| | 443 | } |
| | 444 | |
| | 445 | IWelsTrace::WelsVTrace(m_pTrace, IWelsTrace::WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode); |
| | 446 | return (DECODING_STATE)m_pDecContext->iErrorCode; |
| | 447 | } |
| | 448 | |
| | 449 | return dsErrorFree; |
| | 450 | } |
| | 451 | |
| | 452 | DECODING_STATE CWelsDecoder::DecodeFrame( const unsigned char* kpSrc, |
| | 453 | const int kiSrcLen, |
| | 454 | unsigned char** ppDst, |
| | 455 | int* pStride, |
| | 456 | int& iWidth, |
| | 457 | int& iHeight ) |
| | 458 | { |
| | 459 | DECODING_STATE eDecState = dsErrorFree; |
| | 460 | SBufferInfo DstInfo; |
| | 461 | |
| | 462 | memset(&DstInfo, 0, sizeof(SBufferInfo)); |
| | 463 | DstInfo.UsrData.sSystemBuffer.iStride[0] = pStride[0]; |
| | 464 | DstInfo.UsrData.sSystemBuffer.iStride[1] = pStride[1]; |
| | 465 | DstInfo.UsrData.sSystemBuffer.iWidth = iWidth; |
| | 466 | DstInfo.UsrData.sSystemBuffer.iHeight = iHeight; |
| | 467 | DstInfo.eBufferProperty = BUFFER_HOST; |
| | 468 | |
| | 469 | eDecState = DecodeFrame(kpSrc, kiSrcLen, (void_t **)ppDst, &DstInfo); |
| | 470 | if (eDecState == dsErrorFree) |
| | 471 | { |
| | 472 | pStride[0] = DstInfo.UsrData.sSystemBuffer.iStride[0]; |
| | 473 | pStride[1] = DstInfo.UsrData.sSystemBuffer.iStride[1]; |
| | 474 | iWidth = DstInfo.UsrData.sSystemBuffer.iWidth; |
| | 475 | iHeight = DstInfo.UsrData.sSystemBuffer.iHeight; |
| | 476 | } |
| | 477 | |
| | 478 | return eDecState; |
| | 479 | } |
| | 480 | |
| | 481 | DECODING_STATE CWelsDecoder::DecodeFrameEx(const unsigned char * kpSrc, |
| | 482 | const int kiSrcLen, |
| | 483 | unsigned char * pDst, |
| | 484 | int iDstStride, |
| | 485 | int & iDstLen, |
| | 486 | int & iWidth, |
| | 487 | int & iHeight, |
| | 488 | int & iColorFormat ) |
| | 489 | { |
| | 490 | DECODING_STATE state = dsErrorFree; |
| | 491 | |
| | 492 | return state; |
| | 493 | } |
| | 494 | |
| | 495 | |
| | 496 | } // namespace WelsDec |
| | 497 | |
| | 498 | |
| | 499 | using namespace WelsDec; |
| | 500 | |
| | 501 | /* WINAPI is indeed in prefix due to sync to application layer callings!! */ |
| | 502 | |
| | 503 | /* |
| | 504 | * CreateDecoder |
| | 505 | * @return: success in return 0, otherwise failed. |
| | 506 | */ |
| | 507 | long CreateDecoder( ISVCDecoder** ppDecoder ) |
| | 508 | { |
| | 509 | |
| | 510 | if ( NULL == ppDecoder ){ |
| | 511 | return ERR_INVALID_PARAMETERS; |
| | 512 | } |
| | 513 | |
| | 514 | *ppDecoder = new CWelsDecoder(); |
| | 515 | |
| | 516 | if ( NULL == *ppDecoder ){ |
| | 517 | return ERR_MALLOC_FAILED; |
| | 518 | } |
| | 519 | |
| | 520 | return ERR_NONE; |
| | 521 | } |
| | 522 | |
| | 523 | /* |
| | 524 | * DestroyDecoder |
| | 525 | */ |
| | 526 | void_t DestroyDecoder( ISVCDecoder* pDecoder ) |
| | 527 | { |
| | 528 | if ( NULL != pDecoder ){ |
| | 529 | delete (CWelsDecoder *)pDecoder; |
| | 530 | pDecoder = NULL; |
| | 531 | } |
| | 532 | } |