blob: 790045ea051d1ef9ebd33f4573c7c1b2d231210a [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.org025f4f12013-06-05 11:33:21 +000029 const newapi::VideoSendStream::Config& config)
30 : transport_(transport), config_(config) {
pbos@webrtc.org29d58392013-05-16 12:08:03 +000031
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
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000120bool VideoSendStream::SetTargetBitrate(
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000121 int min_bitrate,
122 int max_bitrate,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000123 const std::vector<SimulcastStream>& streams) {
124 return false;
125}
126
127void VideoSendStream::GetSendCodec(VideoCodec* send_codec) {
128 *send_codec = config_.codec;
129}
130
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000131int VideoSendStream::SendPacket(int /*channel*/,
132 const void* packet,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000133 int length) {
134 // TODO(pbos): Lock these methods and the destructor so it can't be processing
135 // a packet when the destructor has been called.
136 assert(length >= 0);
137 return transport_->SendRTP(packet, static_cast<size_t>(length)) ? 0 : -1;
138}
139
pbos@webrtc.org9b303482013-05-23 12:37:11 +0000140int VideoSendStream::SendRTCPPacket(int /*channel*/,
141 const void* packet,
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000142 int length) {
143 assert(length >= 0);
144 return transport_->SendRTCP(packet, static_cast<size_t>(length)) ? 0 : -1;
145}
146
147} // namespace internal
148} // namespace webrtc