I'm trying to decode H264 stream to YUV data using FFmpeg, then convert YUV data to RGB data by LibYUV, finally paint it. But some strange points (dots) appear. How to fix it?
av_init_packet(&m_avpkt);
int cur_size;
uint8_t *cur_ptr;
while (true)
{
memset(outSampleBuffer, 0, IMAGE_BUFFER);
long ret = m_pInputPortInfo->pPacketPool->receivePacket(outSampleBuffer, info);
cur_size = info.size;
cur_ptr = (uint8_t *)outSampleBuffer;
if (m_de_context == NULL)
continue;
while (cur_size > 0)
{
int len = av_parser_parse2(
pCodecParser, m_de_context,
&m_avpkt.data, &m_avpkt.size,
cur_ptr, cur_size,
AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
cur_ptr += len;
cur_size -= len;
if (m_avpkt.size == 0)
continue;
int got_picture = 0;
int iOutLen = avcodec_decode_video2(m_de_context, m_de_frame, &got_picture, &m_avpkt);
if (got_picture != 0)
{
//YUV to RGB
//...
}
}
In order to find which step is wrong, I save the H264 data before using avcodec_decode_video2
then save the YUV data after decoding. I found all the H264 data is correct and the YUV data is wrong, which is decoded by P frames, I frames decoded data is ok. Here is how i save the YUV data:
int got_picture = 0;
int iOutLen = avcodec_decode_video2(m_de_context, m_de_frame, &got_picture, &m_avpkt);
if (got_picture != 0)
{
if (m_de_frame->format == AVPixelFormat::AV_PIX_FMT_YUV420P)
{
int y = m_de_frame->width*m_de_frame->height;
int u = y / 4;
int v = y / 4;
uint8_t* y_ptr = m_de_frame->data[0];
uint8_t* u_ptr = m_de_frame->data[1];
uint8_t* v_ptr = m_de_frame->data[2];
int yuvbufsize = y + u + v;
char *buf = new char[yuvbufsize];
memcpy(buf, y_ptr, y);
memcpy(buf + y, u_ptr, u);
memcpy(buf + y+u, v_ptr, v);
static int count = 0;
char yuvimgPath[MAX_PATH] = { 0 };
sprintf(yuvimgPath, "d:\\images\\de_%d.yuv", count);
FILE *fp1 = fopen(yuvimgPath, "wb");
fwrite(buf, 1, yuvbufsize, fp1);
fclose(fp1);
count++;
delete[]buf;
}
}