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 | 233 | SVlcTable sVlcTable; // vlc table |
| 234 | 234 | |
| 235 | 235 | SBitStringAux sBs; |
| 236 | + int32_t iMaxBsBufferSizeInByte; //actual memory size for BS buffer | |
| 236 | 237 | |
| 237 | 238 | /* Global memory external */ |
| 238 | 239 | |
| @@ -48,6 +48,28 @@ · 47 unmodified lines | ||
| 48 | 48 | #include "codec_def.h" |
| 49 | 49 | |
| 50 | 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 | 75 | * WelsInitMemory |
| @@ -56,7 +78,7 @@ namespace WelsDec { · 2 unmodified lines | ||
| 56 | 78 | * rbsp_au_buffer, cur_dq_layer_ptr and ref_dq_layer_ptr in MB info cache. |
| 57 | 79 | * return: |
| 58 | 80 | * 0 - success; otherwise returned error_no defined in error_no.h. |
| 59 | −*/ | |
| 81 | + */ | |
| 60 | 82 | int32_t WelsInitMemory (PWelsDecoderContext pCtx); |
| 61 | 83 | |
| 62 | 84 | /* |
| @@ -92,8 +92,9 @@ · 91 unmodified lines | ||
| 92 | 92 | #define LAYER_NUM_EXCHANGEABLE 1 |
| 93 | 93 | |
| 94 | 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 | |
| 96 | −#define BS_BUFFER_SIZE (MAX_ACCESS_UNIT_CAPACITY * 3) //for delay case, keep three AU size to prevent buffer overwrite | |
| 95 | +#define MIN_ACCESS_UNIT_CAPACITY 1048576 // Min AU capacity in bytes: (1<<20) = 1024 KB predefined | |
| 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 | 98 | #define MAX_MACROBLOCK_CAPACITY 5000 //Maximal legal MB capacity, 15000 bits is enough |
| 98 | 99 | |
| 99 | 100 | #endif//WELS_CONSTANCE_H__ |
| @@ -297,6 +297,57 @@ bool FillDefaultSliceHeaderExt (PSliceHeaderExt pShExt, PNalUnitHeaderExt pNalEx · 296 unmodified lines | ||
| 297 | 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 | 352 | * WelsInitMemory |
| 302 | 353 | * Memory request for new introduced data |
| @@ -313,13 +364,8 @@ int32_t WelsInitMemory (PWelsDecoderContext pCtx) { · 10 unmodified lines | ||
| 313 | 364 | if (MemInitNalList (&pCtx->pAccessUnitList, MAX_NAL_UNIT_NUM_IN_AU) != 0) |
| 314 | 365 | return ERR_INFO_OUT_OF_MEMORY; |
| 315 | 366 | |
| 316 | − if ((pCtx->sRawData.pHead = static_cast<uint8_t*> (WelsMalloc (BS_BUFFER_SIZE, | |
| 317 | − "pCtx->sRawData->pHead"))) == NULL) { | |
| 367 | + if (InitBsBuffer (pCtx) != 0) | |
| 318 | 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 | 370 | pCtx->uiTargetDqId = (uint8_t) - 1; |
| 325 | 371 | pCtx->bEndOfStreamFlag = false; |
| @@ -49,6 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | //#include "macros.h" |
| 51 | 51 | #include "decoder.h" |
| 52 | +#include "decoder_core.h" | |
| 52 | 53 | |
| 53 | 54 | extern "C" { |
| 54 | 55 | #include "decoder_core.h" |
| @@ -322,11 +323,7 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, · 267 unmodified lines | ||
| 322 | 323 | const int kiSrcLen, |
| 323 | 324 | unsigned char** ppDst, |
| 324 | 325 | SBufferInfo* pDstInfo) { |
| 325 | − if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY - MAX_MACROBLOCK_CAPACITY) {//prevent from residual reading overflow | |
| 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); | |
| 326 | + if (CheckBsBuffer (m_pDecContext, kiSrcLen)) { | |
| 330 | 327 | return dsOutOfMemory; |
| 331 | 328 | } |
| 332 | 329 | if (kiSrcLen > 0 && kpSrc != NULL) { |