WebRtc libjingle_PeerConnection层(一) 显示本地视频
2015-08-13 15:28
471 查看
只做本地显示,在PeerConnection层调用流程比较简单。代码由Peerconnection_Client扣出来的。
1. 获得摄像头
cricket::VideoCapturer* OpenVideoCaptureDevice()
2. 设置Render
StartLocalRenderer(video_track);
3. 取并显示
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; }
相关文章推荐
- pkg-config工具的使用
- Tez compile, deploy and test
- Js性能问题
- DBCP
- Java初学--无限循环
- 继承中的二义性归属问题
- [转载] Hadoop和Hive单机环境搭建
- 使用观察者模式处理异常信息
- java设计模式之---工厂模式
- SpringMvc的xml文件的配置
- EasyUI datagrid数据表格--获取datagrid中选中行的数据
- 剖析XX联盟 - 英雄对象类
- SpringMVC启动一直卡的解决
- 使用 iscroll 实现焦点图无限循环
- jQuery插件手把手教会(一)
- eclipse 快捷键大全,eclipse查找类,文件,添加注释
- Android开发必知--几种不同对话框的实现
- ChartControl饼状图自定义调色板
- solr添加IK分词和自己定义词库
- Cat VS Dog---hdu3829(最大独立集)