webrtc自定义captuer

之前有一个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 
#include 
#include 
#include 
#include 
#include 
#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 
 
  
#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 
#include 
 
  
//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;
}
 
  

你可能感兴趣的:(c++)