video_rtp_session.cpp 4.79 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
 *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
 *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
 */

#include "video_rtp_session.h"
32
33
#include <sstream>
#include <map>
34
#include <string>
35
36
#include "video_send_thread.h"
#include "video_receive_thread.h"
37
#include "sip/sdp.h"
38
#include "sip/sipvoiplink.h"
39
#include "manager.h"
Tristan Matthews's avatar
Tristan Matthews committed
40
#include "logger.h"
41
42

namespace sfl_video {
43

44
45
46
using std::map;
using std::string;

47
VideoRtpSession::VideoRtpSession(const string &callID, const map<string, string> &txArgs) :
48
    sendThread_(), receiveThread_(), txArgs_(txArgs),
49
    rxArgs_(), sending_(false), receiving_(false), callID_(callID)
50
{}
51

52
void VideoRtpSession::updateSDP(const Sdp &sdp)
53
{
54
    string desc(sdp.getIncomingVideoDescription());
55
    // if port has changed
56
    if (desc != rxArgs_["receiving_sdp"]) {
57
        rxArgs_["receiving_sdp"] = desc;
58
        DEBUG("Updated incoming SDP to:\n %s",
59
              rxArgs_["receiving_sdp"].c_str());
60
    }
61

62
    if (desc.find("sendrecv") != string::npos) {
63
        DEBUG("Sending and receiving video");
64
65
        receiving_ = true;
        sending_ = true;
66
    } else if (desc.find("inactive") != string::npos) {
67
        DEBUG("Video is inactive");
68
        receiving_ = false;
69
        sending_ = false;
70
    } else if (desc.find("sendonly") != string::npos) {
71
        DEBUG("Receiving video disabled, video set to sendonly");
72
73
        receiving_ = false;
        sending_ = true;
74
    } else if (desc.find("recvonly") != string::npos) {
75
        DEBUG("Sending video disabled, video set to recvonly");
76
77
78
        sending_ = false;
        receiving_ = true;
    }
79
80
    // even if it says sendrecv or recvonly, our peer may disable video by
    // setting the port to 0
81
    if (desc.find("m=video 0") != string::npos) {
82
        DEBUG("Receiving video disabled, port was set to 0");
83
84
        receiving_ = false;
    }
85

86
87
    if (sending_)
        sending_ = sdp.getOutgoingVideoSettings(txArgs_);
88
89
}

90
91
void VideoRtpSession::updateDestination(const string &destination,
                                        unsigned int port)
92
{
93
94
95
96
    if (destination.empty()) {
        ERROR("Destination is empty, ignoring");
        return;
    }
97
98

    std::stringstream tmp;
99
    tmp << "rtp://" << destination << ":" << port;
100
    // if destination has changed
101
    if (tmp.str() != txArgs_["destination"]) {
102
103
104
105
        if (sendThread_.get() != 0) {
            ERROR("Video is already being sent");
            return;
        }
106
        txArgs_["destination"] = tmp.str();
107
        DEBUG("updated dest to %s",  txArgs_["destination"].c_str());
108
    }
109

110
    if (port == 0) {
111
        DEBUG("Sending video disabled, port was set to 0");
112
113
        sending_ = false;
    }
114
115
}

Tristan Matthews's avatar
Tristan Matthews committed
116
void VideoRtpSession::start()
117
{
118
    if (sending_) {
119
        if (sendThread_.get())
120
            WARN("Restarting video sender");
121
122
        sendThread_.reset(new VideoSendThread(txArgs_));
        sendThread_->start();
123
    } else {
124
        DEBUG("Video sending disabled");
125
        sendThread_.reset();
126
    }
127

128
    if (receiving_) {
129
130
131
132
133
134
        if (receiveThread_.get())
            WARN("restarting video receiver");
        receiveThread_.reset(new VideoReceiveThread(callID_, rxArgs_));
        receiveThread_->setRequestKeyFrameCallback(&SIPVoIPLink::requestFastPictureUpdate);
        receiveThread_->start();
    } else {
135
        DEBUG("Video receiving disabled");
136
        receiveThread_.reset();
137
    }
138
139
}

140
void VideoRtpSession::stop()
141
{
142
143
    receiveThread_.reset();
    sendThread_.reset();
144
}
145

146
147
148
149
150
void VideoRtpSession::forceKeyFrame()
{
    sendThread_->forceKeyFrame();
}

151
} // end namespace sfl_video