您的位置:首页 > 其它

WebRtc libjingle_PeerConnection层(一) 显示本地视频

2015-08-13 15:28 471 查看
只做本地显示,在PeerConnection层调用流程比较简单。代码由Peerconnection_Client扣出来的。

1. 获得摄像头
cricket::VideoCapturer* OpenVideoCaptureDevice()

2. 设置Render
StartLocalRenderer(video_track);

3. 取并显示

//#include "talk/examples/peerconnection/client/conductor.h"

#include <utility>
#include <vector>

#ifdef WIN32
#include <Windows.h>

#endif

//#include "opencv2\opencv.hpp"

#include "talk/app/webrtc/videosourceinterface.h"
#include "talk/app/webrtc/mediastreaminterface.h"
#include "talk/app/webrtc/peerconnectioninterface.h"
#include "talk/media/devices/devicemanager.h"
//#include "talk/app/webrtc/test/fakeconstraints.h"
#include "talk/media/base/videorenderer.h"
#include "talk/media/base/videoframe.h"
#include "webrtc/base/common.h"
#include "webrtc/base/json.h"
#include "webrtc/base/logging.h"

//#pragma comment(lib, "opencv_world300d.lib")

#define DTLS_ON  true
#define DTLS_OFF false

// Names used for a IceCandidate JSON object.
const char kCandidateSdpMidName[] = "sdpMid";
const char kCandidateSdpMlineIndexName[] = "sdpMLineIndex";
const char kCandidateSdpName[] = "candidate";

// Names used for a SessionDescription JSON object.
const char kSessionDescriptionTypeName[] = "type";
const char kSessionDescriptionSdpName[] = "sdp";

const char kAudioLabel[] = "audio_label";
const char kVideoLabel[] = "video_label";
const char kStreamLabel[] = "stream_label";

// A little helper class to make sure we always to proper locking and
// unlocking when working with VideoRenderer buffers.
template <typename T>
class AutoLock {
public:
explicit AutoLock(T* obj) : obj_(obj) { obj_->Lock(); }
~AutoLock() { obj_->Unlock(); }
protected:
T* obj_;
};

class VideoRenderer : public webrtc::VideoRendererInterface {
public:
VideoRenderer(HWND wnd, int width, int height,
webrtc::VideoTrackInterface* track_to_render);
virtual ~VideoRenderer();

void Lock() {
::EnterCriticalSection(&buffer_lock_);
}

void Unlock() {
::LeaveCriticalSection(&buffer_lock_);
}

// VideoRendererInterface implementation
virtual void SetSize(int width, int height);
virtual void RenderFrame(const cricket::VideoFrame* frame);

const BITMAPINFO& bmi() const { return bmi_; }
const uint8* image() const { return image_.get(); }

protected:
enum {
SET_SIZE,
RENDER_FRAME,
};

HWND wnd_;
BITMAPINFO bmi_;
rtc::scoped_ptr<uint8[]> image_;
CRITICAL_SECTION buffer_lock_;
rtc::scoped_refptr<webrtc::VideoTrackInterface> rendered_track_;
};

//
// VideoRenderer
//
VideoRenderer::VideoRenderer(
HWND wnd, int width, int height,
webrtc::VideoTrackInterface* track_to_render)
: wnd_(wnd), rendered_track_(track_to_render) {
::InitializeCriticalSection(&buffer_lock_);
ZeroMemory(&bmi_, sizeof(bmi_));
bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi_.bmiHeader.biPlanes = 1;
bmi_.bmiHeader.biBitCount = 32;
bmi_.bmiHeader.biCompression = BI_RGB;
bmi_.bmiHeader.biWidth = width;
bmi_.bmiHeader.biHeight = -height;
bmi_.bmiHeader.biSizeImage = width * height *
(bmi_.bmiHeader.biBitCount >> 3);
rendered_track_->AddRenderer(this);
}

VideoRenderer::~VideoRenderer() {
rendered_track_->RemoveRenderer(this);
::DeleteCriticalSection(&buffer_lock_);
}

void VideoRenderer::SetSize(int width, int height) {
AutoLock<VideoRenderer> lock(this);

if (width == bmi_.bmiHeader.biWidth && height == bmi_.bmiHeader.biHeight) {
return;
}

bmi_.bmiHeader.biWidth = width;
bmi_.bmiHeader.biHeight = -height;
bmi_.bmiHeader.biSizeImage = width * height *
(bmi_.bmiHeader.biBitCount >> 3);
image_.reset(new uint8[bmi_.bmiHeader.biSizeImage]);
}
int ii = 0;
void VideoRenderer::RenderFrame(
const cricket::VideoFrame* video_frame) {
if (!video_frame)
return;

{
AutoLock<VideoRenderer> lock(this);

const cricket::VideoFrame* frame =
video_frame->GetCopyWithRotationApplied();

SetSize(static_cast<int>(frame->GetWidth()),
static_cast<int>(frame->GetHeight()));

ASSERT(image_.get() != NULL);
frame->ConvertToRgbBuffer(cricket::FOURCC_ARGB,
image_.get(),
bmi_.bmiHeader.biSizeImage,
bmi_.bmiHeader.biWidth *
bmi_.bmiHeader.biBitCount / 8);
}
InvalidateRect(wnd_, NULL, TRUE);
}

rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory_;

rtc::scoped_ptr<VideoRenderer> local_renderer_;

HWND wnd = NULL;

cricket::VideoCapturer* OpenVideoCaptureDevice() {
rtc::scoped_ptr<cricket::DeviceManagerInterface> dev_manager(
cricket::DeviceManagerFactory::Create());
if (!dev_manager->Init()) {
LOG(LS_ERROR) << "Can't create device manager";
return NULL;
}
std::vector<cricket::Device> devs;
if (!dev_manager->GetVideoCaptureDevices(&devs)) {
LOG(LS_ERROR) << "Can't enumerate video devices";
return NULL;
}
std::vector<cricket::Device>::iterator dev_it = devs.begin();
cricket::VideoCapturer* capturer = NULL;
for (; dev_it != devs.end(); ++dev_it) {
capturer = dev_manager->CreateVideoCapturer(*dev_it);
if (capturer != NULL)
break;
}
return capturer;
}

void StartLocalRenderer(webrtc::VideoTrackInterface* local_video) {
local_renderer_.reset(new VideoRenderer(wnd, 1, 1, local_video));
}

void AddStreams() {

rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
peer_connection_factory_->CreateAudioTrack(
kAudioLabel, peer_connection_factory_->CreateAudioSource(NULL)));

rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
peer_connection_factory_->CreateVideoTrack(
kVideoLabel,
peer_connection_factory_->CreateVideoSource(OpenVideoCaptureDevice(),
NULL)));

StartLocalRenderer(video_track);
}

bool InitializePeerConnection() {
ASSERT(peer_connection_factory_.get() == NULL);
ASSERT(peer_connection_.get() == NULL);

peer_connection_factory_ = webrtc::CreatePeerConnectionFactory();

if (!peer_connection_factory_.get()) {
return false;
}

AddStreams();
return peer_connection_.get() != NULL;
}

void Show()
{
VideoRenderer* local_renderer = local_renderer_.get();
if (local_renderer)
{
AutoLock<VideoRenderer> local_lock(local_renderer);
const BITMAPINFO& bmi = local_renderer->bmi();
const uint8* image = local_renderer->image();
//printf("height=%d  width=%d  biSizeImage=%d \n", bmi.bmiHeader.biHeight, bmi.bmiHeader.biWidth, bmi.bmiHeader.biSizeImage);
//GetBitmapFromScreen("c:\\aa.bmp", (BITMAPINFO)bmi, (uint8*)image);
int rows = abs(bmi.bmiHeader.biHeight);;
int cols = bmi.bmiHeader.biWidth;
static int i = 0;
printf("%d\n", i++);
//cv::Mat img(rows, cols, CV_8UC4, (void*)image, 0U);
//cv::imshow("Video Capture", img);
//cvWaitKey(1);
}
}

void ThreadProc(LPVOID lpParam)
{
while (true)
{
Show();
Sleep(33);
}
}

int main()
{
getchar();

//wnd = FindWindow(L"ConsoleWindowClass", NULL);

if (!InitializePeerConnection())
printf("error\n");

DWORD dwThreadId;

CreateThread(
NULL,//defaultsecurityattributes
0,//usedefaultstacksize
(LPTHREAD_START_ROUTINE)ThreadProc,//threadfunction
NULL,//argumenttothreadfunction
0,//usedefaultcreationflags
&dwThreadId);//returnsthethreadidentifier

getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: