2
* Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
3
* Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
4
* Author: Guillaume Roguez <Guillaume.Roguez@savoirfairelinux.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 3 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
* Additional permission under GNU GPL version 3 section 7:
22
* If you modify this program, or any covered work, by linking or
23
* combining it with the OpenSSL project's OpenSSL library (or a
24
* modified version of that library), containing parts covered by the
25
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
26
* grants you additional permission to convey the resulting work.
27
* Corresponding Source for a non-source form of such a combination
28
* shall include the source code for the parts of OpenSSL used as well
29
* as that of the covered work.
32
#include "video_sender.h"
33
#include "video_mixer.h"
34
#include "socket_pair.h"
35
#include "client/video_controls.h"
47
VideoSender::VideoSender(const std::string &id,
48
const std::map<string, string> &args,
49
SocketPair& socketPair) :
52
, muxContext_(socketPair.createIOContext())
53
, videoEncoder_(new VideoEncoder)
58
const char *enc_name = args_["codec"].c_str();
61
if (!args_["width"].empty()) {
62
const char *s = args_["width"].c_str();
63
videoEncoder_->setOption("width", s);
65
throw VideoSenderException("width option not set");
68
if (!args_["height"].empty()) {
69
const char *s = args_["height"].c_str();
70
videoEncoder_->setOption("height", s);
72
throw VideoSenderException("height option not set");
75
videoEncoder_->setOption("bitrate", args_["bitrate"].c_str());
77
if (!args_["framerate"].empty())
78
videoEncoder_->setOption("framerate", args_["framerate"].c_str());
80
if (!args_["parameters"].empty())
81
videoEncoder_->setOption("parameters", args_["parameters"].c_str());
83
if (!args_["payload_type"].empty()) {
84
DEBUG("Writing stream header for payload type %s",
85
args_["payload_type"].c_str());
86
videoEncoder_->setOption("payload_type", args_["payload_type"].c_str());
89
if (videoEncoder_->openOutput(enc_name, "rtp", args_["destination"].c_str(),
91
throw VideoSenderException("encoder openOutput() failed");
93
videoEncoder_->setIOContext(muxContext_);
94
if (videoEncoder_->startIO())
95
throw VideoSenderException("encoder start failed");
97
videoEncoder_->print_sdp(sdp_);
100
void VideoSender::encodeAndSendVideo(VideoFrame& input_frame)
102
bool is_keyframe = forceKeyFrame_ > 0;
107
if (videoEncoder_->encode(input_frame, is_keyframe, frameNumber_++) < 0)
108
ERROR("encoding failed");
111
void VideoSender::update(Observable<std::shared_ptr<VideoFrame> >* /*obs*/,
112
std::shared_ptr<VideoFrame> & frame_p)
114
encodeAndSendVideo(*frame_p);
117
void VideoSender::forceKeyFrame()
122
} // end namespace sfl_video