Showing the changes to codec/decoder (5 of 5 files). Show all
Unified · Split
| @@ -233,6 +233,7 @@ typedef struct TagWelsDecoderContext { · 232 unmodified lines | |||
| 233 | SVlcTable sVlcTable; // vlc table | 233 | SVlcTable sVlcTable; // vlc table |
| 234 | 234 | ||
| 235 | SBitStringAux sBs; | 235 | SBitStringAux sBs; |
| 236 | int32_t iMaxBsBufferSizeInByte; //actual memory size for BS buffer | ||
| 236 | 237 | ||
| 237 | /* Global memory external */ | 238 | /* Global memory external */ |
| 238 | 239 | ||
| @@ -48,6 +48,28 @@ · 47 unmodified lines | |||
| 48 | #include "codec_def.h" | 48 | #include "codec_def.h" |
| 49 | 49 | ||
| 50 | namespace WelsDec { | 50 | namespace WelsDec { |
| 51 | /* | ||
| 52 | * InitBsBuffer | ||
| 53 | * Memory allocation for Bitstream Buffer | ||
| 54 | * return: | ||
| 55 | * 0 - success; otherwise returned error_no defined in error_no.h. | ||
| 56 | */ | ||
| 57 | int32_t InitBsBuffer (PWelsDecoderContext pCtx); | ||
| 58 | |||
| 59 | /* | ||
| 60 | * ExpandBsBuffer | ||
| 61 | * Expand current BS buffer and copy its content | ||
| 62 | * new buffer size will consider input size as a reference | ||
| 63 | * return: | ||
| 64 | * 0 - success; otherwise returned error_no defined in error_no.h. | ||
| 65 | */ | ||
| 66 | int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen); | ||
| 67 | |||
| 68 | /* | ||
| 69 | * CheckBsBuffer | ||
| 70 | * Check if current buffer size is enough | ||
| 71 | */ | ||
| 72 | int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen); | ||
| 51 | 73 | ||
| 52 | /* | 74 | /* |
| 53 | * WelsInitMemory | 75 | * WelsInitMemory |
| @@ -56,7 +78,7 @@ namespace WelsDec { · 2 unmodified lines | |||
| 56 | * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache. | 78 | * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache. |
| 57 | * return: | 79 | * return: |
| 58 | * 0 - success; otherwise returned error_no defined in error_no.h. | 80 | * 0 - success; otherwise returned error_no defined in error_no.h. |
| 59 | */ | 81 | */ |
| 60 | int32_t WelsInitMemory (PWelsDecoderContext pCtx); | 82 | int32_t WelsInitMemory (PWelsDecoderContext pCtx); |
| 61 | 83 | ||
| 62 | /* | 84 | /* |
| @@ -92,8 +92,9 @@ · 91 unmodified lines | |||
| 92 | #define LAYER_NUM_EXCHANGEABLE 1 | 92 | #define LAYER_NUM_EXCHANGEABLE 1 |
| 93 | 93 | ||
| 94 | #define MAX_NAL_UNIT_NUM_IN_AU 32 // predefined maximal number of NAL Units in an access unit | 94 | #define MAX_NAL_UNIT_NUM_IN_AU 32 // predefined maximal number of NAL Units in an access unit |
| 95 | #define MAX_ACCESS_UNIT_CAPACITY 1048576 // Maximal AU capacity in bytes: (1<<20) = 1024 KB predefined | 95 | #define MIN_ACCESS_UNIT_CAPACITY 1048576 // Min AU capacity in bytes: (1<<20) = 1024 KB predefined |
| 96 | #define BS_BUFFER_SIZE (MAX_ACCESS_UNIT_CAPACITY * 3) //for delay case, keep three AU size to prevent buffer overwrite | 96 | #define MAX_BUFFERED_NUM 3 //mamixum stored number of AU|packet to prevent overwrite |
| 97 | #define MAX_ACCESS_UNIT_CAPACITY 7077888 //Maximum AU size in bytes for level 5.2 for single frame | ||
| 97 | #define MAX_MACROBLOCK_CAPACITY 5000 //Maximal legal MB capacity, 15000 bits is enough | 98 | #define MAX_MACROBLOCK_CAPACITY 5000 //Maximal legal MB capacity, 15000 bits is enough |
| 98 | 99 | ||
| 99 | #endif//WELS_CONSTANCE_H__ | 100 | #endif//WELS_CONSTANCE_H__ |
| @@ -297,6 +297,57 @@ bool FillDefaultSliceHeaderExt (PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalEx · 296 unmodified lines | |||
| 297 | return true; | 297 | return true; |
| 298 | } | 298 | } |
| 299 | 299 | ||
| 300 | int32_t InitBsBuffer (PWelsDecoderContext pCtx) { | ||
| 301 | if (pCtx == NULL) | ||
| 302 | return ERR_INFO_INVALID_PTR; | ||
| 303 | |||
| 304 | pCtx->iMaxBsBufferSizeInByte = MIN_ACCESS_UNIT_CAPACITY * MAX_BUFFERED_NUM; | ||
| 305 | if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc (pCtx->iMaxBsBufferSizeInByte, | ||
| 306 | "pCtx->sRawData.pHead"))) == NULL) { | ||
| 307 | return ERR_INFO_OUT_OF_MEMORY; | ||
| 308 | } | ||
| 309 | pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead; | ||
| 310 | pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte; | ||
| 311 | return ERR_NONE; | ||
| 312 | } | ||
| 313 | |||
| 314 | int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) { | ||
| 315 | if (pCtx == NULL) | ||
| 316 | return ERR_INFO_INVALID_PTR; | ||
| 317 | int32_t iExpandStepShift = 1; | ||
| 318 | int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift)); | ||
| 319 | //allocate new bs buffer | ||
| 320 | uint8_t* pNewBsBuff = static_cast<uint8_t*> (WelsMalloc (iNewBuffLen, "pCtx->sRawData.pHead")); | ||
| 321 | if (pNewBsBuff == NULL) | ||
| 322 | return ERR_INFO_OUT_OF_MEMORY; | ||
| 323 | |||
| 324 | //Copy current buffer status to new buffer | ||
| 325 | memcpy (pNewBsBuff, pCtx->sRawData.pHead, pCtx->iMaxBsBufferSizeInByte); | ||
| 326 | pCtx->iMaxBsBufferSizeInByte = iNewBuffLen; | ||
| 327 | pCtx->sRawData.pStartPos = pNewBsBuff + (pCtx->sRawData.pStartPos - pCtx->sRawData.pHead); | ||
| 328 | pCtx->sRawData.pCurPos = pNewBsBuff + (pCtx->sRawData.pCurPos - pCtx->sRawData.pHead); | ||
| 329 | pCtx->sRawData.pEnd = pNewBsBuff + iNewBuffLen; | ||
| 330 | WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData.pHead"); | ||
| 331 | pCtx->sRawData.pHead = pNewBsBuff; | ||
| 332 | return ERR_NONE; | ||
| 333 | } | ||
| 334 | |||
| 335 | int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) { | ||
| 336 | if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { //exceeds max allowed data | ||
| 337 | WelsLog (pCtx, WELS_LOG_WARNING, "Max AU size exceeded. Allowed size = %d, current size = %d", MAX_ACCESS_UNIT_CAPACITY, | ||
| 338 | kiSrcLen); | ||
| 339 | pCtx->iErrorCode |= dsBitstreamError; | ||
| 340 | return ERR_INFO_INVALID_ACCESS; | ||
| 341 | } else if (kiSrcLen > pCtx->iMaxBsBufferSizeInByte / | ||
| 342 | MAX_BUFFERED_NUM) { //may lead to buffer overwrite, prevent it by expanding buffer | ||
| 343 | if (ExpandBsBuffer (pCtx, kiSrcLen)) { | ||
| 344 | return ERR_INFO_OUT_OF_MEMORY; | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | return ERR_NONE; | ||
| 349 | } | ||
| 350 | |||
| 300 | /* | 351 | /* |
| 301 | * WelsInitMemory | 352 | * WelsInitMemory |
| 302 | * Memory request for new introduced data | 353 | * Memory request for new introduced data |
| @@ -313,13 +364,8 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) { · 10 unmodified lines | |||
| 313 | if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU) != 0) | 364 | if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU) != 0) |
| 314 | return ERR_INFO_OUT_OF_MEMORY; | 365 | return ERR_INFO_OUT_OF_MEMORY; |
| 315 | 366 | ||
| 316 | if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc (BS_BUFFER_SIZE, | 367 | if (InitBsBuffer (pCtx) != 0) |
| 317 | "pCtx->sRawData->pHead"))) == NULL) { | ||
| 318 | return ERR_INFO_OUT_OF_MEMORY; | 368 | return ERR_INFO_OUT_OF_MEMORY; |
| 319 | } | ||
| 320 | pCtx->sRawData.pStartPos = | ||
| 321 | pCtx->sRawData.pCurPos = pCtx->sRawData.pHead; | ||
| 322 | pCtx->sRawData.pEnd = pCtx->sRawData.pHead + BS_BUFFER_SIZE; | ||
| 323 | 369 | ||
| 324 | pCtx->uiTargetDqId = (uint8_t) - 1; | 370 | pCtx->uiTargetDqId = (uint8_t) - 1; |
| 325 | pCtx->bEndOfStreamFlag = false; | 371 | pCtx->bEndOfStreamFlag = false; |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | |||
| 49 | 49 | ||
| 50 | //#include "macros.h" | 50 | //#include "macros.h" |
| 51 | #include "decoder.h" | 51 | #include "decoder.h" |
| 52 | #include "decoder_core.h" | ||
| 52 | 53 | ||
| 53 | extern "C" { | 54 | extern "C" { |
| 54 | #include "decoder_core.h" | 55 | #include "decoder_core.h" |
| @@ -322,11 +323,7 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, · 267 unmodified lines | |||
| 322 | const int kiSrcLen, | 323 | const int kiSrcLen, |
| 323 | unsigned char** ppDst, | 324 | unsigned char** ppDst, |
| 324 | SBufferInfo* pDstInfo) { | 325 | SBufferInfo* pDstInfo) { |
| 325 | if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY - MAX_MACROBLOCK_CAPACITY) {//prevent from residual reading overflow | 326 | if (CheckBsBuffer (m_pDecContext, kiSrcLen)) { |
| 326 | m_pDecContext->iErrorCode |= dsOutOfMemory; | ||
| 327 | IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO, | ||
| 328 | "max AU size exceeded. Allowed size = %d, current size = %d", | ||
| 329 | MAX_ACCESS_UNIT_CAPACITY - MAX_MACROBLOCK_CAPACITY, kiSrcLen); | ||
| 330 | return dsOutOfMemory; | 327 | return dsOutOfMemory; |
| 331 | } | 328 | } |
| 332 | if (kiSrcLen > 0 && kpSrc != NULL) { | 329 | if (kiSrcLen > 0 && kpSrc != NULL) { |