]> git.sesse.net Git - vlc/blob - modules/stream_filter/dash/http/HTTPConnectionManager.cpp
Added DASH stream filter
[vlc] / modules / stream_filter / dash / http / HTTPConnectionManager.cpp
1 /*
2  * HTTPConnectionManager.cpp
3  *****************************************************************************
4  * Copyright (C) 2010 - 2011 Klagenfurt University
5  *
6  * Created on: Aug 10, 2010
7  * Authors: Christopher Mueller <christopher.mueller@itec.uni-klu.ac.at>
8  *          Christian Timmerer  <christian.timmerer@itec.uni-klu.ac.at>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published
12  * by the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include "HTTPConnectionManager.h"
29
30 using namespace dash::http;
31 using namespace dash::logic;
32
33 HTTPConnectionManager::HTTPConnectionManager    (stream_t *stream)
34 {
35     this->timeSecSession    = 0;
36     this->bytesReadSession  = 0;
37     this->timeSecChunk      = 0;
38     this->bytesReadChunk    = 0;
39     this->bpsAvg            = 0;
40     this->bpsLastChunk      = 0;
41     this->chunkCount        = 0;
42     this->stream            = stream;
43 }
44 HTTPConnectionManager::~HTTPConnectionManager   ()
45 {
46     this->closeAllConnections();
47 }
48
49 IHTTPConnection*    HTTPConnectionManager::getConnection            (std::string url)
50 {
51     HTTPConnection *con = new HTTPConnection(url, this->stream);
52     con->init();
53     this->connections.push_back(con);
54     return con;
55 }
56 bool                HTTPConnectionManager::closeConnection          (IHTTPConnection *con)
57 {
58     for(std::vector<HTTPConnection *>::iterator it = this->connections.begin(); it != this->connections.end(); ++it)
59     {
60         if(*it == con)
61         {
62             (*it)->closeSocket();
63             delete(*it);
64             this->connections.erase(it);
65             return true;
66         }
67     }
68     return false;
69 }
70 bool                HTTPConnectionManager::closeConnection          (Chunk *chunk)
71 {
72     HTTPConnection *con = this->chunkMap[chunk];
73     bool ret = this->closeConnection(con);
74     this->chunkMap.erase(chunk);
75     delete(chunk);
76     return ret;
77 }
78 bool                HTTPConnectionManager::closeAllConnections      ()
79 {
80     for(std::vector<HTTPConnection *>::iterator it = this->connections.begin(); it != this->connections.end(); ++it)
81     {
82         (*it)->closeSocket();
83         delete(*it);
84     }
85     this->connections.clear();
86     this->urlMap.clear();
87
88     std::map<Chunk *, HTTPConnection *>::iterator it;
89
90     for(it = this->chunkMap.begin(); it != this->chunkMap.end(); ++it)
91     {
92         delete(it->first);
93     }
94
95     this->chunkMap.clear();
96 }
97 int                 HTTPConnectionManager::read                     (Chunk *chunk, void *p_buffer, size_t len)
98 {
99     if(this->chunkMap.find(chunk) != this->chunkMap.end())
100     {
101         mtime_t start = mdate();
102         int ret = this->chunkMap[chunk]->read(p_buffer, len);
103         mtime_t end = mdate();
104
105         double time = ((double)(end - start)) / 1000000;
106
107         this->bytesReadSession += ret;
108         this->bytesReadChunk   += ret;
109         this->timeSecSession   += time;
110         this->timeSecChunk     += time;
111
112
113         if(this->timeSecSession > 0)
114             this->bpsAvg = (this->bytesReadSession / this->timeSecSession) * 8;
115
116         if(this->timeSecChunk > 0)
117             this->bpsLastChunk = (this->bytesReadChunk / this->timeSecChunk) * 8;
118
119         if(this->bpsAvg < 0 || this->chunkCount < 2)
120             this->bpsAvg = 0;
121
122         if(this->bpsLastChunk < 0 || this->chunkCount < 2)
123             this->bpsLastChunk = 0;
124
125         this->notify();
126
127         if(ret <= 0)
128             this->closeConnection(chunk);
129
130         return ret;
131     }
132     else
133     {
134         this->bytesReadChunk    = 0;
135         this->timeSecChunk      = 0;
136
137         HTTPConnection *con = this->initConnection(chunk);
138         return this->read(chunk, p_buffer, len);
139     }
140 }
141 int                 HTTPConnectionManager::peek                     (Chunk *chunk, const uint8_t **pp_peek, size_t i_peek)
142 {
143     if(this->chunkMap.find(chunk) != this->chunkMap.end())
144         return this->chunkMap[chunk]->peek(pp_peek, i_peek);
145
146     HTTPConnection *con = this->initConnection(chunk);
147     return this->peek(chunk, pp_peek, i_peek);
148 }
149 HTTPConnection*     HTTPConnectionManager::initConnection           (Chunk *chunk)
150 {
151     HTTPConnection *con = new HTTPConnection(chunk->getUrl(), this->stream);
152     con->init();
153     this->connections.push_back(con);
154     this->chunkMap[chunk] = con;
155     this->chunkCount++;
156     return con;
157 }
158 void                HTTPConnectionManager::attach                   (IDownloadRateObserver *observer)
159 {
160     this->rateObservers.push_back(observer);
161 }
162 void                HTTPConnectionManager::notify                   ()
163 {
164     for(int i = 0; i < this->rateObservers.size(); i++)
165         this->rateObservers.at(i)->downloadRateChanged(this->bpsAvg, this->bpsLastChunk);
166 }