在UDP(MPEGTS)中流式传输时FFMPEG损坏帧

时间:2018-04-08 08:03:11

标签: c++ ffmpeg libavcodec libav

我正在开发一个屏幕流媒体程序,到现在为止,我可以将我的屏幕捕获并编码成一个完美的视频。 但是,每当我尝试通过局域网对其进行流式传输,并使用Mplayer进行播放时,它就可以在简单的桌面(文本文档等)中运行,但是当我尝试播放视频时,声明的框架已损坏,直到我退出视频(此视频导致帧损坏最严重https://www.youtube.com/watch?v=1La4QzGeaaQ&t=230s

我不确定为什么在流式传输时,我使用youtube视频损坏了框架,但将其保存到文件中时(将URL从udp://192.168.1.xxx:YYYY更改为文件名C:\ Test。 ts)根本没有损坏的框架。  我的Mplayer日志:

`V:   0.0 1563/1563 51% 43%  0.0% 0 0
[h264 @ 0000000001d04940]Invalid NAL unit 0, skipping.
[h264 @ 0000000001d04940]error while decoding MB 23 51, bytestream -64
[h264 @ 0000000001d04940]concealing 2066 DC, 2066 AC, 2066 MV errors in I frame
V:   0.0 1564/1564 51% 43%  0.0% 0 0
[h264 @ 0000000001d04940]concealing 7598 DC, 7598 AC, 7598 MV errors in P frame
V:   0.0 1652/1652 50% 43%  0.0% 0 0
[h264 @ 0000000001d04940]Invalid NAL unit 0, skipping.
[h264 @ 0000000001d04940]error while decoding MB 26 49, bytestream -55
[h264 @ 0000000001d04940]concealing 2303 DC, 2303 AC, 2303 MV errors in I frame
V:   0.0 1653/1653 50% 43%  0.0% 0 0
[h264 @ 0000000001d04940]concealing 7727 DC, 7727 AC, 7727 MV errors in P frame
V:   0.0 1741/1741 49% 43%  0.0% 0 0
[h264 @ 0000000001d04940]Invalid NAL unit 0, skipping.
[h264 @ 0000000001d04940]error while decoding MB 65 62, bytestream -57
[h264 @ 0000000001d04940]concealing 704 DC, 704 AC, 704 MV errors in I frame
V:   0.0 1742/1742 49% 43%  0.0% 0 0`

流初始化代码

static void Stream_ini(const char *Url, AVFormatContext *&ofmt_ctx, AVCodec *codec, AVCodecContext *c, AVStream *&out_stream)
{
    int ret;


    avformat_alloc_output_context2(&ofmt_ctx, NULL, "mpegts", Url);
    out_stream = avformat_new_stream(ofmt_ctx, codec)
    out_stream->codec = c;
    av_dump_format(ofmt_ctx, 0, Url, 1);


    if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
        out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
    if (!(ofmt_ctx->flags & AVFMT_NOFILE))
    {
        ret = avio_open(&ofmt_ctx->pb, Url, AVIO_FLAG_WRITE);
        if (ret < 0)
        {
            printf("Could not open output URL '%s'", Url);
            return;
        }
    }


    ret = avformat_write_header(ofmt_ctx, NULL);

    if (ret < 0)
    {
        printf("Error occurred when opening output URL\n");
        return;
    }


}

此代码将获取捕获的屏幕并将其发送到编码器:

ScreenCap.load_screen_data(inFrame,timmer)  // this will capture screen and return the time and AVFrame for encoding
sws_scale(ctx, inFrame->data, inFrame->linesize, 0,c->height, frame->data, frame->linesize);

frame->pts = (timmer - first_frame_time) / fps;
EncodeToPkT(c, frame, pkt, ofmt_ctx,out_stream);

av_frame_free(&inFrame);

然后AVFrame将使用avcodec_send_frame()发送到编码器以获取分组数据,并使用av_interleaved_write_frame()通过LAN将其流式传输。

为简单起见,删除了所有错误检查

此外,这是编码器的AVCodecContex设置:

c->bit_rate = 15000000;
c->width = 1920;
c->height = 1080;
c->time_base = AVRational{ 1, 90 };
c->framerate = AVRational{ 90, 1 };
c->gop_size = 90;
c->max_b_frames = 0;
c->pix_fmt = AV_PIX_FMT_RGB0;

我还注意到它只会在我增加编码器比特率(15 MBIT)时发生,但是当它降低到(10 MBIT)时它会发生更少。当它降低到2 MBIT时,损坏的框架不再发生,但质量非常糟糕 我使用以下方法测试LAN中的流媒体:PC - &gt;电缆 - &gt;笔记本电脑,PC-&gt;无线 - &gt;笔记本电脑,PC-&gt;虚拟PC,仅限PC(在程序和Mplayer中输入PC IP地址),都得到了相同的结果。

我还测试我的DXGICap.load_screen_data函数,使其输出原始图像,并且根本没有损坏的图像

有没有人知道为什么。

感谢Nam。

1 个答案:

答案 0 :(得分:1)

这不仅仅是使用UDP的情况,即。您将无序接收数据包,然后解码将失败/抱怨?尝试使用TCP,看看会发生什么。

相关问题