H264 decoding using ffmpeg with strange points in the decoded image

610 views Asked by At

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;
    }
}
0

There are 0 answers