0

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?

Decoded Image

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;
    }
}
ShaoQing
  • 13
  • 4
  • If you dump the decoded yuv data directly to a file and play it with an appropriate raw yuv player, does it look correct? That tells you whether the bug is in the decoding or in the yuv-rgb conversion. Assuming it is in the yuv-rgb conversion (which is what I suspect), can you show that code also? – Ronald S. Bultje Sep 15 '17 at 14:25
  • I add some details in the question, i did some tests followed by your advise, it is really strange, it seems something is wrong after decoding.and I frame is totally correct, and p frames has the dots. @RonaldS.Bultje – ShaoQing Sep 16 '17 at 15:02

0 Answers0