Rtsp.cpp 4.69 KB
Newer Older
xiongziliang committed
1
/*
xiongziliang committed
2
 * MIT License
xzl committed
3
 *
xiongziliang committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * Copyright (c) 2016 xiongziliang <771730766@qq.com>
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
xzl committed
25 26 27
 */

#include <stdlib.h>
xiongzilaing committed
28 29
#include "Rtsp.h"

xiongziliang committed
30 31
namespace mediakit{

xzl committed
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
string FindField(const char* buf, const char* start, const char *end ,int bufSize) {
	if(bufSize <=0 ){
		bufSize = strlen(buf);
	}
	const char *msg_start = buf, *msg_end = buf + bufSize;
	int len = 0;
	if (start != NULL) {
		len = strlen(start);
		msg_start = strstr(buf, start);
	}
	if (msg_start == NULL) {
		return "";
	}
	msg_start += len;
	if (end != NULL) {
		msg_end = strstr(msg_start, end);
		if (msg_end == NULL) {
			return "";
		}
	}
	return string(msg_start, msg_end);
}
54 55 56 57 58 59


void SdpAttr::load(const string &sdp) {
	_track_map.clear();
	string key;
	SdpTrack::Ptr track = std::make_shared<SdpTrack>();
xiongziliang committed
60 61 62 63

	auto lines = split(sdp,"\n");
	for (auto &line : lines){
		trim(line);
64
		if(line.size() < 2 || line[1] != '='){
xiongziliang committed
65 66 67 68 69 70
			continue;
		}
		char opt = line[0];
		string opt_val = line.substr(2);
		switch (opt){
			case 'o':
71 72
				track->_o = opt_val;
				break;
xiongziliang committed
73
			case 's':
74 75
				track->_s = opt_val;
				break;
xiongziliang committed
76
			case 'i':
77 78
				track->_i = opt_val;
				break;
xiongziliang committed
79
			case 'c':
80 81 82 83 84 85 86
				track->_c = opt_val;
				break;
			case 't':
				track->_t = opt_val;
				break;
			case 'b':
				track->_b = opt_val;
xiongziliang committed
87 88
				break;
			case 'm':{
89 90 91 92
				_track_map[key] = track;
				track = std::make_shared<SdpTrack>();
				key = FindField(opt_val.data(), nullptr," ");;
				track->_m = opt_val;
xiongziliang committed
93 94 95 96 97
			}
				break;
			case 'a':{
				string attr = FindField(opt_val.data(), nullptr,":");
				if(attr.empty()){
98
					track->_attr[opt_val] = "";
xiongziliang committed
99
				}else{
100
					track->_attr[attr] = FindField(opt_val.data(),":", nullptr);
xiongziliang committed
101 102 103 104
				}
			}
				break;
			default:
105
				track->_other[opt] = opt_val;
xiongziliang committed
106 107 108
				break;
		}
	}
109 110
	_track_map[key] = track;

xiongziliang committed
111

112 113 114
	for (auto &pr : _track_map) {
		auto &track = *pr.second;
		if (pr.first == "") {
115
			track._type = TrackTitle;
116
		} else if (pr.first == "video") {
117
			track._type = TrackVideo;
xiongziliang committed
118
		} else if (pr.first == "audio") {
119
			track._type = TrackAudio;
120
		} else {
121
			track._type = TrackInvalid;
122
		}
xiongziliang committed
123

124 125 126 127 128 129 130 131 132 133 134
		auto it = track._attr.find("range");
		if (it != track._attr.end()) {
			char name[16] = {0}, start[16] = {0}, end[16] = {0};
			int ret = sscanf(it->second.data(), "%15[^=]=%15[^-]-%15s", name, start, end);
			if (3 == ret || 2 == ret) {
				if (strcmp(start, "now") == 0) {
					strcpy(start, "0");
				}
				track._start = atof(start);
				track._end = atof(end);
				track._duration = track._end - track._start;
xiongziliang committed
135 136 137
			}
		}

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
		it = track._attr.find("rtpmap");
		if(it != track._attr.end()){
			auto rtpmap = it->second;
			int pt, samplerate;
			char codec[16] = {0};
			if (3 == sscanf(rtpmap.data(), "%d %15[^/]/%d", &pt, codec, &samplerate)) {
				track._pt = pt;
				track._codec = codec;
				track._samplerate = samplerate;
			}
		}

		it = track._attr.find("fmtp");
		if(it != track._attr.end()) {
			track._fmtp = it->second;
		}
xiongziliang committed
154

155 156 157
		it = track._attr.find("control");
		if(it != track._attr.end()) {
			track._control = it->second;
xiongziliang committed
158 159
			auto surffix = string("/") + track._control;
			track._control_surffix = surffix.substr(1 + surffix.rfind('/'));
xiongziliang committed
160 161
		}
	}
162
}
xiongziliang committed
163

xiongziliang committed
164 165 166 167 168
bool SdpAttr::available() const {
    return getTrack(TrackAudio) || getTrack(TrackVideo);
}

SdpTrack::Ptr SdpAttr::getTrack(TrackType type) const {
169
	for (auto &pr : _track_map){
170
		if(pr.second->_type == type){
171 172 173 174 175
			return pr.second;
		}
	}
	return nullptr;
}
xiongziliang committed
176

xiongziliang committed
177 178 179 180 181
vector<SdpTrack::Ptr> SdpAttr::getAvailableTrack() const {
	vector<SdpTrack::Ptr> ret;
	auto video = getTrack(TrackVideo);
	if(video){
		ret.emplace_back(video);
xzl committed
182
	}
xiongziliang committed
183 184 185 186 187
	auto audio = getTrack(TrackAudio);
	if(audio){
		ret.emplace_back(audio);
	}
	return ret;
xzl committed
188
}
xiongziliang committed
189

xiongziliang committed
190
}//namespace mediakit
191