JavaCV OpenCV FFmpeg接受Rtmp视频流解析为Mat对象

优化后网络状况好1s以内打开

秒开部分 JavaCV OpenCV FFmpeg接受Rtmp视频流解析为Mat对象_第1张图片

 /**
     * 抓取视频帧(默认跳过音频帧和空帧)
     * @param url -视频源(rtsp/rtmp/hls/文件等等)
     * @param fmt - 像素格式,比如AV_PIX_FMT_BGR24
     * @return
     * @throws IOException
     */
    public void grabVideoFrame(String url,int fmt) throws IOException {


        long statr = System.currentTimeMillis();

        // Open video file
        AVFormatContext pFormatCtx=openInput(url);

        System.out.println("openInput耗时:"+(System.currentTimeMillis()-statr)+"ms");

        long second = System.currentTimeMillis();
        // Retrieve stream information
        // 设置500k能保证高清视频也能读取到关键帧
//
//        pFormatCtx.probesize(300 * 1024);
//
        pFormatCtx.probesize(1024L);

//        pFormatCtx.max_analyze_duration(3*1000000);
        pFormatCtx.max_analyze_duration(100L);


        pFormatCtx.flush_packets(1);

        pFormatCtx=findStreamInfo(pFormatCtx);


        System.out.println("findStreamInfo耗时:"+(System.currentTimeMillis()-second)+"ms");

        // Dump information about file onto standard error
        //av_dump_format(pFormatCtx, 0, url, 0);

        //Find a video stream
        int videoStream=findVideoStreamIndex(pFormatCtx);
        AVCodecContext pCodecCtx =findVideoStream(pFormatCtx,videoStream);


        // Find the decoder for the video stream
        pCodecCtx= findAndOpenCodec(pCodecCtx);

        // Allocate video frame
        AVFrame pFrame = av_frame_alloc();
        //Allocate an AVFrame structure
        AVFrame pFrameRGB = av_frame_alloc();

        width = pCodecCtx.width();
        height = pCodecCtx.height();
        pFrameRGB.width(width);
        pFrameRGB.height(height);
        pFrameRGB.format(fmt);

        // Determine required buffer size and allocate buffer
        int numBytes = avpicture_get_size(fmt, width, height);

        SwsContext sws_ctx = sws_getContext(width, height, pCodecCtx.pix_fmt(), width, height,fmt, SWS_BILINEAR, null, null, (DoublePointer) null);

        BytePointer buffer = new BytePointer(av_malloc(numBytes));
        // Assign appropriate parts of buffer to image planes in pFrameRGB
        // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
        // of AVPicture
        avpicture_fill(new AVPicture(pFrameRGB), buffer, fmt, width, height);


        System.out.println("初始化时间为:"+(System.currentTimeMillis()-statr)+"ms");
        while (true) {

            AVPacket packet = new AVPacket();
            int[] frameFinished = new int[1];
            try {
                // Read frames and save first five frames to disk
                while (av_read_frame(pFormatCtx, packet) >= 0) {
                    // Is this a packet from the video stream?
                    if (packet.stream_index() == videoStream) {
                        // Decode video frame
                        avcodec_decode_video2(pCodecCtx, pFrame, frameFinished, packet);
                        // Did we get a video frame?
                        if (frameFinished != null&&frameFinished[0] != 0) {
                            // Convert the image from its native format to BGR
                            sws_scale(sws_ctx, pFrame.data(), pFrame.linesize(), 0, height, pFrameRGB.data(),pFrameRGB.linesize());
                            //Convert BGR to ByteBuffer
                            ByteBuffer byteBuffer = saveFrame(pFrameRGB, width, height);

                            BufferedImage image= JavaImgConverter.BGR2BufferedImage(byteBuffer,width,height);
                            BufImgToMat bufImgToMat = new BufImgToMat(image, image.getType(), CvType.CV_8UC3);
                            Mat mat = bufImgToMat.getMat();
                            HighGui.imshow("rtmp", mat);
                            HighGui.waitKey(1);
                        }
                    }
                    // Free the packet that was allocated by av_read_frame
                    av_free_packet(packet);
                }

            }finally {
                //Don't free buffer
//   av_free(buffer);
                av_free(pFrameRGB);// Free the RGB image
                av_free(pFrame);// Free the YUV frame
                sws_freeContext(sws_ctx);//Free SwsContext
                avcodec_close(pCodecCtx);// Close the codec
                avformat_close_input(pFormatCtx);// Close the video file
            }
        }

    }

你可能感兴趣的:(JAVA)