Log in

View Full Version : Errors decoding h.264 RTP stream from GXV-3000


sheridan
15th August 2007, 16:15
Hi
I'm having problems decoding rtp stream from Grandstream GXV-3000 videophone.
First frame (NAL=5, IDR picture) decodes almost perfect (some blurry on the top though). Next few non-IDR frames also decoded but then decoder returns error (-1). There is no SPS or PPS packets between decoded packets and errors. Anyone can comment problem?

Below is parts of the code:


----- Init decoder -----

m_codec = avcodec_find_decoder(CODEC_ID_H264);
m_context = avcodec_alloc_context();
m_frame = avcodec_alloc_frame();
m_context->flags|= CODEC_FLAG_TRUNCATED;
m_context->flags |= CODEC_FLAG_EMU_EDGE;
if (avcodec_open(m_context, m_codec) < 0) { ... }




----- Decode(void* buf, size_t bufsize, size_t& retsize)-----
{
static bool started = false;

int bytesDecoded = 0;
int frameFinished = 0;
int frame_size = 0;
char* z = NULL;
retsize = 0;

if ((!started) || (bufsize == 0)) {
return NULL;
}


uint8_t nal = ((char*)buf)[0];
uint8_t type = (nal & 0x1f);
uint8_t start_sequence[]= {0, 0, 1};

Log(__FUNCTION__," -----[NAL:0x%x]------- this=%p -> %d bytes...",type,this,bufsize);

if (((type == 7) || (type == 8)) && (bufsize < 128))
{
LogData((type == 7) ? "SPS buffer" : "PPS buffer",(char*)buf,bufsize);
if (type == 7)
{
m_newSPS = true;
memcpy(m_SPS+sizeof(start_sequence),buf,bufsize);
m_SPSsize = bufsize+sizeof(start_sequence);
bytesDecoded = avcodec_decode_video(m_context,m_frame,&frameFinished,(uint8_t*)m_SPS,bufsize+sizeof(start_sequence));
Log(__FUNCTION__,"SPS DECODED:%d,finished:%d",bytesDecoded,frameFinished);
} else
{
m_newPPS = true;
memcpy(m_PPS+sizeof(start_sequence),buf,bufsize);
m_PPSsize = bufsize+sizeof(start_sequence);

bytesDecoded = avcodec_decode_video(m_context,m_frame,&frameFinished,(uint8_t*)m_PPS,bufsize+sizeof(start_sequence));
Log(__FUNCTION__,"PPS DECODED:%d,finished:%d",bytesDecoded,frameFinished);
}
if (m_newSPS && m_newPPS)
{
/*
if (m_context->extradata)
av_free(m_context->extradata);
m_context->extradata_size = m_SPSsize+m_PPSsize;
m_context->extradata = (uint8_t*)av_malloc(m_context->extradata_size);
memcpy(m_context->extradata,m_SPS,m_SPSsize);
memcpy(m_context->extradata+m_SPSsize,m_PPS,m_PPSsize);
LogData((type == 7) ? "SPS":"PPS",(char*)m_context->extradata,m_context->extradata_size);
*/
m_newSPS = m_newPPS = false;

started = true;
}
retsize = 0;
return NULL;
}

if (!started)
{
return NULL;
}

z = new char[bufsize+sizeof(start_sequence)];
memcpy(z,&start_sequence,sizeof(start_sequence));
memcpy(z+sizeof(start_sequence),buf,bufsize);

bytesDecoded = avcodec_decode_video(m_context,m_frame,&frameFinished,(uint8_t*)z,bufsize+sizeof(start_sequence));

delete z;

if (bytesDecoded < 0)
{
Log(__FUNCTION__,"ERROR %d decoding packet",bytesDecoded);
} else {
if (frameFinished)
{
frame_size = m_context->width*m_context->height;
retsize = frame_size*3/2;
z = new char[retsize];
memcpy(z,m_frame->data[0],frame_size);
memcpy(z+frame_size,m_frame->data[1],frame_size/4);
memcpy(z+frame_size+frame_size/4,m_frame->data[2],frame_size/4);
Log(__FUNCTION__,"returning decoded buffer %d bytes at %p",retsize,z);
return (void*)z;

} else
{
// we have no frame, but packet decoded
}
}
retsize = 0;
return NULL;

------------------------------------------------------