blob: f3441a05bff18318690395c4378cf1b5543c8d32 [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_receive_stream.h"
12
13#include <cassert>
14#include <cstdlib>
15
16#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
17#include "webrtc/system_wrappers/interface/clock.h"
18#include "webrtc/video_engine/include/vie_base.h"
19#include "webrtc/video_engine/include/vie_capture.h"
20#include "webrtc/video_engine/include/vie_codec.h"
21#include "webrtc/video_engine/include/vie_network.h"
22#include "webrtc/video_engine/include/vie_render.h"
23#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
24#include "webrtc/video_engine/new_include/video_receive_stream.h"
25
26namespace webrtc {
27namespace internal {
28
29VideoReceiveStream::VideoReceiveStream(
30 webrtc::VideoEngine* video_engine,
pbos@webrtc.org025f4f12013-06-05 11:33:21 +000031 const newapi::VideoReceiveStream::Config& config,
pbos@webrtc.org29d58392013-05-16 12:08:03 +000032 newapi::Transport* transport)
33 : transport_(transport), config_(config) {
34 video_engine_base_ = ViEBase::GetInterface(video_engine);
35 // TODO(mflodman): Use the other CreateChannel method.
36 video_engine_base_->CreateChannel(channel_);
37 assert(channel_ != -1);
38
39 rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine);
40 assert(rtp_rtcp_ != NULL);
41
42 assert(config_.rtp.ssrc != 0);
43
44 network_ = ViENetwork::GetInterface(video_engine);
45 assert(network_ != NULL);
46
47 network_->RegisterSendTransport(channel_, *this);
48
49 codec_ = ViECodec::GetInterface(video_engine);
50
51 for (size_t i = 0; i < config_.codecs.size(); ++i) {
52 if (codec_->SetReceiveCodec(channel_, config_.codecs[i]) != 0) {
53 // TODO(pbos): Abort gracefully, this can be a runtime error.
54 // Factor out to an Init() method.
55 abort();
56 }
57 }
58
59 render_ = webrtc::ViERender::GetInterface(video_engine);
60 assert(render_ != NULL);
61
62 if (render_->AddRenderer(channel_, kVideoI420, this) != 0) {
63 abort();
64 }
65
66 clock_ = Clock::GetRealTimeClock();
67}
68
69VideoReceiveStream::~VideoReceiveStream() {
70 network_->DeregisterSendTransport(channel_);
71
72 video_engine_base_->Release();
73 codec_->Release();
74 network_->Release();
75 render_->Release();
76 rtp_rtcp_->Release();
77}
78
79void VideoReceiveStream::StartReceive() {
80 if (render_->StartRender(channel_)) {
81 abort();
82 }
83 if (video_engine_base_->StartReceive(channel_) != 0) {
84 abort();
85 }
86}
87
88void VideoReceiveStream::StopReceive() {
89 if (render_->StopRender(channel_)) {
90 abort();
91 }
92 if (video_engine_base_->StopReceive(channel_) != 0) {
93 abort();
94 }
95}
96
97void VideoReceiveStream::GetCurrentReceiveCodec(VideoCodec* receive_codec) {
98 // TODO(pbos): Implement
99}
100
pbos@webrtc.org29d58392013-05-16 12:08:03 +0000101bool VideoReceiveStream::DeliverRtcp(const void* packet, size_t length) {
102 return network_->ReceivedRTCPPacket(channel_, packet, length) == 0;
103}
104
105bool VideoReceiveStream::DeliverRtp(const void* packet, size_t length) {
106 return network_->ReceivedRTPPacket(channel_, packet, length) == 0;
107}
108
109int VideoReceiveStream::FrameSizeChange(unsigned int width, unsigned int height,
110 unsigned int /*number_of_streams*/) {
111 width_ = width;
112 height_ = height;
113 return 0;
114}
115
116int VideoReceiveStream::DeliverFrame(uint8_t* frame, int buffer_size,
117 uint32_t time_stamp, int64_t render_time) {
118 if (config_.renderer == NULL) {
119 return 0;
120 }
121
122 I420VideoFrame video_frame;
123 video_frame.CreateEmptyFrame(width_, height_, width_, height_, height_);
124 ConvertToI420(kI420, frame, 0, 0, width_, height_, buffer_size,
125 webrtc::kRotateNone, &video_frame);
126
127 if (config_.post_decode_callback != NULL) {
128 config_.post_decode_callback->FrameCallback(&video_frame);
129 }
130
131 if (config_.renderer != NULL) {
132 // TODO(pbos): Add timing to RenderFrame call
133 config_.renderer
134 ->RenderFrame(video_frame, render_time - clock_->TimeInMilliseconds());
135 }
136
137 return 0;
138}
139
140int VideoReceiveStream::SendPacket(int /*channel*/, const void* packet,
141 int length) {
142 assert(length >= 0);
143 return transport_->SendRTP(packet, static_cast<size_t>(length)) ? 0 : -1;
144}
145
146int VideoReceiveStream::SendRTCPPacket(int /*channel*/, const void* packet,
147 int length) {
148 assert(length >= 0);
149 return transport_->SendRTCP(packet, static_cast<size_t>(length)) ? 0 : -1;
150}
151} // internal
152} // webrtc