blob: f50ca118193aca3fce7eb051b72c8b37809cfa00 [file] [log] [blame]
pbos@webrtc.org29d58392013-05-16 12:08:03 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/video_engine/internal/video_send_stream.h"
12
13#include <vector>
14
15#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
16#include "webrtc/video_engine/include/vie_base.h"
17#include "webrtc/video_engine/include/vie_capture.h"
18#include "webrtc/video_engine/include/vie_codec.h"
19#include "webrtc/video_engine/include/vie_network.h"
20#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
21#include "webrtc/video_engine/new_include/video_send_stream.h"
22
23namespace webrtc {
24namespace internal {
25
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +000026VideoSendStream::VideoSendStream(newapi::Transport* transport,
27 webrtc::VideoEngine* video_engine,
28 const newapi::VideoSendStream::Config& config)
pbos@webrtc.org025f4f12013-06-05 11:33:21 +000029 : transport_(transport), config_(config) {
pbos@webrtc.org29d58392013-05-16 12:08:03 +000030
31 if (config_.codec.numberOfSimulcastStreams > 0) {
32 assert(config_.rtp.ssrcs.size() == config_.codec.numberOfSimulcastStreams);
33 } else {
34 assert(config_.rtp.ssrcs.size() == 1);
35 }
36
37 video_engine_base_ = ViEBase::GetInterface(video_engine);
38 video_engine_base_->CreateChannel(channel_);
39 assert(channel_ != -1);
40
41 rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine);
42 assert(rtp_rtcp_ != NULL);
43
44 assert(config_.rtp.ssrcs.size() == 1);
45 rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.ssrcs[0]);
46
47 capture_ = ViECapture::GetInterface(video_engine);
48 capture_->AllocateExternalCaptureDevice(capture_id_, external_capture_);
49 capture_->ConnectCaptureDevice(capture_id_, channel_);
50
51 network_ = ViENetwork::GetInterface(video_engine);
52 assert(network_ != NULL);
53
54 network_->RegisterSendTransport(channel_, *this);
55
56 codec_ = ViECodec::GetInterface(video_engine);
57 if (codec_->SetSendCodec(channel_, config_.codec) != 0) {
58 abort();
59 }
60}
61
62VideoSendStream::~VideoSendStream() {
63 network_->DeregisterSendTransport(channel_);
64 video_engine_base_->DeleteChannel(channel_);
65
66 capture_->DisconnectCaptureDevice(channel_);
67 capture_->ReleaseCaptureDevice(capture_id_);
68
69 video_engine_base_->Release();
70 capture_->Release();
71 codec_->Release();
72 network_->Release();
73 rtp_rtcp_->Release();
74}
75
76void VideoSendStream::PutFrame(const I420VideoFrame& frame,
pbos@webrtc.org9b303482013-05-23 12:37:11 +000077 uint32_t time_since_capture_ms) {
78 // TODO(pbos): frame_copy should happen after the VideoProcessingModule has
79 // resized the frame.
pbos@webrtc.org29d58392013-05-16 12:08:03 +000080 I420VideoFrame frame_copy;
81 frame_copy.CopyFrame(frame);
82
83 if (config_.pre_encode_callback != NULL) {
84 config_.pre_encode_callback->FrameCallback(&frame_copy);
85 }
86
87 ViEVideoFrameI420 vf;
88
89 // TODO(pbos): This represents a memcpy step and is only required because
90 // external_capture_ only takes ViEVideoFrameI420s.
91 vf.y_plane = frame_copy.buffer(kYPlane);
92 vf.u_plane = frame_copy.buffer(kUPlane);
93 vf.v_plane = frame_copy.buffer(kVPlane);
94 vf.y_pitch = frame.stride(kYPlane);
95 vf.u_pitch = frame.stride(kUPlane);
96 vf.v_pitch = frame.stride(kVPlane);
97 vf.width = frame.width();
98 vf.height = frame.height();
99
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000100 external_capture_->IncomingFrameI420(vf, frame.render_time_ms());
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000101
102 if (config_.local_renderer != NULL) {
103 config_.local_renderer->RenderFrame(frame, 0);
104 }
105}
106
107newapi::VideoSendStreamInput* VideoSendStream::Input() { return this; }
108
109void VideoSendStream::StartSend() {
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000110 if (video_engine_base_->StartSend(channel_) != 0)
111 abort();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000112}
113
114void VideoSendStream::StopSend() {
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000115 if (video_engine_base_->StopSend(channel_) != 0)
116 abort();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000117}
118
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000119bool VideoSendStream::SetTargetBitrate(
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000120 int min_bitrate,
121 int max_bitrate,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000122 const std::vector<SimulcastStream>& streams) {
123 return false;
124}
125
126void VideoSendStream::GetSendCodec(VideoCodec* send_codec) {
127 *send_codec = config_.codec;
128}
129
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000130int VideoSendStream::SendPacket(int /*channel*/,
131 const void* packet,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000132 int length) {
133 // TODO(pbos): Lock these methods and the destructor so it can't be processing
134 // a packet when the destructor has been called.
135 assert(length >= 0);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000136 bool success = transport_->SendRTP(static_cast<const uint8_t*>(packet),
137 static_cast<size_t>(length));
138 return success ? 0 : -1;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000139}
140
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000141int VideoSendStream::SendRTCPPacket(int /*channel*/,
142 const void* packet,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000143 int length) {
144 assert(length >= 0);
pbos@webrtc.orgaf8d5af2013-07-09 08:02:33 +0000145 bool success = transport_->SendRTCP(static_cast<const uint8_t*>(packet),
146 static_cast<size_t>(length));
147 return success ? 0 : -1;
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000148}
149
150} // namespace internal
151} // namespace webrtc