blob: c81825871cd09243611e4b24cc8afba612d39056 [file] [log] [blame]
pbos@webrtc.orgdc8c8832013-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(
27 newapi::Transport* transport, webrtc::VideoEngine* video_engine,
28 const newapi::VideoSendStreamConfig& send_stream_config)
29 : transport_(transport), config_(send_stream_config) {
30
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,
77 int32_t delta_capture_time) {
78 I420VideoFrame frame_copy;
79 frame_copy.CopyFrame(frame);
80
81 if (config_.pre_encode_callback != NULL) {
82 config_.pre_encode_callback->FrameCallback(&frame_copy);
83 }
84
85 ViEVideoFrameI420 vf;
86
87 // TODO(pbos): This represents a memcpy step and is only required because
88 // external_capture_ only takes ViEVideoFrameI420s.
89 vf.y_plane = frame_copy.buffer(kYPlane);
90 vf.u_plane = frame_copy.buffer(kUPlane);
91 vf.v_plane = frame_copy.buffer(kVPlane);
92 vf.y_pitch = frame.stride(kYPlane);
93 vf.u_pitch = frame.stride(kUPlane);
94 vf.v_pitch = frame.stride(kVPlane);
95 vf.width = frame.width();
96 vf.height = frame.height();
97
98 external_capture_->IncomingFrameI420(vf, frame.timestamp());
99
100 if (config_.local_renderer != NULL) {
101 config_.local_renderer->RenderFrame(frame, 0);
102 }
103}
104
105newapi::VideoSendStreamInput* VideoSendStream::Input() { return this; }
106
107void VideoSendStream::StartSend() {
108 if (video_engine_base_->StartSend(channel_) != 0) abort();
109}
110
111void VideoSendStream::StopSend() {
112 if (video_engine_base_->StopSend(channel_) != 0) abort();
113}
114
115void VideoSendStream::GetSendStatistics(
116 std::vector<newapi::SendStatistics>* statistics) {
117 // TODO(pbos): Implement
118}
119
120bool VideoSendStream::SetTargetBitrate(
121 int min_bitrate, int max_bitrate,
122 const std::vector<SimulcastStream>& streams) {
123 return false;
124}
125
126void VideoSendStream::GetSendCodec(VideoCodec* send_codec) {
127 *send_codec = config_.codec;
128}
129
130int VideoSendStream::SendPacket(int /*channel*/, const void* packet,
131 int length) {
132 // TODO(pbos): Lock these methods and the destructor so it can't be processing
133 // a packet when the destructor has been called.
134 assert(length >= 0);
135 return transport_->SendRTP(packet, static_cast<size_t>(length)) ? 0 : -1;
136}
137
138int VideoSendStream::SendRTCPPacket(int /*channel*/, const void* packet,
139 int length) {
140 assert(length >= 0);
141 return transport_->SendRTCP(packet, static_cast<size_t>(length)) ? 0 : -1;
142}
143
144} // namespace internal
145} // namespace webrtc