schweinsz
23rd September 2009, 23:05
I am coding a directshow-based h.264 decoder. I connect my decoder to the haali media splitter to play media files with h.264 contents. Most are fine. But some files including all avi-format files are not. When I render a avi file in graphedit, it connected to my decoder by the haali media splitter, but when I play it, the graphedit crashed.
I wrote some test code to locate the error and found the following function never run.
where does the error occur?
HRESULT CDiAVC::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
bool retstatus = S_OK, isPure264 = 0;
CheckPointer(pIn,E_POINTER);
CheckPointer(pOut,E_POINTER);
if(handle == 0)
return S_FALSE;
if(pIn->IsDiscontinuity() == S_OK)
{
ll_flush_h264decoder(handle);
pOut->SetDiscontinuity(S_OK);
}
/*if (pIn->IsPreroll() == S_OK) //preroll samples should not be displayed
return S_OK;*/
ll_OutPutFrame *pDsplFrm = &outputFrm;
u_int8 *pBitstrm;
s_int32 totLength;
pIn->GetPointer(&pBitstrm);
bitStrm.pBitStream = pBitstrm;
totLength = pIn->GetActualDataLength();
if(((u_int32*)pBitstrm)[0] == 0x01000000)
isPure264 = 1;
while (totLength > 0)
{
u_int32 cur_len = (pBitstrm[0]<<24)+(pBitstrm[1]<<16)+(pBitstrm[2]<<8)+pBitstrm[3];
if(!isPure264) ((u_int32*)pBitstrm)[0] = 0x01000000;
bitStrm.bs_length = cur_len+4;
if(isPure264)
bitStrm.bs_length = totLength;
else if((u_int32)(bitStrm.bs_length) > totLength)
break;
writToFilew("dcss.264", (char*)(bitStrm.pBitStream), bitStrm.bs_length);
//the input buffer must include one slice at least
s_int32 status = ll_dec_h264decoder(handle, &bitStrm);
if(isPure264)
{
bitStrm.pBitStream += bitStrm.used_bytes;
totLength -= bitStrm.used_bytes;
}
else
{
bitStrm.pBitStream += (cur_len+4);
totLength -= (cur_len+4);
}
pBitstrm = bitStrm.pBitStream;
if(pDsplFrm->p_y_plane)
{
REFERENCE_TIME lasttime,dummy;
pIn->GetTime(&lasttime,&dummy);
if(!m_LastTime || (pIn->IsDiscontinuity() == S_OK) || lasttime < 0)
{
if(lasttime > 0 )
{
m_LastTime=lasttime;
}
else
{
m_LastTime+=m_FrameTime;
}
pOut->SetTime(NULL,NULL);
goto WriteYUVCurrPic;
}
REFERENCE_TIME endtime = m_LastTime + m_FrameTime;
pOut->SetTime(&m_LastTime,&endtime);
m_LastTime = endtime;
WriteYUVCurrPic:
u_int8 *dest_buffer;
if(pOut->GetPointer(&dest_buffer)!=S_OK)
return S_FALSE;
writeI420Tofile(dest_buffer, pDsplFrm);
pOut->SetActualDataLength(pDsplFrm->img_height * pDsplFrm->img_width * 3>>1);
retstatus = S_OK;
}
}
return retstatus;
}
I wrote some test code to locate the error and found the following function never run.
where does the error occur?
HRESULT CDiAVC::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
bool retstatus = S_OK, isPure264 = 0;
CheckPointer(pIn,E_POINTER);
CheckPointer(pOut,E_POINTER);
if(handle == 0)
return S_FALSE;
if(pIn->IsDiscontinuity() == S_OK)
{
ll_flush_h264decoder(handle);
pOut->SetDiscontinuity(S_OK);
}
/*if (pIn->IsPreroll() == S_OK) //preroll samples should not be displayed
return S_OK;*/
ll_OutPutFrame *pDsplFrm = &outputFrm;
u_int8 *pBitstrm;
s_int32 totLength;
pIn->GetPointer(&pBitstrm);
bitStrm.pBitStream = pBitstrm;
totLength = pIn->GetActualDataLength();
if(((u_int32*)pBitstrm)[0] == 0x01000000)
isPure264 = 1;
while (totLength > 0)
{
u_int32 cur_len = (pBitstrm[0]<<24)+(pBitstrm[1]<<16)+(pBitstrm[2]<<8)+pBitstrm[3];
if(!isPure264) ((u_int32*)pBitstrm)[0] = 0x01000000;
bitStrm.bs_length = cur_len+4;
if(isPure264)
bitStrm.bs_length = totLength;
else if((u_int32)(bitStrm.bs_length) > totLength)
break;
writToFilew("dcss.264", (char*)(bitStrm.pBitStream), bitStrm.bs_length);
//the input buffer must include one slice at least
s_int32 status = ll_dec_h264decoder(handle, &bitStrm);
if(isPure264)
{
bitStrm.pBitStream += bitStrm.used_bytes;
totLength -= bitStrm.used_bytes;
}
else
{
bitStrm.pBitStream += (cur_len+4);
totLength -= (cur_len+4);
}
pBitstrm = bitStrm.pBitStream;
if(pDsplFrm->p_y_plane)
{
REFERENCE_TIME lasttime,dummy;
pIn->GetTime(&lasttime,&dummy);
if(!m_LastTime || (pIn->IsDiscontinuity() == S_OK) || lasttime < 0)
{
if(lasttime > 0 )
{
m_LastTime=lasttime;
}
else
{
m_LastTime+=m_FrameTime;
}
pOut->SetTime(NULL,NULL);
goto WriteYUVCurrPic;
}
REFERENCE_TIME endtime = m_LastTime + m_FrameTime;
pOut->SetTime(&m_LastTime,&endtime);
m_LastTime = endtime;
WriteYUVCurrPic:
u_int8 *dest_buffer;
if(pOut->GetPointer(&dest_buffer)!=S_OK)
return S_FALSE;
writeI420Tofile(dest_buffer, pDsplFrm);
pOut->SetActualDataLength(pDsplFrm->img_height * pDsplFrm->img_width * 3>>1);
retstatus = S_OK;
}
}
return retstatus;
}