织梦CMS - 轻松建站从此开始!

罗索

webrtc自定义captuer

jackyhwei 发布于 2021-06-23 09:27 点击:次 
之前有一个MJPG格式的usb摄像头老是获取不到数据,我以为是captuer的问题,于是就考虑从自定义captuer入手,结果后来还是从webrtc内部结局了,这个capture就没用了
TAG: WebRTC  图像采集  

之前有一个MJPG格式的usb摄像头老是获取不到数据,我以为是captuer的问题,于是就考虑从自定义captuer入手,结果后来还是从webrtc内部结局了,这个capture就没用了

特此开源,里面用到了opencv

头文件

/* ---------------------------------------------------------------------------

** This software is in the public domain, furnished "as is", without technical

** support, and with no warranty, express or implied, as to its usefulness for

** any purpose.

**

** rtspvideocapturer.h

**

** -------------------------------------------------------------------------*/

#pragma once

#include <string.h>

#include <vector>

#include <queue>

#include <thread>

#include <mutex>

#include <condition_variable>

#include "opencv2/core/core.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "webrtc/base/thread.h"

#include "webrtc/media/base/codec.h"

#include "webrtc/media/base/videocapturer.h"

#include "webrtc/media/engine/internaldecoderfactory.h"

#include "webrtc/video_decoder.h"

using namespace cv;

class OpenvcCameraCallback

{

public:

    virtual void onData(Mat frame)=0;

    int width;

    int height;

};

class CaptureThread:public rtc::Thread

{

public:

    CaptureThread();

    OpenvcCameraCallback* callback;

    void Run();

};

class USBVideoCapturer : public cricket::VideoCapturer, public OpenvcCameraCallback, public rtc::Thread

{

    public:

        USBVideoCapturer(const std::string & uri, const std::map<std::string,std::string> & opts);

        virtual ~USBVideoCapturer();

        // overide rtc::Thread

        virtual void Run();

        void onData(Mat frame);

        // overide cricket::VideoCapturer

        virtual cricket::CaptureState Start(const cricket::VideoFormat& format);

        virtual void Stop();

        virtual bool GetPreferredFourccs(std::vector<unsigned int>* fourccs);

        virtual bool IsScreencast() const { return false; };

        virtual bool IsRunning() { return this->capture_state() == cricket::CS_RUNNING; }

       

        void ConvertThread();

    private:

        CaptureThread* captureThread;

};

源文件

/* ---------------------------------------------------------------------------

** This software is in the public domain, furnished "as is", without technical

** support, and with no warranty, express or implied, as to its usefulness for

** any purpose.

**

** rtspvideocapturer.cpp

**

** -------------------------------------------------------------------------*/

#include <chrono>

#include "webrtc/base/timeutils.h"

#include "webrtc/base/logging.h"

#include "webrtc/modules/video_coding/h264_sprop_parameter_sets.h"

#include "webrtc/api/video/i420_buffer.h"

#include "webrtc/modules/video_coding/codecs/h264/include/h264.h"

#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"

#include "libyuv/video_common.h"

#include "libyuv/convert.h"

#include "usbvideocapturer.h"

#include <QDebug>

#include <windows.h>

//OpenvcCameraCallback

CaptureThread::CaptureThread()

{

    callback=NULL;

}

void CaptureThread::Run()

{

    VideoCapture capture(0);//如果是笔记本,0打开的是自带的摄像头,1 打开外接的相机

    int w = capture.get(CV_CAP_PROP_FRAME_WIDTH);

    int h = capture.get(CV_CAP_PROP_FRAME_HEIGHT);

    callback->width=w;

    callback->height=h;

    cv::Mat frame;

    while (capture.isOpened())

    {

        capture >> frame;

        callback->onData(frame);

    }

}

USBVideoCapturer::USBVideoCapturer(const std::string & uri, const std::map<std::string,std::string> & opts)

{

    captureThread=new CaptureThread();

    captureThread->callback=this;

}

USBVideoCapturer::~USBVideoCapturer()

{

}

void USBVideoCapturer::onData(Mat frame)

{

    qDebug()<<QString("reveive data,width is:%1,height is:%2").arg(width).arg(height);

    int stride_y = width;

    int stride_uv = (width + 1) / 2;

    int target_width = width;

    int target_height = height;

    qDebug()<<"in onData 1";

    // Setting absolute height (in case it was negative).

    // In Windows, the image starts bottom left, instead of top left.

    // Setting a negative source height, inverts the image (within LibYuv).

    // TODO(nisse): Use a pool?

    rtc::scoped_refptr<webrtc::I420Buffer> buffer = webrtc::I420Buffer::Create(

        target_width, abs(target_height), stride_y, stride_uv, stride_uv);

    qDebug()<<"in onData 2";

    

    /*cv::Mat rgbImg(cy, cx,CV_8UC3);

    memcpy(frame.data, rgbImg.data, width*height);

    cv::cvtColor(yuvImg, rgbImg, CV_M);*/

    

    

    int conversionResult = webrtc::ConvertToI420(webrtc::kARGB, (uint8_t*)frame.data, 0, 0,  // No cropping

        width, height, (size_t)width*height,webrtc::kVideoRotation_0, buffer.get());

    qDebug()<<"in onData 3";

    if (conversionResult < 0)

    {

      qDebug()<< "Failed to convert capture frame from type to I420.";

    }

    qDebug()<<"in onData 4";

    webrtc::VideoFrame captureFrame(buffer, 0, rtc::TimeMillis(),webrtc::kVideoRotation_0);

    qDebug()<<"in onData 5";

    //captureFrame.set_ntp_time_ms(captureTime);

    this->OnFrame(captureFrame, width, height);

}

cricket::CaptureState USBVideoCapturer::Start(const cricket::VideoFormat& format)

{

    SetCaptureFormat(&format);

    SetCaptureState(cricket::CS_RUNNING);

    rtc::Thread::Start();

    return cricket::CS_RUNNING;

}

void USBVideoCapturer::Stop()

{

    rtc::Thread::Stop();

    SetCaptureFormat(NULL);

    SetCaptureState(cricket::CS_STOPPED);

}

void USBVideoCapturer::Run()

{

    captureThread->Start();

}

bool USBVideoCapturer::GetPreferredFourccs(std::vector<unsigned int>* fourccs)

{

    return true;

}

(fanhenghui)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/202106/17838.html]
本文出处:CSDN博客 作者:fanhenghui 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
相关文章
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容