FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
data_uri.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2012 Nicolas George
3
*
4
* This file is part of FFmpeg.
5
*
6
* FFmpeg is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public License
8
* as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* FFmpeg 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 Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
#include <string.h>
22
#include "
libavutil/avstring.h
"
23
#include "
libavutil/base64.h
"
24
#include "
url.h
"
25
26
typedef
struct
{
27
const
uint8_t
*
data
;
28
void
*
tofree
;
29
size_t
size
;
30
size_t
pos
;
31
}
DataContext
;
32
33
static
av_cold
int
data_open
(
URLContext
*h,
const
char
*uri,
int
flags
)
34
{
35
DataContext
*
dc
= h->
priv_data
;
36
const
char
*
data
, *opt, *next;
37
char
*ddata;
38
int
ret
, base64 = 0;
39
size_t
in_size;
40
41
/* data:content/type[;base64],payload */
42
43
av_strstart
(uri,
"data:"
, &uri);
44
data = strchr(uri,
','
);
45
if
(!data) {
46
av_log
(h,
AV_LOG_ERROR
,
"No ',' delimiter in URI\n"
);
47
return
AVERROR
(EINVAL);
48
}
49
opt = uri;
50
while
(opt < data) {
51
next =
av_x_if_null
(memchr(opt,
';'
, data - opt), data);
52
if
(opt == uri) {
53
if
(!memchr(opt,
'/'
, next - opt)) {
/* basic validity check */
54
av_log
(h,
AV_LOG_ERROR
,
"Invalid content-type '%.*s'\n"
,
55
(
int
)(next - opt), opt);
56
return
AVERROR
(EINVAL);
57
}
58
av_log
(h,
AV_LOG_VERBOSE
,
"Content-type: %.*s\n"
,
59
(
int
)(next - opt), opt);
60
}
else
{
61
if
(!
av_strncasecmp
(opt,
"base64"
, next - opt)) {
62
base64 = 1;
63
}
else
{
64
av_log
(h,
AV_LOG_VERBOSE
,
"Ignoring option '%.*s'\n"
,
65
(
int
)(next - opt), opt);
66
}
67
}
68
opt = next + 1;
69
}
70
71
data++;
72
in_size = strlen(data);
73
if
(base64) {
74
size_t
out_size = 3 * (in_size / 4) + 1;
75
76
if
(out_size > INT_MAX || !(ddata =
av_malloc
(out_size)))
77
return
AVERROR
(ENOMEM);
78
if
((ret =
av_base64_decode
(ddata, data, out_size)) < 0) {
79
av_free
(ddata);
80
av_log
(h,
AV_LOG_ERROR
,
"Invalid base64 in URI\n"
);
81
return
ret
;
82
}
83
dc->
data
= dc->
tofree
= ddata;
84
dc->
size
=
ret
;
85
}
else
{
86
dc->
data
=
data
;
87
dc->
size
= in_size;
88
}
89
return
0;
90
}
91
92
static
av_cold
int
data_close
(
URLContext
*h)
93
{
94
DataContext
*
dc
= h->
priv_data
;
95
96
av_freep
(&dc->
tofree
);
97
return
0;
98
}
99
100
static
int
data_read
(
URLContext
*h,
unsigned
char
*
buf
,
int
size
)
101
{
102
DataContext
*
dc
= h->
priv_data
;
103
104
if
(dc->
pos
>= dc->
size
)
105
return
AVERROR_EOF
;
106
size =
FFMIN
(size, dc->
size
- dc->
pos
);
107
memcpy(buf, dc->
data
+ dc->
pos
, size);
108
dc->
pos
+=
size
;
109
return
size
;
110
}
111
112
URLProtocol
ff_data_protocol
= {
113
.
name
=
"data"
,
114
.url_open =
data_open
,
115
.url_close =
data_close
,
116
.url_read =
data_read
,
117
.priv_data_size =
sizeof
(
DataContext
),
118
};
Generated on Sat Jan 25 2014 19:52:02 for FFmpeg by
1.8.2