ffmpeg打开RTSP慢的解决方法

记录一下ffmpeg打开海康NVR的RTSP总是开始耗时太长 竟达2/3秒之久. 代码工程

开始以为是rtsp_transport这里拖慢的

    av_dict_set(&opts, "rtsp_transport", "tcp", 0);     //设置tcp or udp
    av_dict_set(&opts, "stimeout", "3000000", 0);       //设置超时3秒

看来不是的,这里对延迟是有处理机制. 调试才发现

avformat_find_stream_info(pFormatCtx, NULL)

耗时很是严重,查找资料 发现中间做了不少的事,一气呵成. 

在WIN下貌似不做这个处理一样能处理.速度上去了

播放如下:

int CGdiPlay::run()
{
    hdcDes = GetDC(m_hWnd);
    hdcSrc = CreateCompatibleDC(hdcDes);
    packet = av_packet_alloc();
    CalcVideoWH(m_hWnd);

    ::CoInitialize(NULL);
    while (bStateFlag)
    {
        if (packet == NULL)
        {
            packet = av_packet_alloc();
            av_usleep(20 * 1000);
            continue;
        }
        if (av_read_frame(pFormatCtx, packet) >= 0)
        {
            if (packet->stream_index == vindex)
            {
                //下面处理size
                GetClientRect(m_hWnd, &rc);
                if (rc.left != screenRect.left || rc.right != screenRect.right || rc.top != screenRect.top || rc.bottom != screenRect.bottom)
                    CalcVideoWH(m_hWnd);
                if (avcodec_send_packet(pCodecCtx, packet) == 0)
                {
                    if (avcodec_receive_frame(pCodecCtx, pFrame) == 0)
                    {
                        sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
                            pFrameRGB->data, pFrameRGB->linesize);
                        hBitmap = CreateDIBSection(hdcSrc, &bmpinfo, DIB_RGB_COLORS, &pbit, NULL, 0);
                        GetObject(hBitmap, sizeof(BITMAP), &bmp);
                        memcpy(pbit, out_bufRgb, (sW)* (sH) * 4);
                        SelectObject(hdcSrc, hBitmap);
                        BitBlt(hdcDes, 0, 0, sW, sH, hdcSrc, 0, 0, SRCCOPY);
                        DeleteObject(hBitmap);
                        av_usleep(40 * 1000);
                    }
                    else
                        continue;
                }
                else
                    break;
            }
        }
        av_packet_unref(packet);
    }
    avformat_close_input(&pFormatCtx);
    av_packet_unref(packet);
    ::CoUninitialize();
    return 0;
}

int CGdiPlay::play(string filepath)
{
    if (bStateFlag)
        stop();
    av_register_all();
    pFormatCtx = avformat_alloc_context();
    if (avformat_open_input(&pFormatCtx, filepath.c_str(), NULL, NULL) < 0)
        return 0;
    //很卡
    //if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
    //    return 0;
    for (int i = 0; i < (int)pFormatCtx->nb_streams; i++)
    {
        if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
            vindex = i;
        if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
            aindex = i;
    }
    pCodecCtx = avcodec_alloc_context3(NULL);
    if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[vindex]->codecpar) < 0)
        av_log(NULL, AV_LOG_ERROR, "video avcodec_parameters_to_context faild");
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if (pCodec == NULL)
        return 0;
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
        return 0;
    //解码线程开始
    bStateFlag = true;
    m_th = std::thread(std::bind(&CGdiPlay::run, this));
    m_th.detach();      //线程后台运行
    return 1;
}

秒开CCTV的流链接

ffmpeg打开RTSP慢的解决方法_第1张图片

 

你可能感兴趣的:(ffmpeg,流媒体,C++,ffmpeg,视频处理,rtsp,音频编码解码)