blob: adcf818b40acbadca967a87e37761d5d00e546d8 [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
26VideoSendStream::VideoSendStream(
pbos@webrtc.org9b303482013-05-23 12:37:11 +000027 newapi::Transport* transport,
28 webrtc::VideoEngine* video_engine,
pbos@webrtc.org29d58392013-05-16 12:08:03 +000029 const newapi::VideoSendStreamConfig& send_stream_config)
30 : transport_(transport), config_(send_stream_config) {
31
32 if (config_.codec.numberOfSimulcastStreams > 0) {
33 assert(config_.rtp.ssrcs.size() == config_.codec.numberOfSimulcastStreams);
34 } else {
35 assert(config_.rtp.ssrcs.size() == 1);
36 }
37
38 video_engine_base_ = ViEBase::GetInterface(video_engine);
39 video_engine_base_->CreateChannel(channel_);
40 assert(channel_ != -1);
41
42 rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine);
43 assert(rtp_rtcp_ != NULL);
44
45 assert(config_.rtp.ssrcs.size() == 1);
46 rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.ssrcs[0]);
47
48 capture_ = ViECapture::GetInterface(video_engine);
49 capture_->AllocateExternalCaptureDevice(capture_id_, external_capture_);
50 capture_->ConnectCaptureDevice(capture_id_, channel_);
51
52 network_ = ViENetwork::GetInterface(video_engine);
53 assert(network_ != NULL);
54
55 network_->RegisterSendTransport(channel_, *this);
56
57 codec_ = ViECodec::GetInterface(video_engine);
58 if (codec_->SetSendCodec(channel_, config_.codec) != 0) {
59 abort();
60 }
61}
62
63VideoSendStream::~VideoSendStream() {
64 network_->DeregisterSendTransport(channel_);
65 video_engine_base_->DeleteChannel(channel_);
66
67 capture_->DisconnectCaptureDevice(channel_);
68 capture_->ReleaseCaptureDevice(capture_id_);
69
70 video_engine_base_->Release();
71 capture_->Release();
72 codec_->Release();
73 network_->Release();
74 rtp_rtcp_->Release();
75}
76
77void VideoSendStream::PutFrame(const I420VideoFrame& frame,
pbos@webrtc.org9b303482013-05-23 12:37:11 +000078 uint32_t time_since_capture_ms) {
79 // TODO(pbos): frame_copy should happen after the VideoProcessingModule has
80 // resized the frame.
pbos@webrtc.org29d58392013-05-16 12:08:03 +000081 I420VideoFrame frame_copy;
82 frame_copy.CopyFrame(frame);
83
84 if (config_.pre_encode_callback != NULL) {
85 config_.pre_encode_callback->FrameCallback(&frame_copy);
86 }
87
88 ViEVideoFrameI420 vf;
89
90 // TODO(pbos): This represents a memcpy step and is only required because
91 // external_capture_ only takes ViEVideoFrameI420s.
92 vf.y_plane = frame_copy.buffer(kYPlane);
93 vf.u_plane = frame_copy.buffer(kUPlane);
94 vf.v_plane = frame_copy.buffer(kVPlane);
95 vf.y_pitch = frame.stride(kYPlane);
96 vf.u_pitch = frame.stride(kUPlane);
97 vf.v_pitch = frame.stride(kVPlane);
98 vf.width = frame.width();
99 vf.height = frame.height();
100
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000101 external_capture_->IncomingFrameI420(vf, frame.render_time_ms());
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000102
103 if (config_.local_renderer != NULL) {
104 config_.local_renderer->RenderFrame(frame, 0);
105 }
106}
107
108newapi::VideoSendStreamInput* VideoSendStream::Input() { return this; }
109
110void VideoSendStream::StartSend() {
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000111 if (video_engine_base_->StartSend(channel_) != 0)
112 abort();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000113}
114
115void VideoSendStream::StopSend() {
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000116 if (video_engine_base_->StopSend(channel_) != 0)
117 abort();
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000118}
119
120void VideoSendStream::GetSendStatistics(
121 std::vector<newapi::SendStatistics>* statistics) {
122 // TODO(pbos): Implement
123}
124
125bool VideoSendStream::SetTargetBitrate(
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000126 int min_bitrate,
127 int max_bitrate,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000128 const std::vector<SimulcastStream>& streams) {
129 return false;
130}
131
132void VideoSendStream::GetSendCodec(VideoCodec* send_codec) {
133 *send_codec = config_.codec;
134}
135
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000136int VideoSendStream::SendPacket(int /*channel*/,
137 const void* packet,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000138 int length) {
139 // TODO(pbos): Lock these methods and the destructor so it can't be processing
140 // a packet when the destructor has been called.
141 assert(length >= 0);
142 return transport_->SendRTP(packet, static_cast<size_t>(length)) ? 0 : -1;
143}
144
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000145int VideoSendStream::SendRTCPPacket(int /*channel*/,
146 const void* packet,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000147 int length) {
148 assert(length >= 0);
149 return transport_->SendRTCP(packet, static_cast<size_t>(length)) ? 0 : -1;
150}
151
152} // namespace internal
153} // namespace webrtc