【问题标题】:FFmpeg: Decoding AVPackets received from UDP socketFFmpeg:解码从 UDP 套接字接收的 AVPackets
【发布时间】:2018-06-19 18:25:34
【问题描述】:

我正在尝试通过 UDP 将使用 FFmpeg 编码的视频帧从 Unity 游戏流式传输到客户端 UI。具体来说,我从服务器发送 AVPackets(据我了解,其中包含压缩帧),然后在客户端提取如下:

inline UDPpacket* SDLGameClient::receiveData()
{
    if(SDLNet_UDP_Recv(socket, packet))
        return packet;
    else
        return NULL;
}

int main()
{
    ...
    // Initialize UDP
    ...
    UDPpacket *udpPacket;

    int i = 0;

    for(;;)
    {
        udpPacket = client->receiveData();

        if(udpPacket != nullptr)
        {
            i++;
            std::cout << "Packet " << i << " received!" << std::endl;

            AVPacket packet;
            av_init_packet(&packet);

            packet.data = new uint8_t[udpPacket->len];
            memcpy(packet.data, udpPacket->data, udpPacket->len);
            packet.size = udpPacket->len;

            ...

为了实现联网,我使用了 SDL_net 库。分段、发送和接收数据包似乎没有任何问题。我的问题是,如何解码传入的 AVPackets 并将 Unity 中记录的帧流式传输到客户端? 我知道我需要使用avcodec_send_packetavcodec_receive_frame 进行解码(因为在许多示例解码代码中使用的avcodec_decode_video2 已被弃用),但是当我这样做时:

int ret = avcodec_send_packet(codecContext, &packet);
if(ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
    std::cout << "avcodec_send_packet: " << ret << std::endl;
else
{
    while(ret >= 0)
    {
        ret = avcodec_receive_frame(codecContext, frame);
        if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            std::cout << "avcodec_receive_frame: " << ret << std::endl;

        std::cout << "Frame: " << codecContext->frame_number << std::endl;
    }
}

av_packet_unref(packet);

ret 总是返回一个负值 (-22),所以可能是 AVPackets 出了点问题,或者我发送帧的速度太快了,我真的不知道:/

提前感谢您的帮助!

【问题讨论】:

    标签: c++ ffmpeg


    【解决方案1】:

    -22 表示-EINVAL无效参数。您通常可以查看 ffmpeg 错误日志消息以获取更多详细信息。

    我的猜测是你的数据包仍然是碎片的,但 avcodec_send_packet() 期望 AVPacket 总是包含一个完整的帧。根据所涉及的编解码器,您应该考虑使用 AVParser 来恢复成帧或在 UDP 分片之前对数据包进行成帧,这样您就可以自己恢复成帧。

    【讨论】:

    • 是的,这确实是问题所在。使用 av_parser_parse2() 解析数据包后,现在一切正常。非常感谢您的提示:)
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 2013-03-18
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多