Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
9227c871
Commit
9227c871
authored
Nov 25, 2014
by
Francois Cartegnie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
stream_filter: dash: rewrite the http connection and remove double queuing
Ahead chunks now equals network-caching
parent
1afd4f37
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
341 additions
and
335 deletions
+341
-335
modules/stream_filter/dash/DASHDownloader.cpp
modules/stream_filter/dash/DASHDownloader.cpp
+2
-2
modules/stream_filter/dash/DASHDownloader.h
modules/stream_filter/dash/DASHDownloader.h
+0
-1
modules/stream_filter/dash/http/Chunk.cpp
modules/stream_filter/dash/http/Chunk.cpp
+3
-2
modules/stream_filter/dash/http/Chunk.h
modules/stream_filter/dash/http/Chunk.h
+4
-4
modules/stream_filter/dash/http/HTTPConnection.cpp
modules/stream_filter/dash/http/HTTPConnection.cpp
+51
-91
modules/stream_filter/dash/http/HTTPConnection.h
modules/stream_filter/dash/http/HTTPConnection.h
+13
-23
modules/stream_filter/dash/http/HTTPConnectionManager.cpp
modules/stream_filter/dash/http/HTTPConnectionManager.cpp
+68
-44
modules/stream_filter/dash/http/HTTPConnectionManager.h
modules/stream_filter/dash/http/HTTPConnectionManager.h
+4
-6
modules/stream_filter/dash/http/IHTTPConnection.cpp
modules/stream_filter/dash/http/IHTTPConnection.cpp
+112
-21
modules/stream_filter/dash/http/IHTTPConnection.h
modules/stream_filter/dash/http/IHTTPConnection.h
+21
-9
modules/stream_filter/dash/http/PersistentConnection.cpp
modules/stream_filter/dash/http/PersistentConnection.cpp
+50
-117
modules/stream_filter/dash/http/PersistentConnection.h
modules/stream_filter/dash/http/PersistentConnection.h
+11
-15
modules/stream_filter/dash/mpd/BasicCMParser.cpp
modules/stream_filter/dash/mpd/BasicCMParser.cpp
+1
-0
modules/stream_filter/dash/xml/DOMParser.cpp
modules/stream_filter/dash/xml/DOMParser.cpp
+1
-0
No files found.
modules/stream_filter/dash/DASHDownloader.cpp
View file @
9227c871
...
...
@@ -63,10 +63,10 @@ void* DASHDownloader::download (void *thread_sys)
do
{
block_t
*
block
=
NULL
;
ret
=
conManager
->
read
(
&
block
,
BLOCKSIZE
);
ret
=
conManager
->
read
(
&
block
);
if
(
ret
>
0
)
buffer
->
put
(
block
);
}
while
(
ret
&&
!
buffer
->
getEOF
());
}
while
(
ret
>
0
&&
!
buffer
->
getEOF
());
buffer
->
setEOF
(
true
);
...
...
modules/stream_filter/dash/DASHDownloader.h
View file @
9227c871
...
...
@@ -29,7 +29,6 @@
#include "adaptationlogic/IAdaptationLogic.h"
#include "buffer/BlockBuffer.h"
#define BLOCKSIZE 32768
#define CHUNKDEFAULTBITRATE 1
#include <iostream>
...
...
modules/stream_filter/dash/http/Chunk.cpp
View file @
9227c871
...
...
@@ -32,6 +32,7 @@ using namespace dash::http;
Chunk
::
Chunk
()
:
startByte
(
0
),
endByte
(
0
),
bitrate
(
1
),
port
(
0
),
isHostname
(
false
),
length
(
0
),
...
...
@@ -149,11 +150,11 @@ size_t Chunk::getPercentDownloaded () const
{
return
(
size_t
)(((
float
)
this
->
bytesRead
/
this
->
length
)
*
100
);
}
IHTTPConnection
*
Chunk
::
getConnection
()
const
HTTPConnection
*
Chunk
::
getConnection
()
const
{
return
this
->
connection
;
}
void
Chunk
::
setConnection
(
I
HTTPConnection
*
connection
)
void
Chunk
::
setConnection
(
HTTPConnection
*
connection
)
{
this
->
connection
=
connection
;
}
modules/stream_filter/dash/http/Chunk.h
View file @
9227c871
...
...
@@ -32,7 +32,7 @@
#include <vlc_common.h>
#include <vlc_url.h>
#include "
I
HTTPConnection.h"
#include "HTTPConnection.h"
#include <vector>
#include <string>
...
...
@@ -59,9 +59,9 @@ namespace dash
uint64_t
getBytesRead
()
const
;
uint64_t
getBytesToRead
()
const
;
size_t
getPercentDownloaded
()
const
;
IHTTPConnection
*
getConnection
()
const
;
HTTPConnection
*
getConnection
()
const
;
void
setConnection
(
I
HTTPConnection
*
connection
);
void
setConnection
(
HTTPConnection
*
connection
);
void
setBytesRead
(
uint64_t
bytes
);
void
setBytesToRead
(
uint64_t
bytes
);
void
setLength
(
uint64_t
length
);
...
...
@@ -88,7 +88,7 @@ namespace dash
uint64_t
length
;
uint64_t
bytesRead
;
uint64_t
bytesToRead
;
I
HTTPConnection
*
connection
;
HTTPConnection
*
connection
;
};
}
}
...
...
modules/stream_filter/dash/http/HTTPConnection.cpp
View file @
9227c871
...
...
@@ -26,128 +26,88 @@
#endif
#include "HTTPConnection.h"
#include
<vlc_network.h>
#include
"Chunk.h"
#include <sstream>
#include <vlc_stream.h>
using
namespace
dash
::
http
;
HTTPConnection
::
HTTPConnection
(
stream_t
*
stream
)
:
IHTTPConnection
(
stream
),
peekBufferLen
(
0
)
HTTPConnection
::
HTTPConnection
(
stream_t
*
stream
,
Chunk
*
chunk_
)
:
IHTTPConnection
(
stream
)
{
this
->
peekBuffer
=
new
uint8_t
[
PEEKBUFFER
];
toRead
=
0
;
chunk
=
NULL
;
bindChunk
(
chunk_
);
}
HTTPConnection
::~
HTTPConnection
()
std
::
string
HTTPConnection
::
buildRequestHeader
(
const
std
::
string
&
path
)
const
{
delete
[]
this
->
peekBuffer
;
this
->
closeSocket
(
);
std
::
string
req
=
IHTTPConnection
::
buildRequestHeader
(
path
)
;
return
req
.
append
(
"Connection: close
\r\n
"
);
}
int
HTTPConnection
::
read
(
void
*
p_buffer
,
size_t
len
)
void
HTTPConnection
::
bindChunk
(
Chunk
*
chunk_
)
{
if
(
this
->
peekBufferLen
==
0
)
if
(
chunk_
==
chunk
)
return
;
if
(
chunk_
)
{
ssize_t
size
=
net_Read
(
stream
,
httpSocket
,
NULL
,
p_buffer
,
len
,
false
);
if
(
size
<=
0
)
return
0
;
return
size
;
chunk_
->
setConnection
(
this
);
if
(
!
chunk
->
hasHostname
())
chunk
->
setUrl
(
getUrlRelative
(
chunk
));
}
memcpy
(
p_buffer
,
this
->
peekBuffer
,
this
->
peekBufferLen
);
int
ret
=
this
->
peekBufferLen
;
this
->
peekBufferLen
=
0
;
return
ret
;
}
int
HTTPConnection
::
peek
(
const
uint8_t
**
pp_peek
,
size_t
i_peek
)
{
if
(
this
->
peekBufferLen
==
0
)
this
->
peekBufferLen
=
this
->
read
(
this
->
peekBuffer
,
PEEKBUFFER
);
int
size
=
i_peek
>
this
->
peekBufferLen
?
this
->
peekBufferLen
:
i_peek
;
uint8_t
*
peek
=
new
uint8_t
[
size
];
memcpy
(
peek
,
this
->
peekBuffer
,
size
);
*
pp_peek
=
peek
;
return
size
;
chunk
=
chunk_
;
}
std
::
string
HTTPConnection
::
getRequestHeader
(
const
Chunk
*
chunk
)
const
void
HTTPConnection
::
releaseChunk
()
{
return
IHTTPConnection
::
getRequestHeader
(
chunk
)
.
append
(
"Connection: close
\r\n
"
);
}
bool
HTTPConnection
::
init
(
Chunk
*
chunk
)
{
if
(
IHTTPConnection
::
init
(
chunk
))
if
(
chunk
)
{
HeaderReply
reply
;
return
parseHeader
(
&
reply
)
;
chunk
->
setConnection
(
NULL
)
;
chunk
=
NULL
;
}
else
return
false
;
}
bool
HTTPConnection
::
parseHeader
(
HeaderReply
*
reply
)
void
HTTPConnection
::
onHeader
(
const
std
::
string
&
key
,
const
std
::
string
&
value
)
{
std
::
string
line
=
this
->
readLine
();
if
(
line
.
size
()
==
0
)
return
false
;
while
(
line
.
compare
(
"
\r\n
"
))
if
(
key
==
"Content-Length"
)
{
if
(
!
strncasecmp
(
line
.
c_str
(),
"Content-Length"
,
14
))
reply
->
contentLength
=
atoi
(
line
.
substr
(
15
,
line
.
size
()).
c_str
());
line
=
this
->
readLine
();
if
(
line
.
size
()
==
0
)
return
false
;
std
::
istringstream
ss
(
value
);
size_t
length
;
ss
>>
length
;
chunk
->
setLength
(
length
);
toRead
=
length
;
}
return
true
;
}
std
::
string
HTTPConnection
::
readLine
()
std
::
string
HTTPConnection
::
extraRequestHeaders
()
const
{
std
::
stringstream
ss
;
char
c
[
1
];
ssize_t
size
=
net_Read
(
stream
,
httpSocket
,
NULL
,
c
,
1
,
false
);
while
(
size
>=
0
)
if
(
chunk
->
usesByteRange
())
{
ss
<<
c
[
0
];
if
(
c
[
0
]
==
'\n'
)
break
;
size
=
net_Read
(
stream
,
httpSocket
,
NULL
,
c
,
1
,
false
);
ss
<<
"Range: bytes="
<<
chunk
->
getStartByte
()
<<
"-"
;
if
(
chunk
->
getEndByte
())
ss
<<
chunk
->
getEndByte
();
ss
<<
"
\r\n
"
;
}
if
(
size
>
0
)
return
ss
.
str
();
return
""
;
return
ss
.
str
();
}
bool
HTTPConnection
::
send
(
const
std
::
string
&
data
)
{
ssize_t
size
=
net_Write
(
this
->
stream
,
this
->
httpSocket
,
NULL
,
data
.
c_str
(),
data
.
size
());
if
(
size
==
-
1
)
{
return
false
;
}
if
((
size_t
)
size
!=
data
.
length
())
{
this
->
send
(
data
.
substr
(
size
,
data
.
size
()));
}
return
true
;
std
::
string
HTTPConnection
::
getUrlRelative
(
const
Chunk
*
chunk
)
const
{
std
::
stringstream
ss
;
ss
<<
stream
->
psz_access
<<
"://"
<<
Helper
::
combinePaths
(
Helper
::
getDirectoryPath
(
stream
->
psz_path
),
chunk
->
getUrl
());
return
ss
.
str
();
}
void
HTTPConnection
::
closeSocket
()
bool
HTTPConnection
::
isAvailable
()
const
{
if
(
httpSocket
>=
0
)
net_Close
(
httpSocket
);
return
chunk
==
NULL
;
}
void
HTTPConnection
::
disconnect
()
{
toRead
=
0
;
}
modules/stream_filter/dash/http/HTTPConnection.h
View file @
9227c871
...
...
@@ -28,41 +28,31 @@
#include <string>
#include "http/IHTTPConnection.h"
#include "http/Chunk.h"
#include "Helper.h"
#define PEEKBUFFER 4096
namespace
dash
{
namespace
http
{
class
Chunk
;
class
HTTPConnection
:
public
IHTTPConnection
{
public:
HTTPConnection
(
stream_t
*
stream
);
virtual
~
HTTPConnection
(
);
virtual
bool
init
(
Chunk
*
chunk
);
v
oid
closeSocket
()
;
virtual
int
read
(
void
*
p_buffer
,
size_t
len
);
virtual
int
peek
(
const
uint8_t
**
pp_peek
,
size_t
i_peek
);
HTTPConnection
(
stream_t
*
stream
,
Chunk
*
chunk
=
NULL
);
virtual
void
bindChunk
(
Chunk
*
chunk
);
virtual
void
onHeader
(
const
std
::
string
&
line
,
const
std
::
string
&
value
);
v
irtual
bool
isAvailable
()
const
;
virtual
void
disconnect
(
);
virtual
void
releaseChunk
(
);
protected:
size_t
toRead
;
Chunk
*
chunk
;
virtual
std
::
string
extraRequestHeaders
()
const
;
virtual
std
::
string
buildRequestHeader
(
const
std
::
string
&
path
)
const
;
class
HeaderReply
{
public:
int
contentLength
;
};
uint8_t
*
peekBuffer
;
size_t
peekBufferLen
;
virtual
bool
send
(
const
std
::
string
&
data
);
bool
parseHeader
(
HeaderReply
*
);
std
::
string
readLine
();
virtual
std
::
string
getRequestHeader
(
const
Chunk
*
chunk
)
const
;
/* reimpl */
std
::
string
getUrlRelative
(
const
Chunk
*
chunk
)
const
;
};
}
}
...
...
modules/stream_filter/dash/http/HTTPConnectionManager.cpp
View file @
9227c871
...
...
@@ -28,11 +28,13 @@
#include "HTTPConnectionManager.h"
#include "mpd/Segment.h"
#include <vlc_block.h>
#include <vlc_stream.h>
using
namespace
dash
::
http
;
using
namespace
dash
::
logic
;
const
size_t
HTTPConnectionManager
::
PIPELINE
=
80
;
const
size_t
HTTPConnectionManager
::
PIPELINELENGTH
=
2
;
const
uint64_t
HTTPConnectionManager
::
CHUNKDEFAULTBITRATE
=
1
;
HTTPConnectionManager
::
HTTPConnectionManager
(
IAdaptationLogic
*
adaptationLogic
,
stream_t
*
stream
)
:
...
...
@@ -58,52 +60,73 @@ void HTTPConnectionManager::closeAllConnections
vlc_delete_all
(
this
->
connectionPool
);
vlc_delete_all
(
this
->
downloadQueue
);
}
int
HTTPConnectionManager
::
read
(
block_t
**
pp_block
,
size_t
len
)
ssize_t
HTTPConnectionManager
::
read
(
block_t
**
pp_block
)
{
if
(
this
->
downloadQueue
.
size
()
==
0
)
if
(
!
this
->
addChunk
(
this
->
adaptationLogic
->
getNextChunk
()))
return
0
;
Chunk
*
chunk
;
if
(
this
->
downloadQueue
.
front
()
->
getPercentDownloaded
()
>
HTTPConnectionManager
::
PIPELINE
&&
this
->
downloadQueue
.
size
()
<
HTTPConnectionManager
::
PIPELINELENGTH
)
this
->
addChunk
(
this
->
adaptationLogic
->
getNextChunk
());
if
(
downloadQueue
.
empty
())
{
chunk
=
adaptationLogic
->
getNextChunk
();
if
(
!
connectChunk
(
chunk
))
return
-
1
;
else
downloadQueue
.
push_back
(
chunk
);
}
int
ret
=
0
;
chunk
=
downloadQueue
.
front
()
;
block_t
*
block
=
block_Alloc
(
len
);
if
(
chunk
->
getBytesRead
()
==
0
)
{
if
(
!
chunk
->
getConnection
()
->
query
(
chunk
->
getPath
()))
return
-
1
;
}
/* chunk length should be set at connect/query reply time */
size_t
readsize
=
chunk
->
getBytesToRead
();
if
(
readsize
>
128000
)
readsize
=
32768
;
block_t
*
block
=
block_Alloc
(
readsize
);
if
(
!
block
)
return
-
1
;
mtime_t
start
=
mdate
();
ret
=
this
->
downloadQueue
.
front
()
->
getConnection
()
->
read
(
block
->
p_buffer
,
block
->
i_buffer
);
mtime_t
end
=
mdate
()
;
mtime_t
time
=
mdate
();
ssize_t
ret
=
chunk
->
getConnection
()
->
read
(
block
->
p_buffer
,
readsize
);
time
=
mdate
()
-
time
;
block
->
i_length
=
(
mtime_t
)((
ret
*
8
)
/
((
float
)
this
->
downloadQueue
.
front
()
->
getBitrate
()
/
1000000
));
double
time
=
((
double
)(
end
-
start
))
/
1000000
;
block
->
i_length
=
(
mtime_t
)((
ret
*
8
)
/
((
float
)
chunk
->
getBitrate
()
/
CLOCK_FREQ
));
if
(
ret
<=
0
)
{
block_Release
(
block
);
*
pp_block
=
NULL
;
this
->
bpsLastChunk
=
this
->
bpsCurrentChunk
;
this
->
bytesReadChunk
=
0
;
this
->
timeChunk
=
0
;
delete
(
this
->
downloadQueue
.
front
()
);
this
->
downloadQueue
.
pop_front
();
delete
(
chunk
);
downloadQueue
.
pop_front
();
return
this
->
read
(
pp_block
,
len
);
return
read
(
pp_block
);
}
else
{
this
->
updateStatistics
(
ret
,
time
);
updateStatistics
((
size_t
)
ret
,
((
double
)
time
)
/
CLOCK_FREQ
);
block
->
i_buffer
=
ret
;
if
(
chunk
->
getBytesToRead
()
==
0
)
{
chunk
->
onDownload
(
block
->
p_buffer
,
block
->
i_buffer
);
delete
chunk
;
downloadQueue
.
pop_front
();
}
}
*
pp_block
=
block
;
return
ret
;
}
void
HTTPConnectionManager
::
attach
(
IDownloadRateObserver
*
observer
)
{
this
->
rateObservers
.
push_back
(
observer
);
...
...
@@ -115,17 +138,19 @@ void HTTPConnectionManager::notify
for
(
size_t
i
=
0
;
i
<
this
->
rateObservers
.
size
();
i
++
)
this
->
rateObservers
.
at
(
i
)
->
downloadRateChanged
(
this
->
bpsAvg
,
this
->
bpsLastChunk
);
}
std
::
vector
<
PersistentConnection
*>
HTTPConnectionManager
::
getConnectionsForHost
(
const
std
::
string
&
hostname
)
{
std
::
vector
<
PersistentConnection
*>
cons
;
for
(
size_t
i
=
0
;
i
<
this
->
connectionPool
.
size
();
i
++
)
if
(
!
this
->
connectionPool
.
at
(
i
)
->
getHostname
().
compare
(
hostname
)
||
!
this
->
connectionPool
.
at
(
i
)
->
isConnected
())
cons
.
push_back
(
this
->
connectionPool
.
at
(
i
));
return
cons
;
PersistentConnection
*
HTTPConnectionManager
::
getConnectionForHost
(
const
std
::
string
&
hostname
)
{
std
::
vector
<
PersistentConnection
*>::
const_iterator
it
;
for
(
it
=
connectionPool
.
begin
();
it
!=
connectionPool
.
end
();
it
++
)
{
if
(
!
(
*
it
)
->
getHostname
().
compare
(
hostname
))
return
*
it
;
}
return
NULL
;
}
void
HTTPConnectionManager
::
updateStatistics
(
int
bytes
,
double
time
)
void
HTTPConnectionManager
::
updateStatistics
(
size_t
bytes
,
double
time
)
{
this
->
bytesReadSession
+=
bytes
;
this
->
bytesReadChunk
+=
bytes
;
...
...
@@ -143,29 +168,28 @@ void HTTPConnectionManager::updateStatistics
this
->
notify
();
}
bool
HTTPConnectionManager
::
addChunk
(
Chunk
*
chunk
)
bool
HTTPConnectionManager
::
connectChunk
(
Chunk
*
chunk
)
{
if
(
chunk
==
NULL
)
return
false
;
this
->
downloadQueue
.
push_back
(
chunk
);
std
::
vector
<
PersistentConnection
*>
cons
=
this
->
getConnectionsForHost
(
chunk
->
getHostname
());
msg_Dbg
(
stream
,
"Retrieving %s"
,
chunk
->
getUrl
().
c_str
());
if
(
cons
.
size
()
==
0
)
PersistentConnection
*
conn
=
getConnectionForHost
(
chunk
->
getHostname
());
if
(
!
conn
)
{
PersistentConnection
*
con
=
new
PersistentConnection
(
this
->
stream
);
this
->
connectionPool
.
push_back
(
con
);
cons
.
push_back
(
con
);
conn
=
new
PersistentConnection
(
stream
,
chunk
);
if
(
!
conn
)
return
false
;
if
(
!
chunk
->
getConnection
()
->
connect
(
chunk
->
getHostname
(),
chunk
->
getPort
()))
return
false
;
connectionPool
.
push_back
(
conn
);
}
size_t
pos
=
this
->
chunkCount
%
cons
.
size
();
cons
.
at
(
pos
)
->
addChunk
(
chunk
);
chunk
->
setConnection
(
cons
.
at
(
pos
));
conn
->
bindChunk
(
chunk
);
this
->
chunkCount
++
;
chunkCount
++
;
if
(
chunk
->
getBitrate
()
<=
0
)
chunk
->
setBitrate
(
HTTPConnectionManager
::
CHUNKDEFAULTBITRATE
);
...
...
modules/stream_filter/dash/http/HTTPConnectionManager.h
View file @
9227c871
...
...
@@ -48,8 +48,7 @@ namespace dash
virtual
~
HTTPConnectionManager
();
void
closeAllConnections
();
bool
addChunk
(
Chunk
*
chunk
);
int
read
(
block_t
**
,
size_t
);
ssize_t
read
(
block_t
**
);
void
attach
(
dash
::
logic
::
IDownloadRateObserver
*
observer
);
void
notify
();
...
...
@@ -68,12 +67,11 @@ namespace dash
double
timeSession
;
double
timeChunk
;
static
const
size_t
PIPELINE
;
static
const
size_t
PIPELINELENGTH
;
static
const
uint64_t
CHUNKDEFAULTBITRATE
;
std
::
vector
<
PersistentConnection
*>
getConnectionsForHost
(
const
std
::
string
&
hostname
);
void
updateStatistics
(
int
bytes
,
double
time
);
bool
connectChunk
(
Chunk
*
chunk
);
PersistentConnection
*
getConnectionForHost
(
const
std
::
string
&
hostname
);
void
updateStatistics
(
size_t
bytes
,
double
time
);
};
}
...
...
modules/stream_filter/dash/http/IHTTPConnection.cpp
View file @
9227c871
...
...
@@ -24,6 +24,7 @@
#include "dash.hpp"
#include <vlc_network.h>
#include <vlc_stream.h>
#include <sstream>
...
...
@@ -37,45 +38,135 @@ IHTTPConnection::IHTTPConnection(stream_t *stream_)
IHTTPConnection
::~
IHTTPConnection
()
{
disconnect
();
}
bool
IHTTPConnection
::
init
(
Chunk
*
chunk
)
bool
IHTTPConnection
::
connect
(
const
std
::
string
&
hostname
,
int
port
)
{
if
(
chunk
==
NULL
)
httpSocket
=
net_ConnectTCP
(
stream
,
hostname
.
c_str
(),
port
);
this
->
hostname
=
hostname
;
if
(
httpSocket
==
-
1
)
return
false
;
if
(
!
chunk
->
hasHostname
())
return
true
;
}
bool
IHTTPConnection
::
connected
()
const
{
return
(
httpSocket
!=
-
1
);
}
void
IHTTPConnection
::
disconnect
()
{
if
(
httpSocket
>=
0
)
{
chunk
->
setUrl
(
getUrlRelative
(
chunk
));
if
(
!
chunk
->
hasHostname
())
return
false
;
net_Close
(
httpSocket
);
httpSocket
=
-
1
;
}
}
bool
IHTTPConnection
::
query
(
const
std
::
string
&
path
)
{
std
::
string
header
=
buildRequestHeader
(
path
);
header
.
append
(
"
\r\n
"
);
if
(
!
send
(
header
)
||
!
parseReply
())
return
false
;
return
true
;
}
httpSocket
=
net_ConnectTCP
(
stream
,
chunk
->
getHostname
().
c_str
(),
chunk
->
getPort
());
ssize_t
IHTTPConnection
::
read
(
void
*
p_buffer
,
size_t
len
)
{
ssize_t
size
=
net_Read
(
stream
,
httpSocket
,
NULL
,
p_buffer
,
len
,
true
);
if
(
size
<=
0
)
return
-
1
;
else
return
size
;
}
if
(
httpSocket
==
-
1
)
bool
IHTTPConnection
::
send
(
const
std
::
string
&
data
)
{
return
send
(
data
.
c_str
(),
data
.
length
());
}
bool
IHTTPConnection
::
send
(
const
void
*
buf
,
size_t
size
)
{
if
(
size
==
0
)
return
true
;
if
(
httpSocket
==
-
1
)
return
false
;
ssize_t
ret
=
net_Write
(
stream
,
httpSocket
,
NULL
,
buf
,
size
);
if
(
ret
<=
0
)
return
false
;
return
send
(
getRequestHeader
(
chunk
).
append
(
"
\r\n
"
));
if
(
(
size_t
)
ret
<
size
)
send
(
((
uint8_t
*
)
buf
)
+
ret
,
size
-
ret
);
return
true
;
}
std
::
string
IHTTPConnection
::
getRequestHeader
(
const
Chunk
*
chunk
)
const
bool
IHTTPConnection
::
parseReply
()
{
std
::
stringstream
req
;
req
<<
"GET "
<<
chunk
->
getPath
()
<<
" HTTP/1.1
\r\n
"
<<
"Host: "
<<
chunk
->
getHostname
()
<<
"
\r\n
"
<<
"User-Agent: "
<<
std
::
string
(
stream
->
p_sys
->
psz_useragent
)
<<
"
\r\n
"
;
std
::
string
line
=
readLine
();
if
(
chunk
->
usesByteRange
())
re
q
<<
"Range: bytes="
<<
chunk
->
getStartByte
()
<<
"-"
<<
chunk
->
getEndByte
()
<<
"
\r\n
"
;
if
(
line
.
empty
())
re
turn
false
;
return
req
.
str
();
if
(
line
.
compare
(
0
,
9
,
"HTTP/1.1 "
)
!=
0
)
return
false
;
std
::
istringstream
ss
(
line
.
substr
(
9
));
int
replycode
;
ss
>>
replycode
;
if
(
replycode
!=
200
&&
replycode
!=
206
)
return
false
;
readLine
();
while
(
!
line
.
empty
()
&&
line
.
compare
(
"
\r\n
"
))
{
size_t
split
=
line
.
find_first_of
(
':'
);
size_t
value
=
split
+
1
;
while
(
line
.
at
(
value
)
==
' '
)
value
++
;
onHeader
(
line
.
substr
(
0
,
split
),
line
.
substr
(
value
));
line
=
readLine
();
}
return
true
;
}
std
::
string
IHTTPConnection
::
getUrlRelative
(
const
Chunk
*
chunk
)
const
std
::
string
IHTTPConnection
::
readLine
()
{
std
::
stringstream
ss
;
ss
<<
stream
->
psz_access
<<
"://"
<<
Helper
::
combinePaths
(
Helper
::
getDirectoryPath
(
stream
->
psz_path
),
chunk
->
getUrl
());
return
ss
.
str
();
char
c
[
1
];
ssize_t
size
=
net_Read
(
stream
,
httpSocket
,
NULL
,
c
,
1
,
false
);
while
(
size
>=
0
)
{
ss
<<
c
[
0
];
if
(
c
[
0
]
==
'\n'
)
break
;
size
=
net_Read
(
stream
,
httpSocket
,
NULL
,
c
,
1
,
false
);
}
if
(
size
>
0
)
return
ss
.
str
();
return
""
;
}
std
::
string
IHTTPConnection
::
buildRequestHeader
(
const
std
::
string
&
path
)
const
{
std
::
stringstream
req
;
req
<<
"GET "
<<
path
<<
" HTTP/1.1
\r\n
"
<<
"Host: "
<<
hostname
<<
"
\r\n
"
<<
"User-Agent: "
<<
std
::
string
(
stream
->
p_sys
->
psz_useragent
)
<<
"
\r\n
"
;
req
<<
extraRequestHeaders
();
return
req
.
str
();
}
modules/stream_filter/dash/http/IHTTPConnection.h
View file @
9227c871
...
...
@@ -30,27 +30,39 @@
#endif
#include <vlc_common.h>
#include <vlc_stream.h>
#include <string>
namespace
dash
{
namespace
http
{
class
Chunk
;
class
IHTTPConnection
{
public:
IHTTPConnection
(
stream_t
*
stream
);
virtual
~
IHTTPConnection
();
virtual
bool
init
(
Chunk
*
chunk
);
virtual
bool
send
(
const
std
::
string
&
data
)
=
0
;
virtual
int
read
(
void
*
p_buffer
,
size_t
len
)
=
0
;
virtual
int
peek
(
const
uint8_t
**
pp_peek
,
size_t
i_peek
)
=
0
;
virtual
bool
connect
(
const
std
::
string
&
hostname
,
int
port
=
80
);
virtual
bool
connected
()
const
;
virtual
bool
query
(
const
std
::
string
&
path
);
virtual
bool
send
(
const
void
*
buf
,
size_t
size
);
virtual
ssize_t
read
(
void
*
p_buffer
,
size_t
len
);
virtual
void
disconnect
();
virtual
bool
send
(
const
std
::
string
&
data
);
protected:
virtual
std
::
string
getRequestHeader
(
const
Chunk
*
chunk
)
const
;
virtual
std
::
string
getUrlRelative
(
const
Chunk
*
chunk
)
const
;
stream_t
*
stream
;
virtual
void
onHeader
(
const
std
::
string
&
key
,
const
std
::
string
&
value
)
=
0
;
virtual
std
::
string
extraRequestHeaders
()
const
=
0
;
virtual
std
::
string
buildRequestHeader
(
const
std
::
string
&
path
)
const
;
bool
parseReply
();
std
::
string
readLine
();
std
::
string
hostname
;
stream_t
*
stream
;
private:
int
httpSocket
;
};
}
...
...
modules/stream_filter/dash/http/PersistentConnection.cpp
View file @
9227c871
...
...
@@ -26,164 +26,97 @@
#endif
#include "PersistentConnection.h"
#include "Chunk.h"
#include <vlc_network.h>
using
namespace
dash
::
http
;
const
int
PersistentConnection
::
RETRY
=
5
;
PersistentConnection
::
PersistentConnection
(
stream_t
*
stream
)
:
HTTPConnection
(
stream
),
isInit
(
false
)
{
}
PersistentConnection
::~
PersistentConnection
()
PersistentConnection
::
PersistentConnection
(
stream_t
*
stream
,
Chunk
*
chunk
)
:
HTTPConnection
(
stream
,
chunk
)
{
queryOk
=
false
;
retries
=
0
;
}
int
PersistentConnection
::
read
(
void
*
p_buffer
,
size_t
len
)
#include <cassert>
ssize_t
PersistentConnection
::
read
(
void
*
p_buffer
,
size_t
len
)
{
if
(
this
->
chunkQueue
.
size
()
==
0
)
if
(
!
chunk
)
return
-
1
;
Chunk
*
readChunk
=
this
->
chunkQueue
.
front
();
if
(
len
==
0
)
return
0
;
if
(
readChunk
->
getBytesRead
()
==
0
)
if
(
chunk
->
getBytesRead
()
==
0
&&
!
queryOk
)
{
if
(
!
this
->
initChunk
(
readChunk
))
{
this
->
chunkQueue
.
pop_front
();
if
(
!
query
(
chunk
->
getPath
()))
return
-
1
;
}
}
if
(
readChunk
->
getBytesToRead
()
==
0
)
{
this
->
chunkQueue
.
pop_front
();
assert
(
connected
()
&&
queryOk
);
if
(
chunk
->
getBytesToRead
()
==
0
)
return
0
;
}
int
ret
=
0
;
if
(
len
>
readChunk
->
getBytesToRead
())
ret
=
HTTPConnection
::
read
(
p_buffer
,
readChunk
->
getBytesToRead
());
else
ret
=
HTTPConnection
::
read
(
p_buffer
,
len
);
if
(
len
>
chunk
->
getBytesToRead
())
len
=
chunk
->
getBytesToRead
();
ssize_t
ret
=
IHTTPConnection
::
read
(
p_buffer
,
len
);
if
(
ret
<=
0
)
{
readChunk
->
setStartByte
(
readChunk
->
getStartByte
()
+
readChunk
->
getBytesRead
());
readChunk
->
setBytesRead
(
0
);
if
(
!
this
->
reconnect
(
readChunk
))
{
this
->
chunkQueue
.
pop_front
();
chunk
->
setStartByte
(
chunk
->
getStartByte
()
+
chunk
->
getBytesRead
());
chunk
->
setBytesRead
(
0
);
disconnect
();
if
(
retries
++
==
retryCount
||
!
query
(
chunk
->
getPath
()))
return
-
1
;
}
return
this
->
read
(
p_buffer
,
len
);
return
read
(
p_buffer
,
len
);
}
readChunk
->
setBytesRead
(
readChunk
->
getBytesRead
()
+
ret
);
retries
=
0
;
chunk
->
setBytesRead
(
chunk
->
getBytesRead
()
+
ret
);
return
ret
;
}
bool
PersistentConnection
::
init
(
Chunk
*
chunk
)
bool
PersistentConnection
::
query
(
const
std
::
string
&
path
)
{
if
(
isInit
)
return
true
;
if
(
IHTTPConnection
::
init
(
chunk
))
{
isInit
=
true
;
chunkQueue
.
push_back
(
chunk
);
hostname
=
chunk
->
getHostname
();
}
return
isInit
;
}
bool
PersistentConnection
::
addChunk
(
Chunk
*
chunk
)
{
if
(
chunk
==
NULL
)
return
false
;
if
(
!
this
->
isInit
)
return
this
->
init
(
chunk
);
if
(
!
chunk
->
hasHostname
())
{
chunk
->
setUrl
(
getUrlRelative
(
chunk
));
if
(
!
chunk
->
hasHostname
())
return
false
;
}
if
(
chunk
->
getHostname
().
compare
(
this
->
hostname
))
if
(
!
connected
()
&&
!
connect
(
chunk
->
getHostname
(),
chunk
->
getPort
()))
return
false
;
if
(
send
(
getRequestHeader
(
chunk
).
append
(
"
\r\n
"
)))
{
this
->
chunkQueue
.
push_back
(
chunk
);
return
true
;
}
return
false
;
queryOk
=
IHTTPConnection
::
query
(
path
);
return
queryOk
;
}
bool
PersistentConnection
::
initChunk
(
Chunk
*
chunk
)
{
HeaderReply
reply
;
if
(
parseHeader
(
&
reply
))
{
chunk
->
setLength
(
reply
.
contentLength
);
return
true
;
}
if
(
!
reconnect
(
chunk
))
return
false
;
if
(
parseHeader
(
&
reply
))
{
chunk
->
setLength
(
reply
.
contentLength
);
return
true
;
}
return
false
;
}
bool
PersistentConnection
::
reconnect
(
Chunk
*
chunk
)
bool
PersistentConnection
::
connect
(
const
std
::
string
&
hostname
,
int
port
)
{
int
count
=
0
;
std
::
string
request
=
getRequestHeader
(
chunk
).
append
(
"
\r\n
"
);
while
(
count
<
this
->
RETRY
)
{
this
->
httpSocket
=
net_ConnectTCP
(
this
->
stream
,
chunk
->
getHostname
().
c_str
(),
chunk
->
getPort
());
if
(
this
->
httpSocket
!=
-
1
)
if
(
this
->
resendAllRequests
())
return
true
;
count
++
;
}
return
false
;
assert
(
!
connected
());
assert
(
!
queryOk
);
return
IHTTPConnection
::
connect
(
hostname
,
port
);
}
const
std
::
string
&
PersistentConnection
::
getHostname
()
const
void
PersistentConnection
::
releaseChunk
()
{
return
this
->
hostname
;
if
(
!
chunk
)
return
;
if
(
toRead
>
0
&&
connected
())
/* We can't resend request if we haven't finished reading */
disconnect
();
HTTPConnection
::
releaseChunk
();
}
bool
PersistentConnection
::
isConnected
()
const
void
PersistentConnection
::
disconnect
()
{
return
this
->
isInit
;
queryOk
=
false
;
IHTTPConnection
::
disconnect
();
}
bool
PersistentConnection
::
resendAllRequests
()
{
for
(
size_t
i
=
0
;
i
<
chunkQueue
.
size
();
i
++
)
if
(
!
send
(
getRequestHeader
(
chunkQueue
.
at
(
i
)).
append
(
"
\r\n
"
)))
return
false
;
return
true
;
const
std
::
string
&
PersistentConnection
::
getHostname
()
const
{
return
hostname
;
}
std
::
string
PersistentConnection
::
getRequestHeader
(
const
Chunk
*
chunk
)
const
std
::
string
PersistentConnection
::
buildRequestHeader
(
const
std
::
string
&
path
)
const
{
/* can clearly see here that inheritance is reversed :/ */
return
IHTTPConnection
::
getRequestHeader
(
chunk
);
return
IHTTPConnection
::
buildRequestHeader
(
path
);
}
modules/stream_filter/dash/http/PersistentConnection.h
View file @
9227c871
...
...
@@ -35,27 +35,23 @@ namespace dash
class
PersistentConnection
:
public
HTTPConnection
{
public:
PersistentConnection
(
stream_t
*
stream
);
virtual
~
PersistentConnection
();
PersistentConnection
(
stream_t
*
stream
,
Chunk
*
chunk
=
NULL
);
virtual
bool
connect
(
const
std
::
string
&
hostname
,
int
port
=
80
);
virtual
bool
query
(
const
std
::
string
&
path
);
virtual
ssize_t
read
(
void
*
p_buffer
,
size_t
len
);
virtual
void
disconnect
();
virtual
void
releaseChunk
();
virtual
int
read
(
void
*
p_buffer
,
size_t
len
);
virtual
bool
init
(
Chunk
*
chunk
);
bool
addChunk
(
Chunk
*
chunk
);
const
std
::
string
&
getHostname
()
const
;
bool
isConnected
()
const
;
private:
std
::
deque
<
Chunk
*>
chunkQueue
;
bool
isInit
;
std
::
string
hostname
;
static
const
int
RETRY
;
bool
queryOk
;
int
retries
;
protected:
bool
initChunk
(
Chunk
*
chunk
);
bool
reconnect
(
Chunk
*
chunk
);
bool
resendAllRequests
();
virtual
std
::
string
getRequestHeader
(
const
Chunk
*
chunk
)
const
;
/* reimpl */
static
const
int
retryCount
=
5
;
virtual
std
::
string
buildRequestHeader
(
const
std
::
string
&
path
)
const
;
};
}
}
...
...
modules/stream_filter/dash/mpd/BasicCMParser.cpp
View file @
9227c871
...
...
@@ -36,6 +36,7 @@
#include <sstream>
#include <vlc_strings.h>
#include <vlc_stream.h>
using
namespace
dash
::
mpd
;
using
namespace
dash
::
xml
;
...
...
modules/stream_filter/dash/xml/DOMParser.cpp
View file @
9227c871
...
...
@@ -30,6 +30,7 @@
#include <vector>
#include <vlc_xml.h>
#include <vlc_stream.h>
using
namespace
dash
::
xml
;
using
namespace
dash
::
mpd
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment