我尝试使用FFmpeg将H264流解码为YUV数据,然后通过LibYUV将YUV数据转换为RGB数据,最后绘制它。但是出现了一些奇怪的点(点)。如何解决?
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
//...
}
}
为了找出哪个步骤错误,我在使用avcodec_decode_video2
之前保存H264数据,然后在解码后保存YUV数据。我发现所有H264数据都是正确的并且YUV数据是错误的,这是由P帧解码的,I帧解码数据是可以的。以下是我如何保存YUV数据:
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;
}
}