📄 umc_vc1_video_decoder.cpp
字号:
if(m_dataBuffer==NULL)
{
Close();
return UMC_ERR_ALLOC;
}
}
memset(m_dataBuffer,0,bufferSize+4);
m_pContext->m_pBufferStart = (Ipp8u*)m_dataBuffer;
m_pContext->m_bitstream.pBitstream = (Ipp32u*)(m_pContext->m_pBufferStart);
//for slice, field start code
if(m_stCodes == NULL)
{
m_stCodes = (MediaDataEx::_MediaDataEx *)ippsMalloc_8u(START_CODE_NUMBER*2*sizeof(Ipp32s)+sizeof(MediaDataEx::_MediaDataEx));
}
memset(m_stCodes, 0, (START_CODE_NUMBER*2*sizeof(Ipp32s)+sizeof(MediaDataEx::_MediaDataEx)));
m_stCodes->count = 0;
m_stCodes->index = 0;
m_stCodes->bstrm_pos = 0;
m_stCodes->offsets = (Ipp32u*)((Ipp8u*)m_stCodes +
sizeof(MediaDataEx::_MediaDataEx));
m_stCodes->values = (Ipp32u*)((Ipp8u*)m_stCodes->offsets +
START_CODE_NUMBER*sizeof( Ipp32u));
if(m_frameData == NULL)
m_frameData = new UMC::MediaDataEx();
m_frameData->SetBufferPointer(m_dataBuffer, bufferSize);
m_frameData->SetDataSize(bufferSize);
m_frameData->SetExData(m_stCodes);
return UMC_OK;
}
Status VC1VideoDecoder::GetStartCodes (MediaData* in, MediaDataEx* out, Ipp32u* readSize)
{
Ipp8u* readPos = (Ipp8u*)in->GetDataPointer();
Ipp32u readBufSize = (Ipp32u)in->GetDataSize();
Ipp8u* readBuf = (Ipp8u*)in->GetDataPointer();
Ipp8u* currFramePos = (Ipp8u*)out->GetBufferPointer();
Ipp32u frameSize = 0;
Ipp32u frameBufSize = (Ipp32u)out->GetBufferSize();
MediaDataEx::_MediaDataEx *stCodes = out->GetExData();
Ipp32u size = 0;
Ipp8u* ptr = NULL;
Ipp32u readDataSize = 0;
Ipp32u zeroNum = 0;
Ipp32u a = 0x0000FF00 | (*readPos);
Ipp32u b = 0xFFFFFFFF;
Ipp32u FrameNum = 0;
stCodes->count = 0;
memset(stCodes->offsets, 0,START_CODE_NUMBER*sizeof(Ipp32s));
memset(stCodes->values, 0,START_CODE_NUMBER*sizeof(Ipp32s));
while(readPos < (readBuf + readBufSize))
{
//find sequence of 0x000001 or 0x000003
while(!( b == 0x00000001 || b == 0x00000003 )
&&(readPos < (readBuf + readBufSize)))
{
readPos++;
a = (a<<8)| (Ipp32s)(*readPos);
b = a & 0x00FFFFFF;
}
//check end of read buffer
if(readPos < (readBuf + readBufSize - 1))
{
if(*readPos == 0x01)
{
if((*(readPos + 1) == VC1_Slice) || (*(readPos + 1) == VC1_Field)
/*|| (FrameNum)*/)
{
readPos+=2;
ptr = readPos - 5;
//trim zero bytes
while ( (*ptr==0) && (ptr > readBuf) )
ptr--;
//slice or field size
size = (Ipp32u)(ptr - readBuf - readDataSize+1);
if(frameSize + size > frameBufSize)
return UMC_ERR_NOT_ENOUGH_BUFFER;
ippsCopy_8u(readBuf + readDataSize, currFramePos, size);
currFramePos = currFramePos + size;
frameSize = frameSize + size;
zeroNum = frameSize - 4*((frameSize)/4);
if(zeroNum!=0)
zeroNum = 4 - zeroNum;
memset(currFramePos, 0, zeroNum);
//set write parameters
currFramePos = currFramePos + zeroNum;
frameSize = frameSize + zeroNum;
stCodes->offsets[stCodes->count] = frameSize;
stCodes->values[stCodes->count] = ((*(readPos-1))<<24) + ((*(readPos-2))<<16) + ((*(readPos-3))<<8) + (*(readPos-4));
readDataSize = (Ipp32u)(readPos - readBuf - 4);
a = 0x00010b00 |(Ipp32s)(*readPos);
b = a & 0x00FFFFFF;
zeroNum = 0;
stCodes->count++;
}
else
{
if(FrameNum)
{
readPos+=2;
ptr = readPos - 5;
//trim zero bytes
while ( (*ptr==0) && (ptr > readBuf) )
ptr--;
//slice or field size
size = (Ipp32u)(readPos - readBuf - readDataSize - 4);
if(frameSize + size > frameBufSize)
return UMC_ERR_NOT_ENOUGH_BUFFER;
ippsCopy_8u(readBuf + readDataSize, currFramePos, size);
//currFramePos = currFramePos + size;
frameSize = frameSize + size;
stCodes->offsets[stCodes->count] = frameSize;
stCodes->values[stCodes->count] = ((*(readPos-1))<<24) + ((*(readPos-2))<<16) + ((*(readPos-3))<<8) + (*(readPos-4));
stCodes->count++;
out->SetDataSize(frameSize);
readDataSize = readDataSize + size;
*readSize = readDataSize;
return UMC_OK;
}
else
{
//beginning of frame
readPos++;
a = 0x00000100 |(Ipp32s)(*readPos);
b = a & 0x00FFFFFF;
stCodes->offsets[stCodes->count] = (Ipp32u)(0);
stCodes->values[stCodes->count] = ((*(readPos))<<24) + ((*(readPos-1))<<16) + ((*(readPos-2))<<8) + (*(readPos-3));
stCodes->count++;
zeroNum = 0;
FrameNum++;
}
}
}
else //if(*readPos == 0x03)
{
//000003
if((*(readPos + 1) < 0x04))
{
size = (Ipp32u)(readPos - readBuf - readDataSize);
if(frameSize + size > frameBufSize)
return UMC_ERR_NOT_ENOUGH_BUFFER;
ippsCopy_8u(readBuf + readDataSize, currFramePos, size);
frameSize = frameSize + size;
currFramePos = currFramePos + size;
zeroNum = 0;
readPos++;
a = (a<<8)| (Ipp32s)(*readPos);
b = a & 0x00FFFFFF;
readDataSize = readDataSize + size + 1;
}
else
{
readPos++;
a = (a<<8)| (Ipp32s)(*readPos);
b = a & 0x00FFFFFF;
}
}
}
else
{
//end of stream
size = (Ipp32u)(readPos- readBuf - readDataSize);
if(frameSize + size > frameBufSize)
{
return UMC_ERR_NOT_ENOUGH_BUFFER;
}
ippsCopy_8u(readBuf + readDataSize, currFramePos, size);
out->SetDataSize(frameSize + size);
readDataSize = readDataSize + size;
*readSize = readDataSize;
return UMC_OK;
}
}
return UMC_OK;
}
void VC1VideoDecoder::GetFrameSize(MediaData* in)
{
Ipp32s frameSize = 0;
Ipp8u* ptr = m_pContext->m_pBufferStart;
Ipp32u i = 0;
Ipp32u* offset = m_pContext->m_Offsets;
Ipp32u* value = m_pContext->m_values;
m_pContext->m_FrameSize = (Ipp32u)in->GetDataSize();
if(m_pContext->m_seqLayerHeader->PROFILE == VC1_PROFILE_ADVANCED)
{
value++;
i++;
while((*value == 0x0B010000)||(*value == 0x0C010000))
{
value ++;
i++;
}
if(*value != 0x00000000)
{
m_pContext->m_FrameSize = offset[i];
}
}
else
{
if ((*m_pContext->m_bitstream.pBitstream&0xFF) == 0xC5) // sequence header
frameSize = 36; // size of seq header for .rcv format
else
{
frameSize = ((*(ptr))<<24) + ((*(ptr + 1))<<16) + ((*(ptr + 2))<<8) + *(ptr + 3);
frameSize &= 0x0fffffff;
frameSize += 8;
}
}
}
Status VC1VideoDecoder::VC1DecodeFrame(VC1VideoDecoder* pDec,MediaData* in, VideoData* out_data)
{
if (pDec != this)
return UMC_ERR_INIT;
Status umcRes = UMC_OK;
Status umcWRes = UMC_OK;
VC1FrameDescriptor *pCurrDescriptor = NULL;
Ipp32u i;
m_pStore->GetReadyDS(&pCurrDescriptor);
if (NULL == pCurrDescriptor)
throw vc1_exception(internal_pipeline_error);
try // check input frame for valid
{
umcRes = pCurrDescriptor->preProcData(m_pContext->m_pBufferStart,
(Ipp32u)in->GetDataSize(),
m_lFrameCount,
m_bIsWMPSplitter);
ProcessPrevFrame(in, out_data);
pCurrDescriptor->m_pContext->typeOfPreviousFrame = m_pContext->typeOfPreviousFrame;
}
catch (vc1_exception ex)
{
if (invalid_stream == ex.get_exception_type())
{
if (fast_err_detect == vc1_except_profiler::GetEnvDescript().m_Profile)
m_pStore->AddInvalidPerformedDS(pCurrDescriptor);
else if (fast_decoding == vc1_except_profiler::GetEnvDescript().m_Profile)
m_pStore->ResetPerformedDS(pCurrDescriptor);
// for smart decoding we should decode and reconstrcu frame according to standart pipeline
}
}
//if (umcRes != UMC_ERR_INVALID_STREAM)
if (!pCurrDescriptor->isEmpty())//check descriptor correctness
pCurrDescriptor->VC1FrameDescriptor::processFrame(m_pContext->m_Offsets,m_pContext->m_values);
//else
//{
// m_pStore->ResetDS(pCurrDescriptor);
// --m_lFrameCount;
//}
if (umcRes == UMC_WRN_INVALID_STREAM)
m_bIsWarningStream = true;
// for Intensity compensation om multi-threading model
if (VC1_IS_REFERENCE(pCurrDescriptor->m_pContext->m_picLayerHeader->PTYPE))
{
m_pContext->m_bIntensityCompensation = pCurrDescriptor->m_pContext->m_bIntensityCompensation;
}
//else
// pCurrDescriptor->m_pContext->m_bIntensityCompensation = m_pContext->m_bIntensityCompensation;
if (!pCurrDescriptor->isEmpty())//check descriptor correctness
{
if (m_pContext->m_seqLayerHeader->PROFILE == VC1_PROFILE_ADVANCED)
m_pStore->SetDstForFrameAdv(pCurrDescriptor,&m_iRefFramesDst,&m_iBFramesDst);
else
m_pStore->SetDstForFrame(pCurrDescriptor,&m_iRefFramesDst,&m_iBFramesDst);
}
// Wake Upppp
m_pStore->WakeUP();
if (m_lFrameCount == 1)
{
m_pStore->StartDecoding();
m_bLastFrameNeedDisplay = true;
for (i = 1;i < m_iThreadDecoderNum;i += 1)
m_pdecoder[i]->StartProcessing();
}
STATISTICS_END_TIME(m_timeStatistics->ThreadPrep_StartTime,
m_timeStatistics->ThreadPrep_EndTime,
m_timeStatistics->ThreadPrep_TotalTime);
if ((m_pStore->GetProcFramesNumber() == m_iMaxFramesInProcessing)&&
(umcRes != UMC_ERR_INVALID_STREAM))
{
m_bIsFrameToOut = true;
m_pdecoder[0]->processMainThread(); // need to change - special function to 0-th decoder
}
else
m_bIsFrameToOut = false;
if (VC1_IS_REFERENCE(pCurrDescriptor->m_pContext->m_picLayerHeader->PTYPE))
m_pContext->typeOfPreviousFrame = pCurrDescriptor->m_pContext->m_picLayerHeader->FCM;
if (m_bIsFrameToOut)
{
if (m_pStore->GetPerformedDS(&pCurrDescriptor))
{
if (!pCurrDescriptor->isDescriptorValid())
{
umcRes = UMC_ERR_FAILED;
}
else
{
if (VC1_IS_REFERENCE(pCurrDescriptor->m_pContext->m_InitPicLayer->PTYPE))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -