返回

国标视频播放卡顿优化:强制获取I帧解决无I帧导致视频无法播放

闲谈

对于视频播放而言,I帧至关重要。I帧是关键帧,它包含了整个视频帧的所有信息,是视频解码的基础。如果没有I帧,视频解码器就无法正确解码视频,从而导致视频播放卡顿甚至无法播放。

国标协议强制获取I帧

在国标协议中,有一个强制获取I帧的命令。这个命令可以强制流媒体服务器发送一个I帧。在每次拉流之前执行这个命令,就可以保证获取到一个I帧。

GB28181_CMD_IVS_GET_STREAM_INFO = 0x1019
void GB28181_Client_Send_Cmd_GetStreamInfo(int iSocketFd, const char* pszSvrIP, WORD wSvrPort, const char* pszDevID,const char* pszChn, int iStreamType)
{
    if (iSocketFd < 0)
    {
        return;
    }
    int iLen = 0;
    char pBuf[1024] = {0};

    pBuf[iLen++] = 0x80;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    pBuf[iLen++] = 0x10;
    pBuf[iLen++] = 0x19;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    iLen += GB28181_FillDevChn(pszDevID, pszChn, pBuf + iLen);

    pBuf[iLen++] = iStreamType;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;
    pBuf[iLen++] = 0x00;

    iLen += GB28181_FillTail(pBuf + iLen);

    printf("iLen=%d\n", iLen);

    if (send(iSocketFd, pBuf, iLen, 0) < 0)
    {
        printf("iSendData failed!!\n");
        return;
    }
}

执行这个命令后,流媒体服务器就会发送一个I帧。这样,视频解码器就可以正确解码视频,从而解决视频播放卡顿甚至无法播放的问题。

注意事项

需要注意的是,强制获取I帧可能会增加网络流量。因此,在实际应用中,需要根据实际情况权衡利弊,选择是否使用强制获取I帧的优化方案。